Page MenuHomeFreeBSD

D32101.diff
No OneTemporary

D32101.diff

Index: sys/crypto/openssl/ossl.h
===================================================================
--- sys/crypto/openssl/ossl.h
+++ sys/crypto/openssl/ossl.h
@@ -73,5 +73,6 @@
extern struct auth_hash ossl_hash_sha512;
extern struct ossl_cipher ossl_cipher_aes_cbc;
+extern struct ossl_cipher ossl_cipher_chacha20;
#endif /* !__OSSL_H__ */
Index: sys/crypto/openssl/ossl.c
===================================================================
--- sys/crypto/openssl/ossl.c
+++ sys/crypto/openssl/ossl.c
@@ -157,6 +157,9 @@
case CRYPTO_AES_CBC:
cipher = &ossl_cipher_aes_cbc;
break;
+ case CRYPTO_CHACHA20:
+ cipher = &ossl_cipher_chacha20;
+ break;
default:
return (NULL);
}
@@ -182,15 +185,9 @@
return (EINVAL);
break;
case CSP_MODE_CIPHER:
- switch (csp->csp_cipher_alg) {
- case CRYPTO_CHACHA20:
- if (csp->csp_cipher_klen != CHACHA_KEY_SIZE)
- return (EINVAL);
- break;
- default:
- if (!sc->has_aes || ossl_lookup_cipher(csp) == NULL)
- return (EINVAL);
- }
+ if ((!sc->has_aes && csp->csp_cipher_alg != CRYPTO_CHACHA20) ||
+ ossl_lookup_cipher(csp) == NULL)
+ return (EINVAL);
break;
case CSP_MODE_ETA:
if ((!sc->has_aes && csp->csp_cipher_alg != CRYPTO_CHACHA20) ||
@@ -253,9 +250,6 @@
struct ossl_cipher *cipher;
int error;
- if (csp->csp_cipher_alg == CRYPTO_CHACHA20)
- return (0);
-
cipher = ossl_lookup_cipher(csp);
if (cipher == NULL)
return (EINVAL);
@@ -389,10 +383,6 @@
int blocklen, error;
bool encrypt;
- /* CHACHA20 is handled separately for now. */
- if (csp->csp_cipher_alg == CRYPTO_CHACHA20)
- return (ossl_chacha20(crp, csp));
-
cipher = s->cipher.cipher;
encrypt = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
plen = crp->crp_payload_length;
Index: sys/crypto/openssl/ossl_chacha20.c
===================================================================
--- sys/crypto/openssl/ossl_chacha20.c
+++ sys/crypto/openssl/ossl_chacha20.c
@@ -36,62 +36,71 @@
#include <opencrypto/cryptodev.h>
#include <crypto/openssl/ossl.h>
+#include <crypto/openssl/ossl_cipher.h>
#include <crypto/openssl/ossl_chacha.h>
#include <crypto/openssl/ossl_poly1305.h>
+ossl_cipher_setkey_t ossl_chacha20_setkey;
+ossl_cipher_setkey_t ossl_chacha20_setiv;
+ossl_cipher_encrypt_t ossl_chacha20_encrypt;
+
+struct ossl_cipher ossl_cipher_chacha20 = {
+ .type = CRYPTO_CHACHA20,
+ .minkeysize = CHACHA_KEY_SIZE,
+ .maxkeysize = CHACHA_KEY_SIZE,
+ .blocksize = CHACHA_BLK_SIZE,
+ .ivsize = CHACHA_CTR_SIZE,
+ .stream_cipher = true,
+
+ .set_encrypt_key = ossl_chacha20_setkey,
+ .set_decrypt_key = ossl_chacha20_setkey,
+ .set_iv = ossl_chacha20_setiv,
+ .encrypt = ossl_chacha20_encrypt
+};
+
int
-ossl_chacha20(struct cryptop *crp, const struct crypto_session_params *csp)
+ossl_chacha20_setiv(const unsigned char *in, int size, void *out)
{
- _Alignas(8) unsigned int key[CHACHA_KEY_SIZE / 4];
- unsigned int counter[CHACHA_CTR_SIZE / 4];
- unsigned char block[CHACHA_BLK_SIZE];
- struct crypto_buffer_cursor cc_in, cc_out;
- const unsigned char *in, *inseg, *cipher_key;
- unsigned char *out, *outseg;
- size_t resid, todo, inlen, outlen;
- uint32_t next_counter;
- u_int i;
+ const unsigned int *user_counter;
+ unsigned int *counter;
+ int i;
- if (crp->crp_cipher_key != NULL)
- cipher_key = crp->crp_cipher_key;
- else
- cipher_key = csp->csp_cipher_key;
- for (i = 0; i < nitems(key); i++)
- key[i] = CHACHA_U8TOU32(cipher_key + i * 4);
- crypto_read_iv(crp, counter);
- for (i = 0; i < nitems(counter); i++)
- counter[i] = le32toh(counter[i]);
+ user_counter = (const unsigned int *)in;
+ counter = (unsigned int *)out;
- resid = crp->crp_payload_length;
- crypto_cursor_init(&cc_in, &crp->crp_buf);
- crypto_cursor_advance(&cc_in, crp->crp_payload_start);
- inseg = crypto_cursor_segment(&cc_in, &inlen);
- if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
- crypto_cursor_init(&cc_out, &crp->crp_obuf);
- crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
- } else
- cc_out = cc_in;
- outseg = crypto_cursor_segment(&cc_out, &outlen);
- while (resid >= CHACHA_BLK_SIZE) {
- if (inlen < CHACHA_BLK_SIZE) {
- crypto_cursor_copydata(&cc_in, CHACHA_BLK_SIZE, block);
- in = block;
- inlen = CHACHA_BLK_SIZE;
- } else
- in = inseg;
- if (outlen < CHACHA_BLK_SIZE) {
- out = block;
- outlen = CHACHA_BLK_SIZE;
- } else
- out = outseg;
+ for (i = 0; i < size / sizeof(unsigned int); i++)
+ counter[i] = le32toh(user_counter[i]);
- /* Figure out how many blocks we can encrypt/decrypt at once. */
- todo = rounddown(MIN(resid, MIN(inlen, outlen)),
- CHACHA_BLK_SIZE);
+ return (0);
+}
+
+int
+ossl_chacha20_setkey(const unsigned char *in, int size, void *out)
+{
+ int i;
+ uint32_t *key = (uint32_t *)out;
+
+ for (i = 0; i < CHACHA_KEY_SIZE / 4; i++)
+ key[i] = CHACHA_U8TOU32(in + i * 4);
+
+ return (0);
+}
+
+void
+ossl_chacha20_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+ const void *key, unsigned char *iv, int encrypt)
+{
+ unsigned int *counter = (unsigned int *) iv;
+ uint32_t next_counter;
+ size_t todo;
+
+ while (length > 0) {
#ifdef __LP64__
/* ChaCha20_ctr32() assumes length is <= 4GB. */
- todo = (uint32_t)todo;
+ todo = (uint32_t)length;
+#else
+ todo = length;
#endif
/* Truncate if the 32-bit counter would roll over. */
@@ -107,35 +116,8 @@
if (counter[0] == 0)
counter[1]++;
- if (out == block) {
- crypto_cursor_copyback(&cc_out, CHACHA_BLK_SIZE, block);
- outseg = crypto_cursor_segment(&cc_out, &outlen);
- } else {
- crypto_cursor_advance(&cc_out, todo);
- outseg += todo;
- outlen -= todo;
- }
- if (in == block) {
- inseg = crypto_cursor_segment(&cc_in, &inlen);
- } else {
- crypto_cursor_advance(&cc_in, todo);
- inseg += todo;
- inlen -= todo;
- }
- resid -= todo;
+ length -= todo;
}
-
- if (resid > 0) {
- memset(block, 0, sizeof(block));
- crypto_cursor_copydata(&cc_in, resid, block);
- ChaCha20_ctr32(block, block, CHACHA_BLK_SIZE, key, counter);
- crypto_cursor_copyback(&cc_out, resid, block);
- }
-
- explicit_bzero(block, sizeof(block));
- explicit_bzero(counter, sizeof(counter));
- explicit_bzero(key, sizeof(key));
- return (0);
}
int
@@ -436,3 +418,6 @@
explicit_bzero(key, sizeof(key));
return (error);
}
+
+_Static_assert(CHACHA_KEY_SIZE <= sizeof(struct ossl_context),
+ "ossl_context too small");

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 7:18 PM (21 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12691524
Default Alt Text
D32101.diff (6 KB)

Event Timeline