From: Tobias Brunner Date: Wed, 23 Oct 2024 15:14:56 +0000 (+0200) Subject: botan: Add support for AES in ECB mode to support DRBG_CTR_AES X-Git-Tag: 6.0.0rc1~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebdaab6861c8a948131c0d38094ebc415999c248;p=thirdparty%2Fstrongswan.git botan: Add support for AES in ECB mode to support DRBG_CTR_AES This DRBG is used to test ML-KEM. --- diff --git a/src/libstrongswan/plugins/botan/botan_crypter.c b/src/libstrongswan/plugins/botan/botan_crypter.c index d3ccb4bb9b..708c7727ad 100644 --- a/src/libstrongswan/plugins/botan/botan_crypter.c +++ b/src/libstrongswan/plugins/botan/botan_crypter.c @@ -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,6 +50,11 @@ struct private_botan_crypter_t { */ chunk_t key; + /** + * Algorithm identifier + */ + encryption_algorithm_t alg; + /** * The cipher name */ @@ -55,27 +62,48 @@ struct private_botan_crypter_t { }; /** - * Do the actual en/decryption + * Do the actual en/decryption in ECB, which requires a separate "raw" API. */ -static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv, - chunk_t *dst, uint32_t init_flag) +static bool crypt_ecb(private_botan_crypter_t *this, 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; - uint8_t *in, *out; + botan_block_cipher_t cipher; + size_t blocks = len / AES_BLOCK_SIZE; bool success = FALSE; - in = data.ptr; - if (dst) + if (len % AES_BLOCK_SIZE) { - *dst = chunk_alloc(data.len); - out = dst->ptr; + 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 { - out = data.ptr; + 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)) { @@ -85,8 +113,7 @@ static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv, 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) && + len, &output_written, in, len, &input_consumed) && (output_written == input_consumed)) { success = TRUE; @@ -96,13 +123,38 @@ static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv, 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) +{ + uint8_t *in, *out; + + in = data.ptr; + if (dst) + { + *dst = chunk_alloc(data.len); + out = dst->ptr; + } + else + { + out = data.ptr; + } + + if (this->alg == ENCR_AES_ECB) + { + return crypt_ecb(this, in, out, data.len, init_flag); + } + return crypt_modes(this, iv, in, out, data.len, init_flag); +} + METHOD(crypter_t, decrypt, bool, private_botan_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { 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) { diff --git a/src/libstrongswan/plugins/botan/botan_plugin.c b/src/libstrongswan/plugins/botan/botan_plugin.c index 3fe3297658..30a6dcce68 100644 --- a/src/libstrongswan/plugins/botan/botan_plugin.c +++ b/src/libstrongswan/plugins/botan/botan_plugin.c @@ -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 */