botan: Add support for AES in ECB mode to support DRBG_CTR_AES

This DRBG is used to test ML-KEM.
This commit is contained in:
Tobias Brunner
2024-11-22 14:03:17 +01:00
parent 0a3889086d
commit ebdaab6861
2 changed files with 98 additions and 24 deletions
+94 -21
View File
@@ -1,4 +1,6 @@
/*
* Copyright (C) 2024 Tobias Brunner
*
* Copyright (C) 2018 René Korthaus
* Copyright (C) 2018 Konstantinos Kolelis
* Copyright (C) 2018 Tobias Hommel
@@ -48,23 +50,86 @@ struct private_botan_crypter_t {
*/
chunk_t key;
/**
* Algorithm identifier
*/
encryption_algorithm_t alg;
/**
* The cipher name
*/
const char* cipher_name;
};
/**
* Do the actual en/decryption in ECB, which requires a separate "raw" API.
*/
static bool crypt_ecb(private_botan_crypter_t *this, uint8_t *in, uint8_t *out,
size_t len, uint32_t init_flag)
{
botan_block_cipher_t cipher;
size_t blocks = len / AES_BLOCK_SIZE;
bool success = FALSE;
if (len % AES_BLOCK_SIZE)
{
return FALSE;
}
if (botan_block_cipher_init(&cipher, this->cipher_name) ||
botan_block_cipher_set_key(cipher, this->key.ptr, this->key.len))
{
return FALSE;
}
if (init_flag == BOTAN_CIPHER_INIT_FLAG_ENCRYPT)
{
success = !botan_block_cipher_encrypt_blocks(cipher, in, out, blocks);
}
else
{
success = !botan_block_cipher_decrypt_blocks(cipher, in, out, blocks);
}
botan_block_cipher_destroy(cipher);
return success;
}
/**
* Do the actual en/decryption for modes other than ECB.
*/
static bool crypt_modes(private_botan_crypter_t *this, chunk_t iv, uint8_t *in,
uint8_t *out, size_t len, uint32_t init_flag)
{
botan_cipher_t cipher;
size_t output_written = 0;
size_t input_consumed = 0;
bool success = FALSE;
if (botan_cipher_init(&cipher, this->cipher_name, init_flag))
{
return FALSE;
}
if (!botan_cipher_set_key(cipher, this->key.ptr, this->key.len) &&
!botan_cipher_start(cipher, iv.ptr, iv.len) &&
!botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, out,
len, &output_written, in, len, &input_consumed) &&
(output_written == input_consumed))
{
success = TRUE;
}
botan_cipher_destroy(cipher);
return success;
}
/**
* Do the actual en/decryption
*/
static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv,
chunk_t *dst, uint32_t init_flag)
{
botan_cipher_t cipher;
size_t output_written = 0;
size_t input_consumed = 0;
uint8_t *in, *out;
bool success = FALSE;
in = data.ptr;
if (dst)
@@ -77,23 +142,11 @@ static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv,
out = data.ptr;
}
if (botan_cipher_init(&cipher, this->cipher_name, init_flag))
if (this->alg == ENCR_AES_ECB)
{
return FALSE;
return crypt_ecb(this, in, out, data.len, init_flag);
}
if (!botan_cipher_set_key(cipher, this->key.ptr, this->key.len) &&
!botan_cipher_start(cipher, iv.ptr, iv.len) &&
!botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, out,
data.len, &output_written, in, data.len,
&input_consumed) &&
(output_written == input_consumed))
{
success = TRUE;
}
botan_cipher_destroy(cipher);
return success;
return crypt_modes(this, iv, in, out, data.len, init_flag);
}
METHOD(crypter_t, decrypt, bool,
@@ -102,7 +155,6 @@ METHOD(crypter_t, decrypt, bool,
return crypt(this, data, iv, dst, BOTAN_CIPHER_INIT_FLAG_DECRYPT);
}
METHOD(crypter_t, encrypt, bool,
private_botan_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{
@@ -118,7 +170,7 @@ METHOD(crypter_t, get_block_size, size_t,
METHOD(crypter_t, get_iv_size, size_t,
private_botan_crypter_t *this)
{
return AES_BLOCK_SIZE;
return this->alg == ENCR_AES_ECB ? 0 : AES_BLOCK_SIZE;
}
METHOD(crypter_t, get_key_size, size_t,
@@ -161,10 +213,31 @@ botan_crypter_t *botan_crypter_create(encryption_algorithm_t algo,
.destroy = _destroy,
},
},
.alg = algo,
);
switch (algo)
{
case ENCR_AES_ECB:
switch (key_size)
{
case 16:
/* AES 128 */
this->cipher_name = "AES-128";
break;
case 24:
/* AES-192 */
this->cipher_name = "AES-192";
break;
case 32:
/* AES-256 */
this->cipher_name = "AES-256";
break;
default:
free(this);
return NULL;
}
break;
case ENCR_AES_CBC:
switch (key_size)
{
@@ -104,9 +104,11 @@ METHOD(plugin_t, get_features, int,
#endif
/* crypters */
#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
#if defined(BOTAN_HAS_AES)
PLUGIN_REGISTER(CRYPTER, botan_crypter_create),
#ifdef BOTAN_HAS_AES
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 16),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 24),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 32),
#ifdef BOTAN_HAS_MODE_CBC
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
@@ -117,7 +119,6 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CFB, 24),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CFB, 32),
#endif
#endif
#endif
/* AEAD */