Start extracting AES

Pull out AES_set_encrypt_key, AES_set_decrypto_key
AES_encrypt and AES_decrypt

For now we do not pull out AES_KEY, changes here will
come later.

Bug: 392625969
Change-Id: Iaef168dc7cdbda359efd8a1421509e6f6c657cad
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/75788
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/build.json b/build.json
index d480382..8de3def 100644
--- a/build.json
+++ b/build.json
@@ -161,7 +161,8 @@
         ]
     },
     "crypto": {
-        "srcs": [
+      "srcs": [
+            "crypto/aes/aes.cc",
             "crypto/asn1/a_bitstr.cc",
             "crypto/asn1/a_bool.cc",
             "crypto/asn1/a_d2i_fp.cc",
diff --git a/crypto/aes/aes.cc b/crypto/aes/aes.cc
new file mode 100644
index 0000000..65d93e8
--- /dev/null
+++ b/crypto/aes/aes.cc
@@ -0,0 +1,41 @@
+/* Copyright 2025 The BoringSSL Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <assert.h>
+
+#include <openssl/aes.h>
+
+#include "../fipsmodule/bcm_interface.h"
+
+void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+  BCM_aes_encrypt(in, out, key);
+}
+
+void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+  BCM_aes_decrypt(in, out, key);
+}
+
+int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  if (bits != 128 && bits != 192 && bits != 256) {
+    return -2;
+  }
+  return bcm_success(BCM_aes_set_encrypt_key(key, bits, aeskey)) ? 0 : -1;
+}
+
+int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
+  if (bits != 128 && bits != 192 && bits != 256) {
+    return -2;
+  }
+  return bcm_success(BCM_aes_set_decrypt_key(key, bits, aeskey)) ? 0 : -1;
+}
diff --git a/crypto/fipsmodule/aes/aes.cc.inc b/crypto/fipsmodule/aes/aes.cc.inc
index 26e60e7..6df166b 100644
--- a/crypto/fipsmodule/aes/aes.cc.inc
+++ b/crypto/fipsmodule/aes/aes.cc.inc
@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <openssl/aes.h>
-
 #include <assert.h>
 
 #include "internal.h"
+#include "../bcm_interface.h"
 
 
 // Be aware that different sets of AES functions use incompatible key
@@ -24,7 +23,8 @@
 // value, or both. Therefore they cannot mix. Also, on AArch64, the plain-C
 // code, above, is incompatible with the |aes_hw_*| functions.
 
-void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+bcm_infallible BCM_aes_encrypt(const uint8_t *in, uint8_t *out,
+                               const AES_KEY *key) {
   if (hwaes_capable()) {
     aes_hw_encrypt(in, out, key);
   } else if (vpaes_capable()) {
@@ -32,9 +32,11 @@
   } else {
     aes_nohw_encrypt(in, out, key);
   }
+  return bcm_infallible::not_approved;
 }
 
-void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+bcm_infallible BCM_aes_decrypt(const uint8_t *in, uint8_t *out,
+                               const AES_KEY *key) {
   if (hwaes_capable()) {
     aes_hw_decrypt(in, out, key);
   } else if (vpaes_capable()) {
@@ -42,32 +44,41 @@
   } else {
     aes_nohw_decrypt(in, out, key);
   }
+  return bcm_infallible::not_approved;
 }
 
-int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
-  if (bits != 128 && bits != 192 && bits != 256) {
-    return -2;
-  }
+bcm_status BCM_aes_set_encrypt_key(const uint8_t *key, unsigned bits,
+                                   AES_KEY *aeskey) {
+  int ret = -1;
   if (hwaes_capable()) {
-    return aes_hw_set_encrypt_key(key, bits, aeskey);
+    ret = aes_hw_set_encrypt_key(key, bits, aeskey);
   } else if (vpaes_capable()) {
-    return vpaes_set_encrypt_key(key, bits, aeskey);
+    ret = vpaes_set_encrypt_key(key, bits, aeskey);
   } else {
-    return aes_nohw_set_encrypt_key(key, bits, aeskey);
+    ret = aes_nohw_set_encrypt_key(key, bits, aeskey);
   }
+  if (ret < 0) {
+    return bcm_status::failure;
+  }
+  BSSL_CHECK(ret == 0);
+  return bcm_status::not_approved;
 }
 
-int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
-  if (bits != 128 && bits != 192 && bits != 256) {
-    return -2;
-  }
+bcm_status BCM_aes_set_decrypt_key(const uint8_t *key, unsigned bits,
+                                   AES_KEY *aeskey) {
+  int ret = -1;
   if (hwaes_capable()) {
-    return aes_hw_set_decrypt_key(key, bits, aeskey);
+    ret = aes_hw_set_decrypt_key(key, bits, aeskey);
   } else if (vpaes_capable()) {
-    return vpaes_set_decrypt_key(key, bits, aeskey);
+    ret = vpaes_set_decrypt_key(key, bits, aeskey);
   } else {
-    return aes_nohw_set_decrypt_key(key, bits, aeskey);
+    ret = aes_nohw_set_decrypt_key(key, bits, aeskey);
   }
+  if (ret < 0) {
+    return bcm_status::failure;
+  }
+  BSSL_CHECK(ret == 0);
+  return bcm_status::not_approved;
 }
 
 #if defined(HWAES) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
diff --git a/crypto/fipsmodule/aes/internal.h b/crypto/fipsmodule/aes/internal.h
index 7bf28b9..4bb1531 100644
--- a/crypto/fipsmodule/aes/internal.h
+++ b/crypto/fipsmodule/aes/internal.h
@@ -17,8 +17,7 @@
 
 #include <stdlib.h>
 
-#include <openssl/aes.h>
-
+#include "../bcm_interface.h"
 #include "../../internal.h"
 
 extern "C" {
@@ -29,7 +28,7 @@
 // Unlike upstream OpenSSL, it and the other functions in this file hard-code
 // |AES_KEY|. It is undefined in C to call a function pointer with anything
 // other than the original type. Thus we either must match |block128_f| to the
-// type signature of |AES_encrypt| and friends or pass in |void*| wrapper
+// type signature of |BCM_aes_encrypt| and friends or pass in |void*| wrapper
 // functions.
 //
 // These functions are called exclusively with AES, so we use the former.
diff --git a/crypto/fipsmodule/bcm.cc b/crypto/fipsmodule/bcm.cc
index 6429566..5f025bc 100644
--- a/crypto/fipsmodule/bcm.cc
+++ b/crypto/fipsmodule/bcm.cc
@@ -198,7 +198,7 @@
   const uint8_t *const start = BORINGSSL_bcm_text_start;
   const uint8_t *const end = BORINGSSL_bcm_text_end;
 
-  assert_within(start, reinterpret_cast<const void *>(AES_encrypt), end);
+  assert_within(start, reinterpret_cast<const void *>(BCM_aes_encrypt), end);
   assert_within(start, reinterpret_cast<const void *>(RSA_sign), end);
   assert_within(start, reinterpret_cast<const void *>(BCM_rand_bytes), end);
   assert_within(start, reinterpret_cast<const void *>(EC_GROUP_cmp), end);
diff --git a/crypto/fipsmodule/bcm_interface.h b/crypto/fipsmodule/bcm_interface.h
index 2f53777..204c36f 100644
--- a/crypto/fipsmodule/bcm_interface.h
+++ b/crypto/fipsmodule/bcm_interface.h
@@ -15,8 +15,11 @@
 #ifndef OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H
 #define OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H
 
+// For the moment, we reach out for AES_KEY.
+#include <openssl/aes.h>
 #include <openssl/bcm_public.h>
 
+
 // This header will eventually become the interface between BCM and the
 // rest of libcrypto. More cleanly separating the two is still a work in
 // progress (see https://crbug.com/boringssl/722) so, at the moment, we
@@ -789,6 +792,32 @@
     const uint8_t *context, size_t context_len);
 
 
+// AES
+
+// BCM_aes_encrypt encrypts a single block from |in| to |out| with |key|. The
+// |in| and |out| pointers may overlap.
+OPENSSL_EXPORT bcm_infallible BCM_aes_encrypt(const uint8_t *in, uint8_t *out,
+                                              const AES_KEY *key);
+// BCM_aes_decrypt decrypts a single block from |in| to |out| with |key|. The
+// |in| and |out| pointers may overlap.
+OPENSSL_EXPORT bcm_infallible BCM_aes_decrypt(const uint8_t *in, uint8_t *out,
+                                              const AES_KEY *key);
+
+// BCM_aes_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit
+// key, |key|. |key| must point to |bits|/8 bytes. It will return failure if
+// |bits| is an invalid AES key size.
+OPENSSL_EXPORT bcm_status BCM_aes_set_encrypt_key(const uint8_t *key,
+                                                  unsigned bits,
+                                                  AES_KEY *aeskey);
+
+// BCM_aes_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit
+// key, |key|. |key| must point to |bits|/8 bytes. It will return failure if
+// |bits| is an invalid AES key size.
+OPENSSL_EXPORT bcm_status BCM_aes_set_decrypt_key(const uint8_t *key,
+                                                  unsigned bits,
+                                                  AES_KEY *aeskey);
+
+
 #if defined(__cplusplus)
 }  // extern C
 #endif
diff --git a/gen/sources.bzl b/gen/sources.bzl
index faef20e..9f05e6f 100644
--- a/gen/sources.bzl
+++ b/gen/sources.bzl
@@ -261,6 +261,7 @@
 ]
 
 crypto_sources = [
+    "crypto/aes/aes.cc",
     "crypto/asn1/a_bitstr.cc",
     "crypto/asn1/a_bool.cc",
     "crypto/asn1/a_d2i_fp.cc",
diff --git a/gen/sources.cmake b/gen/sources.cmake
index b193769..46de1ff 100644
--- a/gen/sources.cmake
+++ b/gen/sources.cmake
@@ -275,6 +275,7 @@
 set(
   CRYPTO_SOURCES
 
+  crypto/aes/aes.cc
   crypto/asn1/a_bitstr.cc
   crypto/asn1/a_bool.cc
   crypto/asn1/a_d2i_fp.cc
diff --git a/gen/sources.gni b/gen/sources.gni
index b5324ff..0caf80d 100644
--- a/gen/sources.gni
+++ b/gen/sources.gni
@@ -261,6 +261,7 @@
 ]
 
 crypto_sources = [
+  "crypto/aes/aes.cc",
   "crypto/asn1/a_bitstr.cc",
   "crypto/asn1/a_bool.cc",
   "crypto/asn1/a_d2i_fp.cc",
diff --git a/gen/sources.json b/gen/sources.json
index 183ac5c..a94bd55 100644
--- a/gen/sources.json
+++ b/gen/sources.json
@@ -245,6 +245,7 @@
   },
   "crypto": {
     "srcs": [
+      "crypto/aes/aes.cc",
       "crypto/asn1/a_bitstr.cc",
       "crypto/asn1/a_bool.cc",
       "crypto/asn1/a_d2i_fp.cc",
diff --git a/gen/sources.mk b/gen/sources.mk
index 266d960..e795ee2 100644
--- a/gen/sources.mk
+++ b/gen/sources.mk
@@ -255,6 +255,7 @@
   tool/transport_common.h
 
 boringssl_crypto_sources := \
+  crypto/aes/aes.cc \
   crypto/asn1/a_bitstr.cc \
   crypto/asn1/a_bool.cc \
   crypto/asn1/a_d2i_fp.cc \