Changeset View
Changeset View
Standalone View
Standalone View
head/sys/opencrypto/xform_aes_icm.c
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
* PURPOSE. | * PURPOSE. | ||||
*/ | */ | ||||
#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(u_int8_t **, u_int8_t *, int); | static int aes_icm_setkey(u_int8_t **, const u_int8_t *, int); | ||||
static void aes_icm_crypt(caddr_t, u_int8_t *); | static void aes_icm_crypt(caddr_t, u_int8_t *); | ||||
static void aes_icm_zerokey(u_int8_t **); | static void aes_icm_zerokey(u_int8_t **); | ||||
static void aes_icm_reinit(caddr_t, u_int8_t *); | static void aes_icm_reinit(caddr_t, const u_int8_t *); | ||||
static void aes_gcm_reinit(caddr_t, u_int8_t *); | static void aes_gcm_reinit(caddr_t, const u_int8_t *); | ||||
static void aes_ccm_reinit(caddr_t, u_int8_t *); | static void aes_ccm_reinit(caddr_t, const u_int8_t *); | ||||
/* Encryption instances */ | /* Encryption instances */ | ||||
struct enc_xform enc_xform_aes_icm = { | struct enc_xform enc_xform_aes_icm = { | ||||
CRYPTO_AES_ICM, "AES-ICM", | CRYPTO_AES_ICM, "AES-ICM", | ||||
AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY, | AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY, | ||||
aes_icm_crypt, | aes_icm_crypt, | ||||
aes_icm_crypt, | aes_icm_crypt, | ||||
aes_icm_setkey, | aes_icm_setkey, | ||||
Show All 22 Lines | struct enc_xform enc_xform_ccm = { | ||||
.zerokey = aes_icm_zerokey, | .zerokey = aes_icm_zerokey, | ||||
.reinit = aes_ccm_reinit, | .reinit = aes_ccm_reinit, | ||||
}; | }; | ||||
/* | /* | ||||
* Encryption wrapper routines. | * Encryption wrapper routines. | ||||
*/ | */ | ||||
static void | static void | ||||
aes_icm_reinit(caddr_t key, u_int8_t *iv) | aes_icm_reinit(caddr_t key, const u_int8_t *iv) | ||||
{ | { | ||||
struct aes_icm_ctx *ctx; | struct aes_icm_ctx *ctx; | ||||
ctx = (struct aes_icm_ctx *)key; | ctx = (struct aes_icm_ctx *)key; | ||||
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE); | bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE); | ||||
} | } | ||||
static void | static void | ||||
aes_gcm_reinit(caddr_t key, u_int8_t *iv) | aes_gcm_reinit(caddr_t key, const u_int8_t *iv) | ||||
{ | { | ||||
struct aes_icm_ctx *ctx; | struct aes_icm_ctx *ctx; | ||||
aes_icm_reinit(key, iv); | aes_icm_reinit(key, iv); | ||||
ctx = (struct aes_icm_ctx *)key; | ctx = (struct aes_icm_ctx *)key; | ||||
/* GCM starts with 2 as counter 1 is used for final xor of tag. */ | /* GCM starts with 2 as counter 1 is used for final xor of tag. */ | ||||
bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4); | bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4); | ||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2; | ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2; | ||||
} | } | ||||
static void | static void | ||||
aes_ccm_reinit(caddr_t key, u_int8_t *iv) | aes_ccm_reinit(caddr_t key, const u_int8_t *iv) | ||||
{ | { | ||||
struct aes_icm_ctx *ctx; | struct aes_icm_ctx *ctx; | ||||
ctx = (struct aes_icm_ctx*)key; | ctx = (struct aes_icm_ctx*)key; | ||||
/* CCM has flags, then the IV, then the counter, which starts at 1 */ | /* CCM has flags, then the IV, then the counter, which starts at 1 */ | ||||
bzero(ctx->ac_block, sizeof(ctx->ac_block)); | bzero(ctx->ac_block, sizeof(ctx->ac_block)); | ||||
/* 3 bytes for length field; this gives a nonce of 12 bytes */ | /* 3 bytes for length field; this gives a nonce of 12 bytes */ | ||||
Show All 18 Lines | aes_icm_crypt(caddr_t key, u_int8_t *data) | ||||
/* 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 int | static int | ||||
aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len) | aes_icm_setkey(u_int8_t **sched, const u_int8_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; | ||||
*sched = KMALLOC(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA, | *sched = KMALLOC(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA, | ||||
M_NOWAIT | M_ZERO); | M_NOWAIT | M_ZERO); | ||||
if (*sched == NULL) | if (*sched == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
ctx = (struct aes_icm_ctx *)*sched; | ctx = (struct aes_icm_ctx *)*sched; | ||||
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8); | ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, key, len * 8); | ||||
return 0; | return 0; | ||||
} | } | ||||
static void | static void | ||||
aes_icm_zerokey(u_int8_t **sched) | aes_icm_zerokey(u_int8_t **sched) | ||||
{ | { | ||||
bzero(*sched, sizeof(struct aes_icm_ctx)); | bzero(*sched, sizeof(struct aes_icm_ctx)); | ||||
KFREE(*sched, M_CRYPTO_DATA); | KFREE(*sched, M_CRYPTO_DATA); | ||||
*sched = NULL; | *sched = NULL; | ||||
} | } |