crypto: Add AES256-EAX cipher

pull/100/head
Andri Yngvason 2023-09-04 22:15:40 +00:00
parent c6df99ec46
commit f029484a87
2 changed files with 72 additions and 0 deletions

View File

@ -15,6 +15,7 @@ enum crypto_cipher_type {
CRYPTO_CIPHER_INVALID = 0, CRYPTO_CIPHER_INVALID = 0,
CRYPTO_CIPHER_AES128_ECB, CRYPTO_CIPHER_AES128_ECB,
CRYPTO_CIPHER_AES_EAX, CRYPTO_CIPHER_AES_EAX,
CRYPTO_CIPHER_AES256_EAX,
}; };
enum crypto_hash_type { enum crypto_hash_type {

View File

@ -36,15 +36,22 @@ struct crypto_aes_eax {
uint64_t count[2]; uint64_t count[2];
}; };
struct crypto_aes256_eax {
struct EAX_CTX(struct aes256_ctx) ctx;
uint64_t count[2];
};
struct crypto_cipher { struct crypto_cipher {
union { union {
struct aes128_ctx aes128_ecb; struct aes128_ctx aes128_ecb;
struct crypto_aes_eax aes_eax; struct crypto_aes_eax aes_eax;
struct crypto_aes256_eax aes256_eax;
} enc_ctx; } enc_ctx;
union { union {
struct aes128_ctx aes128_ecb; struct aes128_ctx aes128_ecb;
struct crypto_aes_eax aes_eax; struct crypto_aes_eax aes_eax;
struct crypto_aes256_eax aes256_eax;
} dec_ctx; } dec_ctx;
const uint8_t* ad; const uint8_t* ad;
@ -381,6 +388,68 @@ static struct crypto_cipher* crypto_cipher_new_aes_eax(const uint8_t* enc_key,
return self; return self;
} }
static void crypto_aes256_eax_update_nonce(struct crypto_aes256_eax* self)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
EAX_SET_NONCE(&self->ctx, aes256_encrypt, 16, (const uint8_t*)self->count);
#else
uint64_t c[2];
c[0] = __builtin_bswap64(self->count[0]);
c[1] = __builtin_bswap64(self->count[1]);
EAX_SET_NONCE(&self->ctx, aes256_encrypt, 16, (const uint8_t*)c);
#endif
if (++self->count[0] == 0)
++self->count[1];
}
static bool crypto_cipher_aes256_eax_encrypt(struct crypto_cipher* self,
struct vec* dst, uint8_t* mac, const uint8_t* src,
size_t src_len, const uint8_t* ad, size_t ad_len)
{
vec_reserve(dst, dst->len + src_len);
crypto_aes256_eax_update_nonce(&self->enc_ctx.aes256_eax);
EAX_UPDATE(&self->enc_ctx.aes256_eax.ctx, aes256_encrypt, ad_len, ad);
EAX_ENCRYPT(&self->enc_ctx.aes256_eax.ctx, aes256_encrypt, src_len,
(uint8_t*)dst->data + dst->len, src);
dst->len += src_len;
EAX_DIGEST(&self->enc_ctx.aes256_eax.ctx, aes256_encrypt, 16, mac);
return true;
}
static ssize_t crypto_cipher_aes256_eax_decrypt(struct crypto_cipher* self,
uint8_t* dst, uint8_t* mac, const uint8_t* src, size_t len,
const uint8_t* ad, size_t ad_len)
{
crypto_aes256_eax_update_nonce(&self->dec_ctx.aes256_eax);
EAX_UPDATE(&self->dec_ctx.aes256_eax.ctx, aes256_encrypt, ad_len, ad);
EAX_DECRYPT(&self->dec_ctx.aes256_eax.ctx, aes256_encrypt, len, dst, src);
EAX_DIGEST(&self->dec_ctx.aes256_eax.ctx, aes256_encrypt, 16, mac);
return len;
}
static struct crypto_cipher* crypto_cipher_new_aes256_eax(const uint8_t* enc_key,
const uint8_t* dec_key)
{
struct crypto_cipher* self = calloc(1, sizeof(*self));
if (!self)
return NULL;
EAX_SET_KEY(&self->enc_ctx.aes256_eax.ctx, aes256_set_encrypt_key,
aes256_encrypt, enc_key);
EAX_SET_KEY(&self->dec_ctx.aes256_eax.ctx, aes256_set_encrypt_key,
aes256_encrypt, dec_key);
self->encrypt = crypto_cipher_aes256_eax_encrypt;
self->decrypt = crypto_cipher_aes256_eax_decrypt;
return self;
}
struct crypto_cipher* crypto_cipher_new(const uint8_t* enc_key, struct crypto_cipher* crypto_cipher_new(const uint8_t* enc_key,
const uint8_t* dec_key, enum crypto_cipher_type type) const uint8_t* dec_key, enum crypto_cipher_type type)
{ {
@ -389,6 +458,8 @@ struct crypto_cipher* crypto_cipher_new(const uint8_t* enc_key,
return crypto_cipher_new_aes128_ecb(enc_key, dec_key); return crypto_cipher_new_aes128_ecb(enc_key, dec_key);
case CRYPTO_CIPHER_AES_EAX: case CRYPTO_CIPHER_AES_EAX:
return crypto_cipher_new_aes_eax(enc_key, dec_key); return crypto_cipher_new_aes_eax(enc_key, dec_key);
case CRYPTO_CIPHER_AES256_EAX:
return crypto_cipher_new_aes256_eax(enc_key, dec_key);
case CRYPTO_CIPHER_INVALID: case CRYPTO_CIPHER_INVALID:
break; break;
} }