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.