Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ CONFIG_WOLFSSL_SINGLE_THREADED
CONFIG_WOLFSSL_SNI
CONFIG_WOLFSSL_TARGET_HOST
CONFIG_WOLFSSL_TARGET_PORT
CONFIG_WOLFSSL_TLS13_ENABLED
CONFIG_WOLFSSL_TLS_VERSION_1_2
CONFIG_WOLFSSL_TLS_VERSION_1_3
CONFIG_WOLFSSL_XMSS
Expand Down
89 changes: 69 additions & 20 deletions wolfcrypt/src/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@
#define cpuid(a,b,c) __cpuidex((int*)a,b,c)
#endif /* _MSC_VER */

/* Read XCR0. Only valid once CPUID.1:ECX.OSXSAVE[27] is known set. */
#ifndef _MSC_VER
static WC_INLINE word32 cpuid_xgetbv0(void)
{
word32 eax, edx;
__asm__ __volatile__ ("xgetbv"
: "=a" (eax), "=d" (edx) : "c" (0));
(void)edx;
return eax;
}
#else
#define cpuid_xgetbv0() ((word32)_xgetbv(0))
#endif /* _MSC_VER */

#define EAX 0
#define EBX 1
#define ECX 2
Expand Down Expand Up @@ -116,6 +130,31 @@
XMEMCMP((char *)&(reg[ECX]), "cAMD", 4) == 0);
}

/* XCR0 state-component masks. AVX needs the SSE and AVX regions; AVX-512
* also needs opmask, ZMM_Hi256 and Hi16_ZMM on top of them. */
#define WC_XCR0_AVX 0x06
#define WC_XCR0_AVX512 0xe6

/* Return 1 when the OS has enabled XSAVE and every state component in
* 'mask'. CPUID's feature bits only say the silicon has the unit;
* executing the instruction also needs CR4.OSXSAVE and the matching XCR0
* bits, which an OS that does not context-switch those registers leaves
* clear. Without this test wolfSSL dispatches the vector code on such a
* system and it faults with #UD. */
static int cpuid_os_state_enabled(word32 mask)
{
unsigned int reg[5];

XMEMSET(reg, '\0', sizeof(reg));
cpuid(reg, 1, 0);

/* CPUID.1:ECX.OSXSAVE[27] - XGETBV is illegal when this is clear. */
if (((reg[ECX] >> 27) & 0x1) == 0)
return 0;

return (cpuid_xgetbv0() & mask) == mask;
}

static cpuid_flags_t cpuid_flag(word32 leaf, word32 sub, word32 num,
word32 bit)
{
Expand All @@ -139,8 +178,13 @@
#endif
cpuid_flags_t new_cpuid_flags = 0,
old_cpuid_flags = WC_CPUID_INITIALIZER;
if (cpuid_flag(1, 0, ECX, 28)) { new_cpuid_flags |= CPUID_AVX1 ; }
if (cpuid_flag(7, 0, EBX, 5)) { new_cpuid_flags |= CPUID_AVX2 ; }
int os_avx = cpuid_os_state_enabled(WC_XCR0_AVX);
int os_avx512 = cpuid_os_state_enabled(WC_XCR0_AVX512);

if (os_avx) {
if (cpuid_flag(1, 0, ECX, 28)) { new_cpuid_flags |= CPUID_AVX1; }
if (cpuid_flag(7, 0, EBX, 5)) { new_cpuid_flags |= CPUID_AVX2; }
}
if (cpuid_flag(7, 0, EBX, 8)) { new_cpuid_flags |= CPUID_BMI2 ; }
if (cpuid_flag(1, 0, ECX, 30)) { new_cpuid_flags |= CPUID_RDRAND; }
if (cpuid_flag(7, 0, EBX, 18)) { new_cpuid_flags |= CPUID_RDSEED; }
Expand All @@ -149,25 +193,30 @@
if (cpuid_flag(1, 0, ECX, 22)) { new_cpuid_flags |= CPUID_MOVBE ; }
if (cpuid_flag(7, 0, EBX, 3)) { new_cpuid_flags |= CPUID_BMI1 ; }
if (cpuid_flag(7, 0, EBX, 29)) { new_cpuid_flags |= CPUID_SHA ; }
if (cpuid_flag(7, 0, ECX, 9)) { new_cpuid_flags |= CPUID_VAES ; }
if (cpuid_flag(7, 0, EBX, 16)) { new_cpuid_flags |= CPUID_AVX512; }
if (cpuid_flag(7, 0, ECX, 1)) {
new_cpuid_flags |= CPUID_AVX512_VBMI;
}
if (cpuid_flag(7, 0, ECX, 6)) {
new_cpuid_flags |= CPUID_AVX512_VBMI2;
}
if (cpuid_flag(7, 0, EBX, 21)) {
new_cpuid_flags |= CPUID_AVX512_IFMA;
}
if (cpuid_flag(7, 0, EBX, 31)) {
new_cpuid_flags |= CPUID_AVX512_VL;
}
if (cpuid_flag(7, 0, EBX, 17)) {
new_cpuid_flags |= CPUID_AVX512_DQ;
/* VAES is VEX/EVEX encoded, so it needs the AVX state too. */
if (os_avx && cpuid_flag(7, 0, ECX, 9)) {
new_cpuid_flags |= CPUID_VAES;
}
if (cpuid_flag(7, 0, EBX, 30)) {
new_cpuid_flags |= CPUID_AVX512_BW;
if (os_avx512) {
if (cpuid_flag(7, 0, EBX, 16)) { new_cpuid_flags |= CPUID_AVX512; }
if (cpuid_flag(7, 0, ECX, 1)) {
new_cpuid_flags |= CPUID_AVX512_VBMI;
}
if (cpuid_flag(7, 0, ECX, 6)) {
new_cpuid_flags |= CPUID_AVX512_VBMI2;
}
if (cpuid_flag(7, 0, EBX, 21)) {
new_cpuid_flags |= CPUID_AVX512_IFMA;
}
if (cpuid_flag(7, 0, EBX, 31)) {
new_cpuid_flags |= CPUID_AVX512_VL;
}
if (cpuid_flag(7, 0, EBX, 17)) {
new_cpuid_flags |= CPUID_AVX512_DQ;
}
if (cpuid_flag(7, 0, EBX, 30)) {
new_cpuid_flags |= CPUID_AVX512_BW;
}
}
if (cpuid_is_intel()) { new_cpuid_flags |= CPUID_INTEL ; }
if (cpuid_is_amd()) { new_cpuid_flags |= CPUID_AMD ; }
Expand Down
8 changes: 6 additions & 2 deletions wolfcrypt/src/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,14 @@ ECC Curve Sizes:
#define HAVE_ECC_CHECK_PUBKEY_ORDER
#endif

#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
/* MAX_ECC_BITS is MAX_ECC_BITS_NEEDED unless the user raised it, and ecc.h
* rejects a smaller one, so this is the ceiling the caller actually asked for.
* Raising it sizes the working values for a curve that is not compiled in,
* which is what an arbitrary curve passed to wc_ecc_set_custom_curve needs. */
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raised ECC ceiling remains clamped to 521 bits · Logic errors

MAX_ECC_BITS_USE clamps a user-raised MAX_ECC_BITS to the generic-SP default of 521 bits in ECC-only builds. Larger custom curves therefore return WC_KEY_SIZE_E despite being within the configured ceiling.

Suggested fix: For generic-SP ECC builds, derive SP_INT_BITS from MAX_ECC_BITS when the configured ECC ceiling exceeds 521.
Basis: wolfSSL configure.ac documents --with-max-ecc-bits as the number of bits supported for ECC algorithms.

#define MAX_ECC_BITS_USE SP_INT_BITS
#else
#define MAX_ECC_BITS_USE MAX_ECC_BITS_NEEDED
#define MAX_ECC_BITS_USE MAX_ECC_BITS
#endif

#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-aes-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#ifndef WOLFSSL_ARMASM_INLINE
#if !defined(NO_AES) && defined(WOLFSSL_ARMASM)
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
.arch_extension crypto
#ifndef __APPLE__
.text
.globl AES_set_key_AARCH64
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-aes-asm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
; ../wolfssl/wolfcrypt/src/port/arm/armv8-aes-asm.asm
IF :LNOT::DEF:NO_AES :LAND: {TRUE}
IF :LNOT::DEF:WOLFSSL_ARMASM_NO_HW_CRYPTO
; .arch_extension crypto
AREA |.text|, CODE, READONLY
ALIGN 4
EXPORT AES_set_key_AARCH64
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-aes-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#if !defined(NO_AES) && defined(WOLFSSL_ARMASM)
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
__asm__(".arch_extension crypto");

Check failure on line 41 in wolfcrypt/src/port/arm/armv8-aes-asm_c.c

View workflow job for this annotation

GitHub Actions / check

flush-left-call

flush-left function call (debug residue?)
void AES_set_key_AARCH64(const byte* userKey, int keylen, byte* key, int dir)
{
__asm__ __volatile__ (
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-frodokem-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,7 @@ _frodokem_sha3_x2_crypto:
adrp x1, L_sha3_aarch64_r@PAGE
add x1, x1, L_sha3_aarch64_r@PAGEOFF
#endif /* __APPLE__ */
#ifdef __APPLE__
.arch_extension sha3
#endif /* __APPLE__ */
ld4 {v0.d, v1.d, v2.d, v3.d}[0], [x0], #32
ld4 {v4.d, v5.d, v6.d, v7.d}[0], [x0], #32
ld4 {v8.d, v9.d, v10.d, v11.d}[0], [x0], #32
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-frodokem-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,7 @@ void frodokem_sha3_x2_crypto(word64* state)
{
const word64* r = L_sha3_aarch64_r;
__asm__ __volatile__ (
#ifdef __APPLE__
".arch_extension sha3\n\t"
#endif /* __APPLE__ */
"ld4 {v0.d, v1.d, v2.d, v3.d}[0], [%x[state]], #32\n\t"
"ld4 {v4.d, v5.d, v6.d, v7.d}[0], [%x[state]], #32\n\t"
"ld4 {v8.d, v9.d, v10.d, v11.d}[0], [%x[state]], #32\n\t"
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/port/arm/armv8-mlkem-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#ifdef WOLFSSL_ARMASM
#ifdef __aarch64__
#ifndef WOLFSSL_ARMASM_INLINE
#ifdef WOLFSSL_HAVE_MLKEM
#ifndef __APPLE__
.text
.section .rodata
Expand All @@ -49,7 +50,6 @@
#endif /* __APPLE__ */
L_mlkem_aarch64_consts:
.short 0x0d01,0xf301,0x4ebf,0x0549,0x5049,0x0000,0x0000,0x0000
#ifdef WOLFSSL_HAVE_MLKEM
#ifndef __APPLE__
.text
.section .rodata
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/port/arm/armv8-mlkem-asm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
; cd ../scripts
; ruby ./kyber/kyber.rb arm64 \
; ../wolfssl/wolfcrypt/src/port/arm/armv8-mlkem-asm.asm
IF :DEF:WOLFSSL_HAVE_MLKEM
AREA |.rodata|, DATA, READONLY, ALIGN=4
ALIGN 8
L_mlkem_aarch64_consts
DCW 0x0d01, 0xf301, 0x4ebf, 0x0549, 0x5049, 0x0000, 0x0000, 0x0000
IF :DEF:WOLFSSL_HAVE_MLKEM
AREA |.rodata|, DATA, READONLY, ALIGN=4
ALIGN 8
L_mlkem_aarch64_zetas
Expand Down
6 changes: 3 additions & 3 deletions wolfcrypt/src/port/arm/armv8-mlkem-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
#ifdef WOLFSSL_ARMASM
#ifdef __aarch64__
#ifdef WOLFSSL_ARMASM_INLINE
#include <wolfssl/wolfcrypt/wc_mlkem.h>

#ifdef WOLFSSL_HAVE_MLKEM
XALIGNED(4) static const word16 L_mlkem_aarch64_consts[] = {
0x0d01, 0xf301, 0x4ebf, 0x0549, 0x5049, 0x0000, 0x0000, 0x0000,
};

#include <wolfssl/wolfcrypt/wc_mlkem.h>

#ifdef WOLFSSL_HAVE_MLKEM
XALIGNED(4) static const word16 L_mlkem_aarch64_zetas[] = {
0x08ed, 0x0a0b, 0x0b9a, 0x0714, 0x05d5, 0x058e, 0x011f, 0x00ca,
0x0c56, 0x026e, 0x0629, 0x00b6, 0x03c2, 0x084f, 0x073f, 0x05bc,
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-sha256-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,7 @@ L_sha256_len_neon_start:
.size Transform_Sha256_Len_neon,.-Transform_Sha256_Len_neon
#endif /* __APPLE__ */
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
.arch_extension crypto
#ifndef __APPLE__
.text
.section .rodata
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-sha256-asm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,7 @@ L_sha256_len_neon_start
ret
ENDP
IF :LNOT::DEF:WOLFSSL_ARMASM_NO_HW_CRYPTO
; .arch_extension crypto
AREA |.rodata|, DATA, READONLY, ALIGN=4
ALIGN 8
L_SHA256_trans_crypto_len_k
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/port/arm/armv8-sha256-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,7 @@
}

#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
__asm__(".arch_extension crypto");

Check failure on line 1027 in wolfcrypt/src/port/arm/armv8-sha256-asm_c.c

View workflow job for this annotation

GitHub Actions / check

flush-left-call

flush-left function call (debug residue?)
XALIGNED(8) static const word32 L_SHA256_trans_crypto_len_k[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-sha3-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ _BlockSha3_crypto:
adrp x1, L_SHA3_transform_crypto_r@PAGE
add x1, x1, L_SHA3_transform_crypto_r@PAGEOFF
#endif /* __APPLE__ */
#ifdef __APPLE__
.arch_extension sha3
#endif /* __APPLE__ */
ld4 {v0.d, v1.d, v2.d, v3.d}[0], [x0], #32
ld4 {v4.d, v5.d, v6.d, v7.d}[0], [x0], #32
ld4 {v8.d, v9.d, v10.d, v11.d}[0], [x0], #32
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-sha3-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ void BlockSha3_crypto(word64* state)
{
const word64* r = L_SHA3_transform_crypto_r;
__asm__ __volatile__ (
#ifdef __APPLE__
".arch_extension sha3\n\t"
#endif /* __APPLE__ */
"ld4 {v0.d, v1.d, v2.d, v3.d}[0], [%x[state]], #32\n\t"
"ld4 {v4.d, v5.d, v6.d, v7.d}[0], [%x[state]], #32\n\t"
"ld4 {v8.d, v9.d, v10.d, v11.d}[0], [%x[state]], #32\n\t"
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-sha512-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -1136,9 +1136,7 @@ _Transform_Sha512_Len_crypto:
adrp x4, L_SHA512_trans_crypto_len_k@PAGE
add x4, x4, L_SHA512_trans_crypto_len_k@PAGEOFF
#endif /* __APPLE__ */
#ifdef __APPLE__
.arch_extension sha3
#endif /* __APPLE__ */
# Load K into vector registers
ld1 {v8.2d, v9.2d, v10.2d, v11.2d}, [x4], #0x40
ld1 {v12.2d, v13.2d, v14.2d, v15.2d}, [x4], #0x40
Expand Down
2 changes: 0 additions & 2 deletions wolfcrypt/src/port/arm/armv8-sha512-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,9 +1050,7 @@ void Transform_Sha512_Len_crypto(wc_Sha512* sha512, const byte* data,
{
const word64* k = L_SHA512_trans_crypto_len_k;
__asm__ __volatile__ (
#ifdef __APPLE__
".arch_extension sha3\n\t"
#endif /* __APPLE__ */
/* Load K into vector registers */
"ld1 {v8.2d, v9.2d, v10.2d, v11.2d}, [%[k]], #0x40\n\t"
"ld1 {v12.2d, v13.2d, v14.2d, v15.2d}, [%[k]], #0x40\n\t"
Expand Down
18 changes: 9 additions & 9 deletions wolfcrypt/src/sp_x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ static WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -1277,7 +1277,7 @@ static WC_INLINE sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -3482,7 +3482,7 @@ static WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -4165,7 +4165,7 @@ static WC_INLINE sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -6176,7 +6176,7 @@ static WC_INLINE sp_digit div_4096_word_64(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_4096_word_64(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -24637,7 +24637,7 @@ static WC_INLINE sp_digit div_256_word_4(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_256_word_4(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -49485,7 +49485,7 @@ static WC_INLINE sp_digit div_384_word_6(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_384_word_6(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -90454,7 +90454,7 @@ static WC_INLINE sp_digit div_521_word_9(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_521_word_9(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down Expand Up @@ -92647,7 +92647,7 @@ static WC_INLINE sp_digit div_1024_word_16(sp_digit d1, sp_digit d0,
static WC_INLINE sp_digit div_1024_word_16(sp_digit d1, sp_digit d0,
sp_digit div)
{
register sp_digit r asm("rax");
register sp_digit r __asm__("rax");
__asm__ __volatile__ (
"divq %3"
: "=a" (r)
Expand Down
Loading
Loading