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 \