crypto: Re-add encrypt/decrypt_multi hooks to enc_xform.
These callbacks allow multiple contiguous blocks to be manipulated in a single call. Note that any trailing partial block for a stream cipher must still be passed to encrypt/decrypt_last. While here, document the setkey and reinit hooks and reorder the hooks in 'struct enc_xform' to better reflect the life cycle. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33529
This commit is contained in:
parent
8f35841f1f
commit
d7f0b3ce6d
@ -32,6 +32,14 @@ chacha20_xform_crypt(void *ctx, const uint8_t *in, uint8_t *out)
|
|||||||
chacha_encrypt_bytes(ctx, in, out, CHACHA_BLOCKLEN);
|
chacha_encrypt_bytes(ctx, in, out, CHACHA_BLOCKLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chacha20_xform_crypt_multi(void *ctx, const uint8_t *in, uint8_t *out,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
KASSERT(len % CHACHA_BLOCKLEN == 0, ("%s: invalid length", __func__));
|
||||||
|
chacha_encrypt_bytes(ctx, in, out, len);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chacha20_xform_crypt_last(void *ctx, const uint8_t *in, uint8_t *out,
|
chacha20_xform_crypt_last(void *ctx, const uint8_t *in, uint8_t *out,
|
||||||
size_t len)
|
size_t len)
|
||||||
@ -49,10 +57,12 @@ const struct enc_xform enc_xform_chacha20 = {
|
|||||||
.ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN,
|
.ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN,
|
||||||
.minkey = CHACHA_MINKEYLEN,
|
.minkey = CHACHA_MINKEYLEN,
|
||||||
.maxkey = 32,
|
.maxkey = 32,
|
||||||
.encrypt = chacha20_xform_crypt,
|
|
||||||
.decrypt = chacha20_xform_crypt,
|
|
||||||
.setkey = chacha20_xform_setkey,
|
.setkey = chacha20_xform_setkey,
|
||||||
.reinit = chacha20_xform_reinit,
|
.reinit = chacha20_xform_reinit,
|
||||||
|
.encrypt = chacha20_xform_crypt,
|
||||||
|
.decrypt = chacha20_xform_crypt,
|
||||||
|
.encrypt_multi = chacha20_xform_crypt_multi,
|
||||||
|
.decrypt_multi = chacha20_xform_crypt_multi,
|
||||||
.encrypt_last = chacha20_xform_crypt_last,
|
.encrypt_last = chacha20_xform_crypt_last,
|
||||||
.decrypt_last = chacha20_xform_crypt_last,
|
.decrypt_last = chacha20_xform_crypt_last,
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,8 @@ struct aes_cbc_ctx {
|
|||||||
static int aes_cbc_setkey(void *, const uint8_t *, int);
|
static int aes_cbc_setkey(void *, const uint8_t *, int);
|
||||||
static void aes_cbc_encrypt(void *, const uint8_t *, uint8_t *);
|
static void aes_cbc_encrypt(void *, const uint8_t *, uint8_t *);
|
||||||
static void aes_cbc_decrypt(void *, const uint8_t *, uint8_t *);
|
static void aes_cbc_decrypt(void *, const uint8_t *, uint8_t *);
|
||||||
|
static void aes_cbc_encrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
static void aes_cbc_decrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
static void aes_cbc_reinit(void *, const uint8_t *, size_t);
|
static void aes_cbc_reinit(void *, const uint8_t *, size_t);
|
||||||
|
|
||||||
/* Encryption instances */
|
/* Encryption instances */
|
||||||
@ -72,10 +74,12 @@ const struct enc_xform enc_xform_aes_cbc = {
|
|||||||
.ivsize = AES_BLOCK_LEN,
|
.ivsize = AES_BLOCK_LEN,
|
||||||
.minkey = AES_MIN_KEY,
|
.minkey = AES_MIN_KEY,
|
||||||
.maxkey = AES_MAX_KEY,
|
.maxkey = AES_MAX_KEY,
|
||||||
.encrypt = aes_cbc_encrypt,
|
|
||||||
.decrypt = aes_cbc_decrypt,
|
|
||||||
.setkey = aes_cbc_setkey,
|
.setkey = aes_cbc_setkey,
|
||||||
.reinit = aes_cbc_reinit,
|
.reinit = aes_cbc_reinit,
|
||||||
|
.encrypt = aes_cbc_encrypt,
|
||||||
|
.decrypt = aes_cbc_decrypt,
|
||||||
|
.encrypt_multi = aes_cbc_encrypt_multi,
|
||||||
|
.decrypt_multi = aes_cbc_decrypt_multi,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106,6 +110,43 @@ aes_cbc_decrypt(void *vctx, const uint8_t *in, uint8_t *out)
|
|||||||
explicit_bzero(block, sizeof(block));
|
explicit_bzero(block, sizeof(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_cbc_encrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct aes_cbc_ctx *ctx = vctx;
|
||||||
|
|
||||||
|
KASSERT(len % AES_BLOCK_LEN == 0, ("%s: invalid length", __func__));
|
||||||
|
while (len > 0) {
|
||||||
|
for (u_int i = 0; i < AES_BLOCK_LEN; i++)
|
||||||
|
out[i] = in[i] ^ ctx->iv[i];
|
||||||
|
rijndael_encrypt(&ctx->key, out, out);
|
||||||
|
memcpy(ctx->iv, out, AES_BLOCK_LEN);
|
||||||
|
out += AES_BLOCK_LEN;
|
||||||
|
in += AES_BLOCK_LEN;
|
||||||
|
len -= AES_BLOCK_LEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_cbc_decrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct aes_cbc_ctx *ctx = vctx;
|
||||||
|
char block[AES_BLOCK_LEN];
|
||||||
|
|
||||||
|
KASSERT(len % AES_BLOCK_LEN == 0, ("%s: invalid length", __func__));
|
||||||
|
while (len > 0) {
|
||||||
|
memcpy(block, in, AES_BLOCK_LEN);
|
||||||
|
rijndael_decrypt(&ctx->key, in, out);
|
||||||
|
for (u_int i = 0; i < AES_BLOCK_LEN; i++)
|
||||||
|
out[i] ^= ctx->iv[i];
|
||||||
|
memcpy(ctx->iv, block, AES_BLOCK_LEN);
|
||||||
|
out += AES_BLOCK_LEN;
|
||||||
|
in += AES_BLOCK_LEN;
|
||||||
|
len -= AES_BLOCK_LEN;
|
||||||
|
}
|
||||||
|
explicit_bzero(block, sizeof(block));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
aes_cbc_setkey(void *vctx, const uint8_t *key, int len)
|
aes_cbc_setkey(void *vctx, const uint8_t *key, int len)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +66,7 @@ struct aes_ccm_ctx {
|
|||||||
|
|
||||||
static int aes_icm_setkey(void *, const uint8_t *, int);
|
static int aes_icm_setkey(void *, const uint8_t *, int);
|
||||||
static void aes_icm_crypt(void *, const uint8_t *, uint8_t *);
|
static void aes_icm_crypt(void *, const uint8_t *, uint8_t *);
|
||||||
|
static void aes_icm_crypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t);
|
static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
static void aes_icm_reinit(void *, const uint8_t *, size_t);
|
static void aes_icm_reinit(void *, const uint8_t *, size_t);
|
||||||
static int aes_gcm_setkey(void *, const uint8_t *, int);
|
static int aes_gcm_setkey(void *, const uint8_t *, int);
|
||||||
@ -87,10 +88,12 @@ const struct enc_xform enc_xform_aes_icm = {
|
|||||||
.ivsize = AES_BLOCK_LEN,
|
.ivsize = AES_BLOCK_LEN,
|
||||||
.minkey = AES_MIN_KEY,
|
.minkey = AES_MIN_KEY,
|
||||||
.maxkey = AES_MAX_KEY,
|
.maxkey = AES_MAX_KEY,
|
||||||
.encrypt = aes_icm_crypt,
|
|
||||||
.decrypt = aes_icm_crypt,
|
|
||||||
.setkey = aes_icm_setkey,
|
.setkey = aes_icm_setkey,
|
||||||
.reinit = aes_icm_reinit,
|
.reinit = aes_icm_reinit,
|
||||||
|
.encrypt = aes_icm_crypt,
|
||||||
|
.decrypt = aes_icm_crypt,
|
||||||
|
.encrypt_multi = aes_icm_crypt_multi,
|
||||||
|
.decrypt_multi = aes_icm_crypt_multi,
|
||||||
.encrypt_last = aes_icm_crypt_last,
|
.encrypt_last = aes_icm_crypt_last,
|
||||||
.decrypt_last = aes_icm_crypt_last,
|
.decrypt_last = aes_icm_crypt_last,
|
||||||
};
|
};
|
||||||
@ -105,10 +108,12 @@ const struct enc_xform enc_xform_aes_nist_gcm = {
|
|||||||
.minkey = AES_MIN_KEY,
|
.minkey = AES_MIN_KEY,
|
||||||
.maxkey = AES_MAX_KEY,
|
.maxkey = AES_MAX_KEY,
|
||||||
.macsize = AES_GMAC_HASH_LEN,
|
.macsize = AES_GMAC_HASH_LEN,
|
||||||
.encrypt = aes_icm_crypt,
|
|
||||||
.decrypt = aes_icm_crypt,
|
|
||||||
.setkey = aes_gcm_setkey,
|
.setkey = aes_gcm_setkey,
|
||||||
.reinit = aes_gcm_reinit,
|
.reinit = aes_gcm_reinit,
|
||||||
|
.encrypt = aes_icm_crypt,
|
||||||
|
.decrypt = aes_icm_crypt,
|
||||||
|
.encrypt_multi = aes_icm_crypt_multi,
|
||||||
|
.decrypt_multi = aes_icm_crypt_multi,
|
||||||
.encrypt_last = aes_icm_crypt_last,
|
.encrypt_last = aes_icm_crypt_last,
|
||||||
.decrypt_last = aes_icm_crypt_last,
|
.decrypt_last = aes_icm_crypt_last,
|
||||||
.update = aes_gcm_update,
|
.update = aes_gcm_update,
|
||||||
@ -124,10 +129,12 @@ const struct enc_xform enc_xform_ccm = {
|
|||||||
.ivsize = AES_CCM_IV_LEN,
|
.ivsize = AES_CCM_IV_LEN,
|
||||||
.minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY,
|
.minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY,
|
||||||
.macsize = AES_CBC_MAC_HASH_LEN,
|
.macsize = AES_CBC_MAC_HASH_LEN,
|
||||||
.encrypt = aes_icm_crypt,
|
|
||||||
.decrypt = aes_icm_crypt,
|
|
||||||
.setkey = aes_ccm_setkey,
|
.setkey = aes_ccm_setkey,
|
||||||
.reinit = aes_ccm_reinit,
|
.reinit = aes_ccm_reinit,
|
||||||
|
.encrypt = aes_icm_crypt,
|
||||||
|
.decrypt = aes_icm_crypt,
|
||||||
|
.encrypt_multi = aes_icm_crypt_multi,
|
||||||
|
.decrypt_multi = aes_icm_crypt_multi,
|
||||||
.encrypt_last = aes_icm_crypt_last,
|
.encrypt_last = aes_icm_crypt_last,
|
||||||
.decrypt_last = aes_icm_crypt_last,
|
.decrypt_last = aes_icm_crypt_last,
|
||||||
.update = aes_ccm_update,
|
.update = aes_ccm_update,
|
||||||
@ -197,6 +204,31 @@ aes_icm_crypt(void *key, const uint8_t *in, uint8_t *out)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_icm_crypt_multi(void *key, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct aes_icm_ctx *ctx = key;
|
||||||
|
uint8_t keystream[AESICM_BLOCKSIZE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
KASSERT(len % AESICM_BLOCKSIZE == 0, ("%s: invalid length", __func__));
|
||||||
|
while (len > 0) {
|
||||||
|
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
|
||||||
|
for (i = 0; i < AESICM_BLOCKSIZE; i++)
|
||||||
|
out[i] = in[i] ^ keystream[i];
|
||||||
|
|
||||||
|
/* increment counter */
|
||||||
|
for (i = AESICM_BLOCKSIZE - 1; i >= 0; i--)
|
||||||
|
if (++ctx->ac_block[i]) /* continue on overflow */
|
||||||
|
break;
|
||||||
|
|
||||||
|
out += AESICM_BLOCKSIZE;
|
||||||
|
in += AESICM_BLOCKSIZE;
|
||||||
|
len -= AESICM_BLOCKSIZE;
|
||||||
|
}
|
||||||
|
explicit_bzero(keystream, sizeof(keystream));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aes_icm_crypt_last(void *key, const uint8_t *in, uint8_t *out, size_t len)
|
aes_icm_crypt_last(void *key, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int aes_xts_setkey(void *, const uint8_t *, int);
|
static int aes_xts_setkey(void *, const uint8_t *, int);
|
||||||
static void aes_xts_encrypt(void *, const uint8_t *, uint8_t *);
|
static void aes_xts_encrypt(void *, const uint8_t *, uint8_t *);
|
||||||
static void aes_xts_decrypt(void *, const uint8_t *, uint8_t *);
|
static void aes_xts_decrypt(void *, const uint8_t *, uint8_t *);
|
||||||
|
static void aes_xts_encrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
static void aes_xts_decrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
static void aes_xts_reinit(void *, const uint8_t *, size_t);
|
static void aes_xts_reinit(void *, const uint8_t *, size_t);
|
||||||
|
|
||||||
/* Encryption instances */
|
/* Encryption instances */
|
||||||
@ -67,10 +69,12 @@ const struct enc_xform enc_xform_aes_xts = {
|
|||||||
.ivsize = AES_XTS_IV_LEN,
|
.ivsize = AES_XTS_IV_LEN,
|
||||||
.minkey = AES_XTS_MIN_KEY,
|
.minkey = AES_XTS_MIN_KEY,
|
||||||
.maxkey = AES_XTS_MAX_KEY,
|
.maxkey = AES_XTS_MAX_KEY,
|
||||||
|
.setkey = aes_xts_setkey,
|
||||||
|
.reinit = aes_xts_reinit,
|
||||||
.encrypt = aes_xts_encrypt,
|
.encrypt = aes_xts_encrypt,
|
||||||
.decrypt = aes_xts_decrypt,
|
.decrypt = aes_xts_decrypt,
|
||||||
.setkey = aes_xts_setkey,
|
.encrypt_multi = aes_xts_encrypt_multi,
|
||||||
.reinit = aes_xts_reinit
|
.decrypt_multi = aes_xts_decrypt_multi,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -105,44 +109,63 @@ aes_xts_reinit(void *key, const uint8_t *iv, size_t ivlen)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
aes_xts_crypt(struct aes_xts_ctx *ctx, const uint8_t *in, uint8_t *out,
|
aes_xts_crypt(struct aes_xts_ctx *ctx, const uint8_t *in, uint8_t *out,
|
||||||
u_int do_encrypt)
|
size_t len, bool do_encrypt)
|
||||||
{
|
{
|
||||||
uint8_t block[AES_XTS_BLOCKSIZE];
|
uint8_t block[AES_XTS_BLOCKSIZE];
|
||||||
u_int i, carry_in, carry_out;
|
u_int i, carry_in, carry_out;
|
||||||
|
|
||||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
KASSERT(len % AES_XTS_BLOCKSIZE == 0, ("%s: invalid length", __func__));
|
||||||
block[i] = in[i] ^ ctx->tweak[i];
|
while (len > 0) {
|
||||||
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||||
|
block[i] = in[i] ^ ctx->tweak[i];
|
||||||
|
|
||||||
if (do_encrypt)
|
if (do_encrypt)
|
||||||
rijndael_encrypt(&ctx->key1, block, out);
|
rijndael_encrypt(&ctx->key1, block, out);
|
||||||
else
|
else
|
||||||
rijndael_decrypt(&ctx->key1, block, out);
|
rijndael_decrypt(&ctx->key1, block, out);
|
||||||
|
|
||||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||||
out[i] ^= ctx->tweak[i];
|
out[i] ^= ctx->tweak[i];
|
||||||
|
|
||||||
/* Exponentiate tweak */
|
/* Exponentiate tweak */
|
||||||
carry_in = 0;
|
carry_in = 0;
|
||||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
|
||||||
carry_out = ctx->tweak[i] & 0x80;
|
carry_out = ctx->tweak[i] & 0x80;
|
||||||
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
|
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
|
||||||
carry_in = carry_out;
|
carry_in = carry_out;
|
||||||
|
}
|
||||||
|
if (carry_in)
|
||||||
|
ctx->tweak[0] ^= AES_XTS_ALPHA;
|
||||||
|
|
||||||
|
in += AES_XTS_BLOCKSIZE;
|
||||||
|
out += AES_XTS_BLOCKSIZE;
|
||||||
|
len -= AES_XTS_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
if (carry_in)
|
|
||||||
ctx->tweak[0] ^= AES_XTS_ALPHA;
|
|
||||||
explicit_bzero(block, sizeof(block));
|
explicit_bzero(block, sizeof(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aes_xts_encrypt(void *key, const uint8_t *in, uint8_t *out)
|
aes_xts_encrypt(void *key, const uint8_t *in, uint8_t *out)
|
||||||
{
|
{
|
||||||
aes_xts_crypt(key, in, out, 1);
|
aes_xts_crypt(key, in, out, AES_XTS_BLOCKSIZE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aes_xts_decrypt(void *key, const uint8_t *in, uint8_t *out)
|
aes_xts_decrypt(void *key, const uint8_t *in, uint8_t *out)
|
||||||
{
|
{
|
||||||
aes_xts_crypt(key, in, out, 0);
|
aes_xts_crypt(key, in, out, AES_XTS_BLOCKSIZE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_xts_encrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
aes_xts_crypt(vctx, in, out, len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_xts_decrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
aes_xts_crypt(vctx, in, out, len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -98,6 +98,24 @@ chacha20_poly1305_crypt(void *vctx, const uint8_t *in, uint8_t *out)
|
|||||||
ctx->ic++;
|
ctx->ic++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chacha20_poly1305_crypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct chacha20_poly1305_ctx *ctx = vctx;
|
||||||
|
int error __diagused;
|
||||||
|
|
||||||
|
KASSERT(len % CHACHA20_NATIVE_BLOCK_LEN == 0, ("%s: invalid length",
|
||||||
|
__func__));
|
||||||
|
if (ctx->ietf)
|
||||||
|
error = crypto_stream_chacha20_ietf_xor_ic(out, in, len,
|
||||||
|
ctx->nonce, ctx->ic, ctx->key);
|
||||||
|
else
|
||||||
|
error = crypto_stream_chacha20_xor_ic(out, in, len, ctx->nonce,
|
||||||
|
ctx->ic, ctx->key);
|
||||||
|
KASSERT(error == 0, ("%s failed: %d", __func__, error));
|
||||||
|
ctx->ic += len / CHACHA20_NATIVE_BLOCK_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chacha20_poly1305_crypt_last(void *vctx, const uint8_t *in, uint8_t *out,
|
chacha20_poly1305_crypt_last(void *vctx, const uint8_t *in, uint8_t *out,
|
||||||
size_t len)
|
size_t len)
|
||||||
@ -142,10 +160,12 @@ const struct enc_xform enc_xform_chacha20_poly1305 = {
|
|||||||
.minkey = CHACHA20_POLY1305_KEY,
|
.minkey = CHACHA20_POLY1305_KEY,
|
||||||
.maxkey = CHACHA20_POLY1305_KEY,
|
.maxkey = CHACHA20_POLY1305_KEY,
|
||||||
.macsize = POLY1305_HASH_LEN,
|
.macsize = POLY1305_HASH_LEN,
|
||||||
.encrypt = chacha20_poly1305_crypt,
|
|
||||||
.decrypt = chacha20_poly1305_crypt,
|
|
||||||
.setkey = chacha20_poly1305_setkey,
|
.setkey = chacha20_poly1305_setkey,
|
||||||
.reinit = chacha20_poly1305_reinit,
|
.reinit = chacha20_poly1305_reinit,
|
||||||
|
.encrypt = chacha20_poly1305_crypt,
|
||||||
|
.decrypt = chacha20_poly1305_crypt,
|
||||||
|
.encrypt_multi = chacha20_poly1305_crypt_multi,
|
||||||
|
.decrypt_multi = chacha20_poly1305_crypt_multi,
|
||||||
.encrypt_last = chacha20_poly1305_crypt_last,
|
.encrypt_last = chacha20_poly1305_crypt_last,
|
||||||
.decrypt_last = chacha20_poly1305_crypt_last,
|
.decrypt_last = chacha20_poly1305_crypt_last,
|
||||||
.update = chacha20_poly1305_update,
|
.update = chacha20_poly1305_update,
|
||||||
@ -197,10 +217,12 @@ const struct enc_xform enc_xform_xchacha20_poly1305 = {
|
|||||||
.minkey = XCHACHA20_POLY1305_KEY,
|
.minkey = XCHACHA20_POLY1305_KEY,
|
||||||
.maxkey = XCHACHA20_POLY1305_KEY,
|
.maxkey = XCHACHA20_POLY1305_KEY,
|
||||||
.macsize = POLY1305_HASH_LEN,
|
.macsize = POLY1305_HASH_LEN,
|
||||||
.encrypt = chacha20_poly1305_crypt,
|
|
||||||
.decrypt = chacha20_poly1305_crypt,
|
|
||||||
.setkey = xchacha20_poly1305_setkey,
|
.setkey = xchacha20_poly1305_setkey,
|
||||||
.reinit = xchacha20_poly1305_reinit,
|
.reinit = xchacha20_poly1305_reinit,
|
||||||
|
.encrypt = chacha20_poly1305_crypt,
|
||||||
|
.decrypt = chacha20_poly1305_crypt,
|
||||||
|
.encrypt_multi = chacha20_poly1305_crypt_multi,
|
||||||
|
.decrypt_multi = chacha20_poly1305_crypt_multi,
|
||||||
.encrypt_last = chacha20_poly1305_crypt_last,
|
.encrypt_last = chacha20_poly1305_crypt_last,
|
||||||
.decrypt_last = chacha20_poly1305_crypt_last,
|
.decrypt_last = chacha20_poly1305_crypt_last,
|
||||||
.update = chacha20_poly1305_update,
|
.update = chacha20_poly1305_update,
|
||||||
|
@ -61,6 +61,8 @@ struct camellia_cbc_ctx {
|
|||||||
static int cml_setkey(void *, const uint8_t *, int);
|
static int cml_setkey(void *, const uint8_t *, int);
|
||||||
static void cml_encrypt(void *, const uint8_t *, uint8_t *);
|
static void cml_encrypt(void *, const uint8_t *, uint8_t *);
|
||||||
static void cml_decrypt(void *, const uint8_t *, uint8_t *);
|
static void cml_decrypt(void *, const uint8_t *, uint8_t *);
|
||||||
|
static void cml_encrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
static void cml_decrypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
static void cml_reinit(void *, const uint8_t *, size_t);
|
static void cml_reinit(void *, const uint8_t *, size_t);
|
||||||
|
|
||||||
/* Encryption instances */
|
/* Encryption instances */
|
||||||
@ -72,10 +74,12 @@ const struct enc_xform enc_xform_camellia = {
|
|||||||
.ivsize = CAMELLIA_BLOCK_LEN,
|
.ivsize = CAMELLIA_BLOCK_LEN,
|
||||||
.minkey = CAMELLIA_MIN_KEY,
|
.minkey = CAMELLIA_MIN_KEY,
|
||||||
.maxkey = CAMELLIA_MAX_KEY,
|
.maxkey = CAMELLIA_MAX_KEY,
|
||||||
.encrypt = cml_encrypt,
|
|
||||||
.decrypt = cml_decrypt,
|
|
||||||
.setkey = cml_setkey,
|
.setkey = cml_setkey,
|
||||||
.reinit = cml_reinit,
|
.reinit = cml_reinit,
|
||||||
|
.encrypt = cml_encrypt,
|
||||||
|
.decrypt = cml_decrypt,
|
||||||
|
.encrypt_multi = cml_encrypt_multi,
|
||||||
|
.decrypt_multi = cml_decrypt_multi,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106,6 +110,45 @@ cml_decrypt(void *vctx, const uint8_t *in, uint8_t *out)
|
|||||||
explicit_bzero(block, sizeof(block));
|
explicit_bzero(block, sizeof(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cml_encrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct camellia_cbc_ctx *ctx = vctx;
|
||||||
|
|
||||||
|
KASSERT(len % CAMELLIA_BLOCK_LEN == 0, ("%s: invalid length",
|
||||||
|
__func__));
|
||||||
|
while (len > 0) {
|
||||||
|
for (u_int i = 0; i < CAMELLIA_BLOCK_LEN; i++)
|
||||||
|
out[i] = in[i] ^ ctx->iv[i];
|
||||||
|
camellia_encrypt(&ctx->state, out, out);
|
||||||
|
memcpy(ctx->iv, out, CAMELLIA_BLOCK_LEN);
|
||||||
|
out += CAMELLIA_BLOCK_LEN;
|
||||||
|
in += CAMELLIA_BLOCK_LEN;
|
||||||
|
len -= CAMELLIA_BLOCK_LEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cml_decrypt_multi(void *vctx, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
struct camellia_cbc_ctx *ctx = vctx;
|
||||||
|
char block[CAMELLIA_BLOCK_LEN];
|
||||||
|
|
||||||
|
KASSERT(len % CAMELLIA_BLOCK_LEN == 0, ("%s: invalid length",
|
||||||
|
__func__));
|
||||||
|
while (len > 0) {
|
||||||
|
memcpy(block, in, CAMELLIA_BLOCK_LEN);
|
||||||
|
camellia_decrypt(&ctx->state, in, out);
|
||||||
|
for (u_int i = 0; i < CAMELLIA_BLOCK_LEN; i++)
|
||||||
|
out[i] ^= ctx->iv[i];
|
||||||
|
memcpy(ctx->iv, block, CAMELLIA_BLOCK_LEN);
|
||||||
|
out += CAMELLIA_BLOCK_LEN;
|
||||||
|
in += CAMELLIA_BLOCK_LEN;
|
||||||
|
len -= CAMELLIA_BLOCK_LEN;
|
||||||
|
}
|
||||||
|
explicit_bzero(block, sizeof(block));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cml_setkey(void *vctx, const uint8_t *key, int len)
|
cml_setkey(void *vctx, const uint8_t *key, int len)
|
||||||
{
|
{
|
||||||
|
@ -56,14 +56,26 @@ struct enc_xform {
|
|||||||
uint16_t minkey, maxkey;
|
uint16_t minkey, maxkey;
|
||||||
uint16_t macsize; /* For AEAD ciphers. */
|
uint16_t macsize; /* For AEAD ciphers. */
|
||||||
|
|
||||||
|
/* Initialize context and set key. */
|
||||||
|
int (*setkey) (void *, const uint8_t *, int len);
|
||||||
|
|
||||||
|
/* Supply context with nonce/IV. */
|
||||||
|
void (*reinit) (void *, const uint8_t *, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encrypt/decrypt a single block. For stream ciphers this
|
* Encrypt/decrypt a single block. For stream ciphers this
|
||||||
* encrypts/decrypts a single "native" block.
|
* encrypts/decrypts a single "native" block.
|
||||||
*/
|
*/
|
||||||
void (*encrypt) (void *, const uint8_t *, uint8_t *);
|
void (*encrypt) (void *, const uint8_t *, uint8_t *);
|
||||||
void (*decrypt) (void *, const uint8_t *, uint8_t *);
|
void (*decrypt) (void *, const uint8_t *, uint8_t *);
|
||||||
int (*setkey) (void *, const uint8_t *, int len);
|
|
||||||
void (*reinit) (void *, const uint8_t *, size_t);
|
/*
|
||||||
|
* Encrypt/decrypt multiple blocks. For stream ciphers this
|
||||||
|
* encrypts/decrypts multiple "native" blocks. The fourth
|
||||||
|
* argument is a count of bytes.
|
||||||
|
*/
|
||||||
|
void (*encrypt_multi) (void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
void (*decrypt_multi) (void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For stream ciphers, encrypt/decrypt the final partial block
|
* For stream ciphers, encrypt/decrypt the final partial block
|
||||||
|
@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static int null_setkey(void *, const uint8_t *, int);
|
static int null_setkey(void *, const uint8_t *, int);
|
||||||
static void null_crypt(void *, const uint8_t *, uint8_t *);
|
static void null_crypt(void *, const uint8_t *, uint8_t *);
|
||||||
|
static void null_crypt_multi(void *, const uint8_t *, uint8_t *, size_t);
|
||||||
|
|
||||||
static void null_init(void *);
|
static void null_init(void *);
|
||||||
static void null_reinit(void *ctx, const uint8_t *buf, u_int len);
|
static void null_reinit(void *ctx, const uint8_t *buf, u_int len);
|
||||||
@ -70,9 +71,11 @@ const struct enc_xform enc_xform_null = {
|
|||||||
.ivsize = 0,
|
.ivsize = 0,
|
||||||
.minkey = NULL_MIN_KEY,
|
.minkey = NULL_MIN_KEY,
|
||||||
.maxkey = NULL_MAX_KEY,
|
.maxkey = NULL_MAX_KEY,
|
||||||
|
.setkey = null_setkey,
|
||||||
.encrypt = null_crypt,
|
.encrypt = null_crypt,
|
||||||
.decrypt = null_crypt,
|
.decrypt = null_crypt,
|
||||||
.setkey = null_setkey,
|
.encrypt_multi = null_crypt_multi,
|
||||||
|
.decrypt_multi = null_crypt_multi,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Authentication instances */
|
/* Authentication instances */
|
||||||
@ -98,6 +101,11 @@ null_crypt(void *key, const uint8_t *in, uint8_t *out)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
null_crypt_multi(void *key, const uint8_t *in, uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
null_setkey(void *sched, const uint8_t *key, int len)
|
null_setkey(void *sched, const uint8_t *key, int len)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user