Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/xform_aes_xts.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <opencrypto/xform_enc.h> | #include <opencrypto/xform_enc.h> | ||||
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 */ | ||||
const struct enc_xform enc_xform_aes_xts = { | const struct enc_xform enc_xform_aes_xts = { | ||||
.type = CRYPTO_AES_XTS, | .type = CRYPTO_AES_XTS, | ||||
.name = "AES-XTS", | .name = "AES-XTS", | ||||
.ctxsize = sizeof(struct aes_xts_ctx), | .ctxsize = sizeof(struct aes_xts_ctx), | ||||
.blocksize = AES_BLOCK_LEN, | .blocksize = AES_BLOCK_LEN, | ||||
.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, | ||||
}; | }; | ||||
/* | /* | ||||
* Encryption wrapper routines. | * Encryption wrapper routines. | ||||
*/ | */ | ||||
static void | static void | ||||
aes_xts_reinit(void *key, const uint8_t *iv, size_t ivlen) | aes_xts_reinit(void *key, const uint8_t *iv, size_t ivlen) | ||||
{ | { | ||||
Show All 18 Lines | #endif | ||||
/* Last 64 bits of IV are always zero */ | /* Last 64 bits of IV are always zero */ | ||||
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE); | bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE); | ||||
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); | rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); | ||||
} | } | ||||
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; | ||||
while (len > 0) { | |||||
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) | for (i = 0; i < AES_XTS_BLOCKSIZE; i++) | ||||
block[i] = in[i] ^ ctx->tweak[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) | if (carry_in) | ||||
ctx->tweak[0] ^= AES_XTS_ALPHA; | ctx->tweak[0] ^= AES_XTS_ALPHA; | ||||
in += AES_XTS_BLOCKSIZE; | |||||
out += AES_XTS_BLOCKSIZE; | |||||
len -= AES_XTS_BLOCKSIZE; | |||||
} | |||||
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 | ||||
aes_xts_setkey(void *sched, const uint8_t *key, int len) | aes_xts_setkey(void *sched, const uint8_t *key, int len) | ||||
{ | { | ||||
struct aes_xts_ctx *ctx; | struct aes_xts_ctx *ctx; | ||||
if (len != 32 && len != 64) | if (len != 32 && len != 64) | ||||
Show All 9 Lines |