crypto: Add AES256-EAX cipher
parent
c6df99ec46
commit
f029484a87
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue