Add FIPS counters for AES-GCM in EVP_AEAD.
BUG=b/158221316
Change-Id: I42693f760aa2852902d72622e109c5d9cac2c4d9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49485
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/crypto_test.cc b/crypto/crypto_test.cc
index bf0bcd7..7f15a23 100644
--- a/crypto/crypto_test.cc
+++ b/crypto/crypto_test.cc
@@ -18,6 +18,7 @@
#include <string>
#include <openssl/base.h>
+#include <openssl/aead.h>
#include <openssl/crypto.h>
#include <openssl/cipher.h>
#include <openssl/mem.h>
@@ -43,39 +44,97 @@
}
#if defined(BORINGSSL_FIPS_COUNTERS)
+using CounterArray = size_t[fips_counter_max + 1];
+
+static void read_all_counters(CounterArray counters) {
+ for (fips_counter_t counter = static_cast<fips_counter_t>(0);
+ counter <= fips_counter_max;
+ counter = static_cast<fips_counter_t>(counter + 1)) {
+ counters[counter] = FIPS_read_counter(counter);
+ }
+}
+
+static void expect_counter_delta_is_zero_except_for_a_one_at(
+ CounterArray before, CounterArray after, fips_counter_t position) {
+ for (fips_counter_t counter = static_cast<fips_counter_t>(0);
+ counter <= fips_counter_max;
+ counter = static_cast<fips_counter_t>(counter + 1)) {
+ const size_t expected_delta = counter == position ? 1 : 0;
+ EXPECT_EQ(after[counter], before[counter] + expected_delta) << counter;
+ }
+}
+
TEST(CryptoTest, FIPSCountersEVP) {
constexpr struct {
const EVP_CIPHER *(*cipher)();
fips_counter_t counter;
} kTests[] = {
- {
- EVP_aes_128_gcm,
- fips_counter_evp_aes_128_gcm,
- },
- {
- EVP_aes_256_gcm,
- fips_counter_evp_aes_256_gcm,
- },
- {
- EVP_aes_128_ctr,
- fips_counter_evp_aes_128_ctr,
- },
- {
- EVP_aes_256_ctr,
- fips_counter_evp_aes_256_ctr,
- },
+ {
+ EVP_aes_128_gcm,
+ fips_counter_evp_aes_128_gcm,
+ },
+ {
+ EVP_aes_256_gcm,
+ fips_counter_evp_aes_256_gcm,
+ },
+ {
+ EVP_aes_128_ctr,
+ fips_counter_evp_aes_128_ctr,
+ },
+ {
+ EVP_aes_256_ctr,
+ fips_counter_evp_aes_256_ctr,
+ },
};
uint8_t key[EVP_MAX_KEY_LENGTH] = {0};
uint8_t iv[EVP_MAX_IV_LENGTH] = {1};
-
- for (const auto& test : kTests) {
- const size_t before = FIPS_read_counter(test.counter);
-
+ CounterArray before, after;
+ for (const auto &test : kTests) {
+ read_all_counters(before);
bssl::ScopedEVP_CIPHER_CTX ctx;
ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), test.cipher(), /*engine=*/nullptr,
key, iv));
- ASSERT_GT(FIPS_read_counter(test.counter), before);
+ read_all_counters(after);
+
+ expect_counter_delta_is_zero_except_for_a_one_at(before, after,
+ test.counter);
}
}
+
+TEST(CryptoTest, FIPSCountersEVP_AEAD) {
+ constexpr struct {
+ const EVP_AEAD *(*aead)();
+ unsigned key_len;
+ fips_counter_t counter;
+ } kTests[] = {
+ {
+ EVP_aead_aes_128_gcm,
+ 16,
+ fips_counter_evp_aes_128_gcm,
+ },
+ {
+ EVP_aead_aes_256_gcm,
+ 32,
+ fips_counter_evp_aes_256_gcm,
+ },
+ };
+
+ uint8_t key[EVP_AEAD_MAX_KEY_LENGTH] = {0};
+ CounterArray before, after;
+ for (const auto &test : kTests) {
+ ASSERT_LE(test.key_len, sizeof(key));
+
+ read_all_counters(before);
+ bssl::ScopedEVP_AEAD_CTX ctx;
+ ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), test.aead(), key, test.key_len,
+ EVP_AEAD_DEFAULT_TAG_LENGTH,
+ /*engine=*/nullptr));
+ read_all_counters(after);
+
+ expect_counter_delta_is_zero_except_for_a_one_at(before, after,
+ test.counter);
+ }
+}
+
#endif // BORINGSSL_FIPS_COUNTERS
diff --git a/crypto/fipsmodule/cipher/e_aes.c b/crypto/fipsmodule/cipher/e_aes.c
index f77133f..76f4066 100644
--- a/crypto/fipsmodule/cipher/e_aes.c
+++ b/crypto/fipsmodule/cipher/e_aes.c
@@ -911,6 +911,16 @@
size_t key_len, size_t tag_len) {
const size_t key_bits = key_len * 8;
+ switch (key_bits) {
+ case 128:
+ boringssl_fips_inc_counter(fips_counter_evp_aes_128_gcm);
+ break;
+
+ case 256:
+ boringssl_fips_inc_counter(fips_counter_evp_aes_256_gcm);
+ break;
+ }
+
if (key_bits != 128 && key_bits != 192 && key_bits != 256) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; // EVP_AEAD_CTX_init should catch this.