From 8c006d2d7a3e0e4d2c21855540c8d85971d256cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Thu, 25 Jul 2024 16:54:37 +0200 Subject: [PATCH] src: simplify AESCipherTraits::AdditionalConfig Instead of a giant switch statement and a lot of duplicate code, add the NID and the block cipher mode of operation to the VARIANTS list and use those fields to perform configuration appropriately. PR-URL: https://github.com/nodejs/node/pull/53890 Reviewed-By: Yagiz Nizipli --- src/crypto/crypto_aes.cc | 99 +++++++++++----------------------------- src/crypto/crypto_aes.h | 35 ++++++++------ 2 files changed, 48 insertions(+), 86 deletions(-) diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index 6ec43c0a461e78..774030d408711c 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -476,83 +476,38 @@ Maybe AESCipherTraits::AdditionalConfig( params->variant = static_cast(args[offset].As()->Value()); + AESCipherMode cipher_op_mode; int cipher_nid; +#define V(name, _, mode, nid) \ + case kKeyVariantAES_##name: { \ + cipher_op_mode = mode; \ + cipher_nid = nid; \ + break; \ + } switch (params->variant) { - case kKeyVariantAES_CTR_128: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateCounter(env, args[offset + 2], params)) { - return Nothing(); - } - cipher_nid = NID_aes_128_ctr; - break; - case kKeyVariantAES_CTR_192: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateCounter(env, args[offset + 2], params)) { - return Nothing(); - } - cipher_nid = NID_aes_192_ctr; - break; - case kKeyVariantAES_CTR_256: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateCounter(env, args[offset + 2], params)) { - return Nothing(); - } - cipher_nid = NID_aes_256_ctr; - break; - case kKeyVariantAES_CBC_128: - if (!ValidateIV(env, mode, args[offset + 1], params)) - return Nothing(); - cipher_nid = NID_aes_128_cbc; - break; - case kKeyVariantAES_CBC_192: - if (!ValidateIV(env, mode, args[offset + 1], params)) - return Nothing(); - cipher_nid = NID_aes_192_cbc; - break; - case kKeyVariantAES_CBC_256: - if (!ValidateIV(env, mode, args[offset + 1], params)) - return Nothing(); - cipher_nid = NID_aes_256_cbc; - break; - case kKeyVariantAES_KW_128: - UseDefaultIV(params); - cipher_nid = NID_id_aes128_wrap; - break; - case kKeyVariantAES_KW_192: - UseDefaultIV(params); - cipher_nid = NID_id_aes192_wrap; - break; - case kKeyVariantAES_KW_256: - UseDefaultIV(params); - cipher_nid = NID_id_aes256_wrap; - break; - case kKeyVariantAES_GCM_128: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateAuthTag(env, mode, cipher_mode, args[offset + 2], params) || - !ValidateAdditionalData(env, mode, args[offset + 3], params)) { - return Nothing(); - } - cipher_nid = NID_aes_128_gcm; - break; - case kKeyVariantAES_GCM_192: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateAuthTag(env, mode, cipher_mode, args[offset + 2], params) || - !ValidateAdditionalData(env, mode, args[offset + 3], params)) { + VARIANTS(V) + default: + UNREACHABLE(); + } +#undef V + + if (cipher_op_mode != AESCipherMode::KW) { + if (!ValidateIV(env, mode, args[offset + 1], params)) { + return Nothing(); + } + if (cipher_op_mode == AESCipherMode::CTR) { + if (!ValidateCounter(env, args[offset + 2], params)) { return Nothing(); } - cipher_nid = NID_aes_192_gcm; - break; - case kKeyVariantAES_GCM_256: - if (!ValidateIV(env, mode, args[offset + 1], params) || - !ValidateAuthTag(env, mode, cipher_mode, args[offset + 2], params) || + } else if (cipher_op_mode == AESCipherMode::GCM) { + if (!ValidateAuthTag(env, mode, cipher_mode, args[offset + 2], params) || !ValidateAdditionalData(env, mode, args[offset + 3], params)) { return Nothing(); } - cipher_nid = NID_aes_256_gcm; - break; - default: - UNREACHABLE(); + } + } else { + UseDefaultIV(params); } params->cipher = EVP_get_cipherbynid(cipher_nid); @@ -577,8 +532,8 @@ WebCryptoCipherStatus AESCipherTraits::DoCipher( const AESCipherConfig& params, const ByteSource& in, ByteSource* out) { -#define V(name, fn) \ - case kKeyVariantAES_ ## name: \ +#define V(name, fn, _, __) \ + case kKeyVariantAES_##name: \ return fn(env, key_data.get(), cipher_mode, params, in, out); switch (params.variant) { VARIANTS(V) @@ -591,7 +546,7 @@ WebCryptoCipherStatus AESCipherTraits::DoCipher( void AES::Initialize(Environment* env, Local target) { AESCryptoJob::Initialize(env, target); -#define V(name, _) NODE_DEFINE_CONSTANT(target, kKeyVariantAES_ ## name); +#define V(name, _, __, ___) NODE_DEFINE_CONSTANT(target, kKeyVariantAES_##name); VARIANTS(V) #undef V } diff --git a/src/crypto/crypto_aes.h b/src/crypto/crypto_aes.h index 9dfa5edc6544e7..2ddbc14b8e606e 100644 --- a/src/crypto/crypto_aes.h +++ b/src/crypto/crypto_aes.h @@ -15,22 +15,29 @@ constexpr size_t kAesBlockSize = 16; constexpr unsigned kNoAuthTagLength = static_cast(-1); constexpr const char* kDefaultWrapIV = "\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"; -#define VARIANTS(V) \ - V(CTR_128, AES_CTR_Cipher) \ - V(CTR_192, AES_CTR_Cipher) \ - V(CTR_256, AES_CTR_Cipher) \ - V(CBC_128, AES_Cipher) \ - V(CBC_192, AES_Cipher) \ - V(CBC_256, AES_Cipher) \ - V(GCM_128, AES_Cipher) \ - V(GCM_192, AES_Cipher) \ - V(GCM_256, AES_Cipher) \ - V(KW_128, AES_Cipher) \ - V(KW_192, AES_Cipher) \ - V(KW_256, AES_Cipher) +enum class AESCipherMode { + CTR, + CBC, + GCM, + KW, +}; + +#define VARIANTS(V) \ + V(CTR_128, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_128_ctr) \ + V(CTR_192, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_192_ctr) \ + V(CTR_256, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_256_ctr) \ + V(CBC_128, AES_Cipher, AESCipherMode::CBC, NID_aes_128_cbc) \ + V(CBC_192, AES_Cipher, AESCipherMode::CBC, NID_aes_192_cbc) \ + V(CBC_256, AES_Cipher, AESCipherMode::CBC, NID_aes_256_cbc) \ + V(GCM_128, AES_Cipher, AESCipherMode::GCM, NID_aes_128_gcm) \ + V(GCM_192, AES_Cipher, AESCipherMode::GCM, NID_aes_192_gcm) \ + V(GCM_256, AES_Cipher, AESCipherMode::GCM, NID_aes_256_gcm) \ + V(KW_128, AES_Cipher, AESCipherMode::KW, NID_id_aes128_wrap) \ + V(KW_192, AES_Cipher, AESCipherMode::KW, NID_id_aes192_wrap) \ + V(KW_256, AES_Cipher, AESCipherMode::KW, NID_id_aes256_wrap) enum AESKeyVariant { -#define V(name, _) kKeyVariantAES_ ## name, +#define V(name, _, __, ___) kKeyVariantAES_##name, VARIANTS(V) #undef V };