Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/xform_aes_cbc.c
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
struct aes_cbc_ctx { | struct aes_cbc_ctx { | ||||
rijndael_ctx key; | rijndael_ctx key; | ||||
char iv[AES_BLOCK_LEN]; | char iv[AES_BLOCK_LEN]; | ||||
}; | }; | ||||
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 */ | ||||
const struct enc_xform enc_xform_aes_cbc = { | const struct enc_xform enc_xform_aes_cbc = { | ||||
.type = CRYPTO_AES_CBC, | .type = CRYPTO_AES_CBC, | ||||
.name = "AES-CBC", | .name = "AES-CBC", | ||||
.ctxsize = sizeof(struct aes_cbc_ctx), | .ctxsize = sizeof(struct aes_cbc_ctx), | ||||
.blocksize = AES_BLOCK_LEN, | .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_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, | |||||
}; | }; | ||||
/* | /* | ||||
* Encryption wrapper routines. | * Encryption wrapper routines. | ||||
*/ | */ | ||||
static void | static void | ||||
aes_cbc_encrypt(void *vctx, const uint8_t *in, uint8_t *out) | aes_cbc_encrypt(void *vctx, const uint8_t *in, uint8_t *out) | ||||
{ | { | ||||
Show All 11 Lines | aes_cbc_decrypt(void *vctx, const uint8_t *in, uint8_t *out) | ||||
struct aes_cbc_ctx *ctx = vctx; | struct aes_cbc_ctx *ctx = vctx; | ||||
char block[AES_BLOCK_LEN]; | char block[AES_BLOCK_LEN]; | ||||
memcpy(block, in, AES_BLOCK_LEN); | memcpy(block, in, AES_BLOCK_LEN); | ||||
rijndael_decrypt(&ctx->key, in, out); | rijndael_decrypt(&ctx->key, in, out); | ||||
for (u_int i = 0; i < AES_BLOCK_LEN; i++) | for (u_int i = 0; i < AES_BLOCK_LEN; i++) | ||||
out[i] ^= ctx->iv[i]; | out[i] ^= ctx->iv[i]; | ||||
memcpy(ctx->iv, block, AES_BLOCK_LEN); | memcpy(ctx->iv, block, AES_BLOCK_LEN); | ||||
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; | |||||
markj: Perhaps assert `len % AES_BLOCK_LEN == 0 && len >= AES_BLOCK_LEN`. | |||||
jhbAuthorUnsubmitted Done Inline ActionsI think len == 0 will generally work on these, but I could assert for both if you think that's better? jhb: I think len == 0 will generally work on these, but I could assert for both if you think that's… | |||||
markjUnsubmitted Not Done Inline ActionsI think len % AES_BLOCK_LEN == 0 is sufficient then. markj: I think `len % AES_BLOCK_LEN == 0` is sufficient then. | |||||
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]; | |||||
markjUnsubmitted Not Done Inline ActionsSame here. markj: Same here. | |||||
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)); | 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) | ||||
{ | { | ||||
struct aes_cbc_ctx *ctx = vctx; | struct aes_cbc_ctx *ctx = vctx; | ||||
Show All 15 Lines |
Perhaps assert len % AES_BLOCK_LEN == 0 && len >= AES_BLOCK_LEN.