From c583dbea70bf113d30e47685307c162148556b4a Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 23 Oct 2020 12:47:27 -0700 Subject: [PATCH] Have fewer opaque booleans in aead_test.cc These booleans are a little hard to understand in context and adding any more makes things even more complicated. Thus make them flags so that the meaning is articulated locally. Change-Id: I8cdb7fd5657bb12f28a73d7c6818d400c987ad3b Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43684 Commit-Queue: David Benjamin Reviewed-by: David Benjamin --- crypto/cipher_extra/aead_test.cc | 142 +++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 46 deletions(-) diff --git a/crypto/cipher_extra/aead_test.cc b/crypto/cipher_extra/aead_test.cc index fdf71b056..02e0d9947 100644 --- a/crypto/cipher_extra/aead_test.cc +++ b/crypto/cipher_extra/aead_test.cc @@ -30,73 +30,119 @@ #include "../test/test_util.h" #include "../test/wycheproof_util.h" +// kLimitedImplementation indicates that tests that assume a generic AEAD +// interface should not be performed. For example, the key-wrap AEADs only +// handle inputs that are a multiple of eight bytes in length and the TLS CBC +// AEADs have the concept of “direction”. +constexpr uint32_t kLimitedImplementation = 1 << 0; +// kCanTruncateTags indicates that the AEAD supports truncatating tags to +// arbitrary lengths. +constexpr uint32_t kCanTruncateTags = 1 << 1; +// kVariableNonce indicates that the AEAD supports a variable-length nonce. +constexpr uint32_t kVariableNonce = 1 << 2; + +// RequiresADLength encodes an AD length requirement into flags. +constexpr uint32_t RequiresADLength(size_t length) { + // If we had a more recent C++ version we could assert that the length is + // sufficiently small with: + // + // if (length >= 16) { + // __builtin_unreachable(); + // } + return (length & 0xf) << 3; +} + +// RequiredADLength returns the AD length requirement encoded in |flags|, or +// zero if there isn't one. +constexpr size_t RequiredADLength(uint32_t flags) { + return (flags >> 3) & 0xf; +} struct KnownAEAD { const char name[40]; const EVP_AEAD *(*func)(void); const char *test_vectors; - // limited_implementation indicates that tests that assume a generic AEAD - // interface should not be performed. For example, the key-wrap AEADs only - // handle inputs that are a multiple of eight bytes in length and the TLS CBC - // AEADs have the concept of “direction”. - bool limited_implementation; - // truncated_tags is true if the AEAD supports truncating tags to arbitrary - // lengths. - bool truncated_tags; - // variable_nonce is true if the AEAD supports a variable nonce length. - bool variable_nonce; - // ad_len, if non-zero, is the required length of the AD. - size_t ad_len; + uint32_t flags; }; static const struct KnownAEAD kAEADs[] = { - {"AES_128_GCM", EVP_aead_aes_128_gcm, "aes_128_gcm_tests.txt", false, true, - true, 0}, + {"AES_128_GCM", EVP_aead_aes_128_gcm, "aes_128_gcm_tests.txt", + kCanTruncateTags | kVariableNonce}, + {"AES_128_GCM_NIST", EVP_aead_aes_128_gcm, "nist_cavp/aes_128_gcm.txt", - false, true, true, 0}, - {"AES_192_GCM", EVP_aead_aes_192_gcm, "aes_192_gcm_tests.txt", false, true, - true, 0}, - {"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt", false, true, - true, 0}, + kCanTruncateTags | kVariableNonce}, + + {"AES_192_GCM", EVP_aead_aes_192_gcm, "aes_192_gcm_tests.txt", + kCanTruncateTags | kVariableNonce}, + + {"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt", + kCanTruncateTags | kVariableNonce}, + {"AES_256_GCM_NIST", EVP_aead_aes_256_gcm, "nist_cavp/aes_256_gcm.txt", - false, true, true, 0}, + kCanTruncateTags | kVariableNonce}, + {"AES_128_GCM_SIV", EVP_aead_aes_128_gcm_siv, "aes_128_gcm_siv_tests.txt", - false, false, false, 0}, + 0}, + {"AES_256_GCM_SIV", EVP_aead_aes_256_gcm_siv, "aes_256_gcm_siv_tests.txt", - false, false, false, 0}, + 0}, + {"ChaCha20Poly1305", EVP_aead_chacha20_poly1305, - "chacha20_poly1305_tests.txt", false, true, false, 0}, + "chacha20_poly1305_tests.txt", kCanTruncateTags}, + {"XChaCha20Poly1305", EVP_aead_xchacha20_poly1305, - "xchacha20_poly1305_tests.txt", false, true, false, 0}, + "xchacha20_poly1305_tests.txt", kCanTruncateTags}, + {"AES_128_CBC_SHA1_TLS", EVP_aead_aes_128_cbc_sha1_tls, - "aes_128_cbc_sha1_tls_tests.txt", true, false, false, 11}, + "aes_128_cbc_sha1_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_128_CBC_SHA1_TLSImplicitIV", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, - "aes_128_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11}, + "aes_128_cbc_sha1_tls_implicit_iv_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_128_CBC_SHA256_TLS", EVP_aead_aes_128_cbc_sha256_tls, - "aes_128_cbc_sha256_tls_tests.txt", true, false, false, 11}, + "aes_128_cbc_sha256_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_256_CBC_SHA1_TLS", EVP_aead_aes_256_cbc_sha1_tls, - "aes_256_cbc_sha1_tls_tests.txt", true, false, false, 11}, + "aes_256_cbc_sha1_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_256_CBC_SHA1_TLSImplicitIV", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, - "aes_256_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11}, + "aes_256_cbc_sha1_tls_implicit_iv_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_256_CBC_SHA256_TLS", EVP_aead_aes_256_cbc_sha256_tls, - "aes_256_cbc_sha256_tls_tests.txt", true, false, false, 11}, + "aes_256_cbc_sha256_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_256_CBC_SHA384_TLS", EVP_aead_aes_256_cbc_sha384_tls, - "aes_256_cbc_sha384_tls_tests.txt", true, false, false, 11}, + "aes_256_cbc_sha384_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"DES_EDE3_CBC_SHA1_TLS", EVP_aead_des_ede3_cbc_sha1_tls, - "des_ede3_cbc_sha1_tls_tests.txt", true, false, false, 11}, + "des_ede3_cbc_sha1_tls_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"DES_EDE3_CBC_SHA1_TLSImplicitIV", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, - "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt", true, false, false, 11}, + "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt", + kLimitedImplementation | RequiresADLength(11)}, + {"AES_128_CTR_HMAC_SHA256", EVP_aead_aes_128_ctr_hmac_sha256, - "aes_128_ctr_hmac_sha256.txt", false, true, false, 0}, + "aes_128_ctr_hmac_sha256.txt", kCanTruncateTags}, + {"AES_256_CTR_HMAC_SHA256", EVP_aead_aes_256_ctr_hmac_sha256, - "aes_256_ctr_hmac_sha256.txt", false, true, false, 0}, + "aes_256_ctr_hmac_sha256.txt", kCanTruncateTags}, + {"AES_128_CCM_BLUETOOTH", EVP_aead_aes_128_ccm_bluetooth, - "aes_128_ccm_bluetooth_tests.txt", false, false, false, 0}, + "aes_128_ccm_bluetooth_tests.txt", 0}, + {"AES_128_CCM_BLUETOOTH_8", EVP_aead_aes_128_ccm_bluetooth_8, - "aes_128_ccm_bluetooth_8_tests.txt", false, false, false, 0}, + "aes_128_ccm_bluetooth_8_tests.txt", 0}, }; class PerAEADTest : public testing::TestWithParam { @@ -409,7 +455,7 @@ TEST_P(PerAEADTest, CleanupAfterInitFailure) { } TEST_P(PerAEADTest, TruncatedTags) { - if (!GetParam().truncated_tags) { + if (!(GetParam().flags & kCanTruncateTags)) { return; } @@ -469,7 +515,7 @@ TEST_P(PerAEADTest, TruncatedTags) { } TEST_P(PerAEADTest, AliasedBuffers) { - if (GetParam().limited_implementation) { + if (GetParam().flags & kLimitedImplementation) { return; } @@ -555,8 +601,9 @@ TEST_P(PerAEADTest, UnalignedInput) { ASSERT_GE(sizeof(key) - 1, key_len); const size_t nonce_len = EVP_AEAD_nonce_length(aead()); ASSERT_GE(sizeof(nonce) - 1, nonce_len); - const size_t ad_len = - GetParam().ad_len != 0 ? GetParam().ad_len : sizeof(ad) - 1; + const size_t ad_len = RequiredADLength(GetParam().flags) != 0 + ? RequiredADLength(GetParam().flags) + : sizeof(ad) - 1; ASSERT_GE(sizeof(ad) - 1, ad_len); // Encrypt some input. @@ -619,7 +666,7 @@ TEST_P(PerAEADTest, InvalidNonceLength) { // variable-length nonces, it does not allow the empty nonce. nonce_lens.push_back(0); } - if (!GetParam().variable_nonce) { + if (!(GetParam().flags & kVariableNonce)) { nonce_lens.push_back(valid_nonce_len + 1); if (valid_nonce_len != 0) { nonce_lens.push_back(valid_nonce_len - 1); @@ -627,7 +674,9 @@ TEST_P(PerAEADTest, InvalidNonceLength) { } static const uint8_t kZeros[EVP_AEAD_MAX_KEY_LENGTH] = {0}; - const size_t ad_len = GetParam().ad_len != 0 ? GetParam().ad_len : 16; + const size_t ad_len = RequiredADLength(GetParam().flags) != 0 + ? RequiredADLength(GetParam().flags) + : 16; ASSERT_LE(ad_len, sizeof(kZeros)); for (size_t nonce_len : nonce_lens) { @@ -723,9 +772,10 @@ TEST_P(PerAEADTest, ABI) { alignas(2) uint8_t ad_buf[512]; OPENSSL_memset(ad_buf, 'A', sizeof(ad_buf)); const uint8_t *const ad = ad_buf + 1; - ASSERT_LE(GetParam().ad_len, sizeof(ad_buf) - 1); - const size_t ad_len = - GetParam().ad_len != 0 ? GetParam().ad_len : sizeof(ad_buf) - 1; + ASSERT_LE(RequiredADLength(GetParam().flags), sizeof(ad_buf) - 1); + const size_t ad_len = RequiredADLength(GetParam().flags) != 0 + ? RequiredADLength(GetParam().flags) + : sizeof(ad_buf) - 1; uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; const size_t nonce_len = EVP_AEAD_nonce_length(aead());