Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/xform_aes_icm.c
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <opencrypto/xform_enc.h> | #include <opencrypto/xform_enc.h> | ||||
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_last(void *, const uint8_t *, uint8_t *, size_t); | |||||
static void aes_icm_reinit(void *, const uint8_t *); | static void aes_icm_reinit(void *, const uint8_t *); | ||||
static void aes_gcm_reinit(void *, const uint8_t *); | static void aes_gcm_reinit(void *, const uint8_t *); | ||||
static void aes_ccm_reinit(void *, const uint8_t *); | static void aes_ccm_reinit(void *, const uint8_t *); | ||||
/* Encryption instances */ | /* Encryption instances */ | ||||
struct enc_xform enc_xform_aes_icm = { | struct enc_xform enc_xform_aes_icm = { | ||||
.type = CRYPTO_AES_ICM, | .type = CRYPTO_AES_ICM, | ||||
.name = "AES-ICM", | .name = "AES-ICM", | ||||
.ctxsize = sizeof(struct aes_icm_ctx), | .ctxsize = sizeof(struct aes_icm_ctx), | ||||
.blocksize = AES_BLOCK_LEN, | .blocksize = 1, | ||||
.native_blocksize = AES_BLOCK_LEN, | |||||
.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, | .encrypt = aes_icm_crypt, | ||||
.decrypt = aes_icm_crypt, | .decrypt = aes_icm_crypt, | ||||
.setkey = aes_icm_setkey, | .setkey = aes_icm_setkey, | ||||
.reinit = aes_icm_reinit, | .reinit = aes_icm_reinit, | ||||
.encrypt_last = aes_icm_crypt_last, | |||||
.decrypt_last = aes_icm_crypt_last, | |||||
}; | }; | ||||
struct enc_xform enc_xform_aes_nist_gcm = { | struct enc_xform enc_xform_aes_nist_gcm = { | ||||
.type = CRYPTO_AES_NIST_GCM_16, | .type = CRYPTO_AES_NIST_GCM_16, | ||||
.name = "AES-GCM", | .name = "AES-GCM", | ||||
.ctxsize = sizeof(struct aes_icm_ctx), | .ctxsize = sizeof(struct aes_icm_ctx), | ||||
.blocksize = AES_ICM_BLOCK_LEN, | .blocksize = 1, | ||||
.native_blocksize = AES_BLOCK_LEN, | |||||
.ivsize = AES_GCM_IV_LEN, | .ivsize = AES_GCM_IV_LEN, | ||||
.minkey = AES_MIN_KEY, | .minkey = AES_MIN_KEY, | ||||
.maxkey = AES_MAX_KEY, | .maxkey = AES_MAX_KEY, | ||||
.encrypt = aes_icm_crypt, | .encrypt = aes_icm_crypt, | ||||
.decrypt = aes_icm_crypt, | .decrypt = aes_icm_crypt, | ||||
.setkey = aes_icm_setkey, | .setkey = aes_icm_setkey, | ||||
.reinit = aes_gcm_reinit, | .reinit = aes_gcm_reinit, | ||||
.encrypt_last = aes_icm_crypt_last, | |||||
.decrypt_last = aes_icm_crypt_last, | |||||
}; | }; | ||||
struct enc_xform enc_xform_ccm = { | struct enc_xform enc_xform_ccm = { | ||||
.type = CRYPTO_AES_CCM_16, | .type = CRYPTO_AES_CCM_16, | ||||
.name = "AES-CCM", | .name = "AES-CCM", | ||||
.ctxsize = sizeof(struct aes_icm_ctx), | .ctxsize = sizeof(struct aes_icm_ctx), | ||||
.blocksize = AES_ICM_BLOCK_LEN, .ivsize = AES_CCM_IV_LEN, | .blocksize = 1, | ||||
.native_blocksize = AES_BLOCK_LEN, | |||||
.ivsize = AES_CCM_IV_LEN, | |||||
.minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY, | .minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY, | ||||
.encrypt = aes_icm_crypt, | .encrypt = aes_icm_crypt, | ||||
.decrypt = aes_icm_crypt, | .decrypt = aes_icm_crypt, | ||||
.setkey = aes_icm_setkey, | .setkey = aes_icm_setkey, | ||||
.reinit = aes_ccm_reinit, | .reinit = aes_ccm_reinit, | ||||
.encrypt_last = aes_icm_crypt_last, | |||||
.decrypt_last = aes_icm_crypt_last, | |||||
}; | }; | ||||
/* | /* | ||||
* Encryption wrapper routines. | * Encryption wrapper routines. | ||||
*/ | */ | ||||
static void | static void | ||||
aes_icm_reinit(void *key, const uint8_t *iv) | aes_icm_reinit(void *key, const uint8_t *iv) | ||||
{ | { | ||||
Show All 30 Lines | aes_ccm_reinit(void *key, const uint8_t *iv) | ||||
bcopy(iv, ctx->ac_block+1, AES_CCM_IV_LEN); | bcopy(iv, ctx->ac_block+1, AES_CCM_IV_LEN); | ||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 1; | ctx->ac_block[AESICM_BLOCKSIZE - 1] = 1; | ||||
} | } | ||||
static void | static void | ||||
aes_icm_crypt(void *key, const uint8_t *in, uint8_t *out) | aes_icm_crypt(void *key, const uint8_t *in, uint8_t *out) | ||||
{ | { | ||||
struct aes_icm_ctx *ctx; | struct aes_icm_ctx *ctx; | ||||
uint8_t keystream[AESICM_BLOCKSIZE]; | |||||
int i; | int i; | ||||
ctx = key; | ctx = key; | ||||
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream); | aes_icm_crypt_last(key, in, out, AESICM_BLOCKSIZE); | ||||
for (i = 0; i < AESICM_BLOCKSIZE; i++) | |||||
out[i] = in[i] ^ keystream[i]; | |||||
explicit_bzero(keystream, sizeof(keystream)); | |||||
/* increment counter */ | /* increment counter */ | ||||
for (i = AESICM_BLOCKSIZE - 1; | for (i = AESICM_BLOCKSIZE - 1; | ||||
i >= 0; i--) | i >= 0; i--) | ||||
if (++ctx->ac_block[i]) /* continue on overflow */ | if (++ctx->ac_block[i]) /* continue on overflow */ | ||||
break; | break; | ||||
} | |||||
static void | |||||
aes_icm_crypt_last(void *key, const uint8_t *in, uint8_t *out, size_t len) | |||||
{ | |||||
struct aes_icm_ctx *ctx; | |||||
uint8_t keystream[AESICM_BLOCKSIZE]; | |||||
int i; | |||||
ctx = key; | |||||
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream); | |||||
for (i = 0; i < len; i++) | |||||
out[i] = in[i] ^ keystream[i]; | |||||
explicit_bzero(keystream, sizeof(keystream)); | |||||
} | } | ||||
static int | static int | ||||
aes_icm_setkey(void *sched, const uint8_t *key, int len) | aes_icm_setkey(void *sched, const uint8_t *key, int len) | ||||
{ | { | ||||
struct aes_icm_ctx *ctx; | struct aes_icm_ctx *ctx; | ||||
if (len != 16 && len != 24 && len != 32) | if (len != 16 && len != 24 && len != 32) | ||||
return (EINVAL); | return (EINVAL); | ||||
ctx = sched; | ctx = sched; | ||||
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, key, len * 8); | ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, key, len * 8); | ||||
return (0); | return (0); | ||||
} | } |