implemented aes key validation
This commit is contained in:
@@ -13,6 +13,12 @@ static inline void __Array_readNext(u8* dst, Array(u8)* src, size_t size){
|
||||
*src = Array_sliceFrom(*src, size);
|
||||
}
|
||||
|
||||
static void __calcKeyCheckSum(Array(u8) key, void* dst){
|
||||
br_sha256_context sha_ctx;
|
||||
br_sha256_init(&sha_ctx);
|
||||
br_sha256_update(&sha_ctx, key.data, key.size);
|
||||
br_sha256_out(&sha_ctx, dst);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AESBlockEncryptor //
|
||||
@@ -20,20 +26,20 @@ static inline void __Array_readNext(u8* dst, Array(u8)* src, size_t size){
|
||||
|
||||
void AESBlockEncryptor_construct(AESBlockEncryptor* ptr,
|
||||
Array(u8) key, const br_block_cbcenc_class* enc_class)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
{
|
||||
ptr->enc_class = enc_class;
|
||||
ptr->enc_class->init((void*)ptr->enc_keys, key.data, key.size);
|
||||
AESBlockEncryptor_changeKey(ptr, key);
|
||||
|
||||
ptr->rng_ctx.vtable = &br_hmac_drbg_vtable;
|
||||
rng_init_sha256_seedFromSystem(&ptr->rng_ctx.vtable);
|
||||
|
||||
}
|
||||
|
||||
void AESBlockEncryptor_changeKey(AESBlockEncryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->enc_class->init((void*)ptr->enc_keys, key.data, key.size);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
@@ -50,6 +56,7 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
|
||||
EncryptedBlockHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
memcpy(header.key_checksum, ptr->key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
header.padding_size = (16 - src.size % 16) % 16;
|
||||
// write header to buffer
|
||||
memcpy(ptr->buf, &header, sizeof(header));
|
||||
@@ -89,16 +96,15 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
void AESBlockDecryptor_construct(AESBlockDecryptor* ptr,
|
||||
Array(u8) key, const br_block_cbcdec_class* dec_class)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
ptr->dec_class = dec_class;
|
||||
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.size);
|
||||
AESBlockDecryptor_changeKey(ptr, key);
|
||||
}
|
||||
|
||||
void AESBlockDecryptor_changeKey(AESBlockDecryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.size);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
@@ -118,7 +124,14 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
__Array_readNext((void*)&header, &src, sizeof(header));
|
||||
// decrypt header
|
||||
ptr->dec_class->run((void*)ptr->dec_keys, ptr->iv, &header, sizeof(header));
|
||||
|
||||
// validate decrypted data
|
||||
if(memcmp(header.key_checksum, ptr->key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE) != 0){
|
||||
Return RESULT_ERROR("decrypted data is invalid or key is wrong", false);
|
||||
}
|
||||
|
||||
// size of decrypted data without padding
|
||||
try_assert(src.size >= header.padding_size && "invalid padding size");
|
||||
u32 decrypted_size = src.size - header.padding_size;
|
||||
src.size = decrypted_size;
|
||||
|
||||
@@ -153,23 +166,21 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
void AESStreamEncryptor_construct(AESStreamEncryptor* ptr,
|
||||
Array(u8) key, const br_block_ctr_class* ctr_class)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
ptr->ctr_class = ctr_class;
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
AESStreamEncryptor_changeKey(ptr, key);
|
||||
ptr->block_counter = 0;
|
||||
|
||||
br_hmac_drbg_context rng_ctx;
|
||||
rng_ctx.vtable = &br_hmac_drbg_vtable;
|
||||
rng_init_sha256_seedFromSystem(&rng_ctx.vtable);
|
||||
br_hmac_drbg_generate(&rng_ctx, ptr->iv, __AES_STREAM_IV_SIZE);
|
||||
|
||||
ptr->block_counter = 0;
|
||||
}
|
||||
|
||||
void AESStreamEncryptor_changeKey(AESStreamEncryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
@@ -178,17 +189,27 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
Deferral(4);
|
||||
|
||||
u32 encrypted_size = src.size;
|
||||
// if it is the beginning of the stream, write IV
|
||||
// if it is the beginning of the stream,
|
||||
if(ptr->block_counter == 0){
|
||||
// write IV generated during initialization
|
||||
__Array_writeNext(&dst, ptr->iv, __AES_STREAM_IV_SIZE);
|
||||
encrypted_size = AESStreamEncryptor_calcDstSize(encrypted_size);
|
||||
|
||||
// encrypt checksum
|
||||
u8 key_checksum[__AES_BLOCK_KEY_CHECKSUM_SIZE];
|
||||
memcpy(key_checksum, ptr->key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
// write checksum to dst
|
||||
__Array_writeNext(&dst, key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
}
|
||||
try_assert(dst.size >= encrypted_size);
|
||||
|
||||
// encrypt full buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, __AES_BUFFER_SIZE);
|
||||
__Array_writeNext(&dst, ptr->buf, __AES_BUFFER_SIZE);
|
||||
@@ -197,13 +218,12 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
// encrypt remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, src.size);
|
||||
memcpy(dst.data, ptr->buf, src.size);
|
||||
}
|
||||
|
||||
ptr->block_counter++;
|
||||
Return RESULT_VALUE(u, encrypted_size);
|
||||
}
|
||||
|
||||
@@ -215,11 +235,8 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
void AESStreamDecryptor_construct(AESStreamDecryptor* ptr,
|
||||
Array(u8) key, const br_block_ctr_class* ctr_class)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
|
||||
ptr->ctr_class = ctr_class;
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
|
||||
AESStreamDecryptor_changeKey(ptr, key);
|
||||
ptr->block_counter = 0;
|
||||
}
|
||||
|
||||
@@ -227,6 +244,7 @@ void AESStreamDecryptor_changeKey(AESStreamDecryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
@@ -234,9 +252,22 @@ Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
{
|
||||
Deferral(4);
|
||||
|
||||
// if it is the beginning of the stream, read IV
|
||||
// if it is the beginning of the stream
|
||||
if(ptr->block_counter == 0){
|
||||
// read random IV
|
||||
__Array_readNext(ptr->iv, &src, __AES_STREAM_IV_SIZE);
|
||||
|
||||
// read checksum
|
||||
u8 key_checksum[__AES_BLOCK_KEY_CHECKSUM_SIZE];
|
||||
__Array_readNext(key_checksum, &src, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
// decrypt checksum
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
// validate decrypted data
|
||||
if(memcmp(key_checksum, ptr->key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE) != 0){
|
||||
Return RESULT_ERROR("decrypted data is invalid or key is wrong", false);
|
||||
}
|
||||
}
|
||||
// size without IV
|
||||
u32 decrypted_size = src.size;
|
||||
@@ -245,7 +276,7 @@ Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
// decrypt full buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, __AES_BUFFER_SIZE);
|
||||
__Array_writeNext(&dst, ptr->buf, __AES_BUFFER_SIZE);
|
||||
@@ -254,12 +285,11 @@ Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
// decrypt remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, src.size);
|
||||
memcpy(dst.data, ptr->buf, src.size);
|
||||
}
|
||||
|
||||
ptr->block_counter++;
|
||||
Return RESULT_VALUE(u, decrypted_size);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user