Commit d1004c62ac for openssl.org

commit d1004c62ace7bc550b755d5bea356473e6d2df32
Author: Simo Sorce <simo@redhat.com>
Date:   Thu Jun 11 17:22:17 2026 -0400

    Consolidate ARMv8 AES hardware implementations

    Move the ARMv8-specific hardware implementations for AES GCM into a single
    consolidated file (`cipher_aes_hw_armv8.c`). This groups architecture-specific
    optimizations together to improve code organization and maintainability.

    Additionally, remove the unused `keybits` parameter from the ARMv8 provider
    functions to simplify the function signatures.

    Signed-off-by: Simo Sorce <simo@redhat.com>

    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Reviewed-by: Norbert Pocs <norbertp@openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    MergeDate: Sat Jun 27 09:05:50 2026
    (Merged from https://github.com/openssl/openssl/pull/31472)

diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info
index 720874ba78..9dcf738946 100644
--- a/providers/implementations/ciphers/build.info
+++ b/providers/implementations/ciphers/build.info
@@ -108,7 +108,7 @@ SOURCE[$AES_GOAL]=\
         cipher_aes_hw_s390x.c cipher_aes_hw_t4.c \
         cipher_aes_xts.c cipher_aes_xts_hw.c \
         cipher_aes_gcm.c cipher_aes_gcm_hw.c \
-        cipher_aes_gcm_hw_armv8.c cipher_aes_gcm_hw_ppc.c \
+        cipher_aes_gcm_hw_ppc.c \
         cipher_aes_gcm_hw_rv32i.c cipher_aes_gcm_hw_rv64i.c \
         cipher_aes_gcm_hw_s390x.c cipher_aes_gcm_hw_t4.c \
         cipher_aes_ccm.c cipher_aes_ccm_hw.c \
diff --git a/providers/implementations/ciphers/cipher_aes.h b/providers/implementations/ciphers/cipher_aes.h
index 313c91ec9c..0f0aff4891 100644
--- a/providers/implementations/ciphers/cipher_aes.h
+++ b/providers/implementations/ciphers/cipher_aes.h
@@ -88,8 +88,7 @@ void ossl_cipher_aes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src);
 #if defined(AESNI_CAPABLE)
 const PROV_CIPHER_HW *ossl_prov_cipher_hw_aesni(enum aes_modes mode);
 #elif defined(ARMv8_HWAES_CAPABLE)
-const PROV_CIPHER_HW *ossl_prov_cipher_hw_arm(enum aes_modes mode,
-    size_t keybits);
+const PROV_CIPHER_HW *ossl_prov_cipher_hw_arm(enum aes_modes mode);
 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32
 const PROV_CIPHER_HW *ossl_prov_cipher_hw_rv32i(enum aes_modes mode,
     size_t keybits);
diff --git a/providers/implementations/ciphers/cipher_aes_gcm.h b/providers/implementations/ciphers/cipher_aes_gcm.h
index 71ee4c97eb..0b8d23fcb9 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm.h
+++ b/providers/implementations/ciphers/cipher_aes_gcm.h
@@ -57,7 +57,7 @@ const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits);
 const PROV_GCM_HW *ossl_prov_aes_hw_gcm_aesni(void);
 #endif
 #if defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
-const PROV_GCM_HW *ossl_prov_aes_hw_gcm_armv8(size_t keybits);
+const PROV_GCM_HW *ossl_prov_aes_hw_gcm_armv8(void);
 #endif
 #if defined(PPC_AES_GCM_CAPABLE) && defined(_ARCH_PPC64)
 const PROV_GCM_HW *ossl_prov_aes_hw_gcm_ppc(size_t keybits);
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
index 41ff71cd21..0d166b545a 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
@@ -158,7 +158,7 @@ const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits)
 #if defined(AESNI_CAPABLE)
     aes_gcm_hw = ossl_prov_aes_hw_gcm_aesni();
 #elif defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
-    aes_gcm_hw = ossl_prov_aes_hw_gcm_armv8(keybits);
+    aes_gcm_hw = ossl_prov_aes_hw_gcm_armv8();
 #elif defined(PPC_AES_GCM_CAPABLE) && defined(_ARCH_PPC64)
     aes_gcm_hw = ossl_prov_aes_hw_gcm_ppc(keybits);
 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.c b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.c
deleted file mode 100644
index 7d50de2a2f..0000000000
--- a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Crypto extension support for AES GCM.
- * This file is used by cipher_aes_gcm_hw.c
- */
-#include "internal/deprecated.h"
-#include "cipher_aes_gcm.h"
-
-#if defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
-
-size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len,
-    const void *key, unsigned char ivec[16], uint64_t *Xi)
-{
-    AES_KEY *aes_key = (AES_KEY *)key;
-    size_t align_bytes = len - len % 16;
-
-    switch (aes_key->rounds) {
-    case 10:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_enc_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_enc_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    case 12:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_enc_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_enc_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    case 14:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_enc_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_enc_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    }
-    return align_bytes;
-}
-
-size_t armv8_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len,
-    const void *key, unsigned char ivec[16], uint64_t *Xi)
-{
-    AES_KEY *aes_key = (AES_KEY *)key;
-    size_t align_bytes = len - len % 16;
-
-    switch (aes_key->rounds) {
-    case 10:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_dec_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_dec_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    case 12:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_dec_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_dec_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    case 14:
-        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
-            unroll8_eor3_aes_gcm_dec_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        } else {
-            aes_gcm_dec_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
-        }
-        break;
-    }
-    return align_bytes;
-}
-
-static int armv8_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
-    size_t keylen)
-{
-    if (AES_UNROLL12_EOR3_CAPABLE) {
-        return aes_gcm_hw_initkey(ctx, key, keylen,
-            aes_v8_set_encrypt_key, aes_v8_encrypt,
-            aes_v8_ctr32_encrypt_blocks_unroll12_eor3);
-    } else {
-        return aes_gcm_hw_initkey(ctx, key, keylen,
-            aes_v8_set_encrypt_key, aes_v8_encrypt,
-            aes_v8_ctr32_encrypt_blocks);
-    }
-}
-
-static const PROV_GCM_HW armv8_aes_gcm = {
-    armv8_aes_gcm_initkey,
-    ossl_gcm_setiv,
-    ossl_gcm_aad_update,
-    generic_aes_gcm_cipher_update,
-    ossl_gcm_cipher_final,
-    ossl_gcm_one_shot
-};
-
-const PROV_GCM_HW *ossl_prov_aes_hw_gcm_armv8(size_t keybits)
-{
-    return AES_PMULL_CAPABLE ? &armv8_aes_gcm : NULL;
-}
-
-#endif
diff --git a/providers/implementations/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c
index 60abfd1165..e71a15cc00 100644
--- a/providers/implementations/ciphers/cipher_aes_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_hw.c
@@ -219,7 +219,7 @@ static const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_mode(enum aes_modes mode,
 #if defined(AESNI_CAPABLE)
     aes_hw_mode = ossl_prov_cipher_hw_aesni(mode);
 #elif defined(ARMv8_HWAES_CAPABLE)
-    aes_hw_mode = ossl_prov_cipher_hw_arm(mode, keybits);
+    aes_hw_mode = ossl_prov_cipher_hw_arm(mode);
 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32
     aes_hw_mode = ossl_prov_cipher_hw_rv32i(mode, keybits);
 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64
diff --git a/providers/implementations/ciphers/cipher_aes_hw_aesni.c b/providers/implementations/ciphers/cipher_aes_hw_aesni.c
index 6264c88426..15e2d71b3e 100644
--- a/providers/implementations/ciphers/cipher_aes_hw_aesni.c
+++ b/providers/implementations/ciphers/cipher_aes_hw_aesni.c
@@ -8,8 +8,7 @@
  */

 /*-
- * AES-NI support for AES modes ecb, cbc, ofb, cfb, ctr.
- * This file is used by cipher_aes_hw.c
+ * AES-NI support for all hardware accelerated AES modes.
  */

 #include "internal/deprecated.h"
diff --git a/providers/implementations/ciphers/cipher_aes_hw_armv8.c b/providers/implementations/ciphers/cipher_aes_hw_armv8.c
index 773e40a411..da4f9fd0e3 100644
--- a/providers/implementations/ciphers/cipher_aes_hw_armv8.c
+++ b/providers/implementations/ciphers/cipher_aes_hw_armv8.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -8,15 +8,17 @@
  */

 /*
- * Crypto extension support for AES modes ecb, cbc, ofb, cfb, ctr.
- * This file is used by cipher_aes_hw.c
+ * ARMv8 support for all hardware accelerated AES modes.
  */

 #include "internal/deprecated.h"
 #include "cipher_aes.h"
+#include "cipher_aes_gcm.h"

 #if defined(ARMv8_HWAES_CAPABLE)

+/* MODES: ctr */
+
 static int cipher_hw_aes_arm_initkey(PROV_CIPHER_CTX *ctx,
     const unsigned char *key, size_t keylen)
 {
@@ -35,8 +37,7 @@ static const PROV_CIPHER_HW arm_ctr = {
     ossl_cipher_aes_copyctx
 };

-const PROV_CIPHER_HW *ossl_prov_cipher_hw_arm(enum aes_modes mode,
-    size_t keybits)
+const PROV_CIPHER_HW *ossl_prov_cipher_hw_arm(enum aes_modes mode)
 {
     if (ARMv8_HWAES_CAPABLE && mode == AES_MODE_CTR)
         return &arm_ctr;
@@ -44,3 +45,101 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_arm(enum aes_modes mode,
 }

 #endif
+
+/* MODES: GCM */
+
+#if defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
+
+size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+    const void *key, unsigned char ivec[16], uint64_t *Xi)
+{
+    AES_KEY *aes_key = (AES_KEY *)key;
+    size_t align_bytes = len - len % 16;
+
+    switch (aes_key->rounds) {
+    case 10:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_enc_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_enc_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    case 12:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_enc_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_enc_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    case 14:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_enc_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_enc_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    }
+    return align_bytes;
+}
+
+size_t armv8_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len,
+    const void *key, unsigned char ivec[16], uint64_t *Xi)
+{
+    AES_KEY *aes_key = (AES_KEY *)key;
+    size_t align_bytes = len - len % 16;
+
+    switch (aes_key->rounds) {
+    case 10:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_dec_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_dec_128_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    case 12:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_dec_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_dec_192_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    case 14:
+        if (IS_CPU_SUPPORT_UNROLL8_EOR3()) {
+            unroll8_eor3_aes_gcm_dec_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        } else {
+            aes_gcm_dec_256_kernel(in, align_bytes * 8, out, (uint64_t *)Xi, ivec, key);
+        }
+        break;
+    }
+    return align_bytes;
+}
+
+static int armv8_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
+    size_t keylen)
+{
+    if (AES_UNROLL12_EOR3_CAPABLE) {
+        return aes_gcm_hw_initkey(ctx, key, keylen,
+            aes_v8_set_encrypt_key, aes_v8_encrypt,
+            aes_v8_ctr32_encrypt_blocks_unroll12_eor3);
+    } else {
+        return aes_gcm_hw_initkey(ctx, key, keylen,
+            aes_v8_set_encrypt_key, aes_v8_encrypt,
+            aes_v8_ctr32_encrypt_blocks);
+    }
+}
+
+static const PROV_GCM_HW armv8_aes_gcm = {
+    armv8_aes_gcm_initkey,
+    ossl_gcm_setiv,
+    ossl_gcm_aad_update,
+    generic_aes_gcm_cipher_update,
+    ossl_gcm_cipher_final,
+    ossl_gcm_one_shot
+};
+
+const PROV_GCM_HW *ossl_prov_aes_hw_gcm_armv8(void)
+{
+    return AES_PMULL_CAPABLE ? &armv8_aes_gcm : NULL;
+}
+
+#endif