aboutsummaryrefslogtreecommitdiffstats
path: root/include/arch
diff options
context:
space:
mode:
authorNorbert Pocs <[email protected]>2026-04-09 13:38:07 +0200
committerNorbert Pocs <[email protected]>2026-05-10 11:53:33 +0200
commit4124d150697e7e4114015c2b35b2323be0b2bc89 (patch)
tree099a9683b382d486141c80677cc11224a3418cea /include/arch
parentMake test/quic_fc_test.c clang-format friendly (diff)
downloadopenssl-4124d150697e7e4114015c2b35b2323be0b2bc89.tar.gz
openssl-4124d150697e7e4114015c2b35b2323be0b2bc89.zip
Move *_arch.h to include/arch
Move all the architecture specific header files under a single directory in include/ Signed-off-by: Norbert Pocs <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> MergeDate: Sun May 10 09:53:34 2026 (Merged from https://github.com/openssl/openssl/pull/30751)
Diffstat (limited to 'include/arch')
-rw-r--r--include/arch/arm_arch.h218
-rw-r--r--include/arch/loongarch_arch.h19
-rw-r--r--include/arch/mips_arch.h38
-rw-r--r--include/arch/ppc_arch.h29
-rw-r--r--include/arch/riscv_arch.def61
-rw-r--r--include/arch/riscv_arch.h130
-rw-r--r--include/arch/s390x_arch.h207
-rw-r--r--include/arch/sparc_arch.h132
8 files changed, 834 insertions, 0 deletions
diff --git a/include/arch/arm_arch.h b/include/arch/arm_arch.h
new file mode 100644
index 00000000000..5bc61c22e19
--- /dev/null
+++ b/include/arch/arm_arch.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2011-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_CRYPTO_ARM_ARCH_H
+#define OSSL_CRYPTO_ARM_ARCH_H
+
+#if !defined(__ARM_ARCH__)
+#if defined(__CC_ARM)
+#define __ARM_ARCH__ __TARGET_ARCH_ARM
+#if defined(__BIG_ENDIAN)
+#define __ARMEB__
+#else
+#define __ARMEL__
+#endif
+#elif defined(__GNUC__)
+#if defined(__aarch64__)
+#define __ARM_ARCH__ 8
+/*
+ * Why doesn't gcc define __ARM_ARCH__? Instead it defines
+ * bunch of below macros. See all_architectures[] table in
+ * gcc/config/arm/arm.c. On a side note it defines
+ * __ARMEL__/__ARMEB__ for little-/big-endian.
+ */
+#elif defined(__ARM_ARCH)
+#define __ARM_ARCH__ __ARM_ARCH
+#elif defined(__ARM_ARCH_8A__)
+#define __ARM_ARCH__ 8
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+#define __ARM_ARCH__ 7
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+#define __ARM_ARCH__ 6
+#elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
+#define __ARM_ARCH__ 5
+#elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+#define __ARM_ARCH__ 4
+#else
+#error "unsupported ARM architecture"
+#endif
+#elif defined(__ARM_ARCH)
+#define __ARM_ARCH__ __ARM_ARCH
+#endif
+#endif
+
+#if !defined(__ARM_MAX_ARCH__)
+#define __ARM_MAX_ARCH__ __ARM_ARCH__
+#endif
+
+#if __ARM_MAX_ARCH__ < __ARM_ARCH__
+#error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
+#elif __ARM_MAX_ARCH__ != __ARM_ARCH__
+#if __ARM_ARCH__ < 7 && __ARM_MAX_ARCH__ >= 7 && defined(__ARMEB__)
+#error "can't build universal big-endian binary"
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+extern unsigned int OPENSSL_armcap_P;
+extern unsigned int OPENSSL_arm_midr;
+extern unsigned int OPENSSL_armv8_rsa_neonized;
+#endif
+
+#define ARMV7_NEON (1 << 0)
+#define ARMV7_TICK (1 << 1)
+#define ARMV8_AES (1 << 2)
+#define ARMV8_SHA1 (1 << 3)
+#define ARMV8_SHA256 (1 << 4)
+#define ARMV8_PMULL (1 << 5)
+#define ARMV8_SHA512 (1 << 6)
+#define ARMV8_CPUID (1 << 7)
+#define ARMV8_RNG (1 << 8)
+#define ARMV8_SM3 (1 << 9)
+#define ARMV8_SM4 (1 << 10)
+#define ARMV8_SHA3 (1 << 11)
+#define ARMV8_UNROLL8_EOR3 (1 << 12)
+#define ARMV8_SVE (1 << 13)
+#define ARMV9_SVE2 (1 << 14)
+#define ARMV8_HAVE_SHA3_AND_WORTH_USING (1 << 15)
+#define ARMV8_UNROLL12_EOR3 (1 << 16)
+#define ARMV9_SVE2_POLY1305 (1 << 17)
+
+/*
+ * MIDR_EL1 system register
+ *
+ * 63___ _ ___32_31___ _ ___24_23_____20_19_____16_15__ _ __4_3_______0
+ * | | | | | | |
+ * |RES0 | Implementer | Variant | Arch | PartNum |Revision|
+ * |____ _ _____|_____ _ _____|_________|_______ _|____ _ ___|________|
+ *
+ */
+
+#define ARM_CPU_IMP_ARM 0x41
+#define HISI_CPU_IMP 0x48
+#define ARM_CPU_IMP_QCOMM 0x51
+#define ARM_CPU_IMP_APPLE 0x61
+#define ARM_CPU_IMP_MICROSOFT 0x6D
+#define ARM_CPU_IMP_AMPERE 0xC0
+#define ARM_CPU_IMP_NVIDIA 0x4E
+
+#define ARM_CPU_PART_CORTEX_A72 0xD08
+#define ARM_CPU_PART_N1 0xD0C
+#define ARM_CPU_PART_V1 0xD40
+#define ARM_CPU_PART_N2 0xD49
+#define HISI_CPU_PART_KP920 0xD01
+#define ARM_CPU_PART_V2 0xD4F
+#define ARM_CPU_PART_N3 0xD8E
+#define ARM_CPU_PART_V3_AE 0xD83
+#define ARM_CPU_PART_V3 0xD84
+
+#define QCOM_CPU_PART_ORYON_X1 0x001
+
+#define NVIDIA_CPU_PART_OLYMPUS 0x010
+
+#define APPLE_CPU_PART_M1_ICESTORM 0x022
+#define APPLE_CPU_PART_M1_FIRESTORM 0x023
+#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024
+#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025
+#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028
+#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029
+#define APPLE_CPU_PART_M2_BLIZZARD 0x032
+#define APPLE_CPU_PART_M2_AVALANCHE 0x033
+#define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034
+#define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035
+#define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038
+#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039
+
+#define MICROSOFT_CPU_PART_COBALT_100 0xD49
+
+#define MIDR_PARTNUM_SHIFT 4
+#define MIDR_PARTNUM_MASK (0xfffU << MIDR_PARTNUM_SHIFT)
+#define MIDR_PARTNUM(midr) \
+ (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT)
+
+#define MIDR_IMPLEMENTER_SHIFT 24
+#define MIDR_IMPLEMENTER_MASK (0xffU << MIDR_IMPLEMENTER_SHIFT)
+#define MIDR_IMPLEMENTER(midr) \
+ (((midr) & MIDR_IMPLEMENTER_MASK) >> MIDR_IMPLEMENTER_SHIFT)
+
+#define MIDR_ARCHITECTURE_SHIFT 16
+#define MIDR_ARCHITECTURE_MASK (0xfU << MIDR_ARCHITECTURE_SHIFT)
+#define MIDR_ARCHITECTURE(midr) \
+ (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT)
+
+#define MIDR_CPU_MODEL_MASK \
+ (MIDR_IMPLEMENTER_MASK | MIDR_PARTNUM_MASK | MIDR_ARCHITECTURE_MASK)
+
+#define MIDR_CPU_MODEL(imp, partnum) \
+ (((imp) << MIDR_IMPLEMENTER_SHIFT) | (0xfU << MIDR_ARCHITECTURE_SHIFT) | ((partnum) << MIDR_PARTNUM_SHIFT))
+
+#define MIDR_IS_CPU_MODEL(midr, imp, partnum) \
+ (((midr) & MIDR_CPU_MODEL_MASK) == MIDR_CPU_MODEL(imp, partnum))
+
+#if defined(__ASSEMBLER__)
+
+/*
+ * Support macros for
+ * - Armv8.3-A Pointer Authentication and
+ * - Armv8.5-A Branch Target Identification
+ * features which require emitting a .note.gnu.property section with the
+ * appropriate architecture-dependent feature bits set.
+ * Read more: "ELF for the ArmĀ® 64-bit Architecture"
+ */
+
+#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1
+#define GNU_PROPERTY_AARCH64_BTI (1 << 0) /* Has Branch Target Identification */
+#define AARCH64_VALID_CALL_TARGET hint #34 /* BTI 'c' */
+#else
+#define GNU_PROPERTY_AARCH64_BTI 0 /* No Branch Target Identification */
+#define AARCH64_VALID_CALL_TARGET
+#endif
+
+#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 /* Signed with A-key */
+#define GNU_PROPERTY_AARCH64_POINTER_AUTH \
+ (1 << 1) /* Has Pointer Authentication */
+#define AARCH64_SIGN_LINK_REGISTER hint #25 /* PACIASP */
+#define AARCH64_VALIDATE_LINK_REGISTER hint #29 /* AUTIASP */
+#elif defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 2) == 2 /* Signed with B-key */
+#define GNU_PROPERTY_AARCH64_POINTER_AUTH \
+ (1 << 1) /* Has Pointer Authentication */
+#define AARCH64_SIGN_LINK_REGISTER hint #27 /* PACIBSP */
+#define AARCH64_VALIDATE_LINK_REGISTER hint #31 /* AUTIBSP */
+#else
+#define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 /* No Pointer Authentication */
+#if GNU_PROPERTY_AARCH64_BTI != 0
+#define AARCH64_SIGN_LINK_REGISTER AARCH64_VALID_CALL_TARGET
+#else
+#define AARCH64_SIGN_LINK_REGISTER
+#endif
+#define AARCH64_VALIDATE_LINK_REGISTER
+#endif
+
+#if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0
+/* clang-format off */
+.pushsection .note.gnu.property, "a";
+/* clang-format on */
+.balign 8;
+.long 4;
+.long 0x10;
+.long 0x5;
+.asciz "GNU";
+.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
+.long 4;
+.long(GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI);
+.long 0;
+.popsection;
+#endif
+
+#endif /* defined __ASSEMBLER__ */
+
+#define IS_CPU_SUPPORT_UNROLL8_EOR3() \
+ (OPENSSL_armcap_P & ARMV8_UNROLL8_EOR3)
+
+#endif
diff --git a/include/arch/loongarch_arch.h b/include/arch/loongarch_arch.h
new file mode 100644
index 00000000000..e1a7f82293f
--- /dev/null
+++ b/include/arch/loongarch_arch.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022-2023 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
+ */
+#ifndef OSSL_CRYPTO_LOONGARCH_ARCH_H
+#define OSSL_CRYPTO_LOONGARCH_ARCH_H
+
+#ifndef __ASSEMBLER__
+extern unsigned int OPENSSL_loongarch_hwcap_P;
+#endif
+
+#define LOONGARCH_HWCAP_LSX (1 << 4)
+#define LOONGARCH_HWCAP_LASX (1 << 5)
+
+#endif
diff --git a/include/arch/mips_arch.h b/include/arch/mips_arch.h
new file mode 100644
index 00000000000..ddc1293b2e6
--- /dev/null
+++ b/include/arch/mips_arch.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2016 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
+ */
+
+#ifndef OSSL_CRYPTO_MIPS_ARCH_H
+#define OSSL_CRYPTO_MIPS_ARCH_H
+
+#if (defined(__mips_smartmips) || defined(_MIPS_ARCH_MIPS32R3) || defined(_MIPS_ARCH_MIPS32R5) || defined(_MIPS_ARCH_MIPS32R6)) \
+ && !defined(_MIPS_ARCH_MIPS32R2)
+#define _MIPS_ARCH_MIPS32R2
+#endif
+
+#if (defined(_MIPS_ARCH_MIPS64R3) || defined(_MIPS_ARCH_MIPS64R5) || defined(_MIPS_ARCH_MIPS64R6)) \
+ && !defined(_MIPS_ARCH_MIPS64R2)
+#define _MIPS_ARCH_MIPS64R2
+#endif
+
+#if defined(_MIPS_ARCH_MIPS64R6)
+#define dmultu(rs, rt)
+#define mflo(rd, rs, rt) dmulu rd, rs, rt
+#define mfhi(rd, rs, rt) dmuhu rd, rs, rt
+#elif defined(_MIPS_ARCH_MIPS32R6)
+#define multu(rs, rt)
+#define mflo(rd, rs, rt) mulu rd, rs, rt
+#define mfhi(rd, rs, rt) muhu rd, rs, rt
+#else
+#define dmultu(rs, rt) dmultu rs, rt
+#define multu(rs, rt) multu rs, rt
+#define mflo(rd, rs, rt) mflo rd
+#define mfhi(rd, rs, rt) mfhi rd
+#endif
+
+#endif
diff --git a/include/arch/ppc_arch.h b/include/arch/ppc_arch.h
new file mode 100644
index 00000000000..5945853ab17
--- /dev/null
+++ b/include/arch/ppc_arch.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014-2022 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
+ */
+
+#ifndef OSSL_CRYPTO_PPC_ARCH_H
+#define OSSL_CRYPTO_PPC_ARCH_H
+
+extern unsigned int OPENSSL_ppccap_P;
+
+/*
+ * Flags' usage can appear ambiguous, because they are set rather
+ * to reflect OpenSSL performance preferences than actual processor
+ * capabilities.
+ */
+#define PPC_FPU64 (1 << 0)
+#define PPC_ALTIVEC (1 << 1)
+#define PPC_CRYPTO207 (1 << 2)
+#define PPC_FPU (1 << 3)
+#define PPC_MADD300 (1 << 4)
+#define PPC_MFTB (1 << 5)
+#define PPC_MFSPR268 (1 << 6)
+#define PPC_BRD31 (1 << 7)
+
+#endif
diff --git a/include/arch/riscv_arch.def b/include/arch/riscv_arch.def
new file mode 100644
index 00000000000..32147d0939c
--- /dev/null
+++ b/include/arch/riscv_arch.def
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2022-2024 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
+ */
+
+/* X Macro Definitions for Specification of RISC-V Arch Capabilities */
+
+/*
+ * Each RISC-V capability ends up encoded as a single set bit in an array of
+ * words. When specifying a new capability, write a new RISCV_DEFINE_CAP
+ * statement, with an argument as the extension name in all-caps,
+ * second argument as the index in the array where the capability will be stored
+ * and third argument as the index of the bit to be used to encode the
+ * capability.
+ *
+ * The fourth and the fifth arguments are copied from linux header asm/hwprobe.h.
+ * Directly coping values instead of macro names comes from the fact
+ * that an old version may lack definition of some macro.
+ * When there is no hwprobe key/value pair for a capability, the key is set to -1
+ * and the value is set to 0, as when the hwprobe syscall returns a key of -1,
+ * the value is set to 0 and the corresponding capability would not be enabled.
+ *
+ * RISCV_DEFINE_CAP(EXTENSION NAME, array index, bit index, hwprobe key, hwprobe value) */
+
+RISCV_DEFINE_CAP(ZBA, 0, 0, 4, (1 << 3))
+RISCV_DEFINE_CAP(ZBB, 0, 1, 4, (1 << 4))
+RISCV_DEFINE_CAP(ZBC, 0, 2, 4, (1 << 7))
+RISCV_DEFINE_CAP(ZBS, 0, 3, 4, (1 << 5))
+RISCV_DEFINE_CAP(ZBKB, 0, 4, 4, (1 << 8))
+RISCV_DEFINE_CAP(ZBKC, 0, 5, 4, (1 << 9))
+RISCV_DEFINE_CAP(ZBKX, 0, 6, 4, (1 << 10))
+RISCV_DEFINE_CAP(ZKND, 0, 7, 4, (1 << 11))
+RISCV_DEFINE_CAP(ZKNE, 0, 8, 4, (1 << 12))
+RISCV_DEFINE_CAP(ZKNH, 0, 9, 4, (1 << 13))
+RISCV_DEFINE_CAP(ZKSED, 0, 10, 4, (1 << 14))
+RISCV_DEFINE_CAP(ZKSH, 0, 11, 4, (1 << 15))
+RISCV_DEFINE_CAP(ZKR, 0, 12, -1, 0)
+RISCV_DEFINE_CAP(ZKT, 0, 13, 4, (1 << 16))
+RISCV_DEFINE_CAP(V, 0, 14, 4, (1 << 2))
+RISCV_DEFINE_CAP(ZVBB, 0, 15, 4, (1 << 17))
+RISCV_DEFINE_CAP(ZVBC, 0, 16, 4, (1 << 18))
+RISCV_DEFINE_CAP(ZVKB, 0, 17, 4, (1 << 19))
+RISCV_DEFINE_CAP(ZVKG, 0, 18, 4, (1 << 20))
+RISCV_DEFINE_CAP(ZVKNED, 0, 19, 4, (1 << 21))
+RISCV_DEFINE_CAP(ZVKNHA, 0, 20, 4, (1 << 22))
+RISCV_DEFINE_CAP(ZVKNHB, 0, 21, 4, (1 << 23))
+RISCV_DEFINE_CAP(ZVKSED, 0, 22, 4, (1 << 24))
+RISCV_DEFINE_CAP(ZVKSH, 0, 23, 4, (1 << 25))
+
+/*
+ * In the future ...
+ * RISCV_DEFINE_CAP(ZFOO, 0, 31, ..., ...)
+ * RISCV_DEFINE_CAP(ZBAR, 1, 0, ..., ...)
+ * ... and so on.
+ */
+
+#undef RISCV_DEFINE_CAP
diff --git a/include/arch/riscv_arch.h b/include/arch/riscv_arch.h
new file mode 100644
index 00000000000..ddc36e58f1b
--- /dev/null
+++ b/include/arch/riscv_arch.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2022-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
+ */
+
+#ifndef OSSL_CRYPTO_RISCV_ARCH_H
+#define OSSL_CRYPTO_RISCV_ARCH_H
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE)
+#if __has_include(<asm/hwprobe.h>)
+#include <sys/syscall.h>
+#/*
+ * Some environments using musl are reported to have the hwprobe.h include
+ * file but not have the __NR_riscv_hwprobe define.
+ */
+#ifdef __NR_riscv_hwprobe
+#define OSSL_RISCV_HWPROBE
+#include <asm/hwcap.h>
+extern unsigned int OPENSSL_riscv_hwcap_P;
+#define VECTOR_CAPABLE (OPENSSL_riscv_hwcap_P & COMPAT_HWCAP_ISA_V)
+#define ZVX_MIN 15
+#define ZVX_MAX 23
+#define IS_IN_DEPEND_VECTOR(offset) ((ZVX_MIN <= offset) && (offset <= ZVX_MAX))
+#endif
+#endif
+#endif
+
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) +1
+extern uint32_t OPENSSL_riscvcap_P[((
+#include "riscv_arch.def"
+ )
+ + sizeof(uint32_t) - 1)
+ / sizeof(uint32_t)];
+
+#ifdef OPENSSL_RISCVCAP_IMPL
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) +1
+uint32_t OPENSSL_riscvcap_P[((
+#include "riscv_arch.def"
+ )
+ + sizeof(uint32_t) - 1)
+ / sizeof(uint32_t)];
+#endif
+
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) \
+ static inline int RISCV_HAS_##NAME(void) \
+ { \
+ return (OPENSSL_riscvcap_P[INDEX] & (1 << BIT_INDEX)) != 0; \
+ }
+#include "riscv_arch.def"
+
+struct RISCV_capability_s {
+ const char *name;
+ size_t index;
+ size_t bit_offset;
+#ifdef OSSL_RISCV_HWPROBE
+ int32_t hwprobe_key;
+ uint64_t hwprobe_value;
+#endif
+};
+
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ OSSL_RISCV_HWPROBE_KEY, OSSL_RISCV_HWPROBE_VALUE) +1
+extern const struct RISCV_capability_s RISCV_capabilities[
+#include "riscv_arch.def"
+];
+
+#ifdef OPENSSL_RISCVCAP_IMPL
+#ifdef OSSL_RISCV_HWPROBE
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) \
+ { #NAME, INDEX, BIT_INDEX, HWPROBE_KEY, HWPROBE_VALUE },
+#else
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) \
+ { #NAME, INDEX, BIT_INDEX },
+#endif
+const struct RISCV_capability_s RISCV_capabilities[] = {
+#include "riscv_arch.def"
+};
+#endif
+
+#define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \
+ HWPROBE_KEY, HWPROBE_VALUE) +1
+static const size_t kRISCVNumCaps =
+#include "riscv_arch.def"
+ ;
+
+#ifdef OSSL_RISCV_HWPROBE
+/*
+ * Content is an array of { hwprobe_key, 0 } where
+ * hwprobe_key is copied from asm/hwprobe.h.
+ * It should be updated along with riscv_arch.def.
+ */
+#define OSSL_RISCV_HWPROBE_PAIR_COUNT 1
+#define OSSL_RISCV_HWPROBE_PAIR_CONTENT \
+ { 4, 0 },
+#endif
+
+/* Extension combination tests. */
+#define RISCV_HAS_ZBB_AND_ZBC() (RISCV_HAS_ZBB() && RISCV_HAS_ZBC())
+#define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
+#define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
+/*
+ * The ZVBB is the superset of ZVKB extension. We use macro here to replace the
+ * `RISCV_HAS_ZVKB()` with `RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()`.
+ */
+#define RISCV_HAS_ZVKB() (RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB())
+#define RISCV_HAS_ZVKB_AND_ZVKNHA() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHA())
+#define RISCV_HAS_ZVKB_AND_ZVKNHB() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHB())
+#define RISCV_HAS_ZVKB_AND_ZVKSED() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSED())
+#define RISCV_HAS_ZVKB_AND_ZVKSH() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSH())
+
+/*
+ * Get the size of a vector register in bits (VLEN).
+ * If RISCV_HAS_V() is false, then this returns 0.
+ */
+size_t riscv_vlen(void);
+
+#endif
diff --git a/include/arch/s390x_arch.h b/include/arch/s390x_arch.h
new file mode 100644
index 00000000000..f5ff696dcdf
--- /dev/null
+++ b/include/arch/s390x_arch.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2017-2024 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
+ */
+
+#ifndef OSSL_CRYPTO_S390X_ARCH_H
+#define OSSL_CRYPTO_S390X_ARCH_H
+
+#ifndef __ASSEMBLER__
+
+#include "crypto/bn.h"
+
+void s390x_kimd(const unsigned char *in, size_t len, unsigned int fc,
+ void *param);
+void s390x_klmd(const unsigned char *in, size_t inlen, unsigned char *out,
+ size_t outlen, unsigned int fc, void *param);
+void s390x_km(const unsigned char *in, size_t len, unsigned char *out,
+ unsigned int fc, void *param);
+void s390x_kmac(const unsigned char *in, size_t len, unsigned int fc,
+ void *param);
+void s390x_kmo(const unsigned char *in, size_t len, unsigned char *out,
+ unsigned int fc, void *param);
+void s390x_kmf(const unsigned char *in, size_t len, unsigned char *out,
+ unsigned int fc, void *param);
+void s390x_kma(const unsigned char *aad, size_t alen, const unsigned char *in,
+ size_t len, unsigned char *out, unsigned int fc, void *param);
+int s390x_pcc(unsigned int fc, void *param);
+int s390x_kdsa(unsigned int fc, void *param, const unsigned char *in,
+ size_t len);
+void OPENSSL_s390x_cleanup(void);
+
+void s390x_flip_endian32(unsigned char dst[32], const unsigned char src[32]);
+void s390x_flip_endian64(unsigned char dst[64], const unsigned char src[64]);
+
+int s390x_x25519_mul(unsigned char u_dst[32],
+ const unsigned char u_src[32],
+ const unsigned char d_src[32]);
+int s390x_x448_mul(unsigned char u_dst[56],
+ const unsigned char u_src[56],
+ const unsigned char d_src[56]);
+int s390x_ed25519_mul(unsigned char x_dst[32],
+ unsigned char y_dst[32],
+ const unsigned char x_src[32],
+ const unsigned char y_src[32],
+ const unsigned char d_src[32]);
+int s390x_ed448_mul(unsigned char x_dst[57],
+ unsigned char y_dst[57],
+ const unsigned char x_src[57],
+ const unsigned char y_src[57],
+ const unsigned char d_src[57]);
+
+/*
+ * The field elements of OPENSSL_s390xcap_P are the 64-bit words returned by
+ * the STFLE instruction followed by the 64-bit word pairs returned by
+ * instructions' QUERY functions. If STFLE returns fewer data or an instruction
+ * is not supported, the corresponding field elements are zero.
+ */
+struct OPENSSL_s390xcap_st {
+ unsigned long long stfle[4];
+ unsigned long long kimd[2];
+ unsigned long long klmd[2];
+ unsigned long long km[2];
+ unsigned long long kmc[2];
+ unsigned long long kmac[2];
+ unsigned long long kmctr[2];
+ unsigned long long kmo[2];
+ unsigned long long kmf[2];
+ unsigned long long prno[2];
+ unsigned long long kma[2];
+ unsigned long long pcc[2];
+ unsigned long long kdsa[2];
+};
+
+#if defined(__GNUC__) && defined(__linux)
+__attribute__((visibility("hidden")))
+#endif
+extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
+
+#ifdef S390X_MOD_EXP
+#if defined(__GNUC__) && defined(__linux)
+__attribute__((visibility("hidden")))
+#endif
+extern int OPENSSL_s390xcex;
+#if defined(__GNUC__) && defined(__linux)
+__attribute__((visibility("hidden")))
+#endif
+extern int OPENSSL_s390xcex_nodev;
+#endif
+
+/* Max number of 64-bit words currently returned by STFLE */
+#define S390X_STFLE_MAX 3
+
+/* convert facility bit number or function code to bit mask */
+#define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64))
+
+#endif
+
+/* OPENSSL_s390xcap_P offsets [bytes] */
+#define S390X_STFLE 0x00
+#define S390X_KIMD 0x20
+#define S390X_KLMD 0x30
+#define S390X_KM 0x40
+#define S390X_KMC 0x50
+#define S390X_KMAC 0x60
+#define S390X_KMCTR 0x70
+#define S390X_KMO 0x80
+#define S390X_KMF 0x90
+#define S390X_PRNO 0xa0
+#define S390X_KMA 0xb0
+#define S390X_PCC 0xc0
+#define S390X_KDSA 0xd0
+
+/* Facility Bit Numbers */
+#define S390X_MSA 17 /* message-security-assist */
+#define S390X_STCKF 25 /* store-clock-fast */
+#define S390X_MSA5 57 /* message-security-assist-ext. 5 */
+#define S390X_MSA3 76 /* message-security-assist-ext. 3 */
+#define S390X_MSA4 77 /* message-security-assist-ext. 4 */
+#define S390X_MSA12 86 /* message-security-assist-ext. 12 */
+#define S390X_VX 129 /* vector */
+#define S390X_VXD 134 /* vector packed decimal */
+#define S390X_VXE 135 /* vector enhancements 1 */
+#define S390X_MSA8 146 /* message-security-assist-ext. 8 */
+#define S390X_MSA9 155 /* message-security-assist-ext. 9 */
+
+/* Function Codes */
+
+/* all instructions */
+#define S390X_QUERY 0
+
+/* kimd/klmd */
+#define S390X_SHA_1 1
+#define S390X_SHA_256 2
+#define S390X_SHA_512 3
+#define S390X_SHA3_224 32
+#define S390X_SHA3_256 33
+#define S390X_SHA3_384 34
+#define S390X_SHA3_512 35
+#define S390X_KECCAK_224 32
+#define S390X_KECCAK_256 33
+#define S390X_KECCAK_384 34
+#define S390X_KECCAK_512 35
+#define S390X_SHAKE_128 36
+#define S390X_SHAKE_256 37
+#define S390X_GHASH 65
+
+/* km/kmc/kmac/kmctr/kmo/kmf/kma */
+#define S390X_AES_128 18
+#define S390X_AES_192 19
+#define S390X_AES_256 20
+
+/* km */
+#define S390X_XTS_AES_128 50
+#define S390X_XTS_AES_256 52
+#define S390X_XTS_AES_128_MSA10 82
+#define S390X_XTS_AES_256_MSA10 84
+
+/* kmac */
+#define S390X_HMAC_SHA_224 112
+#define S390X_HMAC_SHA_256 113
+#define S390X_HMAC_SHA_384 114
+#define S390X_HMAC_SHA_512 115
+
+/* prno */
+#define S390X_SHA_512_DRNG 3
+#define S390X_TRNG 114
+
+/* pcc */
+#define S390X_SCALAR_MULTIPLY_P256 64
+#define S390X_SCALAR_MULTIPLY_P384 65
+#define S390X_SCALAR_MULTIPLY_P521 66
+#define S390X_SCALAR_MULTIPLY_ED25519 72
+#define S390X_SCALAR_MULTIPLY_ED448 73
+#define S390X_SCALAR_MULTIPLY_X25519 80
+#define S390X_SCALAR_MULTIPLY_X448 81
+
+/* kdsa */
+#define S390X_ECDSA_VERIFY_P256 1
+#define S390X_ECDSA_VERIFY_P384 2
+#define S390X_ECDSA_VERIFY_P521 3
+#define S390X_ECDSA_SIGN_P256 9
+#define S390X_ECDSA_SIGN_P384 10
+#define S390X_ECDSA_SIGN_P521 11
+#define S390X_EDDSA_VERIFY_ED25519 32
+#define S390X_EDDSA_VERIFY_ED448 36
+#define S390X_EDDSA_SIGN_ED25519 40
+#define S390X_EDDSA_SIGN_ED448 44
+
+/* Register 0 Flags */
+#define S390X_DECRYPT 0x80
+#define S390X_KMA_LPC 0x100
+#define S390X_KMA_LAAD 0x200
+#define S390X_KMA_HS 0x400
+#define S390X_KDSA_D 0x80
+#define S390X_KIMD_NIP 0x8000
+#define S390X_KLMD_DUFOP 0x4000
+#define S390X_KLMD_NIP 0x8000
+#define S390X_KLMD_PS 0x100
+#define S390X_KMAC_IKP 0x8000
+#define S390X_KMAC_IIMP 0x4000
+#define S390X_KMAC_CCUP 0x2000
+
+#endif
diff --git a/include/arch/sparc_arch.h b/include/arch/sparc_arch.h
new file mode 100644
index 00000000000..6d47505ae96
--- /dev/null
+++ b/include/arch/sparc_arch.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_CRYPTO_SPARC_ARCH_H
+#define OSSL_CRYPTO_SPARC_ARCH_H
+
+#define SPARCV9_TICK_PRIVILEGED (1 << 0)
+#define SPARCV9_PREFER_FPU (1 << 1)
+#define SPARCV9_VIS1 (1 << 2)
+#define SPARCV9_VIS2 (1 << 3) /* reserved */
+#define SPARCV9_FMADD (1 << 4)
+#define SPARCV9_BLK (1 << 5) /* VIS1 block copy */
+#define SPARCV9_VIS3 (1 << 6)
+#define SPARCV9_RANDOM (1 << 7)
+#define SPARCV9_64BIT_STACK (1 << 8)
+#define SPARCV9_FJAESX (1 << 9) /* Fujitsu SPARC64 X AES */
+#define SPARCV9_FJDESX (1 << 10) /* Fujitsu SPARC64 X DES, reserved */
+#define SPARCV9_FJHPCACE (1 << 11) /* Fujitsu HPC-ACE, reserved */
+#define SPARCV9_IMA (1 << 13) /* reserved */
+#define SPARCV9_VIS4 (1 << 14) /* reserved */
+
+/*
+ * OPENSSL_sparcv9cap_P[1] is copy of Compatibility Feature Register,
+ * %asr26, SPARC-T4 and later. There is no SPARCV9_CFR bit in
+ * OPENSSL_sparcv9cap_P[0], as %cfr copy is sufficient...
+ */
+#define CFR_AES 0x00000001 /* Supports AES opcodes */
+#define CFR_DES 0x00000002 /* Supports DES opcodes */
+#define CFR_KASUMI 0x00000004 /* Supports KASUMI opcodes */
+#define CFR_CAMELLIA 0x00000008 /* Supports CAMELLIA opcodes */
+#define CFR_MD5 0x00000010 /* Supports MD5 opcodes */
+#define CFR_SHA1 0x00000020 /* Supports SHA1 opcodes */
+#define CFR_SHA256 0x00000040 /* Supports SHA256 opcodes */
+#define CFR_SHA512 0x00000080 /* Supports SHA512 opcodes */
+#define CFR_MPMUL 0x00000100 /* Supports MPMUL opcodes */
+#define CFR_MONTMUL 0x00000200 /* Supports MONTMUL opcodes */
+#define CFR_MONTSQR 0x00000400 /* Supports MONTSQR opcodes */
+#define CFR_CRC32C 0x00000800 /* Supports CRC32C opcodes */
+#define CFR_XMPMUL 0x00001000 /* Supports XMPMUL opcodes */
+#define CFR_XMONTMUL 0x00002000 /* Supports XMONTMUL opcodes */
+#define CFR_XMONTSQR 0x00004000 /* Supports XMONTSQR opcodes */
+
+#if defined(OPENSSL_PIC) && !defined(__PIC__)
+#define __PIC__
+#endif
+
+#if defined(__SUNPRO_C) && defined(__sparcv9) && !defined(__arch64__)
+#define __arch64__
+#endif
+
+/* clang-format off */
+# define SPARC_PIC_THUNK(reg) \
+ .align 32; \
+.Lpic_thunk: \
+ jmp %o7 + 8; \
+ add %o7, reg, reg;
+
+# define SPARC_PIC_THUNK_CALL(reg) \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), reg; \
+ call .Lpic_thunk; \
+ or reg, %lo(_GLOBAL_OFFSET_TABLE_+4), reg;
+
+# if 1
+# define SPARC_SETUP_GOT_REG(reg) SPARC_PIC_THUNK_CALL(reg)
+# else
+# define SPARC_SETUP_GOT_REG(reg) \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), reg; \
+ call .+8; \
+ or reg,%lo(_GLOBAL_OFFSET_TABLE_+4), reg; \
+ add %o7, reg, reg
+# endif
+/* clang-format on */
+
+#if defined(__arch64__)
+
+/* clang-format off */
+#define SPARC_LOAD_ADDRESS(SYM, reg) \
+ setx SYM, %o7, reg;
+/* clang-format on */
+#define LDPTR ldx
+/* clang-format off */
+#define SIZE_T_CC %xcc
+/* clang-format on */
+#define STACK_FRAME 192
+#define STACK_BIAS 2047
+#define STACK_7thARG (STACK_BIAS + 176)
+
+#else
+
+#define SPARC_LOAD_ADDRESS(SYM, reg) \
+ set SYM, reg;
+#define LDPTR ld
+/* clang-format off */
+#define SIZE_T_CC %icc
+/* clang-format on */
+#define STACK_FRAME 112
+#define STACK_BIAS 0
+#define STACK_7thARG 92
+#define SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp) SPARC_LOAD_ADDRESS(SYM, reg)
+
+#endif
+
+/* clang-format off */
+# ifdef __PIC__
+# undef SPARC_LOAD_ADDRESS
+# undef SPARC_LOAD_ADDRESS_LEAF
+# define SPARC_LOAD_ADDRESS(SYM, reg) \
+ SPARC_SETUP_GOT_REG(reg); \
+ sethi %hi(SYM), %o7; \
+ or %o7, %lo(SYM), %o7; \
+ LDPTR [reg + %o7], reg;
+# endif
+
+# ifndef SPARC_LOAD_ADDRESS_LEAF
+# define SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp) \
+ mov %o7, tmp; \
+ SPARC_LOAD_ADDRESS(SYM, reg) \
+ mov tmp, %o7;
+# endif
+/* clang-format on */
+
+#ifndef __ASSEMBLER__
+extern unsigned int OPENSSL_sparcv9cap_P[2];
+#endif
+
+#endif /* OSSL_CRYPTO_SPARC_ARCH_H */