FrodoKEM: Initial implementation

Supports Fast C code, small C code, small stack and assembly for x86_64, Aarch64, Aarch32, Thumb2.
This commit is contained in:
Sean Parkinson
2026-07-08 10:42:30 +10:00
parent 2c5e135bf9
commit 607d7cfdb3
73 changed files with 39316 additions and 276 deletions
+12
View File
@@ -0,0 +1,12 @@
# codespell configuration (read automatically from the repository root).
#
# "SME" is the Arm Scalable Matrix Extension, referenced throughout the
# FrodoKEM Aarch64 code (comments, CPUID_..._SME macros, frodokem_..._sme
# identifiers, "sve2+sme" build strings). codespell's dictionary treats it as
# a misspelling of some/same/sms. The ignore-regex below drops the standalone
# SME token (any case, including "_sme" / "+sme") before spell-checking, while
# still flagging "sme" embedded in a larger alphabetic word - so genuine typos
# are unaffected. Kept out of ignore-words-list so "sme" is not globally
# whitelisted for every file.
[codespell]
ignore-regex = (?i)(?<![a-z])sme(?![a-z])
+41 -1
View File
@@ -43,7 +43,7 @@ jobs:
- name: Install dependencies
uses: ./.github/actions/install-apt-deps
with:
packages: autoconf automake libtool build-essential bubblewrap
packages: autoconf automake libtool build-essential bubblewrap crossbuild-essential-arm64 crossbuild-essential-armhf
ghcr-debs-tag: ubuntu-24.04-minimal
# ccache via the cross-platform composite; the script passes the
@@ -154,6 +154,46 @@ jobs:
"--enable-dilithium=yes,no-ctx", "--enable-dual-alg-certs",
"--disable-qt",
"CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]},
{"name": "all-frodokem", "minutes": 3.5,
"configure": ["--enable-intelasm", "--enable-sp-asm",
"--enable-all", "--enable-testcert", "--enable-experimental",
"--enable-mlkem=yes,kyber,ml-kem",
"--enable-frodokem=aes,ephemeral", "--disable-qt",
"CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]},
{"name": "frodokem-small-smallstack-noasm", "minutes": 2.5,
"configure": ["--disable-intelasm", "--enable-smallstack",
"--enable-smallstackcache", "--enable-experimental",
"--enable-frodokem=aes,ephemeral,small",
"CPPFLAGS=-Wdeclaration-after-statement"]},
{"name": "frodokem-976-only-noasm", "minutes": 1.5,
"comment": "976-only builds D=16 (q=2^16) alone; no-asm the C path",
"configure": ["--disable-intelasm", "--enable-experimental",
"--enable-frodokem=aes,ephemeral,no-640,no-1344",
"CPPFLAGS=-Wdeclaration-after-statement"]},
{"name": "frodokem-640-shake-only", "minutes": 1.5,
"comment": "640-only builds D=15 (q=2^15); shake-only, with asm",
"configure": ["--enable-intelasm", "--enable-sp-asm",
"--enable-experimental",
"--enable-frodokem=no-976,no-1344,no-aes",
"CPPFLAGS=-Wdeclaration-after-statement"]},
{"name": "frodokem-aarch64-armasm", "minutes": 4, "check": false,
"cc": "ccache aarch64-linux-gnu-gcc",
"comment": "Cross-build only (no ARM runner): catches ARM asm link/compile breaks. sve+sme+aes A-gen all live in the .S.",
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
"--enable-armasm", "--enable-experimental",
"--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]},
{"name": "frodokem-aarch64-armasm-inline", "minutes": 4,
"check": false, "cc": "ccache aarch64-linux-gnu-gcc",
"comment": "Inline armasm: sve/sme/aes are .S-only, so they must fall back to NEON/C; guards the inline-asm link break.",
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
"--enable-armasm=inline", "--enable-experimental",
"--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]},
{"name": "frodokem-arm32-armasm", "minutes": 4, "check": false,
"cc": "ccache arm-linux-gnueabihf-gcc",
"comment": "Cross-build only: AArch32 NEON matrix ops + AES-crypto A-gen.",
"configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly",
"--enable-armasm", "--enable-experimental",
"--enable-frodokem=aes,ephemeral", "--disable-examples"]},
{"name": "ubsan-mldsa-mlkem", "minutes": 2.5,
"configure": ["--disable-shared", "--enable-dilithium",
"--enable-mlkem",
+1
View File
@@ -7,6 +7,7 @@ ctaocrypt/src/src/
*.d
*.libs
*.cache
*.su
.dirstamp
*.user
!*-VS2022.vcxproj.user
+8
View File
@@ -335,6 +335,8 @@ HSM_OP_KEY_GENERATION_FLAGS_CREATE
HSM_OP_KEY_GENERATION_FLAGS_UPDATE
HSM_SVC_KEY_STORE_FLAGS_UPDATE
HWCAP_ASIMDRDM
HWCAP2_SME
HWCAP_SVE
IDIRECT_DEV_RANDOM
IDIRECT_DEV_TIME
ID_TRNG
@@ -1111,7 +1113,13 @@ __ARCH_STRNCPY_NO_REDIRECT
__ARCH_STRSTR_NO_REDIRECT
__ARM_ARCH_7M__
__ARM_FEATURE_CRYPTO
__ARM_FEATURE_DSP
__ARM_FEATURE_SIMD32
__ARM_FEATURE_SME
__ARM_FEATURE_SVE
__ARM_FEATURE_UNALIGNED
__ARM_NEON
__ARM_NEON__
__ASSEMBLER__
__ATOMIC_CONSUME
__ATOMIC_RELAXED
+146
View File
@@ -1037,6 +1037,56 @@ add_option(WOLFSSL_EXTRA_PQC_HYBRIDS
"Enable extra PQ/T hybrid combinations (default: disabled)"
"no" "yes;no")
# FrodoKEM reference implementation (experimental)
add_option(WOLFSSL_FRODOKEM
"Enable the wolfSSL FrodoKEM reference implementation (requires WOLFSSL_EXPERIMENTAL) (default: disabled)"
"no" "yes;no")
# FrodoKEM matrix A generation with SHAKE-128 (default: enabled when FrodoKEM on)
add_option(WOLFSSL_FRODOKEM_SHAKE
"Enable FrodoKEM SHAKE-128 matrix A generation (default: enabled)"
"yes" "yes;no")
# FrodoKEM matrix A generation with AES-128 (default: disabled)
add_option(WOLFSSL_FRODOKEM_AES
"Enable FrodoKEM AES-128 matrix A generation (default: disabled)"
"no" "yes;no")
# eFrodoKEM (ephemeral, salt-less) variants (default: disabled)
add_option(WOLFSSL_FRODOKEM_EPHEMERAL
"Enable eFrodoKEM (ephemeral) variants (default: disabled)"
"no" "yes;no")
# FrodoKEM parameter sets (each default: enabled)
add_option(WOLFSSL_FRODOKEM_640
"Enable the FrodoKEM-640 parameter set (default: enabled)"
"yes" "yes;no")
add_option(WOLFSSL_FRODOKEM_976
"Enable the FrodoKEM-976 parameter set (default: enabled)"
"yes" "yes;no")
add_option(WOLFSSL_FRODOKEM_1344
"Enable the FrodoKEM-1344 parameter set (default: enabled)"
"yes" "yes;no")
# FrodoKEM operations (each default: enabled)
add_option(WOLFSSL_FRODOKEM_MAKE_KEY
"Enable FrodoKEM key generation (default: enabled)"
"yes" "yes;no")
add_option(WOLFSSL_FRODOKEM_ENCAPSULATE
"Enable FrodoKEM encapsulation (default: enabled)"
"yes" "yes;no")
add_option(WOLFSSL_FRODOKEM_DECAPSULATE
"Enable FrodoKEM decapsulation (default: enabled)"
"yes" "yes;no")
# Small-footprint FrodoKEM: looped (not unrolled) matrix arithmetic
# (default: disabled)
add_option(WOLFSSL_FRODOKEM_SMALL
"Enable small-footprint FrodoKEM (default: disabled)"
"no" "yes;no")
# FrodoKEM AArch64 SVE / SME acceleration (default: disabled; AArch64 asm only)
add_option(WOLFSSL_FRODOKEM_SVE
"Enable FrodoKEM AArch64 SVE acceleration (default: disabled)"
"no" "yes;no")
add_option(WOLFSSL_FRODOKEM_SME
"Enable FrodoKEM AArch64 SME acceleration (default: disabled)"
"no" "yes;no")
message(STATUS "Looking for WOLFSSL_EXPERIMENTAL")
if (WOLFSSL_EXPERIMENTAL)
message(STATUS "Looking for WOLFSSL_EXPERIMENTAL - found")
@@ -1092,6 +1142,98 @@ if (WOLFSSL_EXPERIMENTAL)
message(STATUS "Looking for WOLFSSL_EXTRA_PQC_HYBRIDS - not found")
endif()
# Checking for experimental feature: FrodoKEM
message(STATUS "Looking for WOLFSSL_FRODOKEM")
if (WOLFSSL_FRODOKEM)
set(WOLFSSL_FOUND_EXPERIMENTAL_FEATURE 1)
message(STATUS "Looking for WOLFSSL_FRODOKEM - found")
# At least one matrix A generation method must be enabled.
if (NOT WOLFSSL_FRODOKEM_SHAKE AND NOT WOLFSSL_FRODOKEM_AES)
message(FATAL_ERROR
"WOLFSSL_FRODOKEM requires WOLFSSL_FRODOKEM_SHAKE and/or WOLFSSL_FRODOKEM_AES.")
endif()
# At least one parameter set must be enabled.
if (NOT WOLFSSL_FRODOKEM_640 AND NOT WOLFSSL_FRODOKEM_976 AND
NOT WOLFSSL_FRODOKEM_1344)
message(FATAL_ERROR
"WOLFSSL_FRODOKEM requires at least one of WOLFSSL_FRODOKEM_640, WOLFSSL_FRODOKEM_976 or WOLFSSL_FRODOKEM_1344.")
endif()
# At least one operation must be enabled.
if (NOT WOLFSSL_FRODOKEM_MAKE_KEY AND NOT WOLFSSL_FRODOKEM_ENCAPSULATE
AND NOT WOLFSSL_FRODOKEM_DECAPSULATE)
message(FATAL_ERROR
"WOLFSSL_FRODOKEM requires at least one of WOLFSSL_FRODOKEM_MAKE_KEY, WOLFSSL_FRODOKEM_ENCAPSULATE or WOLFSSL_FRODOKEM_DECAPSULATE.")
endif()
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_HAVE_FRODOKEM")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHA3")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE128")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE256")
set_wolfssl_definitions("WOLFSSL_HAVE_FRODOKEM" RESULT)
set_wolfssl_definitions("WOLFSSL_SHA3" RESULT)
set_wolfssl_definitions("WOLFSSL_SHAKE128" RESULT)
set_wolfssl_definitions("WOLFSSL_SHAKE256" RESULT)
if (WOLFSSL_FRODOKEM_SHAKE)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_SHAKE")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_SHAKE" RESULT)
endif()
if (WOLFSSL_FRODOKEM_AES)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_AES")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_DIRECT")
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_AES_ECB")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_AES" RESULT)
set_wolfssl_definitions("WOLFSSL_AES_DIRECT" RESULT)
set_wolfssl_definitions("HAVE_AES_ECB" RESULT)
endif()
if (WOLFSSL_FRODOKEM_EPHEMERAL)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_EPHEMERAL")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_EPHEMERAL" RESULT)
endif()
if (WOLFSSL_FRODOKEM_SMALL)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_SMALL")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_SMALL" RESULT)
endif()
if (WOLFSSL_FRODOKEM_SVE)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_SVE")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_SVE" RESULT)
endif()
if (WOLFSSL_FRODOKEM_SME)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_SME")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_SME" RESULT)
endif()
# Excluded parameter sets.
if (NOT WOLFSSL_FRODOKEM_640)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_NO_FRODOKEM_640")
set_wolfssl_definitions("WOLFSSL_NO_FRODOKEM_640" RESULT)
endif()
if (NOT WOLFSSL_FRODOKEM_976)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_NO_FRODOKEM_976")
set_wolfssl_definitions("WOLFSSL_NO_FRODOKEM_976" RESULT)
endif()
if (NOT WOLFSSL_FRODOKEM_1344)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_NO_FRODOKEM_1344")
set_wolfssl_definitions("WOLFSSL_NO_FRODOKEM_1344" RESULT)
endif()
# Excluded operations.
if (NOT WOLFSSL_FRODOKEM_MAKE_KEY)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_NO_MAKE_KEY")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_NO_MAKE_KEY" RESULT)
endif()
if (NOT WOLFSSL_FRODOKEM_ENCAPSULATE)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_NO_ENCAPSULATE")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_NO_ENCAPSULATE" RESULT)
endif()
if (NOT WOLFSSL_FRODOKEM_DECAPSULATE)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FRODOKEM_NO_DECAPSULATE")
set_wolfssl_definitions("WOLFSSL_FRODOKEM_NO_DECAPSULATE" RESULT)
endif()
else()
message(STATUS "Looking for WOLFSSL_FRODOKEM - not found")
endif()
# Other experimental feature detection can be added here...
# Were any experimental features found? Display a message.
@@ -1110,6 +1252,9 @@ else()
if (WOLFSSL_FALCON)
message(FATAL_ERROR "Error: WOLFSSL_FALCON requires WOLFSSL_EXPERIMENTAL at this time.")
endif()
if (WOLFSSL_FRODOKEM)
message(FATAL_ERROR "Error: WOLFSSL_FRODOKEM requires WOLFSSL_EXPERIMENTAL at this time.")
endif()
endif()
# LMS
@@ -4184,6 +4329,7 @@ if(WOLFSSL_EXAMPLES)
tests/api/test_ed25519.c
tests/api/test_curve448.c
tests/api/test_ed448.c
tests/api/test_frodokem.c
tests/api/test_mlkem.c
tests/api/test_mldsa.c
tests/api/test_mldsa_legacy.c
+32
View File
@@ -253,6 +253,9 @@ function(generate_build_flags)
if(WOLFSSL_MLKEM OR WOLFSSL_USER_SETTINGS)
set(BUILD_WC_MLKEM "yes" PARENT_SCOPE)
endif()
if(WOLFSSL_FRODOKEM OR WOLFSSL_USER_SETTINGS)
set(BUILD_WC_FRODOKEM "yes" PARENT_SCOPE)
endif()
if(WOLFSSL_MLDSA OR WOLFSSL_DILITHIUM OR WOLFSSL_USER_SETTINGS)
set(BUILD_MLDSA "yes" PARENT_SCOPE)
endif()
@@ -1175,6 +1178,35 @@ function(generate_lib_src_list LIB_SOURCES)
endif()
endif()
if(BUILD_WC_FRODOKEM)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_frodokem.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_frodokem_mat.c)
if(BUILD_ARMASM)
if(BUILD_ARMASM_INLINE)
list(APPEND LIB_SOURCES
wolfcrypt/src/port/arm/armv8-frodokem-asm_c.c
wolfcrypt/src/port/arm/armv8-32-frodokem-asm_c.c)
else()
list(APPEND LIB_SOURCES
wolfcrypt/src/port/arm/armv8-frodokem-asm.S
wolfcrypt/src/port/arm/armv8-32-frodokem-asm.S)
endif()
if(BUILD_ARMASM_INLINE AND BUILD_ARM_THUMB)
list(APPEND LIB_SOURCES
wolfcrypt/src/port/arm/thumb2-frodokem-asm_c.c)
elseif(BUILD_ARM_THUMB)
list(APPEND LIB_SOURCES
wolfcrypt/src/port/arm/thumb2-frodokem-asm.S)
endif()
endif()
if(BUILD_INTELASM)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_frodokem_asm.S)
endif()
endif()
if(BUILD_WC_LMS)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_lms.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_lms_impl.c)
+210
View File
@@ -1904,6 +1904,166 @@ AC_ARG_ENABLE([extra-pqc-hybrids],
)
# FrodoKEM (experimental reference implementation)
AC_ARG_ENABLE([frodokem],
[AS_HELP_STRING([--enable-frodokem],[Enable FrodoKEM reference implementation, optionally with a comma-separated list of sub-options e.g. aes,ephemeral,small,no-640 (requires --enable-experimental) (default: disabled)])],
[ ENABLED_FRODOKEM=$enableval ],
[ ENABLED_FRODOKEM=no ]
)
AS_IF([ test "$ENABLED_FRODOKEM" != "no" && test "$ENABLED_EXPERIMENTAL" != "yes" ],[ AC_MSG_ERROR([frodokem requires --enable-experimental.]) ])
# FrodoKEM matrix A generation with SHAKE-128 (default: enabled with frodokem).
AC_ARG_ENABLE([frodokem-shake],
[AS_HELP_STRING([--enable-frodokem-shake],[Enable FrodoKEM SHAKE-128 matrix A generation (default: enabled)])],
[ ENABLED_FRODOKEM_SHAKE=$enableval ],
[ ENABLED_FRODOKEM_SHAKE=default ]
)
# FrodoKEM matrix A generation with AES-128 (default: disabled).
AC_ARG_ENABLE([frodokem-aes],
[AS_HELP_STRING([--enable-frodokem-aes],[Enable FrodoKEM AES-128 matrix A generation (default: disabled)])],
[ ENABLED_FRODOKEM_AES=$enableval ],
[ ENABLED_FRODOKEM_AES=no ]
)
# AArch64 SVE S*A accumulate, selected at run time by HWCAP (default: disabled).
AC_ARG_ENABLE([frodokem-sve],
[AS_HELP_STRING([--enable-frodokem-sve],[Enable FrodoKEM AArch64 SVE matrix acceleration (default: disabled)])],
[ ENABLED_FRODOKEM_SVE=$enableval ],
[ ENABLED_FRODOKEM_SVE=no ]
)
# AArch64 SME B*S via the ZA-tile UMOPA, selected at run time (default: disabled).
AC_ARG_ENABLE([frodokem-sme],
[AS_HELP_STRING([--enable-frodokem-sme],[Enable FrodoKEM AArch64 SME matrix acceleration (default: disabled)])],
[ ENABLED_FRODOKEM_SME=$enableval ],
[ ENABLED_FRODOKEM_SME=no ]
)
# eFrodoKEM (ephemeral, salt-less) variants (default: disabled).
AC_ARG_ENABLE([frodokem-ephemeral],
[AS_HELP_STRING([--enable-frodokem-ephemeral],[Enable eFrodoKEM (ephemeral) variants (default: disabled)])],
[ ENABLED_FRODOKEM_EPHEMERAL=$enableval ],
[ ENABLED_FRODOKEM_EPHEMERAL=no ]
)
# FrodoKEM parameter sets (each default: enabled with frodokem).
AC_ARG_ENABLE([frodokem-640],
[AS_HELP_STRING([--enable-frodokem-640],[Enable the FrodoKEM-640 parameter set (default: enabled)])],
[ ENABLED_FRODOKEM_640=$enableval ],
[ ENABLED_FRODOKEM_640=yes ]
)
AC_ARG_ENABLE([frodokem-976],
[AS_HELP_STRING([--enable-frodokem-976],[Enable the FrodoKEM-976 parameter set (default: enabled)])],
[ ENABLED_FRODOKEM_976=$enableval ],
[ ENABLED_FRODOKEM_976=yes ]
)
AC_ARG_ENABLE([frodokem-1344],
[AS_HELP_STRING([--enable-frodokem-1344],[Enable the FrodoKEM-1344 parameter set (default: enabled)])],
[ ENABLED_FRODOKEM_1344=$enableval ],
[ ENABLED_FRODOKEM_1344=yes ]
)
# FrodoKEM operations (each default: enabled with frodokem).
AC_ARG_ENABLE([frodokem-make-key],
[AS_HELP_STRING([--enable-frodokem-make-key],[Enable FrodoKEM key generation (default: enabled)])],
[ ENABLED_FRODOKEM_MAKE_KEY=$enableval ],
[ ENABLED_FRODOKEM_MAKE_KEY=yes ]
)
AC_ARG_ENABLE([frodokem-encapsulate],
[AS_HELP_STRING([--enable-frodokem-encapsulate],[Enable FrodoKEM encapsulation (default: enabled)])],
[ ENABLED_FRODOKEM_ENCAPSULATE=$enableval ],
[ ENABLED_FRODOKEM_ENCAPSULATE=yes ]
)
AC_ARG_ENABLE([frodokem-decapsulate],
[AS_HELP_STRING([--enable-frodokem-decapsulate],[Enable FrodoKEM decapsulation (default: enabled)])],
[ ENABLED_FRODOKEM_DECAPSULATE=$enableval ],
[ ENABLED_FRODOKEM_DECAPSULATE=yes ]
)
# Small-footprint FrodoKEM: use the looped (not fully unrolled) matrix
# arithmetic (default: disabled).
AC_ARG_ENABLE([frodokem-small],
[AS_HELP_STRING([--enable-frodokem-small],[Enable small-footprint FrodoKEM (default: disabled)])],
[ ENABLED_FRODOKEM_SMALL=$enableval ],
[ ENABLED_FRODOKEM_SMALL=no ]
)
# The FrodoKEM sub-options may also be given as a comma-separated list to
# --enable-frodokem, e.g. --enable-frodokem=aes,ephemeral,small,no-640. Each
# token sets the matching --enable-frodokem-<option> value ("no-<option>"
# disables). This is equivalent to passing the individual --enable-frodokem-*
# options.
case "$ENABLED_FRODOKEM" in
no | yes | '')
;;
*)
frodokem_opts="$ENABLED_FRODOKEM"
ENABLED_FRODOKEM=yes
for frodokem_opt in $(echo "$frodokem_opts" | tr ',' ' ')
do
case "$frodokem_opt" in
yes) ;;
small) ENABLED_FRODOKEM_SMALL=yes ;;
no-small) ENABLED_FRODOKEM_SMALL=no ;;
shake) ENABLED_FRODOKEM_SHAKE=yes ;;
no-shake) ENABLED_FRODOKEM_SHAKE=no ;;
aes) ENABLED_FRODOKEM_AES=yes ;;
no-aes) ENABLED_FRODOKEM_AES=no ;;
sve) ENABLED_FRODOKEM_SVE=yes ;;
no-sve) ENABLED_FRODOKEM_SVE=no ;;
sme) ENABLED_FRODOKEM_SME=yes ;;
no-sme) ENABLED_FRODOKEM_SME=no ;;
ephemeral) ENABLED_FRODOKEM_EPHEMERAL=yes ;;
no-ephemeral) ENABLED_FRODOKEM_EPHEMERAL=no ;;
640) ENABLED_FRODOKEM_640=yes ;;
no-640) ENABLED_FRODOKEM_640=no ;;
976) ENABLED_FRODOKEM_976=yes ;;
no-976) ENABLED_FRODOKEM_976=no ;;
1344) ENABLED_FRODOKEM_1344=yes ;;
no-1344) ENABLED_FRODOKEM_1344=no ;;
make-key) ENABLED_FRODOKEM_MAKE_KEY=yes ;;
no-make-key) ENABLED_FRODOKEM_MAKE_KEY=no ;;
encapsulate) ENABLED_FRODOKEM_ENCAPSULATE=yes ;;
no-encapsulate) ENABLED_FRODOKEM_ENCAPSULATE=no ;;
decapsulate) ENABLED_FRODOKEM_DECAPSULATE=yes ;;
no-decapsulate) ENABLED_FRODOKEM_DECAPSULATE=no ;;
*) AC_MSG_ERROR([Unknown --enable-frodokem option: $frodokem_opt]) ;;
esac
done
;;
esac
AS_IF([ test "$ENABLED_FRODOKEM" = "no" &&
( test "$ENABLED_FRODOKEM_AES" != "no" ||
test "$ENABLED_FRODOKEM_EPHEMERAL" != "no" ) ],
[ AC_MSG_ERROR([frodokem-aes and frodokem-ephemeral require --enable-frodokem.]) ])
if test "$ENABLED_FRODOKEM" != "no"
then
# SHAKE-128 matrix A generation is on by default unless explicitly disabled.
if test "$ENABLED_FRODOKEM_SHAKE" = "default"; then
ENABLED_FRODOKEM_SHAKE=yes
fi
# At least one matrix A generation method must be enabled.
if test "$ENABLED_FRODOKEM_SHAKE" = "no" && test "$ENABLED_FRODOKEM_AES" = "no"
then
AC_MSG_ERROR([frodokem requires at least one of --enable-frodokem-shake or --enable-frodokem-aes.])
fi
# At least one parameter set must be enabled.
if test "$ENABLED_FRODOKEM_640" = "no" && \
test "$ENABLED_FRODOKEM_976" = "no" && \
test "$ENABLED_FRODOKEM_1344" = "no"
then
AC_MSG_ERROR([frodokem requires at least one of --enable-frodokem-640, --enable-frodokem-976 or --enable-frodokem-1344.])
fi
# At least one operation must be enabled.
if test "$ENABLED_FRODOKEM_MAKE_KEY" = "no" && \
test "$ENABLED_FRODOKEM_ENCAPSULATE" = "no" && \
test "$ENABLED_FRODOKEM_DECAPSULATE" = "no"
then
AC_MSG_ERROR([frodokem requires at least one of --enable-frodokem-make-key, --enable-frodokem-encapsulate or --enable-frodokem-decapsulate.])
fi
else
if test "$ENABLED_FRODOKEM_SHAKE" = "default"; then
ENABLED_FRODOKEM_SHAKE=no
fi
fi
# Dilithium
# - SHA3, Shake128 and Shake256
AC_ARG_ENABLE([mldsa],
@@ -7639,6 +7799,12 @@ then
ENABLED_SHAKE128=yes
ENABLED_SHAKE256=yes
fi
if test "$ENABLED_FRODOKEM" != "no"
then
ENABLED_SHA3=yes
ENABLED_SHAKE128=yes
ENABLED_SHAKE256=yes
fi
# Set SHA-3 flags
if test "$ENABLED_SHA3" != "no"
@@ -11916,6 +12082,39 @@ AS_IF([test "x$ENABLED_SYS_CA_CERTS" = "xyes"],
AS_IF([test "x$ENABLED_DUAL_ALG_CERTS" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DUAL_ALG_CERTS"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_FRODOKEM"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_HAVE_FRODOKEM"])
AS_IF([test "x$ENABLED_FRODOKEM_SHAKE" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_SHAKE"])
AS_IF([test "x$ENABLED_FRODOKEM_AES" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_AES -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB"])
AS_IF([test "x$ENABLED_FRODOKEM_SVE" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_SVE"])
AS_IF([test "x$ENABLED_FRODOKEM_SME" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_SME"])
AS_IF([test "x$ENABLED_FRODOKEM_EPHEMERAL" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_EPHEMERAL"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && \
test "x$ENABLED_FRODOKEM_SMALL" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_SMALL"])
# Parameter sets and operations excluded from the build.
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && test "x$ENABLED_FRODOKEM_640" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_FRODOKEM_640"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && test "x$ENABLED_FRODOKEM_976" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_FRODOKEM_976"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && test "x$ENABLED_FRODOKEM_1344" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_FRODOKEM_1344"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && \
test "x$ENABLED_FRODOKEM_MAKE_KEY" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_NO_MAKE_KEY"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && \
test "x$ENABLED_FRODOKEM_ENCAPSULATE" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_NO_ENCAPSULATE"])
AS_IF([test "x$ENABLED_FRODOKEM" = "xyes" && \
test "x$ENABLED_FRODOKEM_DECAPSULATE" = "xno"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FRODOKEM_NO_DECAPSULATE"])
AS_IF([test "x$ENABLED_RPK" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DHAVE_RPK"])
@@ -12578,6 +12777,7 @@ AM_CONDITIONAL([BUILD_WC_LMS],[test "x$ENABLED_LMS" != "xno" || test "x$ENABLED_
AM_CONDITIONAL([BUILD_WC_XMSS],[test "x$ENABLED_XMSS" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_WC_SLHDSA],[test "x$ENABLED_SLHDSA" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_WC_MLKEM],[test "x$ENABLED_MLKEM" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_WC_FRODOKEM],[test "x$ENABLED_FRODOKEM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_MLDSA],[test "x$ENABLED_MLDSA" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_ECCSI],[test "x$ENABLED_ECCSI" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_SAKKE],[test "x$ENABLED_SAKKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
@@ -13300,6 +13500,16 @@ echo " * Maxim Integrated MAXQ10XX: $ENABLED_MAXQ10XX"
echo " * PSA: $ENABLED_PSA"
echo " * System CA certs: $ENABLED_SYS_CA_CERTS"
echo " * Dual alg cert support: $ENABLED_DUAL_ALG_CERTS"
echo " * FrodoKEM (experimental): $ENABLED_FRODOKEM"
echo " * FrodoKEM SHAKE-128 matrix A: $ENABLED_FRODOKEM_SHAKE"
echo " * FrodoKEM AES-128 matrix A: $ENABLED_FRODOKEM_AES"
echo " * eFrodoKEM (ephemeral): $ENABLED_FRODOKEM_EPHEMERAL"
echo " * FrodoKEM-640: $ENABLED_FRODOKEM_640"
echo " * FrodoKEM-976: $ENABLED_FRODOKEM_976"
echo " * FrodoKEM-1344: $ENABLED_FRODOKEM_1344"
echo " * FrodoKEM make key: $ENABLED_FRODOKEM_MAKE_KEY"
echo " * FrodoKEM encapsulate: $ENABLED_FRODOKEM_ENCAPSULATE"
echo " * FrodoKEM decapsulate: $ENABLED_FRODOKEM_DECAPSULATE"
echo " * ERR Queues per Thread: $ENABLED_ERRORQUEUEPERTHREAD"
echo " * rwlock: $ENABLED_RWLOCK"
echo " * keylog export: $ENABLED_KEYLOG_EXPORT"
@@ -39,6 +39,18 @@
selected when the key is initialized via wc_MlKemKey_Init() or
wc_MlKemKey_New().
\defgroup FRODO_KEM Algorithms - FrodoKEM
FrodoKEM is a conservative, unstructured-lattice (plain LWE) key
encapsulation mechanism. This is an experimental reference
implementation following the ISO/CFRG (salted) FrodoKEM and the
ephemeral eFrodoKEM (salt-less) variants. Three parameter sets are
provided - FrodoKEM-640 (NIST level 1), FrodoKEM-976 (level 3) and
FrodoKEM-1344 (level 5) - each with either SHAKE-128 or AES-128
generation of the public matrix A. The variant is selected by the
key type (a base parameter set optionally OR'd with FRODOKEM_AES
and/or FRODOKEM_EPHEMERAL) when the key is initialized via
wc_FrodoKemKey_Init() or wc_FrodoKemKey_New().
\defgroup SLH_DSA Algorithms - SLH-DSA (FIPS 205)
SLH-DSA (Stateless Hash-based Digital Signature Algorithm) is a
quantum-resistant signature scheme standardized by NIST as
+462
View File
@@ -0,0 +1,462 @@
/*!
\ingroup FRODO_KEM
\brief Allocates and initializes a new FrodoKemKey on the heap. The
returned pointer must be released with wc_FrodoKemKey_Delete().
FrodoKEM is a conservative, unstructured-lattice key encapsulation
mechanism. The type parameter is a base parameter set -
WC_FRODOKEM_640_SHAKE (NIST level 1), WC_FRODOKEM_976_SHAKE
(level 3) or WC_FRODOKEM_1344_SHAKE (level 5) - optionally OR'd with
FRODOKEM_AES (generate matrix A with AES-128 instead of SHAKE-128)
and/or FRODOKEM_EPHEMERAL (eFrodoKEM: ephemeral, no salt). Named
combinations such as WC_FRODOKEM_640_AES and WC_EFRODOKEM_1344_SHAKE
are provided.
\return Pointer to a freshly allocated FrodoKemKey on success.
\return NULL on allocation failure or if type is invalid.
\param [in] type FrodoKEM key type: a base parameter set optionally
OR'd with FRODOKEM_AES and/or FRODOKEM_EPHEMERAL.
\param [in] heap Heap hint for dynamic memory allocation. May be
NULL.
\param [in] devId Device identifier for hardware crypto callbacks.
Use INVALID_DEVID for software-only.
_Example_
\code
FrodoKemKey* key = wc_FrodoKemKey_New(WC_FRODOKEM_640_SHAKE, NULL,
INVALID_DEVID);
if (key == NULL) {
// allocation failed
}
// ... use key ...
wc_FrodoKemKey_Delete(key, &key);
\endcode
\sa wc_FrodoKemKey_Delete
\sa wc_FrodoKemKey_Init
*/
FrodoKemKey* wc_FrodoKemKey_New(int type, void* heap, int devId);
/*!
\ingroup FRODO_KEM
\brief Frees and zeros a heap-allocated FrodoKemKey previously
returned by wc_FrodoKemKey_New(). On success the caller's pointer
variable is set to NULL via key_p when key_p is not NULL.
\return 0 on success.
\return BAD_FUNC_ARG if key is NULL.
\param [in,out] key The FrodoKemKey to free.
\param [in,out] key_p Optional address of the caller's pointer
variable; when not NULL, it is set to NULL on success.
\sa wc_FrodoKemKey_New
*/
int wc_FrodoKemKey_Delete(FrodoKemKey* key, FrodoKemKey** key_p);
/*!
\ingroup FRODO_KEM
\brief Initializes a FrodoKemKey object in place. The type parameter
selects the FrodoKEM variant: a base parameter set
(WC_FRODOKEM_640_SHAKE, WC_FRODOKEM_976_SHAKE or
WC_FRODOKEM_1344_SHAKE) optionally OR'd with FRODOKEM_AES and/or
FRODOKEM_EPHEMERAL.
\return 0 on success.
\return BAD_FUNC_ARG if key is NULL or type has bits set outside a
base parameter set, FRODOKEM_AES and FRODOKEM_EPHEMERAL.
\return NOT_COMPILED_IN if type names a valid variant whose
parameter set or matrix-A generation method was disabled at build
time.
\param [in,out] key Pointer to the FrodoKemKey to initialize.
\param [in] type FrodoKEM key type: a base parameter set optionally
OR'd with FRODOKEM_AES and/or FRODOKEM_EPHEMERAL.
\param [in] heap Heap hint for dynamic memory allocation. May be
NULL.
\param [in] devId Device identifier for hardware crypto callbacks.
_Example_
\code
FrodoKemKey key;
int ret;
ret = wc_FrodoKemKey_Init(&key, WC_FRODOKEM_640_SHAKE, NULL,
INVALID_DEVID);
if (ret != 0) {
// error initializing key
}
// ... use key ...
wc_FrodoKemKey_Free(&key);
\endcode
\sa wc_FrodoKemKey_Free
\sa wc_FrodoKemKey_MakeKey
*/
int wc_FrodoKemKey_Init(FrodoKemKey* key, int type, void* heap,
int devId);
/*!
\ingroup FRODO_KEM
\brief Releases the resources held by a FrodoKemKey initialized with
wc_FrodoKemKey_Init() and zeroizes its secret material. The key
object itself is not freed (it was not allocated by Init).
\return 0 on success.
\return BAD_FUNC_ARG if key is NULL.
\param [in,out] key The FrodoKemKey to free.
\sa wc_FrodoKemKey_Init
*/
int wc_FrodoKemKey_Free(FrodoKemKey* key);
/*!
\ingroup FRODO_KEM
\brief Generates a FrodoKEM key pair into an initialized key using
the provided random number generator. On success the key holds both
the public and private keys, which can be serialized with
wc_FrodoKemKey_EncodePublicKey() and wc_FrodoKemKey_EncodePrivateKey().
\return 0 on success.
\return BAD_FUNC_ARG if key or rng is NULL.
\return MEMORY_E on allocation failure.
\return A negative error code from the RNG or hashing on failure.
\param [in,out] key An initialized FrodoKemKey to hold the generated
key pair.
\param [in] rng An initialized random number generator.
_Example_
\code
FrodoKemKey key;
WC_RNG rng;
int ret;
wc_InitRng(&rng);
wc_FrodoKemKey_Init(&key, WC_FRODOKEM_640_SHAKE, NULL, INVALID_DEVID);
ret = wc_FrodoKemKey_MakeKey(&key, &rng);
if (ret != 0) {
// error generating key pair
}
wc_FrodoKemKey_Free(&key);
wc_FreeRng(&rng);
\endcode
\sa wc_FrodoKemKey_MakeKeyWithRandom
\sa wc_FrodoKemKey_Encapsulate
\sa wc_FrodoKemKey_EncodePublicKey
*/
int wc_FrodoKemKey_MakeKey(FrodoKemKey* key, WC_RNG* rng);
/*!
\ingroup FRODO_KEM
\brief Generates a FrodoKEM key pair from caller-supplied random
bytes rather than an RNG. This is primarily for testing and known
answer tests; production code should use wc_FrodoKemKey_MakeKey().
The required length depends on the parameter set (for example
WC_FRODOKEM_640_MAKEKEY_RAND_SZ for FrodoKEM-640).
\return 0 on success.
\return BAD_FUNC_ARG if key or rand is NULL, or len is not the
length required for the key's parameter set.
\param [in,out] key An initialized FrodoKemKey to hold the generated
key pair.
\param [in] rand Buffer of random bytes.
\param [in] len Length of rand in bytes; must equal the parameter
set's WC_FRODOKEM_<set>_MAKEKEY_RAND_SZ.
\sa wc_FrodoKemKey_MakeKey
*/
int wc_FrodoKemKey_MakeKeyWithRandom(FrodoKemKey* key,
const unsigned char* rand, int len);
/*!
\ingroup FRODO_KEM
\brief Returns, through len, the size in bytes of a ciphertext
(encapsulation) for the key's parameter set. Use this to size the
ct buffer passed to wc_FrodoKemKey_Encapsulate().
\return 0 on success.
\return BAD_FUNC_ARG if key or len is NULL.
\param [in] key An initialized FrodoKemKey.
\param [out] len Set to the ciphertext size in bytes.
\sa wc_FrodoKemKey_Encapsulate
\sa wc_FrodoKemKey_SharedSecretSize
*/
int wc_FrodoKemKey_CipherTextSize(FrodoKemKey* key, word32* len);
/*!
\ingroup FRODO_KEM
\brief Returns, through len, the size in bytes of a shared secret
for the key's parameter set. Use this to size the ss buffer passed
to wc_FrodoKemKey_Encapsulate() and wc_FrodoKemKey_Decapsulate().
\return 0 on success.
\return BAD_FUNC_ARG if key or len is NULL.
\param [in] key An initialized FrodoKemKey.
\param [out] len Set to the shared secret size in bytes.
\sa wc_FrodoKemKey_CipherTextSize
\sa wc_FrodoKemKey_Encapsulate
*/
int wc_FrodoKemKey_SharedSecretSize(FrodoKemKey* key, word32* len);
/*!
\ingroup FRODO_KEM
\brief Encapsulates to a public key: generates a random shared
secret and the ciphertext that encapsulates it under key's public
key. The key must hold a public key (from wc_FrodoKemKey_MakeKey()
or wc_FrodoKemKey_DecodePublicKey()). Size the ct and ss buffers with
wc_FrodoKemKey_CipherTextSize() and wc_FrodoKemKey_SharedSecretSize().
\return 0 on success.
\return BAD_FUNC_ARG if key, ct, ss or rng is NULL.
\return BAD_STATE_E if key does not hold a public key.
\return MEMORY_E on allocation failure.
\param [in] key A FrodoKemKey holding a public key.
\param [out] ct Buffer to receive the ciphertext.
\param [out] ss Buffer to receive the shared secret.
\param [in] rng An initialized random number generator.
_Example_
\code
FrodoKemKey key;
WC_RNG rng;
word32 ctSz, ssSz;
byte ct[WC_FRODOKEM_640_CIPHER_TEXT_SIZE];
byte ss[WC_FRODOKEM_640_SS_SIZE];
int ret;
// key holds a decoded/generated public key
wc_FrodoKemKey_CipherTextSize(&key, &ctSz);
wc_FrodoKemKey_SharedSecretSize(&key, &ssSz);
ret = wc_FrodoKemKey_Encapsulate(&key, ct, ss, &rng);
if (ret != 0) {
// error encapsulating
}
\endcode
\sa wc_FrodoKemKey_Decapsulate
\sa wc_FrodoKemKey_EncapsulateWithRandom
\sa wc_FrodoKemKey_CipherTextSize
*/
int wc_FrodoKemKey_Encapsulate(FrodoKemKey* key, unsigned char* ct,
unsigned char* ss, WC_RNG* rng);
/*!
\ingroup FRODO_KEM
\brief Encapsulates using caller-supplied random bytes rather than
an RNG. This is primarily for testing and known answer tests;
production code should use wc_FrodoKemKey_Encapsulate(). The required
length depends on the parameter set (for example
WC_FRODOKEM_640_ENC_RAND_SZ for FrodoKEM-640).
\return 0 on success.
\return BAD_FUNC_ARG if key, ct, ss or rand is NULL, or len is not
the length required for the key's parameter set.
\return BAD_STATE_E if key does not hold a public key.
\param [in] key A FrodoKemKey holding a public key.
\param [out] ct Buffer to receive the ciphertext.
\param [out] ss Buffer to receive the shared secret.
\param [in] rand Buffer of random bytes.
\param [in] len Length of rand in bytes; must equal the parameter
set's WC_FRODOKEM_<set>_ENC_RAND_SZ.
\sa wc_FrodoKemKey_Encapsulate
*/
int wc_FrodoKemKey_EncapsulateWithRandom(FrodoKemKey* key,
unsigned char* ct, unsigned char* ss, const unsigned char* rand,
int len);
/*!
\ingroup FRODO_KEM
\brief Decapsulates a ciphertext to recover the shared secret using
the key's private key. FrodoKEM is IND-CCA2 secure: a ciphertext
that does not decrypt consistently yields a pseudo-random shared
secret (implicit rejection) rather than an error, so decapsulation
of a valid ciphertext reproduces the shared secret from
encapsulation. Size the ss buffer with
wc_FrodoKemKey_SharedSecretSize().
\return 0 on success (a shared secret is always produced for a
correctly sized ciphertext).
\return BAD_FUNC_ARG if key, ss or ct is NULL, or len is not the
ciphertext size for the key's parameter set.
\return BAD_STATE_E if key does not hold a private key.
\return MEMORY_E on allocation failure.
\param [in] key A FrodoKemKey holding a private key.
\param [out] ss Buffer to receive the shared secret.
\param [in] ct The ciphertext to decapsulate.
\param [in] len Length of ct in bytes; must equal the ciphertext
size for the key's parameter set.
_Example_
\code
FrodoKemKey key;
word32 ssSz;
byte ss[WC_FRODOKEM_640_SS_SIZE];
int ret;
// key holds a decoded/generated private key
wc_FrodoKemKey_SharedSecretSize(&key, &ssSz);
ret = wc_FrodoKemKey_Decapsulate(&key, ss, ct, ctSz);
if (ret != 0) {
// error decapsulating
}
\endcode
\sa wc_FrodoKemKey_Encapsulate
\sa wc_FrodoKemKey_SharedSecretSize
*/
int wc_FrodoKemKey_Decapsulate(FrodoKemKey* key, unsigned char* ss,
const unsigned char* ct, word32 len);
/*!
\ingroup FRODO_KEM
\brief Decodes (imports) a FrodoKEM private key from its serialized
form into an initialized key. The expected length matches
wc_FrodoKemKey_PrivateKeySize() for the key's parameter set.
\return 0 on success.
\return BAD_FUNC_ARG if key or in is NULL, or len is not the private
key size for the key's parameter set.
\param [in,out] key An initialized FrodoKemKey to hold the private
key.
\param [in] in The serialized private key.
\param [in] len Length of in in bytes.
\sa wc_FrodoKemKey_EncodePrivateKey
\sa wc_FrodoKemKey_PrivateKeySize
\sa wc_FrodoKemKey_Decapsulate
*/
int wc_FrodoKemKey_DecodePrivateKey(FrodoKemKey* key,
const unsigned char* in, word32 len);
/*!
\ingroup FRODO_KEM
\brief Decodes (imports) a FrodoKEM public key from its serialized
form into an initialized key. The expected length matches
wc_FrodoKemKey_PublicKeySize() for the key's parameter set.
\return 0 on success.
\return BAD_FUNC_ARG if key or in is NULL, or len is not the public
key size for the key's parameter set.
\param [in,out] key An initialized FrodoKemKey to hold the public
key.
\param [in] in The serialized public key.
\param [in] len Length of in in bytes.
\sa wc_FrodoKemKey_EncodePublicKey
\sa wc_FrodoKemKey_PublicKeySize
\sa wc_FrodoKemKey_Encapsulate
*/
int wc_FrodoKemKey_DecodePublicKey(FrodoKemKey* key,
const unsigned char* in, word32 len);
/*!
\ingroup FRODO_KEM
\brief Returns, through len, the size in bytes of a serialized
private key for the key's parameter set. Use this to size the buffer
passed to wc_FrodoKemKey_EncodePrivateKey().
\return 0 on success.
\return BAD_FUNC_ARG if key or len is NULL.
\param [in] key An initialized FrodoKemKey.
\param [out] len Set to the private key size in bytes.
\sa wc_FrodoKemKey_EncodePrivateKey
\sa wc_FrodoKemKey_DecodePrivateKey
*/
int wc_FrodoKemKey_PrivateKeySize(FrodoKemKey* key, word32* len);
/*!
\ingroup FRODO_KEM
\brief Returns, through len, the size in bytes of a serialized
public key for the key's parameter set. Use this to size the buffer
passed to wc_FrodoKemKey_EncodePublicKey().
\return 0 on success.
\return BAD_FUNC_ARG if key or len is NULL.
\param [in] key An initialized FrodoKemKey.
\param [out] len Set to the public key size in bytes.
\sa wc_FrodoKemKey_EncodePublicKey
\sa wc_FrodoKemKey_DecodePublicKey
*/
int wc_FrodoKemKey_PublicKeySize(FrodoKemKey* key, word32* len);
/*!
\ingroup FRODO_KEM
\brief Encodes (exports) the private key held by key into its
serialized form. The out buffer must be at least
wc_FrodoKemKey_PrivateKeySize() bytes.
\return 0 on success.
\return BAD_FUNC_ARG if key or out is NULL, or len is smaller than
the private key size for the key's parameter set.
\return BAD_STATE_E if key does not hold a private key.
\param [in] key A FrodoKemKey holding a private key.
\param [out] out Buffer to receive the serialized private key.
\param [in] len Length of the out buffer in bytes.
\sa wc_FrodoKemKey_DecodePrivateKey
\sa wc_FrodoKemKey_PrivateKeySize
*/
int wc_FrodoKemKey_EncodePrivateKey(FrodoKemKey* key,
unsigned char* out, word32 len);
/*!
\ingroup FRODO_KEM
\brief Encodes (exports) the public key held by key into its
serialized form. The out buffer must be at least
wc_FrodoKemKey_PublicKeySize() bytes.
\return 0 on success.
\return BAD_FUNC_ARG if key or out is NULL, or len is smaller than
the public key size for the key's parameter set.
\return BAD_STATE_E if key does not hold a public key.
\param [in] key A FrodoKemKey holding a public key.
\param [out] out Buffer to receive the serialized public key.
\param [in] len Length of the out buffer in bytes.
\sa wc_FrodoKemKey_DecodePublicKey
\sa wc_FrodoKemKey_PublicKeySize
*/
int wc_FrodoKemKey_EncodePublicKey(FrodoKemKey* key,
unsigned char* out, word32 len);
+37
View File
@@ -1849,6 +1849,43 @@ src_libwolfssl@LIBSUFFIX@_la_SOURCES += \
wolfcrypt/src/logging.c \
wolfcrypt/src/wc_port.c
# FrodoKEM (experimental reference implementation)
if BUILD_WC_FRODOKEM
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_frodokem.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_frodokem_mat.c
if BUILD_INTELASM
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_frodokem_asm.S
endif BUILD_INTELASM
# AArch64: NEON, plus the opt-in SVE and SME ops (guarded by WOLFSSL_FRODOKEM_SVE
# / WOLFSSL_FRODOKEM_SME), all in the one armv8-frodokem-asm file.
if BUILD_ARMASM_NEON
if BUILD_ARMASM_INLINE
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/armv8-frodokem-asm_c.c
else
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/armv8-frodokem-asm.S
endif !BUILD_ARMASM_INLINE
endif BUILD_ARMASM_NEON
# AArch32: NEON and the 32-bit-SIMD (SMLAD/SADD16/...) NEON-absent fallback share
# the one armv8-32-frodokem-asm file, built for ARM (non-Thumb) with or without
# NEON. Thumb2 has its own file.
if BUILD_ARMASM
if BUILD_ARM_NONTHUMB
if BUILD_ARMASM_INLINE
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/armv8-32-frodokem-asm_c.c
else
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/armv8-32-frodokem-asm.S
endif !BUILD_ARMASM_INLINE
endif BUILD_ARM_NONTHUMB
if BUILD_ARM_THUMB
if BUILD_ARMASM_INLINE
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/thumb2-frodokem-asm_c.c
else
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/thumb2-frodokem-asm.S
endif !BUILD_ARMASM_INLINE
endif BUILD_ARM_THUMB
endif BUILD_ARMASM
endif
if BUILD_ERROR_STRINGS
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/error.c
endif
+2
View File
@@ -235,6 +235,7 @@
#include <tests/api/test_curve448.h>
#include <tests/api/test_ed448.h>
#include <tests/api/test_mlkem.h>
#include <tests/api/test_frodokem.h>
#include <tests/api/test_mldsa.h>
#include <tests/api/test_slhdsa.h>
#include <tests/api/test_signature.h>
@@ -36979,6 +36980,7 @@ TEST_CASE testCases[] = {
TEST_ED448_DECLS,
/* Kyber */
TEST_MLKEM_DECLS,
TEST_FRODOKEM_DECLS,
/* Dilithium */
TEST_MLDSA_DECLS,
/* SLH-DSA */
+2
View File
@@ -47,6 +47,7 @@ tests_unit_test_SOURCES += tests/api/test_ed25519.c
tests_unit_test_SOURCES += tests/api/test_curve448.c
tests_unit_test_SOURCES += tests/api/test_ed448.c
tests_unit_test_SOURCES += tests/api/test_mlkem.c
tests_unit_test_SOURCES += tests/api/test_frodokem.c
tests_unit_test_SOURCES += tests/api/test_mldsa.c
tests_unit_test_SOURCES += tests/api/test_mldsa_legacy.c
tests_unit_test_SOURCES += tests/api/test_slhdsa.c
@@ -163,6 +164,7 @@ EXTRA_DIST += tests/api/test_ed25519.h
EXTRA_DIST += tests/api/test_curve448.h
EXTRA_DIST += tests/api/test_ed448.h
EXTRA_DIST += tests/api/test_mlkem.h
EXTRA_DIST += tests/api/test_frodokem.h
EXTRA_DIST += tests/api/test_mldsa.h
EXTRA_DIST += tests/api/test_slhdsa.h
EXTRA_DIST += tests/api/test_signature.h
File diff suppressed because it is too large Load Diff
+54
View File
@@ -0,0 +1,54 @@
/* test_frodokem.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLFCRYPT_TEST_FRODOKEM_H
#define WOLFCRYPT_TEST_FRODOKEM_H
#include <tests/api/api_decl.h>
int test_wc_frodokem_make_key_kats(void);
int test_wc_frodokem_encapsulate_kats(void);
int test_wc_frodokem_decapsulate_kats(void);
int test_wc_frodokem_roundtrip(void);
int test_wc_frodokem_encode_decode(void);
int test_wc_frodokem_decap_implicit_reject(void);
int test_wc_frodokem_decapsulate_pubonly_fails(void);
int test_wc_frodokem_decode_privkey_bad_pkh(void);
int test_wc_frodokem_bad_args(void);
int test_wc_frodokem_op_len_checks(void);
int test_wc_frodokem_new_delete(void);
int test_wc_frodokem_not_compiled_in(void);
#define TEST_FRODOKEM_DECLS \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_make_key_kats), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_encapsulate_kats), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_decapsulate_kats), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_roundtrip), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_encode_decode), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_decap_implicit_reject), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_decapsulate_pubonly_fails),\
TEST_DECL_GROUP("frodokem", test_wc_frodokem_decode_privkey_bad_pkh), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_bad_args), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_op_len_checks), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_new_delete), \
TEST_DECL_GROUP("frodokem", test_wc_frodokem_not_compiled_in)
#endif /* WOLFCRYPT_TEST_FRODOKEM_H */
+293 -2
View File
@@ -171,6 +171,9 @@
#ifdef WOLFSSL_HAVE_MLKEM
#include <wolfssl/wolfcrypt/wc_mlkem.h>
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
#include <wolfssl/wolfcrypt/wc_frodokem.h>
#endif
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
#include <wolfssl/wolfcrypt/wc_lms.h>
#endif
@@ -914,6 +917,12 @@ static WC_INLINE void bench_append_memory_info(char* buffer, size_t size,
#define BENCH_ML_KEM_1024 0x00000080
#define BENCH_ML_KEM (BENCH_ML_KEM_512 | BENCH_ML_KEM_768 | \
BENCH_ML_KEM_1024)
#define BENCH_FRODOKEM_640 0x00000100
#define BENCH_FRODOKEM_976 0x00000200
#define BENCH_FRODOKEM_1344 0x00000400
#define BENCH_FRODOKEM (BENCH_FRODOKEM_640 | \
BENCH_FRODOKEM_976 | \
BENCH_FRODOKEM_1344)
#define BENCH_FALCON_LEVEL1_SIGN 0x00000001
#define BENCH_FALCON_LEVEL5_SIGN 0x00000002
#define BENCH_ML_DSA_44_SIGN 0x04000000
@@ -1359,8 +1368,8 @@ static const bench_pq_hash_sig_alg bench_pq_hash_sig_opt[] = {
#endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */
#if !defined(WOLFSSL_BENCHMARK_ALL) && !defined(MAIN_NO_ARGS)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(HAVE_FALCON) || \
defined(WOLFSSL_HAVE_MLDSA)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_HAVE_FRODOKEM) || \
defined(HAVE_FALCON) || defined(WOLFSSL_HAVE_MLDSA)
/* The post-quantum-specific mapping of command line option to bit values and
* OQS name. */
typedef struct bench_pq_alg {
@@ -1384,6 +1393,12 @@ static const bench_pq_alg bench_pq_asym_opt[] = {
{ "-ml-kem-768", BENCH_ML_KEM_768 },
{ "-ml-kem-1024", BENCH_ML_KEM_1024 },
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
{ "-frodokem", BENCH_FRODOKEM },
{ "-frodokem-640", BENCH_FRODOKEM_640 },
{ "-frodokem-976", BENCH_FRODOKEM_976 },
{ "-frodokem-1344", BENCH_FRODOKEM_1344 },
#endif
#if defined(HAVE_FALCON)
{ "-falcon_level1", BENCH_FALCON_LEVEL1_SIGN },
{ "-falcon_level5", BENCH_FALCON_LEVEL5_SIGN },
@@ -4458,6 +4473,26 @@ static void* benchmarks_do(void* args)
}
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
if (bench_all || (bench_pq_asym_algs & BENCH_FRODOKEM)) {
#ifdef WOLFSSL_WC_FRODOKEM_640
if (bench_all || (bench_pq_asym_algs & BENCH_FRODOKEM_640)) {
bench_frodokem(WC_FRODOKEM_640);
}
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
if (bench_all || (bench_pq_asym_algs & BENCH_FRODOKEM_976)) {
bench_frodokem(WC_FRODOKEM_976);
}
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
if (bench_all || (bench_pq_asym_algs & BENCH_FRODOKEM_1344)) {
bench_frodokem(WC_FRODOKEM_1344);
}
#endif
}
#endif
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
if (bench_all || (bench_pq_hash_sig_algs & BENCH_LMS_HSS)) {
bench_lms();
@@ -11439,6 +11474,262 @@ void bench_mlkem(int type)
}
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
static void bench_frodokem_keygen(int type, const char* name, int keySize,
FrodoKemKey* key)
{
#ifndef WOLFSSL_FRODOKEM_NO_MAKE_KEY
int ret = 0, times, count, pending = 0;
double start;
const char**desc = bench_desc_words[lng_index];
DECLARE_MULTI_VALUE_STATS_VARS()
bench_stats_prepare();
/* FrodoKEM Make Key */
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
wc_FrodoKemKey_Free(key);
ret = wc_FrodoKemKey_Init(key, type, HEAP_HINT, INVALID_DEVID);
if (ret != 0)
goto exit;
ret = wc_FrodoKemKey_MakeKey(key, &gRng);
if (ret != 0)
goto exit;
RECORD_MULTI_VALUE_STATS();
} /* for times */
count += times;
} while (bench_stats_check(start)
#ifdef MULTI_VALUE_STATISTICS
|| runs < minimum_runs
#endif
);
exit:
bench_stats_asym_finish(name, keySize, desc[2], 0, count, start, ret);
#ifdef MULTI_VALUE_STATISTICS
bench_multi_value_stats(max, min, sum, squareSum, runs);
#endif
#else
(void)type;
(void)name;
(void)keySize;
(void)key;
#endif /* !WOLFSSL_FRODOKEM_NO_MAKE_KEY */
}
#if !defined(WOLFSSL_FRODOKEM_NO_ENCAPSULATE) || \
!defined(WOLFSSL_FRODOKEM_NO_DECAPSULATE)
static void bench_frodokem_encap(int type, const char* name, int keySize,
FrodoKemKey* key1, FrodoKemKey* key2)
{
int ret = 0, times, count, pending = 0;
double start;
const char**desc = bench_desc_words[lng_index];
WC_DECLARE_VAR(ct, byte, FRODOKEM_MAX_CIPHER_TEXT_SIZE, HEAP_HINT);
WC_DECLARE_VAR(ss, byte, FRODOKEM_MAX_LENSEC, HEAP_HINT);
WC_DECLARE_VAR(pub, byte, FRODOKEM_MAX_PUBLIC_KEY_SIZE, HEAP_HINT);
word32 pubLen;
word32 ctSz;
DECLARE_MULTI_VALUE_STATS_VARS()
bench_stats_prepare();
WC_ALLOC_VAR(ct, byte, FRODOKEM_MAX_CIPHER_TEXT_SIZE, HEAP_HINT);
WC_ALLOC_VAR(ss, byte, FRODOKEM_MAX_LENSEC, HEAP_HINT);
WC_ALLOC_VAR(pub, byte, FRODOKEM_MAX_PUBLIC_KEY_SIZE, HEAP_HINT);
ret = wc_FrodoKemKey_PublicKeySize(key1, &pubLen);
if (ret != 0) {
goto exit;
}
ret = wc_FrodoKemKey_EncodePublicKey(key1, pub, pubLen);
if (ret != 0) {
goto exit;
}
ret = wc_FrodoKemKey_Init(key2, type, HEAP_HINT, INVALID_DEVID);
if (ret != 0) {
goto exit;
}
ret = wc_FrodoKemKey_DecodePublicKey(key2, pub, pubLen);
if (ret != 0) {
goto exit;
}
ret = wc_FrodoKemKey_CipherTextSize(key2, &ctSz);
if (ret != 0) {
goto exit;
}
#ifndef WOLFSSL_FRODOKEM_NO_ENCAPSULATE
/* FrodoKEM Encapsulate */
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
ret = wc_FrodoKemKey_Encapsulate(key2, ct, ss, &gRng);
if (ret != 0)
goto exit_encap;
RECORD_MULTI_VALUE_STATS();
} /* for times */
count += times;
} while (bench_stats_check(start)
#ifdef MULTI_VALUE_STATISTICS
|| runs < minimum_runs
#endif
);
exit_encap:
bench_stats_asym_finish(name, keySize, desc[9], 0, count, start, ret);
#ifdef MULTI_VALUE_STATISTICS
bench_multi_value_stats(max, min, sum, squareSum, runs);
#endif
#endif
#ifndef WOLFSSL_FRODOKEM_NO_DECAPSULATE
RESET_MULTI_VALUE_STATS_VARS();
/* FrodoKEM Decapsulate */
PRIVATE_KEY_UNLOCK();
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
ret = wc_FrodoKemKey_Decapsulate(key1, ss, ct, ctSz);
if (ret != 0)
goto exit_decap;
RECORD_MULTI_VALUE_STATS();
} /* for times */
count += times;
} while (bench_stats_check(start)
#ifdef MULTI_VALUE_STATISTICS
|| runs < minimum_runs
#endif
);
exit_decap:
PRIVATE_KEY_LOCK();
bench_stats_asym_finish(name, keySize, desc[13], 0, count, start, ret);
#ifdef MULTI_VALUE_STATISTICS
bench_multi_value_stats(max, min, sum, squareSum, runs);
#endif
#endif
exit:
WC_FREE_VAR(ct, HEAP_HINT);
WC_FREE_VAR(ss, HEAP_HINT);
WC_FREE_VAR(pub, HEAP_HINT);
if (ret != 0)
printf("error: bench_frodokem_encap() failed with code %d.\n", ret);
return;
}
#endif
void bench_frodokem(int type)
{
#ifdef WOLFSSL_SMALL_STACK
FrodoKemKey *key1 = NULL;
FrodoKemKey *key2 = NULL;
#else
FrodoKemKey key1[1];
FrodoKemKey key2[1];
#endif
/* Matrix-A method and eFrodoKEM modifiers to layer onto the base parameter
* set. Only combinations that are compiled in are listed, so every built
* variant of the requested parameter set is benchmarked. */
static const int mods[] = {
#ifdef WOLFSSL_FRODOKEM_SHAKE
0,
#ifdef WOLFSSL_FRODOKEM_EPHEMERAL
FRODOKEM_EPHEMERAL,
#endif
#endif
#ifdef WOLFSSL_FRODOKEM_AES
FRODOKEM_AES,
#ifdef WOLFSSL_FRODOKEM_EPHEMERAL
FRODOKEM_AES | FRODOKEM_EPHEMERAL,
#endif
#endif
};
int base = type & ~(FRODOKEM_AES | FRODOKEM_EPHEMERAL);
const char* baseName = NULL;
int keySize = 0;
size_t v;
switch (base) {
#ifdef WOLFSSL_WC_FRODOKEM_640
case WC_FRODOKEM_640:
baseName = "640 ";
keySize = 128;
break;
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
case WC_FRODOKEM_976:
baseName = "976 ";
keySize = 192;
break;
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
case WC_FRODOKEM_1344:
baseName = "1344";
keySize = 256;
break;
#endif
default:
return;
}
#ifdef WOLFSSL_SMALL_STACK
key1 = (FrodoKemKey *)XMALLOC(sizeof(*key1), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (key1 == NULL)
return;
key2 = (FrodoKemKey *)XMALLOC(sizeof(*key2), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (key2 == NULL) {
XFREE(key1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return;
}
#endif
/* Zero the key objects so the wc_FrodoKemKey_Free calls below are safe even
* if a benchmark helper returns before initializing its key. */
XMEMSET(key1, 0, sizeof(*key1));
XMEMSET(key2, 0, sizeof(*key2));
for (v = 0; v < sizeof(mods) / sizeof(mods[0]); v++) {
int mod = mods[v];
int fullType = base | mod;
/* e.g. "FRODOKEM 640 SHAKE" or "EFRODOKEM 1344 AES". */
char name[24];
(void)XSNPRINTF(name, sizeof(name), "%sFRODOKEM %s %s",
(mod & FRODOKEM_EPHEMERAL) ? "E" : "",
baseName,
(mod & FRODOKEM_AES) ? "AES" : "SHAKE");
bench_frodokem_keygen(fullType, name, keySize, key1);
#if !defined(WOLFSSL_FRODOKEM_NO_ENCAPSULATE) || \
!defined(WOLFSSL_FRODOKEM_NO_DECAPSULATE)
bench_frodokem_encap(fullType, name, keySize, key1, key2);
#endif
}
wc_FrodoKemKey_Free(key2);
wc_FrodoKemKey_Free(key1);
WC_FREE_VAR_EX(key1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(key2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
#ifndef WOLFSSL_WC_LMS_SERIALIZE_STATE
#ifndef WOLFSSL_NO_LMS_SHA256_256
+1
View File
@@ -104,6 +104,7 @@ void bench_rsa(int useDeviceID);
void bench_rsa_key(int useDeviceID, word32 keySz);
void bench_dh(int useDeviceID);
void bench_mlkem(int type);
void bench_frodokem(int type);
void bench_lms(void);
void bench_xmss(int hash);
void bench_slhdsa(int param);
+93 -101
View File
@@ -6459,8 +6459,7 @@ _TEXT ENDS
IFDEF WOLFSSL_AESGCM_SIV
_DATA SEGMENT
ALIGN 16
L_aes_gcm_siv_bswap_mask QWORD \
08090a0b0c0d0e0fh, 0001020304050607h
L_aes_gcm_siv_bswap_mask QWORD 08090a0b0c0d0e0fh, 0001020304050607h
ptr_L_aes_gcm_siv_bswap_mask QWORD L_aes_gcm_siv_bswap_mask
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -6825,8 +6824,7 @@ AES_GCMSIV_polyval_aesni ENDP
_TEXT ENDS
_DATA SEGMENT
ALIGN 16
L_aes_gcmsiv_ctr_aesni_one QWORD \
0000000000000001h, 0000000000000000h
L_aes_gcmsiv_ctr_aesni_one QWORD 0000000000000001h, 0000000000000000h
ptr_L_aes_gcmsiv_ctr_aesni_one QWORD L_aes_gcmsiv_ctr_aesni_one
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -12471,8 +12469,7 @@ _TEXT ENDS
IFDEF WOLFSSL_AESGCM_SIV
_DATA SEGMENT
ALIGN 16
L_aes_gcm_siv_bswap_mask_avx1 QWORD \
08090a0b0c0d0e0fh, 0001020304050607h
L_aes_gcm_siv_bswap_mask_avx1 QWORD 08090a0b0c0d0e0fh, 0001020304050607h
ptr_L_aes_gcm_siv_bswap_mask_avx1 QWORD L_aes_gcm_siv_bswap_mask_avx1
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -12738,8 +12735,7 @@ AES_GCMSIV_polyval_avx1 ENDP
_TEXT ENDS
_DATA SEGMENT
ALIGN 16
L_aes_gcmsiv_ctr_avx1_one QWORD \
0000000000000001h, 0000000000000000h
L_aes_gcmsiv_ctr_avx1_one QWORD 0000000000000001h, 0000000000000000h
ptr_L_aes_gcmsiv_ctr_avx1_one QWORD L_aes_gcmsiv_ctr_avx1_one
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -25206,8 +25202,7 @@ _TEXT ENDS
IFDEF WOLFSSL_AESGCM_SIV
_DATA SEGMENT
ALIGN 16
L_aes_gcm_siv_bswap_mask_vaes QWORD \
08090a0b0c0d0e0fh, 0001020304050607h
L_aes_gcm_siv_bswap_mask_vaes QWORD 08090a0b0c0d0e0fh, 0001020304050607h
ptr_L_aes_gcm_siv_bswap_mask_vaes QWORD L_aes_gcm_siv_bswap_mask_vaes
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -25743,24 +25738,23 @@ AES_GCMSIV_polyval_vaes ENDP
_TEXT ENDS
_DATA SEGMENT
ALIGN 16
L_aes_gcmsiv_ctr_inc_vaes QWORD \
0000000000000000h, 0000000000000000h,
0000000000000001h, 0000000000000000h,
0000000000000002h, 0000000000000000h,
0000000000000003h, 0000000000000000h,
0000000000000004h, 0000000000000000h,
0000000000000005h, 0000000000000000h,
0000000000000006h, 0000000000000000h,
0000000000000007h, 0000000000000000h,
0000000000000008h, 0000000000000000h,
0000000000000009h, 0000000000000000h,
000000000000000ah, 0000000000000000h,
000000000000000bh, 0000000000000000h,
000000000000000ch, 0000000000000000h,
000000000000000dh, 0000000000000000h,
000000000000000eh, 0000000000000000h,
000000000000000fh, 0000000000000000h,
0000000000000010h, 0000000000000000h
L_aes_gcmsiv_ctr_inc_vaes QWORD 0000000000000000h, 0000000000000000h
QWORD 0000000000000001h, 0000000000000000h
QWORD 0000000000000002h, 0000000000000000h
QWORD 0000000000000003h, 0000000000000000h
QWORD 0000000000000004h, 0000000000000000h
QWORD 0000000000000005h, 0000000000000000h
QWORD 0000000000000006h, 0000000000000000h
QWORD 0000000000000007h, 0000000000000000h
QWORD 0000000000000008h, 0000000000000000h
QWORD 0000000000000009h, 0000000000000000h
QWORD 000000000000000ah, 0000000000000000h
QWORD 000000000000000bh, 0000000000000000h
QWORD 000000000000000ch, 0000000000000000h
QWORD 000000000000000dh, 0000000000000000h
QWORD 000000000000000eh, 0000000000000000h
QWORD 000000000000000fh, 0000000000000000h
QWORD 0000000000000010h, 0000000000000000h
ptr_L_aes_gcmsiv_ctr_inc_vaes QWORD L_aes_gcmsiv_ctr_inc_vaes
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -25777,10 +25771,10 @@ AES_GCMSIV_ctr_vaes PROC
vmovdqu OWORD PTR [rsp+48], xmm9
vmovdqu OWORD PTR [rsp+64], xmm10
vmovdqu OWORD PTR [rsp+80], xmm11
vbroadcasti128 ymm7, [r10]
vbroadcasti128 ymm8, [ptr_L_aes_gcmsiv_ctr_inc_vaes+128]
vbroadcasti128 ymm9, [ptr_L_aes_gcmsiv_ctr_inc_vaes+32]
vbroadcasti128 ymm10, [ptr_L_aes_gcmsiv_ctr_inc_vaes+16]
vbroadcasti128 ymm7, OWORD PTR [r10]
vbroadcasti128 ymm8, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_vaes+128]
vbroadcasti128 ymm9, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_vaes+32]
vbroadcasti128 ymm10, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_vaes+16]
xor r11d, r11d
cmp r8d, 128
mov r12d, r8d
@@ -25803,81 +25797,81 @@ L_AES_GCMSIV_ctr_vaes_enc_128:
vpaddd ymm6, ymm6, ymm8
vpaddd ymm7, ymm7, ymm8
; aes_enc_block
vbroadcasti128 ymm11, [r9]
vbroadcasti128 ymm11, OWORD PTR [r9]
vpxor ymm0, ymm0, ymm11
vpxor ymm1, ymm1, ymm11
vpxor ymm2, ymm2, ymm11
vpxor ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+16]
vbroadcasti128 ymm11, OWORD PTR [r9+16]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+32]
vbroadcasti128 ymm11, OWORD PTR [r9+32]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+48]
vbroadcasti128 ymm11, OWORD PTR [r9+48]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+64]
vbroadcasti128 ymm11, OWORD PTR [r9+64]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+80]
vbroadcasti128 ymm11, OWORD PTR [r9+80]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+96]
vbroadcasti128 ymm11, OWORD PTR [r9+96]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+112]
vbroadcasti128 ymm11, OWORD PTR [r9+112]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+128]
vbroadcasti128 ymm11, OWORD PTR [r9+128]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+144]
vbroadcasti128 ymm11, OWORD PTR [r9+144]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
cmp eax, 11
vbroadcasti128 ymm11, [r9+160]
vbroadcasti128 ymm11, OWORD PTR [r9+160]
jl L_AES_GCMSIV_ctr_vaes_128_aes_enc_block_last
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+176]
vbroadcasti128 ymm11, OWORD PTR [r9+176]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
cmp eax, 13
vbroadcasti128 ymm11, [r9+192]
vbroadcasti128 ymm11, OWORD PTR [r9+192]
jl L_AES_GCMSIV_ctr_vaes_128_aes_enc_block_last
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+208]
vbroadcasti128 ymm11, OWORD PTR [r9+208]
vaesenc ymm0, ymm0, ymm11
vaesenc ymm1, ymm1, ymm11
vaesenc ymm2, ymm2, ymm11
vaesenc ymm3, ymm3, ymm11
vbroadcasti128 ymm11, [r9+224]
vbroadcasti128 ymm11, OWORD PTR [r9+224]
L_AES_GCMSIV_ctr_vaes_128_aes_enc_block_last:
vaesenclast ymm0, ymm0, ymm11
vaesenclast ymm1, ymm1, ymm11
@@ -25908,39 +25902,39 @@ L_AES_GCMSIV_ctr_vaes_enc_32:
vpaddd ymm0, ymm7, [ptr_L_aes_gcmsiv_ctr_inc_vaes]
vpaddd ymm7, ymm7, ymm9
; aes_enc_block
vbroadcasti128 ymm11, [r9]
vbroadcasti128 ymm11, OWORD PTR [r9]
vpxor ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+16]
vbroadcasti128 ymm11, OWORD PTR [r9+16]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+32]
vbroadcasti128 ymm11, OWORD PTR [r9+32]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+48]
vbroadcasti128 ymm11, OWORD PTR [r9+48]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+64]
vbroadcasti128 ymm11, OWORD PTR [r9+64]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+80]
vbroadcasti128 ymm11, OWORD PTR [r9+80]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+96]
vbroadcasti128 ymm11, OWORD PTR [r9+96]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+112]
vbroadcasti128 ymm11, OWORD PTR [r9+112]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+128]
vbroadcasti128 ymm11, OWORD PTR [r9+128]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+144]
vbroadcasti128 ymm11, OWORD PTR [r9+144]
vaesenc ymm0, ymm0, ymm11
cmp eax, 11
vbroadcasti128 ymm11, [r9+160]
vbroadcasti128 ymm11, OWORD PTR [r9+160]
jl L_AES_GCMSIV_ctr_vaes_32_aes_enc_block_last
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+176]
vbroadcasti128 ymm11, OWORD PTR [r9+176]
vaesenc ymm0, ymm0, ymm11
cmp eax, 13
vbroadcasti128 ymm11, [r9+192]
vbroadcasti128 ymm11, OWORD PTR [r9+192]
jl L_AES_GCMSIV_ctr_vaes_32_aes_enc_block_last
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+208]
vbroadcasti128 ymm11, OWORD PTR [r9+208]
vaesenc ymm0, ymm0, ymm11
vbroadcasti128 ymm11, [r9+224]
vbroadcasti128 ymm11, OWORD PTR [r9+224]
L_AES_GCMSIV_ctr_vaes_32_aes_enc_block_last:
vaesenclast ymm0, ymm0, ymm11
vpxor ymm0, ymm0, [r13]
@@ -35966,8 +35960,7 @@ _TEXT ENDS
IFDEF WOLFSSL_AESGCM_SIV
_DATA SEGMENT
ALIGN 16
L_aes_gcm_siv_bswap_mask_avx512 QWORD \
08090a0b0c0d0e0fh, 0001020304050607h
L_aes_gcm_siv_bswap_mask_avx512 QWORD 08090a0b0c0d0e0fh, 0001020304050607h
ptr_L_aes_gcm_siv_bswap_mask_avx512 QWORD L_aes_gcm_siv_bswap_mask_avx512
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -36702,24 +36695,23 @@ AES_GCMSIV_polyval_avx512 ENDP
_TEXT ENDS
_DATA SEGMENT
ALIGN 16
L_aes_gcmsiv_ctr_inc_avx512 QWORD \
0000000000000000h, 0000000000000000h,
0000000000000001h, 0000000000000000h,
0000000000000002h, 0000000000000000h,
0000000000000003h, 0000000000000000h,
0000000000000004h, 0000000000000000h,
0000000000000005h, 0000000000000000h,
0000000000000006h, 0000000000000000h,
0000000000000007h, 0000000000000000h,
0000000000000008h, 0000000000000000h,
0000000000000009h, 0000000000000000h,
000000000000000ah, 0000000000000000h,
000000000000000bh, 0000000000000000h,
000000000000000ch, 0000000000000000h,
000000000000000dh, 0000000000000000h,
000000000000000eh, 0000000000000000h,
000000000000000fh, 0000000000000000h,
0000000000000010h, 0000000000000000h
L_aes_gcmsiv_ctr_inc_avx512 QWORD 0000000000000000h, 0000000000000000h
QWORD 0000000000000001h, 0000000000000000h
QWORD 0000000000000002h, 0000000000000000h
QWORD 0000000000000003h, 0000000000000000h
QWORD 0000000000000004h, 0000000000000000h
QWORD 0000000000000005h, 0000000000000000h
QWORD 0000000000000006h, 0000000000000000h
QWORD 0000000000000007h, 0000000000000000h
QWORD 0000000000000008h, 0000000000000000h
QWORD 0000000000000009h, 0000000000000000h
QWORD 000000000000000ah, 0000000000000000h
QWORD 000000000000000bh, 0000000000000000h
QWORD 000000000000000ch, 0000000000000000h
QWORD 000000000000000dh, 0000000000000000h
QWORD 000000000000000eh, 0000000000000000h
QWORD 000000000000000fh, 0000000000000000h
QWORD 0000000000000010h, 0000000000000000h
ptr_L_aes_gcmsiv_ctr_inc_avx512 QWORD L_aes_gcmsiv_ctr_inc_avx512
_DATA ENDS
_TEXT SEGMENT READONLY PARA
@@ -36740,32 +36732,32 @@ AES_GCMSIV_ctr_avx512 PROC
vmovdqu OWORD PTR [rsp+112], xmm13
vmovdqu OWORD PTR [rsp+128], xmm14
vmovdqu OWORD PTR [rsp+144], xmm15
vbroadcasti32x4 zmm7, [r10]
vbroadcasti32x4 zmm8, [ptr_L_aes_gcmsiv_ctr_inc_avx512+256]
vbroadcasti32x4 zmm9, [ptr_L_aes_gcmsiv_ctr_inc_avx512+64]
vbroadcasti32x4 zmm10, [ptr_L_aes_gcmsiv_ctr_inc_avx512+16]
vbroadcasti32x4 zmm7, OWORD PTR [r10]
vbroadcasti32x4 zmm8, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_avx512+256]
vbroadcasti32x4 zmm9, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_avx512+64]
vbroadcasti32x4 zmm10, OWORD PTR [ptr_L_aes_gcmsiv_ctr_inc_avx512+16]
xor r11d, r11d
cmp r8d, 64
jl L_AES_GCMSIV_ctr_avx512_done_64
vbroadcasti32x4 zmm12, [r9]
vbroadcasti32x4 zmm13, [r9+16]
vbroadcasti32x4 zmm14, [r9+32]
vbroadcasti32x4 zmm15, [r9+48]
vbroadcasti32x4 zmm16, [r9+64]
vbroadcasti32x4 zmm17, [r9+80]
vbroadcasti32x4 zmm18, [r9+96]
vbroadcasti32x4 zmm19, [r9+112]
vbroadcasti32x4 zmm20, [r9+128]
vbroadcasti32x4 zmm21, [r9+144]
vbroadcasti32x4 zmm22, [r9+160]
vbroadcasti32x4 zmm12, OWORD PTR [r9]
vbroadcasti32x4 zmm13, OWORD PTR [r9+16]
vbroadcasti32x4 zmm14, OWORD PTR [r9+32]
vbroadcasti32x4 zmm15, OWORD PTR [r9+48]
vbroadcasti32x4 zmm16, OWORD PTR [r9+64]
vbroadcasti32x4 zmm17, OWORD PTR [r9+80]
vbroadcasti32x4 zmm18, OWORD PTR [r9+96]
vbroadcasti32x4 zmm19, OWORD PTR [r9+112]
vbroadcasti32x4 zmm20, OWORD PTR [r9+128]
vbroadcasti32x4 zmm21, OWORD PTR [r9+144]
vbroadcasti32x4 zmm22, OWORD PTR [r9+160]
cmp eax, 11
jl L_AES_GCMSIV_ctr_avx512_key_cached
vbroadcasti32x4 zmm23, [r9+176]
vbroadcasti32x4 zmm24, [r9+192]
vbroadcasti32x4 zmm23, OWORD PTR [r9+176]
vbroadcasti32x4 zmm24, OWORD PTR [r9+192]
cmp eax, 13
jl L_AES_GCMSIV_ctr_avx512_key_cached
vbroadcasti32x4 zmm25, [r9+208]
vbroadcasti32x4 zmm26, [r9+224]
vbroadcasti32x4 zmm25, OWORD PTR [r9+208]
vbroadcasti32x4 zmm26, OWORD PTR [r9+224]
L_AES_GCMSIV_ctr_avx512_key_cached:
cmp r8d, 256
mov r12d, r8d
+57 -19
View File
@@ -154,7 +154,27 @@
#define CPUID_AARCH64_FEAT_SHA3 ((word64)1 << 32)
#define CPUID_AARCH64_FEAT_SM3 ((word64)1 << 36)
#define CPUID_AARCH64_FEAT_SM4 ((word64)1 << 40)
/* ID_AA64PFR0_EL1.AdvSIMD field [23:20]: 0xf means NEON is NOT implemented. */
#define CPUID_AARCH64_FEAT_ASIMD ((word64)0xf << 20)
/* ID_AA64PFR0_EL1.SVE field [35:32]: non-zero means SVE is implemented. */
#define CPUID_AARCH64_FEAT_SVE ((word64)0xf << 32)
/* ID_AA64PFR1_EL1.SME field [27:24]: non-zero means SME is implemented. */
#define CPUID_AARCH64_FEAT_SME ((word64)0xf << 24)
/* SVE and/or SME are guaranteed present when the architecture the code is
* compiled for includes them (the ACLE __ARM_FEATURE_* macros). In that case
* the flag is set unconditionally: the runtime detection below can be
* unavailable or incomplete on some platforms, but the feature is known usable.
*/
#if defined(__ARM_FEATURE_SVE) && defined(__ARM_FEATURE_SME)
#define CPUID_AARCH64_COMPILED (CPUID_SVE | CPUID_SME)
#elif defined(__ARM_FEATURE_SVE)
#define CPUID_AARCH64_COMPILED CPUID_SVE
#elif defined(__ARM_FEATURE_SME)
#define CPUID_AARCH64_COMPILED CPUID_SME
#else
#define CPUID_AARCH64_COMPILED 0
#endif
#ifdef WOLFSSL_AARCH64_PRIVILEGE_MODE
/* https://developer.arm.com/documentation/ddi0601/2024-09/AArch64-Registers
@@ -163,22 +183,11 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
word64 features;
#ifndef WOLFSSL_ARMASM_NO_NEON
__asm__ __volatile (
"mrs %[feat], ID_AA64PFR0_EL1\n"
: [feat] "=r" (features)
:
:
);
if ((features & CPUID_AARCH64_FEAT_ASIMD) !=
CPUID_AARCH64_FEAT_ASIMD)
new_cpuid_flags |= CPUID_ASIMD;
#endif
word64 pfr0;
word64 pfr1;
__asm__ __volatile (
"mrs %[feat], ID_AA64ISAR0_EL1\n"
@@ -186,7 +195,27 @@
:
:
);
__asm__ __volatile (
"mrs %[feat], ID_AA64PFR0_EL1\n"
: [feat] "=r" (pfr0)
:
:
);
__asm__ __volatile (
"mrs %[feat], ID_AA64PFR1_EL1\n"
: [feat] "=r" (pfr1)
:
:
);
#ifndef WOLFSSL_ARMASM_NO_NEON
if ((pfr0 & CPUID_AARCH64_FEAT_ASIMD) != CPUID_AARCH64_FEAT_ASIMD)
new_cpuid_flags |= CPUID_ASIMD;
#endif
if (pfr0 & CPUID_AARCH64_FEAT_SVE)
new_cpuid_flags |= CPUID_SVE;
if (pfr1 & CPUID_AARCH64_FEAT_SME)
new_cpuid_flags |= CPUID_SME;
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
if (features & CPUID_AARCH64_FEAT_AES)
new_cpuid_flags |= CPUID_AES;
@@ -232,7 +261,7 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
word64 hwcaps = getauxval(AT_HWCAP);
@@ -269,6 +298,15 @@
if (hwcaps & HWCAP_SM4)
new_cpuid_flags |= CPUID_SM4;
#endif
#ifdef HWCAP_SVE
if (hwcaps & HWCAP_SVE)
new_cpuid_flags |= CPUID_SVE;
#endif
#ifdef HWCAP2_SME
/* SME is reported in the second HWCAP word. */
if (getauxval(AT_HWCAP2) & HWCAP2_SME)
new_cpuid_flags |= CPUID_SME;
#endif
(void)hwcaps;
(void)wolfSSL_Atomic_Uint_CompareExchange
@@ -284,7 +322,7 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
word64 features = android_getCpuFeatures();
@@ -324,7 +362,7 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
#ifndef WOLFSSL_ARMASM_NO_NEON
@@ -370,7 +408,7 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
word64 features = 0;
@@ -486,7 +524,7 @@
static WC_INLINE void cpuid_set_flags(void)
{
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t new_cpuid_flags = 0,
cpuid_flags_t new_cpuid_flags = CPUID_AARCH64_COMPILED,
old_cpuid_flags = WC_CPUID_INITIALIZER;
#ifndef WOLFSSL_ARMASM_NO_NEON
new_cpuid_flags |= CPUID_ASIMD;
+2 -2
View File
@@ -29542,10 +29542,10 @@ L_AES_GCMSIV_ctr_base_end:
#endif /* WOLFSSL_AESGCM_SIV */
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
#endif /* !NO_AES */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -30555,7 +30555,7 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_ctr_base(const unsigned char* in,
#endif /* WOLFSSL_AESGCM_SIV */
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
#endif /* !NO_AES */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -1246,10 +1246,10 @@ L_chacha_use_over_arm32_done:
.size wc_chacha_use_over,.-wc_chacha_use_over
#endif /* !WOLFSSL_ARMASM_NO_NEON */
#endif /* HAVE_CHACHA */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -1435,7 +1435,7 @@ WC_OMIT_FRAME_POINTER void wc_chacha_use_over(byte* over, byte* output,
#endif /* !WOLFSSL_ARMASM_NO_NEON */
#endif /* HAVE_CHACHA */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -9678,10 +9678,10 @@ sc_muladd:
#endif /* !CURVE25519_SMALL || !ED25519_SMALL */
#endif /* HAVE_CURVE25519 || HAVE_ED25519 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -10446,7 +10446,7 @@ WC_OMIT_FRAME_POINTER void sc_muladd(byte* s, const byte* a, const byte* b,
#endif /* !CURVE25519_SMALL || !ED25519_SMALL */
#endif /* HAVE_CURVE25519 || HAVE_ED25519 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -0,0 +1,690 @@
/* armv8-32-frodokem-asm
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Generated using (from wolfssl):
* cd ../scripts
* ruby ./frodokem/frodokem.rb arm32 \
* ../wolfssl/wolfcrypt/src/port/arm/armv8-32-frodokem-asm.S
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources_asm.h>
#ifdef WOLFSSL_ARMASM
#if !defined(__aarch64__) && !defined(WOLFSSL_ARMASM_THUMB2)
#ifndef WOLFSSL_ARMASM_INLINE
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifndef WOLFSSL_ARMASM_NO_NEON
.text
.align 4
.fpu neon
.globl frodokem_add_neon
.type frodokem_add_neon, %function
frodokem_add_neon:
vdup.16 q2, r2
mov r3, #8
L_frodokem_add_neon_blk:
vld1.16 {d0-d1}, [r0]
vld1.16 {d2-d3}, [r1]!
vadd.i16 q0, q0, q1
vand q0, q0, q2
vst1.16 {d0-d1}, [r0]!
subs r3, r3, #1
bne L_frodokem_add_neon_blk
bx lr
.size frodokem_add_neon,.-frodokem_add_neon
.text
.align 4
.fpu neon
.globl frodokem_sample_neon
.type frodokem_sample_neon, %function
frodokem_sample_neon:
push {r4, lr}
vpush {d8-d11}
L_frodokem_sample_neon_blk:
vld1.16 {d0-d1}, [r0]
vshr.u16 q1, q0, #1
vmov.i16 q2, #1
vand q2, q2, q0
vmov.i16 q3, #0
mov r12, r2
mov lr, r3
L_frodokem_sample_neon_cdf:
ldrh r4, [r12]
add r12, r12, #2
vdup.16 q4, r4
vsub.i16 q4, q4, q1
vshr.u16 q4, q4, #15
vadd.i16 q3, q3, q4
subs lr, lr, #1
bne L_frodokem_sample_neon_cdf
vneg.s16 q5, q2
veor q3, q3, q5
vadd.i16 q3, q3, q2
vst1.16 {d6-d7}, [r0]!
subs r1, r1, #8
bne L_frodokem_sample_neon_blk
vpop {d8-d11}
pop {r4, pc}
.size frodokem_sample_neon,.-frodokem_sample_neon
.text
.align 4
.fpu neon
.globl frodokem_sa_accum_neon
.type frodokem_sa_accum_neon, %function
frodokem_sa_accum_neon:
push {r4, r5, r6, r7, r8, lr}
ldr r12, [sp, #24]
lsl lr, r12, #1
add r4, r1, r3, lsl #1
mov r7, #8
L_frodokem_sa_accum_neon_i:
ldrh r8, [r4]
vdup.16 q0, r8
add r4, r4, lr
mov r5, r2
lsr r6, lr, #4
L_frodokem_sa_accum_neon_k:
vld1.16 {d2-d3}, [r0]
vld1.16 {d4-d5}, [r5]!
vmla.i16 q1, q2, q0
vst1.16 {d2-d3}, [r0]!
subs r6, r6, #1
bne L_frodokem_sa_accum_neon_k
subs r7, r7, #1
bne L_frodokem_sa_accum_neon_i
pop {r4, r5, r6, r7, r8, pc}
.size frodokem_sa_accum_neon,.-frodokem_sa_accum_neon
.text
.align 4
.fpu neon
.globl frodokem_as_accum_neon
.type frodokem_as_accum_neon, %function
frodokem_as_accum_neon:
push {r4, r5, r6, r7, r8, r9, lr}
vpush {d8-d15}
ldr r12, [sp, #92]
lsl lr, r12, #1
add r7, r0, r3, lsl #4
mov r6, r2
mov r4, r1
veor q0, q0, q0
veor q1, q1, q1
veor q2, q2, q2
veor q3, q3, q3
veor q4, q4, q4
veor q5, q5, q5
veor q6, q6, q6
veor q7, q7, q7
lsr r8, lr, #4
L_frodokem_as_accum_neon_k:
vld1.16 {d16-d17}, [r6]!
mov r5, r4
vld1.16 {d18-d19}, [r5]
vmla.i16 q0, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q1, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q2, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q3, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q4, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q5, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q6, q8, q9
add r5, r5, lr
vld1.16 {d18-d19}, [r5]
vmla.i16 q7, q8, q9
add r5, r5, lr
add r4, r4, #16
subs r8, r8, #1
bne L_frodokem_as_accum_neon_k
vadd.i16 d18, d0, d1
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d20[0], r9
vadd.i16 d18, d2, d3
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d20[1], r9
vadd.i16 d18, d4, d5
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d20[2], r9
vadd.i16 d18, d6, d7
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d20[3], r9
vadd.i16 d18, d8, d9
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d21[0], r9
vadd.i16 d18, d10, d11
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d21[1], r9
vadd.i16 d18, d12, d13
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d21[2], r9
vadd.i16 d18, d14, d15
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r9, d18[0]
vmov.16 d21[3], r9
vld1.16 {d22-d23}, [r7]
vadd.i16 q10, q10, q11
vst1.16 {d20-d21}, [r7]
vpop {d8-d15}
pop {r4, r5, r6, r7, r8, r9, pc}
.size frodokem_as_accum_neon,.-frodokem_as_accum_neon
.text
.align 4
.fpu neon
.globl frodokem_mul_bs_neon
.type frodokem_mul_bs_neon, %function
frodokem_mul_bs_neon:
push {r4, r5, r6, r7, r8, r9, r10, lr}
vpush {d8-d15}
ldr lr, [sp, #96]
lsl r12, r3, #1
vdup.16 q11, lr
mov r7, r0
mov r4, r1
mov r9, #8
L_frodokem_mul_bs_neon_r:
mov r5, r2
veor q0, q0, q0
veor q1, q1, q1
veor q2, q2, q2
veor q3, q3, q3
veor q4, q4, q4
veor q5, q5, q5
veor q6, q6, q6
veor q7, q7, q7
lsr r8, r12, #4
L_frodokem_mul_bs_neon_k:
vld1.16 {d16-d17}, [r4]!
mov r6, r5
vld1.16 {d18-d19}, [r6]
vmla.i16 q0, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q1, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q2, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q3, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q4, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q5, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q6, q8, q9
add r6, r6, r12
vld1.16 {d18-d19}, [r6]
vmla.i16 q7, q8, q9
add r6, r6, r12
add r5, r5, #16
subs r8, r8, #1
bne L_frodokem_mul_bs_neon_k
vadd.i16 d18, d0, d1
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d20[0], r10
vadd.i16 d18, d2, d3
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d20[1], r10
vadd.i16 d18, d4, d5
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d20[2], r10
vadd.i16 d18, d6, d7
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d20[3], r10
vadd.i16 d18, d8, d9
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d21[0], r10
vadd.i16 d18, d10, d11
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d21[1], r10
vadd.i16 d18, d12, d13
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d21[2], r10
vadd.i16 d18, d14, d15
vpadd.i16 d18, d18, d18
vpadd.i16 d18, d18, d18
vmov.u16 r10, d18[0]
vmov.16 d21[3], r10
vand q10, q10, q11
vst1.16 {d20-d21}, [r7]!
subs r9, r9, #1
bne L_frodokem_mul_bs_neon_r
vpop {d8-d15}
pop {r4, r5, r6, r7, r8, r9, r10, pc}
.size frodokem_mul_bs_neon,.-frodokem_mul_bs_neon
.text
.align 4
.fpu neon
.globl frodokem_mul_add_sb_plus_e_neon
.type frodokem_mul_add_sb_plus_e_neon, %function
frodokem_mul_add_sb_plus_e_neon:
push {r4, r5, r6, r7, r8, r9, lr}
vpush {d8-d15}
ldr lr, [sp, #92]
lsl r12, r3, #1
vdup.16 q10, lr
mov r4, r1
mov r5, r2
mov r7, r0
vld1.16 {d0-d1}, [r7]!
vld1.16 {d2-d3}, [r7]!
vld1.16 {d4-d5}, [r7]!
vld1.16 {d6-d7}, [r7]!
vld1.16 {d8-d9}, [r7]!
vld1.16 {d10-d11}, [r7]!
vld1.16 {d12-d13}, [r7]!
vld1.16 {d14-d15}, [r7]!
mov r8, r3
L_frodokem_mul_add_sb_plus_e_neon_j:
vld1.16 {d16-d17}, [r4]!
mov r6, r5
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q0, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q1, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q2, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q3, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q4, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q5, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q6, q8, q9
add r6, r6, r12
ldrh r9, [r6]
vdup.16 q9, r9
vmla.i16 q7, q8, q9
add r6, r6, r12
add r5, r5, #2
subs r8, r8, #1
bne L_frodokem_mul_add_sb_plus_e_neon_j
mov r7, r0
vand q0, q0, q10
vst1.16 {d0-d1}, [r7]!
vand q1, q1, q10
vst1.16 {d2-d3}, [r7]!
vand q2, q2, q10
vst1.16 {d4-d5}, [r7]!
vand q3, q3, q10
vst1.16 {d6-d7}, [r7]!
vand q4, q4, q10
vst1.16 {d8-d9}, [r7]!
vand q5, q5, q10
vst1.16 {d10-d11}, [r7]!
vand q6, q6, q10
vst1.16 {d12-d13}, [r7]!
vand q7, q7, q10
vst1.16 {d14-d15}, [r7]!
vpop {d8-d15}
pop {r4, r5, r6, r7, r8, r9, pc}
.size frodokem_mul_add_sb_plus_e_neon,.-frodokem_mul_add_sb_plus_e_neon
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_HAVE_FRODOKEM */
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifndef WOLFSSL_ARMASM_NO_NEON
.fpu crypto-neon-fp-armv8
.text
.align 4
.globl frodokem_gen_a_rows_aes_arm32
.type frodokem_gen_a_rows_aes_arm32, %function
frodokem_gen_a_rows_aes_arm32:
push {r4, r5, r6, r7, r8, r9, lr}
vpush {d8-d15}
ldr lr, [sp, #96]
lsl lr, lr, #1
ldr r4, [sp, #92]
mul r4, r4, lr
ldr r12, [sp, #100]
vld1.8 {d0-d1}, [r2]!
vld1.8 {d2-d3}, [r2]!
vld1.8 {d4-d5}, [r2]!
vld1.8 {d6-d7}, [r2]!
vld1.8 {d8-d9}, [r2]!
vld1.8 {d10-d11}, [r2]!
vld1.8 {d12-d13}, [r2]!
vld1.8 {d14-d15}, [r2]!
vld1.8 {d16-d17}, [r2]!
vld1.8 {d18-d19}, [r2]!
vld1.8 {d20-d21}, [r2]!
vdup.16 q13, r12
movw r8, #0
#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7)
orr r8, r8, #0x80000
#else
movt r8, #0x8
#endif
mov r9, #0
mov r5, r0
L_frodokem_gen_a_rows_aes_arm32_row:
mov r7, r3
add r6, r5, lr
L_frodokem_gen_a_rows_aes_arm32_blk:
str r7, [r5], #4
str r9, [r5], #4
str r9, [r5], #4
str r9, [r5], #4
add r7, r7, r8
cmp r5, r6
blt L_frodokem_gen_a_rows_aes_arm32_blk
add r3, r3, #1
add r6, r0, r4
cmp r5, r6
blt L_frodokem_gen_a_rows_aes_arm32_row
L_frodokem_gen_a_rows_aes_arm32_aes:
vld1.8 {d22-d23}, [r0]!
vld1.8 {d24-d25}, [r0]!
aese.8 q11, q0
aese.8 q12, q0
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q1
aese.8 q12, q1
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q2
aese.8 q12, q2
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q3
aese.8 q12, q3
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q4
aese.8 q12, q4
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q5
aese.8 q12, q5
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q6
aese.8 q12, q6
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q7
aese.8 q12, q7
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q8
aese.8 q12, q8
aesmc.8 q11, q11
aesmc.8 q12, q12
aese.8 q11, q9
aese.8 q12, q9
veor q11, q11, q10
veor q12, q12, q10
vand q11, q11, q13
vand q12, q12, q13
vst1.8 {d22-d23}, [r1]!
vst1.8 {d24-d25}, [r1]!
subs r4, r4, #32
bne L_frodokem_gen_a_rows_aes_arm32_aes
vpop {d8-d15}
pop {r4, r5, r6, r7, r8, r9, pc}
.size frodokem_gen_a_rows_aes_arm32,.-frodokem_gen_a_rows_aes_arm32
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_HAVE_FRODOKEM */
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifdef __ARM_FEATURE_SIMD32
#if (!defined(__ARM_NEON) && !defined(__ARM_NEON__)) || defined(WOLFSSL_ARMASM_NO_NEON)
.text
.align 4
.globl frodokem_add_simd32
.type frodokem_add_simd32, %function
frodokem_add_simd32:
push {lr}
orr r2, r2, r2, lsl #16
mov r3, #32
L_frodokem_add_simd32_blk:
ldr r12, [r0]
ldr lr, [r1], #4
sadd16 r12, r12, lr
and r12, r12, r2
str r12, [r0], #4
subs r3, r3, #1
bne L_frodokem_add_simd32_blk
pop {pc}
.size frodokem_add_simd32,.-frodokem_add_simd32
.text
.align 4
.globl frodokem_sa_accum_simd32
.type frodokem_sa_accum_simd32, %function
frodokem_sa_accum_simd32:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
ldr r12, [sp, #36]
lsl r12, r12, #1
add lr, r1, r3, lsl #1
mov r6, #8
L_frodokem_sa_accum_simd32_i:
ldrh r7, [lr]
add lr, lr, r12
mov r4, r2
lsr r5, r12, #2
L_frodokem_sa_accum_simd32_k:
ldr r9, [r0]
ldr r8, [r4], #4
smulbb r10, r7, r8
smulbt r11, r7, r8
pkhbt r10, r10, r11, LSL #16
sadd16 r9, r9, r10
str r9, [r0], #4
subs r5, r5, #1
bne L_frodokem_sa_accum_simd32_k
subs r6, r6, #1
bne L_frodokem_sa_accum_simd32_i
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.size frodokem_sa_accum_simd32,.-frodokem_sa_accum_simd32
.text
.align 4
.globl frodokem_as_accum_simd32
.type frodokem_as_accum_simd32, %function
frodokem_as_accum_simd32:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
ldr r12, [sp, #36]
lsl r12, r12, #1
add lr, r0, r3, lsl #4
mov r4, r1
mov r7, #8
L_frodokem_as_accum_simd32_c:
mov r9, #0
mov r5, r2
mov r6, r4
lsr r8, r12, #2
L_frodokem_as_accum_simd32_j:
ldr r10, [r5], #4
ldr r11, [r6], #4
smlad r9, r10, r11, r9
subs r8, r8, #1
bne L_frodokem_as_accum_simd32_j
ldrh r10, [lr]
add r10, r10, r9
strh r10, [lr]
add lr, lr, #2
add r4, r4, r12
subs r7, r7, #1
bne L_frodokem_as_accum_simd32_c
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.size frodokem_as_accum_simd32,.-frodokem_as_accum_simd32
.text
.align 4
.globl frodokem_mul_bs_simd32
.type frodokem_mul_bs_simd32, %function
frodokem_mul_bs_simd32:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
mov r12, r1
mov r6, #8
L_frodokem_mul_bs_simd32_i:
mov lr, r2
mov r7, #8
L_frodokem_mul_bs_simd32_c:
mov r9, #0
mov r4, r12
mov r5, lr
lsr r8, r3, #1
L_frodokem_mul_bs_simd32_j:
ldr r10, [r4], #4
ldr r11, [r5], #4
smlad r9, r10, r11, r9
subs r8, r8, #1
bne L_frodokem_mul_bs_simd32_j
ldr r10, [sp, #36]
orr r10, r10, r10, lsl #16
and r9, r9, r10
strh r9, [r0]
add r0, r0, #2
add lr, lr, r3, lsl #1
subs r7, r7, #1
bne L_frodokem_mul_bs_simd32_c
add r12, r12, r3, lsl #1
subs r6, r6, #1
bne L_frodokem_mul_bs_simd32_i
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.size frodokem_mul_bs_simd32,.-frodokem_mul_bs_simd32
.text
.align 4
.globl frodokem_mul_add_sb_plus_e_simd32
.type frodokem_mul_add_sb_plus_e_simd32, %function
frodokem_mul_add_sb_plus_e_simd32:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
sub sp, sp, #8
lsl r9, r3, #1
str r9, [sp, #4]
str r1, [sp]
mov r12, #8
L_frodokem_mul_add_sb_plus_e_simd32_i:
ldr r9, [sp, #4]
add r3, r2, r9
ldr r1, [sp]
mov lr, r2
ldr r4, [r0]
ldr r5, [r0, #4]
ldr r6, [r0, #8]
ldr r7, [r0, #12]
L_frodokem_mul_add_sb_plus_e_simd32_j:
ldrh r8, [lr]
add lr, lr, #2
ldr r9, [r1]
smulbb r10, r8, r9
smulbt r11, r8, r9
pkhbt r10, r10, r11, LSL #16
sadd16 r4, r4, r10
ldr r9, [r1, #4]
smulbb r10, r8, r9
smulbt r11, r8, r9
pkhbt r10, r10, r11, LSL #16
sadd16 r5, r5, r10
ldr r9, [r1, #8]
smulbb r10, r8, r9
smulbt r11, r8, r9
pkhbt r10, r10, r11, LSL #16
sadd16 r6, r6, r10
ldr r9, [r1, #12]
smulbb r10, r8, r9
smulbt r11, r8, r9
pkhbt r10, r10, r11, LSL #16
sadd16 r7, r7, r10
add r1, r1, #16
cmp lr, r3
bne L_frodokem_mul_add_sb_plus_e_simd32_j
ldr r9, [sp, #44]
orr r9, r9, r9, lsl #16
and r4, r4, r9
and r5, r5, r9
and r6, r6, r9
and r7, r7, r9
str r4, [r0]
str r5, [r0, #4]
str r6, [r0, #8]
str r7, [r0, #12]
add r0, r0, #16
mov r2, r3
subs r12, r12, #1
bne L_frodokem_mul_add_sb_plus_e_simd32_i
add sp, sp, #8
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.size frodokem_mul_add_sb_plus_e_simd32,.-frodokem_mul_add_sb_plus_e_simd32
#endif /* (!defined(__ARM_NEON) && !defined(__ARM_NEON__)) || defined(WOLFSSL_ARMASM_NO_NEON) */
#endif /* __ARM_FEATURE_SIMD32 */
#endif /* WOLFSSL_HAVE_FRODOKEM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -0,0 +1,877 @@
/* armv8-32-frodokem-asm
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Generated using (from wolfssl):
* cd ../scripts
* ruby ./frodokem/frodokem.rb arm32 \
* ../wolfssl/wolfcrypt/src/port/arm/armv8-32-frodokem-asm.c
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources_asm.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef WOLFSSL_ARMASM
#if !defined(__aarch64__) && !defined(WOLFSSL_ARMASM_THUMB2)
#ifdef WOLFSSL_ARMASM_INLINE
#ifdef __IAR_SYSTEMS_ICC__
#define __asm__ asm
#define __volatile__ volatile
#define WOLFSSL_NO_VAR_ASSIGN_REG
#endif /* __IAR_SYSTEMS_ICC__ */
#ifdef __KEIL__
#define __asm__ __asm
#define __volatile__ volatile
#endif /* __KEIL__ */
#ifdef __ghs__
#define __asm__ __asm
#define __volatile__
#define WOLFSSL_NO_VAR_ASSIGN_REG
#endif /* __ghs__ */
#include <wolfssl/wolfcrypt/wc_frodokem_mat.h>
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifndef WOLFSSL_ARMASM_NO_NEON
void frodokem_add_neon(word16* a_p, const word16* b_p, int qmask_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_add_neon(word16* a_p, const word16* b_p,
int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_add_neon(word16* a, const word16* b,
int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* a __asm__ ("r0") = (word16*)a_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register int qmask __asm__ ("r2") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"vdup.16 q2, %[qmask]\n\t"
"mov r3, #8\n\t"
"\n"
"L_frodokem_add_neon_blk_%=:\n\t"
"vld1.16 {d0-d1}, [%[a]]\n\t"
"vld1.16 {d2-d3}, [%[b]]!\n\t"
"vadd.i16 q0, q0, q1\n\t"
"vand q0, q0, q2\n\t"
"vst1.16 {d0-d1}, [%[a]]!\n\t"
"subs r3, r3, #1\n\t"
"bne L_frodokem_add_neon_blk_%=\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [a] "+r" (a), [b] "+r" (b), [qmask] "+r" (qmask)
:
#else
:
: [a] "r" (a), [b] "r" (b), [qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r3", "q0", "q1", "q2"
);
}
void frodokem_sample_neon(word16* mat_p, int cnt_p, const word16* cdf_p,
int cdflen_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_sample_neon(word16* mat_p, int cnt_p,
const word16* cdf_p, int cdflen_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_sample_neon(word16* mat, int cnt,
const word16* cdf, int cdflen)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* mat __asm__ ("r0") = (word16*)mat_p;
register int cnt __asm__ ("r1") = (int)cnt_p;
register const word16* cdf __asm__ ("r2") = (const word16*)cdf_p;
register int cdflen __asm__ ("r3") = (int)cdflen_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"\n"
"L_frodokem_sample_neon_blk_%=:\n\t"
"vld1.16 {d0-d1}, [%[mat]]\n\t"
"vshr.u16 q1, q0, #1\n\t"
"vmov.i16 q2, #1\n\t"
"vand q2, q2, q0\n\t"
"vmov.i16 q3, #0\n\t"
"mov r12, %[cdf]\n\t"
"mov lr, %[cdflen]\n\t"
"\n"
"L_frodokem_sample_neon_cdf_%=:\n\t"
"ldrh r4, [r12]\n\t"
"add r12, r12, #2\n\t"
"vdup.16 q4, r4\n\t"
"vsub.i16 q4, q4, q1\n\t"
"vshr.u16 q4, q4, #15\n\t"
"vadd.i16 q3, q3, q4\n\t"
"subs lr, lr, #1\n\t"
"bne L_frodokem_sample_neon_cdf_%=\n\t"
"vneg.s16 q5, q2\n\t"
"veor q3, q3, q5\n\t"
"vadd.i16 q3, q3, q2\n\t"
"vst1.16 {d6-d7}, [%[mat]]!\n\t"
"subs %[cnt], %[cnt], #8\n\t"
"bne L_frodokem_sample_neon_blk_%=\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [mat] "+r" (mat), [cnt] "+r" (cnt), [cdf] "+r" (cdf),
[cdflen] "+r" (cdflen)
:
#else
:
: [mat] "r" (mat), [cnt] "r" (cnt), [cdf] "r" (cdf),
[cdflen] "r" (cdflen)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r12", "lr", "r4", "q0", "q1", "q2", "q3", "q4", "q5"
);
}
void frodokem_sa_accum_neon(word16* out_p, const word16* s_p,
const word16* row_p, int j_p, int n_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_neon(word16* out_p,
const word16* s_p, const word16* row_p, int j_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_neon(word16* out, const word16* s,
const word16* row, int j, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int j __asm__ ("r3") = (int)j_p;
register int n __asm__ ("r12") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[n]}\n\t"
"ldr r12, [sp]\n\t"
"lsl lr, r12, #1\n\t"
"add r4, %[s], %[j], lsl #1\n\t"
"mov r7, #8\n\t"
"\n"
"L_frodokem_sa_accum_neon_i_%=:\n\t"
"ldrh r8, [r4]\n\t"
"vdup.16 q0, r8\n\t"
"add r4, r4, lr\n\t"
"mov r5, %[row]\n\t"
"lsr r6, lr, #4\n\t"
"\n"
"L_frodokem_sa_accum_neon_k_%=:\n\t"
"vld1.16 {d2-d3}, [%[out]]\n\t"
"vld1.16 {d4-d5}, [r5]!\n\t"
"vmla.i16 q1, q2, q0\n\t"
"vst1.16 {d2-d3}, [%[out]]!\n\t"
"subs r6, r6, #1\n\t"
"bne L_frodokem_sa_accum_neon_k_%=\n\t"
"subs r7, r7, #1\n\t"
"bne L_frodokem_sa_accum_neon_i_%=\n\t"
"pop {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [j] "+r" (j),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [j] "r" (j),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "q0", "q1", "q2"
);
}
void frodokem_as_accum_neon(word16* out_p, const word16* s_p,
const word16* row_p, int i_p, int n_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_as_accum_neon(word16* out_p,
const word16* s_p, const word16* row_p, int i_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_as_accum_neon(word16* out, const word16* s,
const word16* row, int i, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int i __asm__ ("r3") = (int)i_p;
register int n __asm__ ("r12") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[n]}\n\t"
"ldr r12, [sp]\n\t"
"lsl lr, r12, #1\n\t"
"add r7, %[out], %[i], lsl #4\n\t"
"mov r6, %[row]\n\t"
"mov r4, %[s]\n\t"
"veor q0, q0, q0\n\t"
"veor q1, q1, q1\n\t"
"veor q2, q2, q2\n\t"
"veor q3, q3, q3\n\t"
"veor q4, q4, q4\n\t"
"veor q5, q5, q5\n\t"
"veor q6, q6, q6\n\t"
"veor q7, q7, q7\n\t"
"lsr r8, lr, #4\n\t"
"\n"
"L_frodokem_as_accum_neon_k_%=:\n\t"
"vld1.16 {d16-d17}, [r6]!\n\t"
"mov r5, r4\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q0, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q1, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q2, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q3, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q4, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q5, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q6, q8, q9\n\t"
"add r5, r5, lr\n\t"
"vld1.16 {d18-d19}, [r5]\n\t"
"vmla.i16 q7, q8, q9\n\t"
"add r5, r5, lr\n\t"
"add r4, r4, #16\n\t"
"subs r8, r8, #1\n\t"
"bne L_frodokem_as_accum_neon_k_%=\n\t"
"vadd.i16 d18, d0, d1\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d20[0], r9\n\t"
"vadd.i16 d18, d2, d3\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d20[1], r9\n\t"
"vadd.i16 d18, d4, d5\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d20[2], r9\n\t"
"vadd.i16 d18, d6, d7\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d20[3], r9\n\t"
"vadd.i16 d18, d8, d9\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d21[0], r9\n\t"
"vadd.i16 d18, d10, d11\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d21[1], r9\n\t"
"vadd.i16 d18, d12, d13\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d21[2], r9\n\t"
"vadd.i16 d18, d14, d15\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r9, d18[0]\n\t"
"vmov.16 d21[3], r9\n\t"
"vld1.16 {d22-d23}, [r7]\n\t"
"vadd.i16 q10, q10, q11\n\t"
"vst1.16 {d20-d21}, [r7]\n\t"
"pop {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [i] "+r" (i),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [i] "r" (i),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "q0", "q1",
"q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11"
);
}
void frodokem_mul_bs_neon(word16* out_p, const word16* b_p, const word16* s_p,
int n_p, int qmask_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_neon(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_neon(word16* out, const word16* b,
const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r12") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[qmask]}\n\t"
"ldr lr, [sp]\n\t"
"lsl r12, %[n], #1\n\t"
"vdup.16 q11, lr\n\t"
"mov r7, %[out]\n\t"
"mov r4, %[b]\n\t"
"mov r9, #8\n\t"
"\n"
"L_frodokem_mul_bs_neon_r_%=:\n\t"
"mov r5, %[s]\n\t"
"veor q0, q0, q0\n\t"
"veor q1, q1, q1\n\t"
"veor q2, q2, q2\n\t"
"veor q3, q3, q3\n\t"
"veor q4, q4, q4\n\t"
"veor q5, q5, q5\n\t"
"veor q6, q6, q6\n\t"
"veor q7, q7, q7\n\t"
"lsr r8, r12, #4\n\t"
"\n"
"L_frodokem_mul_bs_neon_k_%=:\n\t"
"vld1.16 {d16-d17}, [r4]!\n\t"
"mov r6, r5\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q0, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q1, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q2, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q3, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q4, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q5, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q6, q8, q9\n\t"
"add r6, r6, r12\n\t"
"vld1.16 {d18-d19}, [r6]\n\t"
"vmla.i16 q7, q8, q9\n\t"
"add r6, r6, r12\n\t"
"add r5, r5, #16\n\t"
"subs r8, r8, #1\n\t"
"bne L_frodokem_mul_bs_neon_k_%=\n\t"
"vadd.i16 d18, d0, d1\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d20[0], r10\n\t"
"vadd.i16 d18, d2, d3\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d20[1], r10\n\t"
"vadd.i16 d18, d4, d5\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d20[2], r10\n\t"
"vadd.i16 d18, d6, d7\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d20[3], r10\n\t"
"vadd.i16 d18, d8, d9\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d21[0], r10\n\t"
"vadd.i16 d18, d10, d11\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d21[1], r10\n\t"
"vadd.i16 d18, d12, d13\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d21[2], r10\n\t"
"vadd.i16 d18, d14, d15\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vpadd.i16 d18, d18, d18\n\t"
"vmov.u16 r10, d18[0]\n\t"
"vmov.16 d21[3], r10\n\t"
"vand q10, q10, q11\n\t"
"vst1.16 {d20-d21}, [r7]!\n\t"
"subs r9, r9, #1\n\t"
"bne L_frodokem_mul_bs_neon_r_%=\n\t"
"pop {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "q0",
"q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11"
);
}
void frodokem_mul_add_sb_plus_e_neon(word16* out_p, const word16* b_p,
const word16* s_p, int n_p, int qmask_p);
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_neon(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_neon(word16* out,
const word16* b, const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r12") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[qmask]}\n\t"
"ldr lr, [sp]\n\t"
"lsl r12, %[n], #1\n\t"
"vdup.16 q10, lr\n\t"
"mov r4, %[b]\n\t"
"mov r5, %[s]\n\t"
"mov r7, %[out]\n\t"
"vld1.16 {d0-d1}, [r7]!\n\t"
"vld1.16 {d2-d3}, [r7]!\n\t"
"vld1.16 {d4-d5}, [r7]!\n\t"
"vld1.16 {d6-d7}, [r7]!\n\t"
"vld1.16 {d8-d9}, [r7]!\n\t"
"vld1.16 {d10-d11}, [r7]!\n\t"
"vld1.16 {d12-d13}, [r7]!\n\t"
"vld1.16 {d14-d15}, [r7]!\n\t"
"mov r8, %[n]\n\t"
"\n"
"L_frodokem_mul_add_sb_plus_e_neon_j_%=:\n\t"
"vld1.16 {d16-d17}, [r4]!\n\t"
"mov r6, r5\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q0, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q1, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q2, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q3, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q4, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q5, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q6, q8, q9\n\t"
"add r6, r6, r12\n\t"
"ldrh r9, [r6]\n\t"
"vdup.16 q9, r9\n\t"
"vmla.i16 q7, q8, q9\n\t"
"add r6, r6, r12\n\t"
"add r5, r5, #2\n\t"
"subs r8, r8, #1\n\t"
"bne L_frodokem_mul_add_sb_plus_e_neon_j_%=\n\t"
"mov r7, %[out]\n\t"
"vand q0, q0, q10\n\t"
"vst1.16 {d0-d1}, [r7]!\n\t"
"vand q1, q1, q10\n\t"
"vst1.16 {d2-d3}, [r7]!\n\t"
"vand q2, q2, q10\n\t"
"vst1.16 {d4-d5}, [r7]!\n\t"
"vand q3, q3, q10\n\t"
"vst1.16 {d6-d7}, [r7]!\n\t"
"vand q4, q4, q10\n\t"
"vst1.16 {d8-d9}, [r7]!\n\t"
"vand q5, q5, q10\n\t"
"vst1.16 {d10-d11}, [r7]!\n\t"
"vand q6, q6, q10\n\t"
"vst1.16 {d12-d13}, [r7]!\n\t"
"vand q7, q7, q10\n\t"
"vst1.16 {d14-d15}, [r7]!\n\t"
"pop {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "q0", "q1",
"q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10"
);
}
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_HAVE_FRODOKEM */
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifdef __ARM_FEATURE_SIMD32
#if (!defined(__ARM_NEON) && !defined(__ARM_NEON__)) || \
defined(WOLFSSL_ARMASM_NO_NEON)
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_add_simd32(word16* a_p, const word16* b_p,
int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_add_simd32(word16* a, const word16* b,
int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* a __asm__ ("r0") = (word16*)a_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register int qmask __asm__ ("r2") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"orr %[qmask], %[qmask], %[qmask], lsl #16\n\t"
"mov r3, #32\n\t"
"\n"
"L_frodokem_add_simd32_blk_%=:\n\t"
"ldr r12, [%[a]]\n\t"
"ldr lr, [%[b]], #4\n\t"
"sadd16 r12, r12, lr\n\t"
"and r12, r12, %[qmask]\n\t"
"str r12, [%[a]], #4\n\t"
"subs r3, r3, #1\n\t"
"bne L_frodokem_add_simd32_blk_%=\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [a] "+r" (a), [b] "+r" (b), [qmask] "+r" (qmask)
:
#else
:
: [a] "r" (a), [b] "r" (b), [qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r3", "r12", "lr"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_simd32(word16* out_p,
const word16* s_p, const word16* row_p, int j_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_simd32(word16* out,
const word16* s, const word16* row, int j, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int j __asm__ ("r3") = (int)j_p;
register int n __asm__ ("r12") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[n]}\n\t"
"ldr r12, [sp]\n\t"
"lsl r12, r12, #1\n\t"
"add lr, %[s], %[j], lsl #1\n\t"
"mov r6, #8\n\t"
"\n"
"L_frodokem_sa_accum_simd32_i_%=:\n\t"
"ldrh r7, [lr]\n\t"
"add lr, lr, r12\n\t"
"mov r4, %[row]\n\t"
"lsr r5, r12, #2\n\t"
"\n"
"L_frodokem_sa_accum_simd32_k_%=:\n\t"
"ldr r9, [%[out]]\n\t"
"ldr r8, [r4], #4\n\t"
"smulbb r10, r7, r8\n\t"
"smulbt r11, r7, r8\n\t"
"pkhbt r10, r10, r11, LSL #16\n\t"
"sadd16 r9, r9, r10\n\t"
"str r9, [%[out]], #4\n\t"
"subs r5, r5, #1\n\t"
"bne L_frodokem_sa_accum_simd32_k_%=\n\t"
"subs r6, r6, #1\n\t"
"bne L_frodokem_sa_accum_simd32_i_%=\n\t"
"pop {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [j] "+r" (j),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [j] "r" (j),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_as_accum_simd32(word16* out_p,
const word16* s_p, const word16* row_p, int i_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_as_accum_simd32(word16* out,
const word16* s, const word16* row, int i, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int i __asm__ ("r3") = (int)i_p;
register int n __asm__ ("r12") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[n]}\n\t"
"ldr r12, [sp]\n\t"
"lsl r12, r12, #1\n\t"
"add lr, %[out], %[i], lsl #4\n\t"
"mov r4, %[s]\n\t"
"mov r7, #8\n\t"
"\n"
"L_frodokem_as_accum_simd32_c_%=:\n\t"
"mov r9, #0\n\t"
"mov r5, %[row]\n\t"
"mov r6, r4\n\t"
"lsr r8, r12, #2\n\t"
"\n"
"L_frodokem_as_accum_simd32_j_%=:\n\t"
"ldr r10, [r5], #4\n\t"
"ldr r11, [r6], #4\n\t"
"smlad r9, r10, r11, r9\n\t"
"subs r8, r8, #1\n\t"
"bne L_frodokem_as_accum_simd32_j_%=\n\t"
"ldrh r10, [lr]\n\t"
"add r10, r10, r9\n\t"
"strh r10, [lr]\n\t"
"add lr, lr, #2\n\t"
"add r4, r4, r12\n\t"
"subs r7, r7, #1\n\t"
"bne L_frodokem_as_accum_simd32_c_%=\n\t"
"pop {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [i] "+r" (i),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [i] "r" (i),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_simd32(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_simd32(word16* out, const word16* b,
const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r12") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[qmask]}\n\t"
"mov r12, %[b]\n\t"
"mov r6, #8\n\t"
"\n"
"L_frodokem_mul_bs_simd32_i_%=:\n\t"
"mov lr, %[s]\n\t"
"mov r7, #8\n\t"
"\n"
"L_frodokem_mul_bs_simd32_c_%=:\n\t"
"mov r9, #0\n\t"
"mov r4, r12\n\t"
"mov r5, lr\n\t"
"lsr r8, %[n], #1\n\t"
"\n"
"L_frodokem_mul_bs_simd32_j_%=:\n\t"
"ldr r10, [r4], #4\n\t"
"ldr r11, [r5], #4\n\t"
"smlad r9, r10, r11, r9\n\t"
"subs r8, r8, #1\n\t"
"bne L_frodokem_mul_bs_simd32_j_%=\n\t"
"ldr r10, [sp]\n\t"
"orr r10, r10, r10, lsl #16\n\t"
"and r9, r9, r10\n\t"
"strh r9, [%[out]]\n\t"
"add %[out], %[out], #2\n\t"
"add lr, lr, %[n], lsl #1\n\t"
"subs r7, r7, #1\n\t"
"bne L_frodokem_mul_bs_simd32_c_%=\n\t"
"add r12, r12, %[n], lsl #1\n\t"
"subs r6, r6, #1\n\t"
"bne L_frodokem_mul_bs_simd32_i_%=\n\t"
"pop {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_simd32(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_simd32(word16* out,
const word16* b, const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r12") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"push {%[qmask]}\n\t"
"sub sp, sp, #8\n\t"
"lsl r9, %[n], #1\n\t"
"str r9, [sp, #4]\n\t"
"str %[b], [sp]\n\t"
"mov r12, #8\n\t"
"\n"
"L_frodokem_mul_add_sb_plus_e_simd32_i_%=:\n\t"
"ldr r9, [sp, #4]\n\t"
"add %[n], %[s], r9\n\t"
"ldr %[b], [sp]\n\t"
"mov lr, %[s]\n\t"
"ldr r4, [%[out]]\n\t"
"ldr r5, [%[out], #4]\n\t"
"ldr r6, [%[out], #8]\n\t"
"ldr r7, [%[out], #12]\n\t"
"\n"
"L_frodokem_mul_add_sb_plus_e_simd32_j_%=:\n\t"
"ldrh r8, [lr]\n\t"
"add lr, lr, #2\n\t"
"ldr r9, [%[b]]\n\t"
"smulbb r10, r8, r9\n\t"
"smulbt r11, r8, r9\n\t"
"pkhbt r10, r10, r11, LSL #16\n\t"
"sadd16 r4, r4, r10\n\t"
"ldr r9, [%[b], #4]\n\t"
"smulbb r10, r8, r9\n\t"
"smulbt r11, r8, r9\n\t"
"pkhbt r10, r10, r11, LSL #16\n\t"
"sadd16 r5, r5, r10\n\t"
"ldr r9, [%[b], #8]\n\t"
"smulbb r10, r8, r9\n\t"
"smulbt r11, r8, r9\n\t"
"pkhbt r10, r10, r11, LSL #16\n\t"
"sadd16 r6, r6, r10\n\t"
"ldr r9, [%[b], #12]\n\t"
"smulbb r10, r8, r9\n\t"
"smulbt r11, r8, r9\n\t"
"pkhbt r10, r10, r11, LSL #16\n\t"
"sadd16 r7, r7, r10\n\t"
"add %[b], %[b], #16\n\t"
"cmp lr, %[n]\n\t"
"bne L_frodokem_mul_add_sb_plus_e_simd32_j_%=\n\t"
"ldr r9, [sp, #8]\n\t"
"orr r9, r9, r9, lsl #16\n\t"
"and r4, r4, r9\n\t"
"and r5, r5, r9\n\t"
"and r6, r6, r9\n\t"
"and r7, r7, r9\n\t"
"str r4, [%[out]]\n\t"
"str r5, [%[out], #4]\n\t"
"str r6, [%[out], #8]\n\t"
"str r7, [%[out], #12]\n\t"
"add %[out], %[out], #16\n\t"
"mov %[s], %[n]\n\t"
"subs r12, r12, #1\n\t"
"bne L_frodokem_mul_add_sb_plus_e_simd32_i_%=\n\t"
"add sp, sp, #8\n\t"
"pop {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11"
);
}
#endif /* (!defined(__ARM_NEON) && !defined(__ARM_NEON__)) ||
* defined(WOLFSSL_ARMASM_NO_NEON) */
#endif /* __ARM_FEATURE_SIMD32 */
#endif /* WOLFSSL_HAVE_FRODOKEM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -8508,10 +8508,10 @@ L_mlkem_arm32_rej_uniform_done:
pop {r4, r5, r6, r7, r8, pc}
.size mlkem_arm32_rej_uniform,.-mlkem_arm32_rej_uniform
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -8664,7 +8664,7 @@ WC_OMIT_FRAME_POINTER unsigned int mlkem_arm32_rej_uniform(sword16* p,
}
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -1296,10 +1296,10 @@ poly1305_final:
.size poly1305_final,.-poly1305_final
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* HAVE_POLY1305 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -1446,7 +1446,7 @@ WC_OMIT_FRAME_POINTER void poly1305_final(Poly1305* ctx, byte* mac)
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* HAVE_POLY1305 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -3772,10 +3772,10 @@ L_sha256_len_crypto_begin:
#endif /* WOLFSSL_ARMASM_NO_HW_CRYPTO */
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* !NO_SHA256 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -3861,7 +3861,7 @@ WC_OMIT_FRAME_POINTER void Transform_Sha256_Len_crypto(wc_Sha256* sha256,
#endif /* WOLFSSL_ARMASM_NO_HW_CRYPTO */
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* !NO_SHA256 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -2325,10 +2325,10 @@ L_sha3_arm32_begin:
.size BlockSha3,.-BlockSha3
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA3 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -2367,7 +2367,7 @@ WC_OMIT_FRAME_POINTER void BlockSha3(word64* state)
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA3 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -9060,10 +9060,10 @@ L_SHA512_transform_neon_len_start:
.size Transform_Sha512_Len_neon,.-Transform_Sha512_Len_neon
#endif /* !WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -9118,7 +9118,7 @@ WC_OMIT_FRAME_POINTER void Transform_Sha512_Len_neon(wc_Sha512* sha512,
#endif /* !WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* !__aarch64__ && !WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -8861,10 +8861,10 @@ L_AES_GCMSIV_ctr_thumb2_end:
.size AES_GCMSIV_ctr_thumb2,.-AES_GCMSIV_ctr_thumb2
#endif /* WOLFSSL_AESGCM_SIV */
#endif /* !NO_AES */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+46 -62
View File
@@ -374,6 +374,7 @@ WC_OMIT_FRAME_POINTER void AES_set_encrypt_key(const unsigned char* key,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[L_AES_Thumb2_rcon]}\n\t"
"MOV r10, %[L_AES_Thumb2_te]\n\t"
"MOV lr, %[L_AES_Thumb2_rcon]\n\t"
"CMP %[len], #0x80\n\t"
@@ -632,6 +633,7 @@ WC_OMIT_FRAME_POINTER void AES_set_encrypt_key(const unsigned char* key,
#else
"L_AES_set_encrypt_key_end_%=:\n\t"
#endif
"POP {%[L_AES_Thumb2_rcon]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [key] "+r" (key), [len] "+r" (len), [ks] "+r" (ks),
[L_AES_Thumb2_te] "+r" (L_AES_Thumb2_te_c),
@@ -926,13 +928,10 @@ WC_OMIT_FRAME_POINTER void AES_ECB_encrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[nr], %[L_AES_Thumb2_te_ecb]}\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_te_ecb]\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r12, r4\n\t"
#else
"MOV r12, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"LDR r12, [sp]\n\t"
"PUSH {%[ks]}\n\t"
"CMP r12, #10\n\t"
#if defined(__GNUC__)
@@ -1763,6 +1762,7 @@ WC_OMIT_FRAME_POINTER void AES_ECB_encrypt(const unsigned char* in,
"L_AES_ECB_encrypt_end_%=:\n\t"
#endif
"POP {%[ks]}\n\t"
"POP {%[nr], %[L_AES_Thumb2_te_ecb]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [L_AES_Thumb2_te_ecb] "+r" (L_AES_Thumb2_te_ecb_c)
@@ -1808,16 +1808,10 @@ WC_OMIT_FRAME_POINTER void AES_CBC_encrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r4\n\t"
#else
"MOV r8, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r9, r5\n\t"
#else
"MOV r9, %[iv]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"PUSH {%[L_AES_Thumb2_te_ecb]}\n\t"
"PUSH {%[nr], %[iv]}\n\t"
"LDR r8, [sp]\n\t"
"LDR r9, [sp, #4]\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_te_ecb]\n\t"
"LDM r9, {r4, r5, r6, r7}\n\t"
@@ -2664,6 +2658,8 @@ WC_OMIT_FRAME_POINTER void AES_CBC_encrypt(const unsigned char* in,
#endif
"POP {%[ks], r9}\n\t"
"STM r9, {r4, r5, r6, r7}\n\t"
"POP {%[nr], %[iv]}\n\t"
"POP {%[L_AES_Thumb2_te_ecb]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [iv] "+r" (iv),
@@ -2711,16 +2707,10 @@ WC_OMIT_FRAME_POINTER void AES_CTR_encrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r12, r4\n\t"
#else
"MOV r12, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r5\n\t"
#else
"MOV r8, %[ctr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"PUSH {%[L_AES_Thumb2_te_ctr]}\n\t"
"PUSH {%[nr], %[ctr]}\n\t"
"LDR r12, [sp]\n\t"
"LDR r8, [sp, #4]\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_te_ctr]\n\t"
"LDM r8, {r4, r5, r6, r7}\n\t"
@@ -3588,6 +3578,8 @@ WC_OMIT_FRAME_POINTER void AES_CTR_encrypt(const unsigned char* in,
"REV r6, r6\n\t"
"REV r7, r7\n\t"
"STM r8, {r4, r5, r6, r7}\n\t"
"POP {%[nr], %[ctr]}\n\t"
"POP {%[L_AES_Thumb2_te_ctr]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [ctr] "+r" (ctr),
@@ -3917,11 +3909,9 @@ WC_OMIT_FRAME_POINTER void AES_ECB_decrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r4\n\t"
#else
"MOV r8, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"PUSH {%[L_AES_Thumb2_td4]}\n\t"
"PUSH {%[nr], %[L_AES_Thumb2_td_ecb]}\n\t"
"LDR r8, [sp]\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_td_ecb]\n\t"
"MOV r12, %[len]\n\t"
@@ -4751,6 +4741,8 @@ WC_OMIT_FRAME_POINTER void AES_ECB_decrypt(const unsigned char* in,
#else
"L_AES_ECB_decrypt_end_%=:\n\t"
#endif
"POP {%[nr], %[L_AES_Thumb2_td_ecb]}\n\t"
"POP {%[L_AES_Thumb2_td4]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [L_AES_Thumb2_td_ecb] "+r" (L_AES_Thumb2_td_ecb_c),
@@ -4800,20 +4792,14 @@ WC_OMIT_FRAME_POINTER void AES_CBC_decrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[L_AES_Thumb2_td_ecb], %[L_AES_Thumb2_td4]}\n\t"
"PUSH {%[nr], %[iv]}\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_td_ecb]\n\t"
"MOV r12, %[len]\n\t"
"MOV r2, %[L_AES_Thumb2_td4]\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r4\n\t"
#else
"MOV r8, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r4, r5\n\t"
#else
"MOV r4, %[iv]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"LDR r8, [sp]\n\t"
"LDR r4, [sp, #4]\n\t"
"PUSH {%[ks], r4}\n\t"
"CMP r8, #10\n\t"
#if defined(__GNUC__)
@@ -6469,6 +6455,8 @@ WC_OMIT_FRAME_POINTER void AES_CBC_decrypt(const unsigned char* in,
"L_AES_CBC_decrypt_end_%=:\n\t"
#endif
"POP {%[ks], r4}\n\t"
"POP {%[nr], %[iv]}\n\t"
"POP {%[L_AES_Thumb2_td_ecb], %[L_AES_Thumb2_td4]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [iv] "+r" (iv),
@@ -6522,6 +6510,7 @@ WC_OMIT_FRAME_POINTER void GCM_gmult_len(unsigned char* x,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[L_GCM_gmult_len_r]}\n\t"
"MOV lr, %[L_GCM_gmult_len_r]\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
@@ -7056,6 +7045,7 @@ WC_OMIT_FRAME_POINTER void GCM_gmult_len(unsigned char* x,
#else
"BNE.W L_GCM_gmult_len_start_block_%=\n\t"
#endif
"POP {%[L_GCM_gmult_len_r]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [x] "+r" (x), [m] "+r" (m), [data] "+r" (data), [len] "+r" (len),
[L_GCM_gmult_len_r] "+r" (L_GCM_gmult_len_r_c)
@@ -7100,16 +7090,10 @@ WC_OMIT_FRAME_POINTER void AES_GCM_encrypt(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r12, r4\n\t"
#else
"MOV r12, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r5\n\t"
#else
"MOV r8, %[ctr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"PUSH {%[L_AES_Thumb2_te_gcm]}\n\t"
"PUSH {%[nr], %[ctr]}\n\t"
"LDR r12, [sp]\n\t"
"LDR r8, [sp, #4]\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_Thumb2_te_gcm]\n\t"
"LDM r8, {r4, r5, r6, r7}\n\t"
@@ -7968,6 +7952,8 @@ WC_OMIT_FRAME_POINTER void AES_GCM_encrypt(const unsigned char* in,
"REV r6, r6\n\t"
"REV r7, r7\n\t"
"STM r8, {r4, r5, r6, r7}\n\t"
"POP {%[nr], %[ctr]}\n\t"
"POP {%[L_AES_Thumb2_te_gcm]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks),
[nr] "+r" (nr), [ctr] "+r" (ctr),
@@ -8018,6 +8004,7 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_polyval_thumb2(unsigned char* s,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[L_AES_Thumb2_te_gcm], %[L_AES_GCMSIV_polyval_thumb2_r]}\n\t"
"MOV r8, %[L_AES_GCMSIV_polyval_thumb2_r]\n\t"
"CMP %[blocks], #0\n\t"
#if defined(__GNUC__)
@@ -8714,6 +8701,7 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_polyval_thumb2(unsigned char* s,
#else
"L_AES_GCMSIV_polyval_thumb2_done_%=:\n\t"
#endif
"POP {%[L_AES_Thumb2_te_gcm], %[L_AES_GCMSIV_polyval_thumb2_r]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [s] "+r" (s), [m] "+r" (m), [data] "+r" (data),
[blocks] "+r" (blocks),
@@ -8825,16 +8813,10 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_ctr_thumb2(const unsigned char* in,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r12, r4\n\t"
#else
"MOV r12, %[nr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
"MOV r8, r5\n\t"
#else
"MOV r8, %[ctr]\n\t"
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
"PUSH {%[L_AES_GCMSIV_ctr_thumb2_te]}\n\t"
"PUSH {%[nr], %[ctr]}\n\t"
"LDR r12, [sp]\n\t"
"LDR r8, [sp, #4]\n\t"
"MOV lr, %[in]\n\t"
"MOV r0, %[L_AES_GCMSIV_ctr_thumb2_te]\n\t"
"LDM r8, {r4, r5, r6, r7}\n\t"
@@ -9708,6 +9690,8 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_ctr_thumb2(const unsigned char* in,
"REV r6, r6\n\t"
"REV r7, r7\n\t"
"STM r8, {r4, r5, r6, r7}\n\t"
"POP {%[nr], %[ctr]}\n\t"
"POP {%[L_AES_GCMSIV_ctr_thumb2_te]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [in] "+r" (in), [out] "+r" (out), [length] "+r" (length),
[KS] "+r" (KS), [nr] "+r" (nr), [ctr] "+r" (ctr),
@@ -9725,7 +9709,7 @@ WC_OMIT_FRAME_POINTER void AES_GCMSIV_ctr_thumb2(const unsigned char* in,
#endif /* WOLFSSL_AESGCM_SIV */
#endif /* !NO_AES */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -567,10 +567,10 @@ L_chacha_thumb2_over_done:
/* Cycle Count = 108 */
.size wc_chacha_use_over,.-wc_chacha_use_over
#endif /* HAVE_CHACHA */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -760,7 +760,7 @@ WC_OMIT_FRAME_POINTER void wc_chacha_use_over(byte* over, byte* output,
}
#endif /* HAVE_CHACHA */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -7519,10 +7519,10 @@ sc_muladd:
#endif /* !CURVE25519_SMALL || !ED25519_SMALL */
#endif /* HAVE_CURVE25519 || HAVE_ED25519 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -8450,7 +8450,7 @@ WC_OMIT_FRAME_POINTER void sc_muladd(byte* s, const byte* a, const byte* b,
#endif /* !CURVE25519_SMALL || !ED25519_SMALL */
#endif /* HAVE_CURVE25519 || HAVE_ED25519 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -0,0 +1,264 @@
/* thumb2-frodokem-asm
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Generated using (from wolfssl):
* cd ../scripts
* ruby ./frodokem/frodokem.rb \
* thumb2 ../wolfssl/wolfcrypt/src/port/arm/thumb2-frodokem-asm.S
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources_asm.h>
#ifdef WOLFSSL_ARMASM
#ifdef WOLFSSL_ARMASM_THUMB2
#ifndef WOLFSSL_ARMASM_INLINE
.thumb
.syntax unified
#ifdef WOLFSSL_HAVE_FRODOKEM
.text
.align 4
.globl frodokem_add_thumb2
.type frodokem_add_thumb2, %function
frodokem_add_thumb2:
PUSH {r4, r5, lr}
ORR r2, r2, r2, LSL #16
MOV r3, #32
L_frodokem_add_thumb2_blk:
LDR r4, [r0]
LDR r5, [r1], #4
SADD16 r4, r4, r5
AND r4, r4, r2
STR r4, [r0], #4
SUBS r3, r3, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_add_thumb2_blk
#else
BNE.N L_frodokem_add_thumb2_blk
#endif
POP {r4, r5, pc}
/* Cycle Count = 23 */
.size frodokem_add_thumb2,.-frodokem_add_thumb2
.text
.align 4
.globl frodokem_sa_accum_thumb2
.type frodokem_sa_accum_thumb2, %function
frodokem_sa_accum_thumb2:
PUSH {r4, r5, r6, r7, r8, r9, r10, r11, lr}
LDR r4, [sp, #36]
LSL r4, r4, #1
ADD r5, r1, r3, LSL #1
MOV r8, #8
L_frodokem_sa_accum_thumb2_i:
LDRH r9, [r5]
ADD r5, r5, r4
MOV r6, r2
LSR r7, r4, #2
L_frodokem_sa_accum_thumb2_k:
LDR r11, [r0]
LDR r10, [r6], #4
SMULBB r12, r9, r10
SMULBT lr, r9, r10
PKHBT r12, r12, lr, LSL #16
SADD16 r11, r11, r12
STR r11, [r0], #4
SUBS r7, r7, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_sa_accum_thumb2_k
#else
BNE.N L_frodokem_sa_accum_thumb2_k
#endif
SUBS r8, r8, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_sa_accum_thumb2_i
#else
BNE.N L_frodokem_sa_accum_thumb2_i
#endif
POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
/* Cycle Count = 50 */
.size frodokem_sa_accum_thumb2,.-frodokem_sa_accum_thumb2
.text
.align 4
.globl frodokem_as_accum_thumb2
.type frodokem_as_accum_thumb2, %function
frodokem_as_accum_thumb2:
PUSH {r4, r5, r6, r7, r8, r9, r10, r11, lr}
LDR r4, [sp, #36]
LSL r4, r4, #1
ADD r5, r0, r3, LSL #4
MOV r6, r1
MOV r9, #8
L_frodokem_as_accum_thumb2_c:
MOV r11, #0
MOV r7, r2
MOV r8, r6
LSR r10, r4, #2
L_frodokem_as_accum_thumb2_j:
LDR r12, [r7], #4
LDR lr, [r8], #4
SMLAD r11, r12, lr, r11
SUBS r10, r10, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_as_accum_thumb2_j
#else
BNE.N L_frodokem_as_accum_thumb2_j
#endif
LDRH r12, [r5]
ADD r12, r12, r11
STRH r12, [r5]
ADD r5, r5, #2
ADD r6, r6, r4
SUBS r9, r9, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_as_accum_thumb2_c
#else
BNE.N L_frodokem_as_accum_thumb2_c
#endif
POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
/* Cycle Count = 52 */
.size frodokem_as_accum_thumb2,.-frodokem_as_accum_thumb2
.text
.align 4
.globl frodokem_mul_bs_thumb2
.type frodokem_mul_bs_thumb2, %function
frodokem_mul_bs_thumb2:
PUSH {r4, r5, r6, r7, r8, r9, r10, r11, lr}
MOV r4, r1
MOV r8, #8
L_frodokem_mul_bs_thumb2_i:
MOV r5, r2
MOV r9, #8
L_frodokem_mul_bs_thumb2_c:
MOV r11, #0
MOV r6, r4
MOV r7, r5
LSR r10, r3, #1
L_frodokem_mul_bs_thumb2_j:
LDR r12, [r6], #4
LDR lr, [r7], #4
SMLAD r11, r12, lr, r11
SUBS r10, r10, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_mul_bs_thumb2_j
#else
BNE.N L_frodokem_mul_bs_thumb2_j
#endif
LDR r12, [sp, #36]
ORR r12, r12, r12, LSL #16
AND r11, r11, r12
STRH r11, [r0]
ADD r0, r0, #2
ADD r5, r5, r3, LSL #1
SUBS r9, r9, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_mul_bs_thumb2_c
#else
BNE.N L_frodokem_mul_bs_thumb2_c
#endif
ADD r4, r4, r3, LSL #1
SUBS r8, r8, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_mul_bs_thumb2_i
#else
BNE.N L_frodokem_mul_bs_thumb2_i
#endif
POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
/* Cycle Count = 57 */
.size frodokem_mul_bs_thumb2,.-frodokem_mul_bs_thumb2
.text
.align 4
.globl frodokem_mul_add_sb_plus_e_thumb2
.type frodokem_mul_add_sb_plus_e_thumb2, %function
frodokem_mul_add_sb_plus_e_thumb2:
PUSH {r4, r5, r6, r7, r8, r9, r10, r11, lr}
SUB sp, sp, #8
LSL r11, r3, #1
STR r11, [sp, #4]
STR r1, [sp]
MOV r4, #8
L_frodokem_mul_add_sb_plus_e_thumb2_i:
LDR r11, [sp, #4]
ADD r3, r2, r11
LDR r1, [sp]
MOV r5, r2
LDR r6, [r0]
LDR r7, [r0, #4]
LDR r8, [r0, #8]
LDR r9, [r0, #12]
L_frodokem_mul_add_sb_plus_e_thumb2_j:
LDRH r10, [r5]
ADD r5, r5, #2
LDR r11, [r1]
SMULBB r12, r10, r11
SMULBT lr, r10, r11
PKHBT r12, r12, lr, LSL #16
SADD16 r6, r6, r12
LDR r11, [r1, #4]
SMULBB r12, r10, r11
SMULBT lr, r10, r11
PKHBT r12, r12, lr, LSL #16
SADD16 r7, r7, r12
LDR r11, [r1, #8]
SMULBB r12, r10, r11
SMULBT lr, r10, r11
PKHBT r12, r12, lr, LSL #16
SADD16 r8, r8, r12
LDR r11, [r1, #12]
SMULBB r12, r10, r11
SMULBT lr, r10, r11
PKHBT r12, r12, lr, LSL #16
SADD16 r9, r9, r12
ADD r1, r1, #16
CMP r5, r3
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_mul_add_sb_plus_e_thumb2_j
#else
BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_j
#endif
LDR r11, [sp, #44]
ORR r11, r11, r11, LSL #16
AND r6, r6, r11
AND r7, r7, r11
AND r8, r8, r11
AND r9, r9, r11
STR r6, [r0]
STR r7, [r0, #4]
STR r8, [r0, #8]
STR r9, [r0, #12]
ADD r0, r0, #16
MOV r2, r3
SUBS r4, r4, #1
#if defined(__GNUC__) || defined(__ICCARM__) || defined(__IAR_SYSTEMS_ICC__)
BNE L_frodokem_mul_add_sb_plus_e_thumb2_i
#else
BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_i
#endif
ADD sp, sp, #8
POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
/* Cycle Count = 97 */
.size frodokem_mul_add_sb_plus_e_thumb2,.-frodokem_mul_add_sb_plus_e_thumb2
#endif /* WOLFSSL_HAVE_FRODOKEM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -0,0 +1,461 @@
/* thumb2-frodokem-asm
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Generated using (from wolfssl):
* cd ../scripts
* ruby ./frodokem/frodokem.rb \
* thumb2 ../wolfssl/wolfcrypt/src/port/arm/thumb2-frodokem-asm.c
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources_asm.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef WOLFSSL_ARMASM
#ifdef WOLFSSL_ARMASM_THUMB2
#ifdef WOLFSSL_ARMASM_INLINE
#ifdef __IAR_SYSTEMS_ICC__
#define __asm__ asm
#define __volatile__ volatile
#define WOLFSSL_NO_VAR_ASSIGN_REG
#endif /* __IAR_SYSTEMS_ICC__ */
#ifdef __KEIL__
#define __asm__ __asm
#define __volatile__ volatile
#endif /* __KEIL__ */
#ifdef __ghs__
#define __asm__ __asm
#define __volatile__
#define WOLFSSL_NO_VAR_ASSIGN_REG
#endif /* __ghs__ */
#include <wolfssl/wolfcrypt/wc_frodokem_mat.h>
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_add_thumb2(word16* a_p, const word16* b_p,
int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_add_thumb2(word16* a, const word16* b,
int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* a __asm__ ("r0") = (word16*)a_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register int qmask __asm__ ("r2") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"ORR %[qmask], %[qmask], %[qmask], LSL #16\n\t"
"MOV r3, #32\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_add_thumb2_blk:\n\t"
#else
"L_frodokem_add_thumb2_blk_%=:\n\t"
#endif
"LDR r4, [%[a]]\n\t"
"LDR r5, [%[b]], #4\n\t"
"SADD16 r4, r4, r5\n\t"
"AND r4, r4, %[qmask]\n\t"
"STR r4, [%[a]], #4\n\t"
"SUBS r3, r3, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_add_thumb2_blk_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_add_thumb2_blk\n\t"
#else
"BNE.N L_frodokem_add_thumb2_blk_%=\n\t"
#endif
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [a] "+r" (a), [b] "+r" (b), [qmask] "+r" (qmask)
:
#else
:
: [a] "r" (a), [b] "r" (b), [qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r3", "r4", "r5"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_thumb2(word16* out_p,
const word16* s_p, const word16* row_p, int j_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_sa_accum_thumb2(word16* out,
const word16* s, const word16* row, int j, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int j __asm__ ("r3") = (int)j_p;
register int n __asm__ ("r4") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[n]}\n\t"
"LDR r4, [sp]\n\t"
"LSL r4, r4, #1\n\t"
"ADD r5, %[s], %[j], LSL #1\n\t"
"MOV r8, #8\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_sa_accum_thumb2_i:\n\t"
#else
"L_frodokem_sa_accum_thumb2_i_%=:\n\t"
#endif
"LDRH r9, [r5]\n\t"
"ADD r5, r5, r4\n\t"
"MOV r6, %[row]\n\t"
"LSR r7, r4, #2\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_sa_accum_thumb2_k:\n\t"
#else
"L_frodokem_sa_accum_thumb2_k_%=:\n\t"
#endif
"LDR r11, [%[out]]\n\t"
"LDR r10, [r6], #4\n\t"
"SMULBB r12, r9, r10\n\t"
"SMULBT lr, r9, r10\n\t"
"PKHBT r12, r12, lr, LSL #16\n\t"
"SADD16 r11, r11, r12\n\t"
"STR r11, [%[out]], #4\n\t"
"SUBS r7, r7, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_sa_accum_thumb2_k_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_sa_accum_thumb2_k\n\t"
#else
"BNE.N L_frodokem_sa_accum_thumb2_k_%=\n\t"
#endif
"SUBS r8, r8, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_sa_accum_thumb2_i_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_sa_accum_thumb2_i\n\t"
#else
"BNE.N L_frodokem_sa_accum_thumb2_i_%=\n\t"
#endif
"POP {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [j] "+r" (j),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [j] "r" (j),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
"lr"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_as_accum_thumb2(word16* out_p,
const word16* s_p, const word16* row_p, int i_p, int n_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_as_accum_thumb2(word16* out,
const word16* s, const word16* row, int i, int n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* s __asm__ ("r1") = (const word16*)s_p;
register const word16* row __asm__ ("r2") = (const word16*)row_p;
register int i __asm__ ("r3") = (int)i_p;
register int n __asm__ ("r4") = (int)n_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[n]}\n\t"
"LDR r4, [sp]\n\t"
"LSL r4, r4, #1\n\t"
"ADD r5, %[out], %[i], LSL #4\n\t"
"MOV r6, %[s]\n\t"
"MOV r9, #8\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_as_accum_thumb2_c:\n\t"
#else
"L_frodokem_as_accum_thumb2_c_%=:\n\t"
#endif
"MOV r11, #0\n\t"
"MOV r7, %[row]\n\t"
"MOV r8, r6\n\t"
"LSR r10, r4, #2\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_as_accum_thumb2_j:\n\t"
#else
"L_frodokem_as_accum_thumb2_j_%=:\n\t"
#endif
"LDR r12, [r7], #4\n\t"
"LDR lr, [r8], #4\n\t"
"SMLAD r11, r12, lr, r11\n\t"
"SUBS r10, r10, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_as_accum_thumb2_j_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_as_accum_thumb2_j\n\t"
#else
"BNE.N L_frodokem_as_accum_thumb2_j_%=\n\t"
#endif
"LDRH r12, [r5]\n\t"
"ADD r12, r12, r11\n\t"
"STRH r12, [r5]\n\t"
"ADD r5, r5, #2\n\t"
"ADD r6, r6, r4\n\t"
"SUBS r9, r9, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_as_accum_thumb2_c_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_as_accum_thumb2_c\n\t"
#else
"BNE.N L_frodokem_as_accum_thumb2_c_%=\n\t"
#endif
"POP {%[n]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [s] "+r" (s), [row] "+r" (row), [i] "+r" (i),
[n] "+r" (n)
:
#else
:
: [out] "r" (out), [s] "r" (s), [row] "r" (row), [i] "r" (i),
[n] "r" (n)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
"lr"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_thumb2(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_bs_thumb2(word16* out, const word16* b,
const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r4") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[qmask]}\n\t"
"MOV r4, %[b]\n\t"
"MOV r8, #8\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_mul_bs_thumb2_i:\n\t"
#else
"L_frodokem_mul_bs_thumb2_i_%=:\n\t"
#endif
"MOV r5, %[s]\n\t"
"MOV r9, #8\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_mul_bs_thumb2_c:\n\t"
#else
"L_frodokem_mul_bs_thumb2_c_%=:\n\t"
#endif
"MOV r11, #0\n\t"
"MOV r6, r4\n\t"
"MOV r7, r5\n\t"
"LSR r10, %[n], #1\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_mul_bs_thumb2_j:\n\t"
#else
"L_frodokem_mul_bs_thumb2_j_%=:\n\t"
#endif
"LDR r12, [r6], #4\n\t"
"LDR lr, [r7], #4\n\t"
"SMLAD r11, r12, lr, r11\n\t"
"SUBS r10, r10, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_mul_bs_thumb2_j_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_mul_bs_thumb2_j\n\t"
#else
"BNE.N L_frodokem_mul_bs_thumb2_j_%=\n\t"
#endif
"LDR r12, [sp]\n\t"
"ORR r12, r12, r12, LSL #16\n\t"
"AND r11, r11, r12\n\t"
"STRH r11, [%[out]]\n\t"
"ADD %[out], %[out], #2\n\t"
"ADD r5, r5, %[n], LSL #1\n\t"
"SUBS r9, r9, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_mul_bs_thumb2_c_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_mul_bs_thumb2_c\n\t"
#else
"BNE.N L_frodokem_mul_bs_thumb2_c_%=\n\t"
#endif
"ADD r4, r4, %[n], LSL #1\n\t"
"SUBS r8, r8, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_mul_bs_thumb2_i_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_mul_bs_thumb2_i\n\t"
#else
"BNE.N L_frodokem_mul_bs_thumb2_i_%=\n\t"
#endif
"POP {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
"lr"
);
}
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_thumb2(word16* out_p,
const word16* b_p, const word16* s_p, int n_p, int qmask_p)
#else
WC_OMIT_FRAME_POINTER void frodokem_mul_add_sb_plus_e_thumb2(word16* out,
const word16* b, const word16* s, int n, int qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
{
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
register word16* out __asm__ ("r0") = (word16*)out_p;
register const word16* b __asm__ ("r1") = (const word16*)b_p;
register const word16* s __asm__ ("r2") = (const word16*)s_p;
register int n __asm__ ("r3") = (int)n_p;
register int qmask __asm__ ("r4") = (int)qmask_p;
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[qmask]}\n\t"
"SUB sp, sp, #8\n\t"
"LSL r11, %[n], #1\n\t"
"STR r11, [sp, #4]\n\t"
"STR %[b], [sp]\n\t"
"MOV r4, #8\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_mul_add_sb_plus_e_thumb2_i:\n\t"
#else
"L_frodokem_mul_add_sb_plus_e_thumb2_i_%=:\n\t"
#endif
"LDR r11, [sp, #4]\n\t"
"ADD %[n], %[s], r11\n\t"
"LDR %[b], [sp]\n\t"
"MOV r5, %[s]\n\t"
"LDR r6, [%[out]]\n\t"
"LDR r7, [%[out], #4]\n\t"
"LDR r8, [%[out], #8]\n\t"
"LDR r9, [%[out], #12]\n\t"
"\n"
#if defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"L_frodokem_mul_add_sb_plus_e_thumb2_j:\n\t"
#else
"L_frodokem_mul_add_sb_plus_e_thumb2_j_%=:\n\t"
#endif
"LDRH r10, [r5]\n\t"
"ADD r5, r5, #2\n\t"
"LDR r11, [%[b]]\n\t"
"SMULBB r12, r10, r11\n\t"
"SMULBT lr, r10, r11\n\t"
"PKHBT r12, r12, lr, LSL #16\n\t"
"SADD16 r6, r6, r12\n\t"
"LDR r11, [%[b], #4]\n\t"
"SMULBB r12, r10, r11\n\t"
"SMULBT lr, r10, r11\n\t"
"PKHBT r12, r12, lr, LSL #16\n\t"
"SADD16 r7, r7, r12\n\t"
"LDR r11, [%[b], #8]\n\t"
"SMULBB r12, r10, r11\n\t"
"SMULBT lr, r10, r11\n\t"
"PKHBT r12, r12, lr, LSL #16\n\t"
"SADD16 r8, r8, r12\n\t"
"LDR r11, [%[b], #12]\n\t"
"SMULBB r12, r10, r11\n\t"
"SMULBT lr, r10, r11\n\t"
"PKHBT r12, r12, lr, LSL #16\n\t"
"SADD16 r9, r9, r12\n\t"
"ADD %[b], %[b], #16\n\t"
"CMP r5, %[n]\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_mul_add_sb_plus_e_thumb2_j_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_j\n\t"
#else
"BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_j_%=\n\t"
#endif
"LDR r11, [sp, #8]\n\t"
"ORR r11, r11, r11, LSL #16\n\t"
"AND r6, r6, r11\n\t"
"AND r7, r7, r11\n\t"
"AND r8, r8, r11\n\t"
"AND r9, r9, r11\n\t"
"STR r6, [%[out]]\n\t"
"STR r7, [%[out], #4]\n\t"
"STR r8, [%[out], #8]\n\t"
"STR r9, [%[out], #12]\n\t"
"ADD %[out], %[out], #16\n\t"
"MOV %[s], %[n]\n\t"
"SUBS r4, r4, #1\n\t"
#if defined(__GNUC__)
"BNE L_frodokem_mul_add_sb_plus_e_thumb2_i_%=\n\t"
#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ < 9000000)
"BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_i\n\t"
#else
"BNE.N L_frodokem_mul_add_sb_plus_e_thumb2_i_%=\n\t"
#endif
"ADD sp, sp, #8\n\t"
"POP {%[qmask]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [out] "+r" (out), [b] "+r" (b), [s] "+r" (s), [n] "+r" (n),
[qmask] "+r" (qmask)
:
#else
:
: [out] "r" (out), [b] "r" (b), [s] "r" (s), [n] "r" (n),
[qmask] "r" (qmask)
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
: "memory", "cc", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
"lr"
);
}
#endif /* WOLFSSL_HAVE_FRODOKEM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -3583,10 +3583,10 @@ L_mlkem_thumb2_rej_uniform_done:
/* Cycle Count = 225 */
.size mlkem_thumb2_rej_uniform,.-mlkem_thumb2_rej_uniform
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+4 -2
View File
@@ -3550,6 +3550,7 @@ WC_OMIT_FRAME_POINTER unsigned int mlkem_thumb2_rej_uniform(sword16* p,
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
__asm__ __volatile__ (
"PUSH {%[L_mlkem_basemul_mont_zetas]}\n\t"
"MOV r8, #0xd01\n\t"
"MOV r9, #0\n\t"
"\n"
@@ -3870,6 +3871,7 @@ WC_OMIT_FRAME_POINTER unsigned int mlkem_thumb2_rej_uniform(sword16* p,
"L_mlkem_thumb2_rej_uniform_done_%=:\n\t"
#endif
"LSR r0, r9, #1\n\t"
"POP {%[L_mlkem_basemul_mont_zetas]}\n\t"
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
: [p] "+r" (p), [len] "+r" (len), [r] "+r" (r), [rLen] "+r" (rLen),
[L_mlkem_basemul_mont_zetas] "+r" (L_mlkem_basemul_mont_zetas_c)
@@ -3885,7 +3887,7 @@ WC_OMIT_FRAME_POINTER unsigned int mlkem_thumb2_rej_uniform(sword16* p,
}
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -364,10 +364,10 @@ poly1305_final:
/* Cycle Count = 82 */
.size poly1305_final,.-poly1305_final
#endif /* HAVE_POLY1305 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
@@ -441,7 +441,7 @@ WC_OMIT_FRAME_POINTER void poly1305_final(Poly1305* ctx, byte* mac)
}
#endif /* HAVE_POLY1305 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -2322,10 +2322,10 @@ L_SHA256_transform_len_blk_end_15:
.size Transform_Sha256_Len_base,.-Transform_Sha256_Len_base
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* !NO_SHA256 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -2488,7 +2488,7 @@ WC_OMIT_FRAME_POINTER void Transform_Sha256_Len_base(wc_Sha256* sha256,
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* !NO_SHA256 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -1138,10 +1138,10 @@ L_sha3_thumb2_begin:
/* Cycle Count = 1505 */
.size BlockSha3,.-BlockSha3
#endif /* WOLFSSL_SHA3 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -1169,7 +1169,7 @@ WC_OMIT_FRAME_POINTER void BlockSha3(word64* state)
}
#endif /* WOLFSSL_SHA3 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -3555,10 +3555,10 @@ L_SHA512_transform_len_start:
.size Transform_Sha512_Len_base,.-Transform_Sha512_Len_base
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+2 -2
View File
@@ -3602,7 +3602,7 @@ WC_OMIT_FRAME_POINTER void Transform_Sha512_Len_base(wc_Sha512* sha512,
#endif /* WOLFSSL_ARMASM_NO_NEON */
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
#endif /* WOLFSSL_ARMASM_INLINE */
#endif /* WOLFSSL_ARMASM_THUMB2 */
#endif /* WOLFSSL_ARMASM */
+8452 -1
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+18 -26
View File
@@ -45883,60 +45883,52 @@ _TEXT ENDS
IFDEF HAVE_INTEL_AVX2
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_order DWORD \
00632551h, 01e84f3bh, 03bce6fah, 03ffffffh,
03ff0000h, 00000000h, 00000000h, 00000000h,
0272b0bfh, 02b69c5eh, 03ffffffh, 000003ffh,
003fffffh, 00000000h, 00000000h, 00000000h
L_sp256_mod_inv_avx2_4_order DWORD 00632551h, 01e84f3bh, 03bce6fah, 03ffffffh
DWORD 03ff0000h, 00000000h, 00000000h, 00000000h
DWORD 0272b0bfh, 02b69c5eh, 03ffffffh, 000003ffh
DWORD 003fffffh, 00000000h, 00000000h, 00000000h
ptr_L_sp256_mod_inv_avx2_4_order QWORD L_sp256_mod_inv_avx2_4_order
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_one QWORD \
0000000000000001h, 0000000000000000h,
0000000000000000h, 0000000000000000h
L_sp256_mod_inv_avx2_4_one QWORD 0000000000000001h, 0000000000000000h
QWORD 0000000000000000h, 0000000000000000h
ptr_L_sp256_mod_inv_avx2_4_one QWORD L_sp256_mod_inv_avx2_4_one
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_all_one DWORD \
00000001h, 00000001h, 00000001h, 00000001h,
00000001h, 00000001h, 00000001h, 00000001h
L_sp256_mod_inv_avx2_4_all_one DWORD 00000001h, 00000001h, 00000001h, 00000001h
DWORD 00000001h, 00000001h, 00000001h, 00000001h
ptr_L_sp256_mod_inv_avx2_4_all_one QWORD L_sp256_mod_inv_avx2_4_all_one
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_mask01111 DWORD \
00000000h, 00000001h, 00000001h, 00000001h,
00000001h, 00000000h, 00000000h, 00000000h
L_sp256_mod_inv_avx2_4_mask01111 DWORD 00000000h, 00000001h, 00000001h, 00000001h
DWORD 00000001h, 00000000h, 00000000h, 00000000h
ptr_L_sp256_mod_inv_avx2_4_mask01111 QWORD L_sp256_mod_inv_avx2_4_mask01111
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_down_one_dword DWORD \
00000001h, 00000002h, 00000003h, 00000004h,
00000005h, 00000006h, 00000007h, 00000007h
L_sp256_mod_inv_avx2_4_down_one_dword DWORD 00000001h, 00000002h, 00000003h, 00000004h
DWORD 00000005h, 00000006h, 00000007h, 00000007h
ptr_L_sp256_mod_inv_avx2_4_down_one_dword QWORD L_sp256_mod_inv_avx2_4_down_one_dword
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_neg DWORD \
00000000h, 00000000h, 00000000h, 00000000h,
80000000h, 00000000h, 00000000h, 00000000h
L_sp256_mod_inv_avx2_4_neg DWORD 00000000h, 00000000h, 00000000h, 00000000h
DWORD 80000000h, 00000000h, 00000000h, 00000000h
ptr_L_sp256_mod_inv_avx2_4_neg QWORD L_sp256_mod_inv_avx2_4_neg
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_up_one_dword DWORD \
00000007h, 00000000h, 00000001h, 00000002h,
00000003h, 00000007h, 00000007h, 00000007h
L_sp256_mod_inv_avx2_4_up_one_dword DWORD 00000007h, 00000000h, 00000001h, 00000002h
DWORD 00000003h, 00000007h, 00000007h, 00000007h
ptr_L_sp256_mod_inv_avx2_4_up_one_dword QWORD L_sp256_mod_inv_avx2_4_up_one_dword
_DATA ENDS
_DATA SEGMENT
ALIGN 16
L_sp256_mod_inv_avx2_4_mask26 DWORD \
03ffffffh, 03ffffffh, 03ffffffh, 03ffffffh,
03ffffffh, 00000000h, 00000000h, 00000000h
L_sp256_mod_inv_avx2_4_mask26 DWORD 03ffffffh, 03ffffffh, 03ffffffh, 03ffffffh
DWORD 03ffffffh, 00000000h, 00000000h, 00000000h
ptr_L_sp256_mod_inv_avx2_4_mask26 QWORD L_sp256_mod_inv_avx2_4_mask26
_DATA ENDS
; /* Non-constant time modular inversion.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+163
View File
@@ -395,6 +395,9 @@ static const byte const_byte_array[] = "A+Gd\0\0\0";
#ifdef WOLFSSL_HAVE_MLKEM
#include <wolfssl/wolfcrypt/wc_mlkem.h>
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
#include <wolfssl/wolfcrypt/wc_frodokem.h>
#endif
#ifdef WOLFSSL_HAVE_MLDSA
#include <wolfssl/wolfcrypt/wc_mldsa.h>
#endif
@@ -974,6 +977,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#ifdef WOLFSSL_HAVE_MLKEM
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void);
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t frodokem_test(void);
#endif
#ifdef WOLFSSL_HAVE_MLDSA
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mldsa_test(void);
#endif
@@ -3189,6 +3195,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
PRIVATE_KEY_LOCK();
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
if ( (ret = frodokem_test()) != 0)
TEST_FAIL("FRODOKEM test failed!\n", ret);
else
TEST_PASS("FRODOKEM test passed!\n");
#endif
#ifdef WOLFSSL_HAVE_MLDSA
PRIVATE_KEY_UNLOCK();
if ( (ret = mldsa_test()) != 0)
@@ -53563,6 +53576,152 @@ out:
}
#endif /* WOLFSSL_HAVE_MLKEM */
#ifdef WOLFSSL_HAVE_FRODOKEM
/* Basic FrodoKEM test: for each compiled variant generate a key, encapsulate
* and decapsulate (shared secrets must match), then confirm an encode/decode
* round trip of the private key still decapsulates correctly. */
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t frodokem_test(void)
{
wc_test_ret_t ret = 0;
#if !defined(WC_NO_RNG) && !defined(WOLFSSL_FRODOKEM_NO_MAKE_KEY) && \
!defined(WOLFSSL_FRODOKEM_NO_ENCAPSULATE) && \
!defined(WOLFSSL_FRODOKEM_NO_DECAPSULATE)
static const int types[] = {
#ifdef WOLFSSL_FRODOKEM_SHAKE
#ifdef WOLFSSL_WC_FRODOKEM_640
WC_FRODOKEM_640_SHAKE,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
WC_FRODOKEM_976_SHAKE,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
WC_FRODOKEM_1344_SHAKE,
#endif
#endif
#ifdef WOLFSSL_FRODOKEM_AES
#ifdef WOLFSSL_WC_FRODOKEM_640
WC_FRODOKEM_640_AES,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
WC_FRODOKEM_976_AES,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
WC_FRODOKEM_1344_AES,
#endif
#endif
#ifdef WOLFSSL_FRODOKEM_EPHEMERAL
#ifdef WOLFSSL_FRODOKEM_SHAKE
#ifdef WOLFSSL_WC_FRODOKEM_640
WC_EFRODOKEM_640_SHAKE,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
WC_EFRODOKEM_976_SHAKE,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
WC_EFRODOKEM_1344_SHAKE,
#endif
#endif
#ifdef WOLFSSL_FRODOKEM_AES
#ifdef WOLFSSL_WC_FRODOKEM_640
WC_EFRODOKEM_640_AES,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_976
WC_EFRODOKEM_976_AES,
#endif
#ifdef WOLFSSL_WC_FRODOKEM_1344
WC_EFRODOKEM_1344_AES,
#endif
#endif
#endif
0 /* sentinel so the array is never empty */
};
int numTypes = (int)(sizeof(types) / sizeof(types[0])) - 1;
int i;
WC_RNG rng;
int rngInit = 0;
FrodoKemKey* key = NULL;
byte* ct = NULL;
byte* pk = NULL;
byte* sk = NULL;
byte ss[FRODOKEM_MAX_LENSEC];
byte ss2[FRODOKEM_MAX_LENSEC];
word32 pkLen = 0;
word32 skLen = 0;
word32 ctLen = 0;
word32 ssLen = 0;
key = (FrodoKemKey*)XMALLOC(sizeof(*key), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
ct = (byte*)XMALLOC(FRODOKEM_MAX_CIPHER_TEXT_SIZE, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
pk = (byte*)XMALLOC(FRODOKEM_MAX_PUBLIC_KEY_SIZE, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
sk = (byte*)XMALLOC(FRODOKEM_MAX_PRIVATE_KEY_SIZE, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if ((key == NULL) || (ct == NULL) || (pk == NULL) || (sk == NULL)) {
ret = WC_TEST_RET_ENC_NC;
goto out;
}
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
if (ret != 0) {
ret = WC_TEST_RET_ENC_EC(ret);
goto out;
}
rngInit = 1;
for (i = 0; i < numTypes; i++) {
ret = wc_FrodoKemKey_Init(key, types[i], HEAP_HINT, devId);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_PublicKeySize(key, &pkLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_PrivateKeySize(key, &skLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_CipherTextSize(key, &ctLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_SharedSecretSize(key, &ssLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_MakeKey(key, &rng);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_Encapsulate(key, ct, ss, &rng);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_Decapsulate(key, ss2, ct, ctLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
if (XMEMCMP(ss, ss2, ssLen) != 0) {
ret = WC_TEST_RET_ENC_NC; break;
}
/* Encode then decode the private key and decapsulate again. */
ret = wc_FrodoKemKey_EncodePublicKey(key, pk, pkLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_EncodePrivateKey(key, sk, skLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_DecodePrivateKey(key, sk, skLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
ret = wc_FrodoKemKey_Decapsulate(key, ss2, ct, ctLen);
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); break; }
if (XMEMCMP(ss, ss2, ssLen) != 0) {
ret = WC_TEST_RET_ENC_NC; break;
}
wc_FrodoKemKey_Free(key);
}
out:
if (key != NULL)
wc_FrodoKemKey_Free(key);
if (rngInit)
wc_FreeRng(&rng);
XFREE(sk, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(pk, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ct, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* !WC_NO_RNG */
return ret;
}
#endif /* WOLFSSL_HAVE_FRODOKEM */
#ifdef WOLFSSL_HAVE_MLDSA
#ifndef WOLFSSL_MLDSA_NO_VERIFY
static wc_test_ret_t mldsa_param_vfy_test(int param, const byte* pubKey,
@@ -78285,6 +78444,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
if (ret == 0)
ret = mlkem_test();
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
if (ret == 0)
ret = frodokem_test();
#endif
#ifdef WOLFSSL_HAVE_MLDSA
if (ret == 0)
ret = mldsa_test();
+15 -1
View File
@@ -76,7 +76,7 @@
the WOLFSSL_ARMASM* defines below); a symbol that is left undefined
here simply drops the matching assembly (safe - the C caller then uses
a C fallback), while a symbol enabled here but not in C is dead code. -->
<WolfSSLArmAsmDefs>-PreDefine "HAVE_AES_CBC SETL {TRUE}" -PreDefine "HAVE_AESCCM SETL {TRUE}" -PreDefine "HAVE_AESGCM SETL {TRUE}" -PreDefine "HAVE_AES_ECB SETL {TRUE}" -PreDefine "HAVE_AES_DECRYPT SETL {TRUE}" -PreDefine "WOLFSSL_AES_COUNTER SETL {TRUE}" -PreDefine "WOLFSSL_AES_DIRECT SETL {TRUE}" -PreDefine "WOLFSSL_AES_XTS SETL {TRUE}" -PreDefine "WOLFSSL_AESGCM_STREAM SETL {TRUE}" -PreDefine "WOLFSSL_SHA224 SETL {TRUE}" -PreDefine "WOLFSSL_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_SHA384 SETL {TRUE}" -PreDefine "WOLFSSL_SHA512 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA512 SETL {TRUE}" -PreDefine "HAVE_CHACHA SETL {TRUE}" -PreDefine "HAVE_CURVE25519 SETL {TRUE}" -PreDefine "HAVE_ED25519 SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_MLKEM SETL {TRUE}"</WolfSSLArmAsmDefs>
<WolfSSLArmAsmDefs>-PreDefine "HAVE_AES_CBC SETL {TRUE}" -PreDefine "HAVE_AESCCM SETL {TRUE}" -PreDefine "HAVE_AESGCM SETL {TRUE}" -PreDefine "HAVE_AES_ECB SETL {TRUE}" -PreDefine "HAVE_AES_DECRYPT SETL {TRUE}" -PreDefine "WOLFSSL_AES_COUNTER SETL {TRUE}" -PreDefine "WOLFSSL_AES_DIRECT SETL {TRUE}" -PreDefine "WOLFSSL_AES_XTS SETL {TRUE}" -PreDefine "WOLFSSL_AESGCM_STREAM SETL {TRUE}" -PreDefine "WOLFSSL_SHA224 SETL {TRUE}" -PreDefine "WOLFSSL_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_SHA384 SETL {TRUE}" -PreDefine "WOLFSSL_SHA512 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA512 SETL {TRUE}" -PreDefine "HAVE_CHACHA SETL {TRUE}" -PreDefine "HAVE_CURVE25519 SETL {TRUE}" -PreDefine "HAVE_ED25519 SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_MLKEM SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_FRODOKEM SETL {TRUE}"</WolfSSLArmAsmDefs>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -462,6 +462,8 @@
<ClCompile Include="wolfcrypt\src\kdf.c" />
<ClCompile Include="wolfcrypt\src\wc_mlkem.c" />
<ClCompile Include="wolfcrypt\src\wc_mlkem_poly.c" />
<ClCompile Include="wolfcrypt\src\wc_frodokem.c" />
<ClCompile Include="wolfcrypt\src\wc_frodokem_mat.c" />
<ClCompile Include="wolfcrypt\src\logging.c" />
<ClCompile Include="wolfcrypt\src\md2.c" />
<ClCompile Include="wolfcrypt\src\md4.c" />
@@ -677,6 +679,12 @@
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\port\arm\armv8-frodokem-asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">false</ExcludedFromBuild>
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\port\arm\armv8-poly1305-asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">false</ExcludedFromBuild>
@@ -701,6 +709,12 @@
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\wc_frodokem_asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">false</ExcludedFromBuild>
<Command Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">ml64.exe /c /Zi /DWOLFSSL_X86_64_BUILD /DWOLFSSL_HAVE_FRODOKEM /Fo"$(IntDir)%(Filename).obj" %(Identity)</Command>
<Outputs Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<ClInclude Include="IDE\WIN\user_settings.h" />
</ItemGroup>
<ItemGroup>
+15 -1
View File
@@ -75,7 +75,7 @@
the WOLFSSL_ARMASM* defines below); a symbol that is left undefined
here simply drops the matching assembly (safe - the C caller then uses
a C fallback), while a symbol enabled here but not in C is dead code. -->
<WolfSSLArmAsmDefs>-PreDefine "HAVE_AES_CBC SETL {TRUE}" -PreDefine "HAVE_AESCCM SETL {TRUE}" -PreDefine "HAVE_AESGCM SETL {TRUE}" -PreDefine "HAVE_AES_ECB SETL {TRUE}" -PreDefine "HAVE_AES_DECRYPT SETL {TRUE}" -PreDefine "WOLFSSL_AES_COUNTER SETL {TRUE}" -PreDefine "WOLFSSL_AES_DIRECT SETL {TRUE}" -PreDefine "WOLFSSL_AES_XTS SETL {TRUE}" -PreDefine "WOLFSSL_AESGCM_STREAM SETL {TRUE}" -PreDefine "WOLFSSL_SHA224 SETL {TRUE}" -PreDefine "WOLFSSL_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_SHA384 SETL {TRUE}" -PreDefine "WOLFSSL_SHA512 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA512 SETL {TRUE}" -PreDefine "HAVE_CHACHA SETL {TRUE}" -PreDefine "HAVE_CURVE25519 SETL {TRUE}" -PreDefine "HAVE_ED25519 SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_MLKEM SETL {TRUE}"</WolfSSLArmAsmDefs>
<WolfSSLArmAsmDefs>-PreDefine "HAVE_AES_CBC SETL {TRUE}" -PreDefine "HAVE_AESCCM SETL {TRUE}" -PreDefine "HAVE_AESGCM SETL {TRUE}" -PreDefine "HAVE_AES_ECB SETL {TRUE}" -PreDefine "HAVE_AES_DECRYPT SETL {TRUE}" -PreDefine "WOLFSSL_AES_COUNTER SETL {TRUE}" -PreDefine "WOLFSSL_AES_DIRECT SETL {TRUE}" -PreDefine "WOLFSSL_AES_XTS SETL {TRUE}" -PreDefine "WOLFSSL_AESGCM_STREAM SETL {TRUE}" -PreDefine "WOLFSSL_SHA224 SETL {TRUE}" -PreDefine "WOLFSSL_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA3 SETL {TRUE}" -PreDefine "WOLFSSL_SHA384 SETL {TRUE}" -PreDefine "WOLFSSL_SHA512 SETL {TRUE}" -PreDefine "WOLFSSL_ARMASM_CRYPTO_SHA512 SETL {TRUE}" -PreDefine "HAVE_CHACHA SETL {TRUE}" -PreDefine "HAVE_CURVE25519 SETL {TRUE}" -PreDefine "HAVE_ED25519 SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_MLKEM SETL {TRUE}" -PreDefine "WOLFSSL_HAVE_FRODOKEM SETL {TRUE}"</WolfSSLArmAsmDefs>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -462,6 +462,8 @@
<ClCompile Include="wolfcrypt\src\kdf.c" />
<ClCompile Include="wolfcrypt\src\wc_mlkem.c" />
<ClCompile Include="wolfcrypt\src\wc_mlkem_poly.c" />
<ClCompile Include="wolfcrypt\src\wc_frodokem.c" />
<ClCompile Include="wolfcrypt\src\wc_frodokem_mat.c" />
<ClCompile Include="wolfcrypt\src\logging.c" />
<ClCompile Include="wolfcrypt\src\md2.c" />
<ClCompile Include="wolfcrypt\src\md4.c" />
@@ -677,6 +679,12 @@
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\port\arm\armv8-frodokem-asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">false</ExcludedFromBuild>
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\port\arm\armv8-poly1305-asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">false</ExcludedFromBuild>
@@ -701,6 +709,12 @@
<Command Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">armasm64.exe -o "$(IntDir)%(Filename).obj" $(WolfSSLArmAsmDefs) %(Identity)</Command>
<Outputs Condition="'$(WolfSSLAarch64Asm)'=='true' And '$(Platform)'=='ARM64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="wolfcrypt\src\wc_frodokem_asm.asm">
<ExcludedFromBuild>true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">false</ExcludedFromBuild>
<Command Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">ml64.exe /c /Zi /DWOLFSSL_X86_64_BUILD /DWOLFSSL_HAVE_FRODOKEM /Fo"$(IntDir)%(Filename).obj" %(Identity)</Command>
<Outputs Condition="'$(WolfSSLIntelAsm)'=='true' And '$(Platform)'=='x64'">$(IntDir)%(Filename).obj</Outputs>
</CustomBuild>
<ClInclude Include="IDE\WIN\user_settings.h" />
</ItemGroup>
<ItemGroup>
+4
View File
@@ -99,6 +99,8 @@ typedef word32 cpuid_flags_t;
#define CPUID_SM4 0x0080 /* SM4 enc/dec */
#define CPUID_SB 0x0100 /* Speculation barrier */
#define CPUID_ASIMD 0x0200 /* ASIMD - NEON */
#define CPUID_SVE 0x0400 /* Scalable Vector Extension */
#define CPUID_SME 0x0800 /* Scalable Matrix Extension */
#define IS_AARCH64_AES(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AES)
#define IS_AARCH64_PMULL(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_PMULL)
@@ -110,6 +112,8 @@ typedef word32 cpuid_flags_t;
#define IS_AARCH64_SM4(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SM4)
#define IS_AARCH64_SB(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SB)
#define IS_AARCH64_ASIMD(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_ASIMD)
#define IS_AARCH64_SVE(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SVE)
#define IS_AARCH64_SME(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SME)
#elif defined(HAVE_CPUID_PPC64)
+2
View File
@@ -79,6 +79,8 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/cryptocb.h \
wolfssl/wolfcrypt/wc_mldsa.h \
wolfssl/wolfcrypt/wc_mlkem.h \
wolfssl/wolfcrypt/wc_frodokem.h \
wolfssl/wolfcrypt/wc_frodokem_mat.h \
wolfssl/wolfcrypt/sm2.h \
wolfssl/wolfcrypt/sm3.h \
wolfssl/wolfcrypt/sm4.h \
+4
View File
@@ -262,6 +262,10 @@ WOLFSSL_LOCAL void BlockSha3(word64 *s);
word64 c);
WOLFSSL_LOCAL void sha3_block_avx2(word64* s);
WOLFSSL_LOCAL void sha3_blocksx4_avx2(word64* s);
WOLFSSL_LOCAL void sha3_blocksx4_out_avx2(word64* s, byte* out,
word32 len);
WOLFSSL_LOCAL void sha3_blocksx8_out_avx512(word64* s, byte* out,
word32 len);
WOLFSSL_LOCAL void sha3_128_blocksx4_seed_avx2(word64* s, byte* seed);
WOLFSSL_LOCAL void sha3_256_blocksx4_seed_avx2(word64* s, byte* seed);
+328
View File
@@ -0,0 +1,328 @@
/* wc_frodokem.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_frodokem.h
*/
#ifndef WOLF_CRYPT_WC_FRODOKEM_H
#define WOLF_CRYPT_WC_FRODOKEM_H
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/sha3.h>
#ifdef WOLFSSL_FRODOKEM_AES
#include <wolfssl/wolfcrypt/aes.h>
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifdef __cplusplus
extern "C" {
#endif
/* Define algorithm parameter sets when not excluded. */
#ifndef WOLFSSL_NO_FRODOKEM_640
#define WOLFSSL_WC_FRODOKEM_640
#endif
#ifndef WOLFSSL_NO_FRODOKEM_976
#define WOLFSSL_WC_FRODOKEM_976
#endif
#ifndef WOLFSSL_NO_FRODOKEM_1344
#define WOLFSSL_WC_FRODOKEM_1344
#endif
#if !defined(WOLFSSL_WC_FRODOKEM_640) && !defined(WOLFSSL_WC_FRODOKEM_976) && \
!defined(WOLFSSL_WC_FRODOKEM_1344)
#error "No FrodoKEM parameter set chosen."
#endif
/* Matrix A generation method(s). AES-128 (Section 6.7.1) and SHAKE-128
* (Section 6.7.2) are independently selectable build options; at least one
* must be enabled. */
#if !defined(WOLFSSL_FRODOKEM_AES) && !defined(WOLFSSL_FRODOKEM_SHAKE)
#error "FrodoKEM needs WOLFSSL_FRODOKEM_AES and/or WOLFSSL_FRODOKEM_SHAKE."
#endif
/* WOLFSSL_FRODOKEM_EPHEMERAL enables the eFrodoKEM (ephemeral, salt-less)
* parameter set types. */
/* Operations are individually selectable: define WOLFSSL_FRODOKEM_NO_MAKE_KEY,
* WOLFSSL_FRODOKEM_NO_ENCAPSULATE and/or WOLFSSL_FRODOKEM_NO_DECAPSULATE to
* exclude them. At least one operation must remain. */
#if defined(WOLFSSL_FRODOKEM_NO_MAKE_KEY) && \
defined(WOLFSSL_FRODOKEM_NO_ENCAPSULATE) && \
defined(WOLFSSL_FRODOKEM_NO_DECAPSULATE)
#error "No FrodoKEM operations to be built."
#endif
/* Number of columns in the "small" matrices - constant across all parameter
* sets (n-bar = m-bar = 8). */
#define FRODOKEM_NBAR 8
/* Number of elements in an nbar x nbar matrix. */
#define FRODOKEM_NBAR_SQ (FRODOKEM_NBAR * FRODOKEM_NBAR)
/* Length of the seed for generating matrix A (lenA / 8 = 128 / 8). */
#define FRODOKEM_SEEDA_SZ 16
/* Size in bytes of a public key: seedA || b (b = nbar * n coefficients of D
* bits each = D * n bytes, nbar == 8). */
#define FRODOKEM_PK_SZ(n, d) (FRODOKEM_SEEDA_SZ + ((d) * (n)))
/* Size in bytes of a private key: s || seedA || b || S^T || pkh.
* S^T holds nbar * n coefficients, each stored as 2 bytes. */
#define FRODOKEM_SK_SZ(n, d, ls) ((ls) + FRODOKEM_SEEDA_SZ + ((d) * (n)) + \
(2 * FRODOKEM_NBAR * (n)) + (ls))
/* Size in bytes of a ciphertext: c1 || c2 || salt.
* c1 = D * nbar * n bits, c2 = D * nbar * nbar bits. */
#define FRODOKEM_CT_SZ(n, d, lsalt) (((d) * (n)) + ((d) * FRODOKEM_NBAR) + \
(lsalt))
/* FrodoKEM-640 parameters. */
#define WC_FRODOKEM_640_N 640
#define WC_FRODOKEM_640_D 15
#define WC_FRODOKEM_640_LENSEC 16 /* lensec / 8 = 128 / 8 */
#define WC_FRODOKEM_640_LENSE 32 /* lenSE / 8 = 256 / 8 */
#define WC_FRODOKEM_640_LENSALT 32 /* lensalt / 8 = 256 / 8 */
#define WC_FRODOKEM_640_PUBLIC_KEY_SIZE \
FRODOKEM_PK_SZ(WC_FRODOKEM_640_N, WC_FRODOKEM_640_D)
#define WC_FRODOKEM_640_PRIVATE_KEY_SIZE \
FRODOKEM_SK_SZ(WC_FRODOKEM_640_N, WC_FRODOKEM_640_D, WC_FRODOKEM_640_LENSEC)
#define WC_FRODOKEM_640_CIPHER_TEXT_SIZE \
FRODOKEM_CT_SZ(WC_FRODOKEM_640_N, WC_FRODOKEM_640_D, \
WC_FRODOKEM_640_LENSALT)
#define WC_FRODOKEM_640_SS_SIZE WC_FRODOKEM_640_LENSEC
#define WC_FRODOKEM_640_MAKEKEY_RAND_SZ \
(WC_FRODOKEM_640_LENSEC + WC_FRODOKEM_640_LENSE + FRODOKEM_SEEDA_SZ)
#define WC_FRODOKEM_640_ENC_RAND_SZ \
(WC_FRODOKEM_640_LENSEC + WC_FRODOKEM_640_LENSALT)
/* FrodoKEM-976 parameters. */
#define WC_FRODOKEM_976_N 976
#define WC_FRODOKEM_976_D 16
#define WC_FRODOKEM_976_LENSEC 24 /* lensec / 8 = 192 / 8 */
#define WC_FRODOKEM_976_LENSE 48 /* lenSE / 8 = 384 / 8 */
#define WC_FRODOKEM_976_LENSALT 48 /* lensalt / 8 = 384 / 8 */
#define WC_FRODOKEM_976_PUBLIC_KEY_SIZE \
FRODOKEM_PK_SZ(WC_FRODOKEM_976_N, WC_FRODOKEM_976_D)
#define WC_FRODOKEM_976_PRIVATE_KEY_SIZE \
FRODOKEM_SK_SZ(WC_FRODOKEM_976_N, WC_FRODOKEM_976_D, WC_FRODOKEM_976_LENSEC)
#define WC_FRODOKEM_976_CIPHER_TEXT_SIZE \
FRODOKEM_CT_SZ(WC_FRODOKEM_976_N, WC_FRODOKEM_976_D, \
WC_FRODOKEM_976_LENSALT)
#define WC_FRODOKEM_976_SS_SIZE WC_FRODOKEM_976_LENSEC
#define WC_FRODOKEM_976_MAKEKEY_RAND_SZ \
(WC_FRODOKEM_976_LENSEC + WC_FRODOKEM_976_LENSE + FRODOKEM_SEEDA_SZ)
#define WC_FRODOKEM_976_ENC_RAND_SZ \
(WC_FRODOKEM_976_LENSEC + WC_FRODOKEM_976_LENSALT)
/* FrodoKEM-1344 parameters. */
#define WC_FRODOKEM_1344_N 1344
#define WC_FRODOKEM_1344_D 16
#define WC_FRODOKEM_1344_LENSEC 32 /* lensec / 8 = 256 / 8 */
#define WC_FRODOKEM_1344_LENSE 64 /* lenSE / 8 = 512 / 8 */
#define WC_FRODOKEM_1344_LENSALT 64 /* lensalt / 8 = 512 / 8 */
#define WC_FRODOKEM_1344_PUBLIC_KEY_SIZE \
FRODOKEM_PK_SZ(WC_FRODOKEM_1344_N, WC_FRODOKEM_1344_D)
#define WC_FRODOKEM_1344_PRIVATE_KEY_SIZE \
FRODOKEM_SK_SZ(WC_FRODOKEM_1344_N, WC_FRODOKEM_1344_D, \
WC_FRODOKEM_1344_LENSEC)
#define WC_FRODOKEM_1344_CIPHER_TEXT_SIZE \
FRODOKEM_CT_SZ(WC_FRODOKEM_1344_N, WC_FRODOKEM_1344_D, \
WC_FRODOKEM_1344_LENSALT)
#define WC_FRODOKEM_1344_SS_SIZE WC_FRODOKEM_1344_LENSEC
#define WC_FRODOKEM_1344_MAKEKEY_RAND_SZ \
(WC_FRODOKEM_1344_LENSEC + WC_FRODOKEM_1344_LENSE + FRODOKEM_SEEDA_SZ)
#define WC_FRODOKEM_1344_ENC_RAND_SZ \
(WC_FRODOKEM_1344_LENSEC + WC_FRODOKEM_1344_LENSALT)
/* Maximum dimensions and sizes over the enabled parameter sets. */
#ifdef WOLFSSL_WC_FRODOKEM_1344
#define FRODOKEM_MAX_N WC_FRODOKEM_1344_N
#define FRODOKEM_MAX_LENSEC WC_FRODOKEM_1344_LENSEC
#define FRODOKEM_MAX_LENSE WC_FRODOKEM_1344_LENSE
#define FRODOKEM_MAX_LENSALT WC_FRODOKEM_1344_LENSALT
#define FRODOKEM_MAX_D WC_FRODOKEM_1344_D
#define FRODOKEM_MAX_PUBLIC_KEY_SIZE WC_FRODOKEM_1344_PUBLIC_KEY_SIZE
#define FRODOKEM_MAX_PRIVATE_KEY_SIZE WC_FRODOKEM_1344_PRIVATE_KEY_SIZE
#define FRODOKEM_MAX_CIPHER_TEXT_SIZE WC_FRODOKEM_1344_CIPHER_TEXT_SIZE
#elif defined(WOLFSSL_WC_FRODOKEM_976)
#define FRODOKEM_MAX_N WC_FRODOKEM_976_N
#define FRODOKEM_MAX_LENSEC WC_FRODOKEM_976_LENSEC
#define FRODOKEM_MAX_LENSE WC_FRODOKEM_976_LENSE
#define FRODOKEM_MAX_LENSALT WC_FRODOKEM_976_LENSALT
#define FRODOKEM_MAX_D WC_FRODOKEM_976_D
#define FRODOKEM_MAX_PUBLIC_KEY_SIZE WC_FRODOKEM_976_PUBLIC_KEY_SIZE
#define FRODOKEM_MAX_PRIVATE_KEY_SIZE WC_FRODOKEM_976_PRIVATE_KEY_SIZE
#define FRODOKEM_MAX_CIPHER_TEXT_SIZE WC_FRODOKEM_976_CIPHER_TEXT_SIZE
#else
#define FRODOKEM_MAX_N WC_FRODOKEM_640_N
#define FRODOKEM_MAX_LENSEC WC_FRODOKEM_640_LENSEC
#define FRODOKEM_MAX_LENSE WC_FRODOKEM_640_LENSE
#define FRODOKEM_MAX_LENSALT WC_FRODOKEM_640_LENSALT
#define FRODOKEM_MAX_D WC_FRODOKEM_640_D
#define FRODOKEM_MAX_PUBLIC_KEY_SIZE WC_FRODOKEM_640_PUBLIC_KEY_SIZE
#define FRODOKEM_MAX_PRIVATE_KEY_SIZE WC_FRODOKEM_640_PRIVATE_KEY_SIZE
#define FRODOKEM_MAX_CIPHER_TEXT_SIZE WC_FRODOKEM_640_CIPHER_TEXT_SIZE
#endif
/* Size in bytes of the packed public matrix b (D * n bits => D * n bytes as
* nbar == 8). */
#define FRODOKEM_MAX_B_SZ (FRODOKEM_MAX_D * FRODOKEM_MAX_N)
/* Number of coefficients in the secret matrix S^T (nbar * n). */
#define FRODOKEM_MAX_S_CNT (FRODOKEM_NBAR * FRODOKEM_MAX_N)
enum {
/* Base parameter sets. On their own these select the standard (salted)
* FrodoKEM using SHAKE-128 to generate matrix A. */
WC_FRODOKEM_640 = 0,
WC_FRODOKEM_976 = 1,
WC_FRODOKEM_1344 = 2,
/* Modifier bits OR'd with a base parameter set to form a key type. */
FRODOKEM_AES = 0x10, /* Generate matrix A with AES-128. */
FRODOKEM_EPHEMERAL = 0x20, /* eFrodoKEM: ephemeral, no salt. */
/* Mask to extract the base parameter set from a type. */
FRODOKEM_BASE_MASK = 0x0F,
/* Explicit named types: FrodoKEM (standard, salted). */
WC_FRODOKEM_640_SHAKE = WC_FRODOKEM_640,
WC_FRODOKEM_976_SHAKE = WC_FRODOKEM_976,
WC_FRODOKEM_1344_SHAKE = WC_FRODOKEM_1344,
WC_FRODOKEM_640_AES = WC_FRODOKEM_640 | FRODOKEM_AES,
WC_FRODOKEM_976_AES = WC_FRODOKEM_976 | FRODOKEM_AES,
WC_FRODOKEM_1344_AES = WC_FRODOKEM_1344 | FRODOKEM_AES,
/* Explicit named types: eFrodoKEM (ephemeral). */
WC_EFRODOKEM_640_SHAKE = WC_FRODOKEM_640 | FRODOKEM_EPHEMERAL,
WC_EFRODOKEM_976_SHAKE = WC_FRODOKEM_976 | FRODOKEM_EPHEMERAL,
WC_EFRODOKEM_1344_SHAKE = WC_FRODOKEM_1344 | FRODOKEM_EPHEMERAL,
WC_EFRODOKEM_640_AES = WC_EFRODOKEM_640_SHAKE | FRODOKEM_AES,
WC_EFRODOKEM_976_AES = WC_EFRODOKEM_976_SHAKE | FRODOKEM_AES,
WC_EFRODOKEM_1344_AES = WC_EFRODOKEM_1344_SHAKE | FRODOKEM_AES,
/* Flags indicating what is stored in a key. */
FRODOKEM_FLAG_PRIV_SET = 0x0001,
FRODOKEM_FLAG_PUB_SET = 0x0002,
FRODOKEM_FLAG_BOTH_SET = 0x0003,
FRODOKEM_FLAG_PKH_SET = 0x0004
};
/* Run-time parameters for a FrodoKEM parameter set. The definition is internal
* (see wc_frodokem_mat.h); a key only holds a pointer to a constant instance. */
typedef struct FrodoKemParams FrodoKemParams;
/* FrodoKEM key. */
typedef struct FrodoKemKey {
/* Type of key: a base parameter set optionally OR'd with FRODOKEM_AES
* and/or FRODOKEM_EPHEMERAL. */
int type;
/* Parameters for this key type (points to a constant). Set by Init. */
const FrodoKemParams* params;
/* Dynamic memory allocation hint. */
void* heap;
/* Device Id. */
int devId;
/* Flags indicating what is stored in the key. */
int flags;
/* Secret value used for implicit rejection (length lenSec). */
byte s[FRODOKEM_MAX_LENSEC];
/* Secret matrix S^T (nbar x n) stored row-major as residues modulo q. */
word16 sMat[FRODOKEM_MAX_S_CNT];
/* Seed used to generate matrix A. */
byte seedA[FRODOKEM_SEEDA_SZ];
/* Packed public matrix B (D * n bytes). */
byte b[FRODOKEM_MAX_B_SZ];
/* Hash of the public key (length lenSec). */
byte pkh[FRODOKEM_MAX_LENSEC];
/* Reusable SHAKE object for all hashing and matrix-A generation. Embedded
* (not allocated); initialized by wc_FrodoKemKey_Init for the key's SHAKE
* variant. Matrix-A generation always uses SHAKE-128; the hashing SHAKE is
* SHAKE-128 for FrodoKEM-640 and SHAKE-256 for -976 / -1344. */
wc_Shake shake;
#ifdef WOLFSSL_FRODOKEM_AES
/* Reusable AES-128 object for matrix-A generation (AES key type). Embedded
* (not allocated); wc_AesInit'd by wc_FrodoKemKey_Init and re-keyed with
* seedA per operation. */
Aes aes;
#endif
} FrodoKemKey;
WOLFSSL_API FrodoKemKey* wc_FrodoKemKey_New(int type, void* heap, int devId);
WOLFSSL_API int wc_FrodoKemKey_Delete(FrodoKemKey* key, FrodoKemKey** key_p);
WOLFSSL_API int wc_FrodoKemKey_Init(FrodoKemKey* key, int type, void* heap,
int devId);
WOLFSSL_API int wc_FrodoKemKey_Free(FrodoKemKey* key);
#ifndef WOLFSSL_FRODOKEM_NO_MAKE_KEY
WOLFSSL_API int wc_FrodoKemKey_MakeKey(FrodoKemKey* key, WC_RNG* rng);
WOLFSSL_API int wc_FrodoKemKey_MakeKeyWithRandom(FrodoKemKey* key,
const unsigned char* rand, int len);
#endif
WOLFSSL_API int wc_FrodoKemKey_CipherTextSize(const FrodoKemKey* key,
word32* len);
WOLFSSL_API int wc_FrodoKemKey_SharedSecretSize(const FrodoKemKey* key,
word32* len);
#ifndef WOLFSSL_FRODOKEM_NO_ENCAPSULATE
WOLFSSL_API int wc_FrodoKemKey_Encapsulate(FrodoKemKey* key, unsigned char* ct,
unsigned char* ss, WC_RNG* rng);
WOLFSSL_API int wc_FrodoKemKey_EncapsulateWithRandom(FrodoKemKey* key,
unsigned char* ct, unsigned char* ss, const unsigned char* rand, int len);
#endif
#ifndef WOLFSSL_FRODOKEM_NO_DECAPSULATE
WOLFSSL_API int wc_FrodoKemKey_Decapsulate(FrodoKemKey* key, unsigned char* ss,
const unsigned char* ct, word32 len);
#endif
WOLFSSL_API int wc_FrodoKemKey_DecodePrivateKey(FrodoKemKey* key,
const unsigned char* in, word32 len);
WOLFSSL_API int wc_FrodoKemKey_DecodePublicKey(FrodoKemKey* key,
const unsigned char* in, word32 len);
WOLFSSL_API int wc_FrodoKemKey_PrivateKeySize(const FrodoKemKey* key,
word32* len);
WOLFSSL_API int wc_FrodoKemKey_PublicKeySize(const FrodoKemKey* key,
word32* len);
WOLFSSL_API int wc_FrodoKemKey_EncodePrivateKey(FrodoKemKey* key,
unsigned char* out, word32 len);
WOLFSSL_API int wc_FrodoKemKey_EncodePublicKey(FrodoKemKey* key,
unsigned char* out, word32 len);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLFSSL_HAVE_FRODOKEM */
#endif /* WOLF_CRYPT_WC_FRODOKEM_H */
+466
View File
@@ -0,0 +1,466 @@
/* wc_frodokem_mat.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_frodokem_mat.h
*/
/* Internal-only declarations for the FrodoKEM reference implementation: the
* run-time parameter set, the assembly dispatch configuration and the low-level
* matrix / encoding operations shared by wc_frodokem.c and wc_frodokem_mat.c
* (and the generated inline-assembly _c.c files). The public API and the
* FrodoKemKey object live in wc_frodokem.h. */
#ifndef WOLF_CRYPT_WC_FRODOKEM_MAT_H
#define WOLF_CRYPT_WC_FRODOKEM_MAT_H
#include <wolfssl/wolfcrypt/wc_frodokem.h>
#ifdef WOLFSSL_HAVE_FRODOKEM
#ifdef __cplusplus
extern "C" {
#endif
/* When the multi-way AVX2/AVX512 Keccak squeeze routines are compiled in,
* matrix-A rows for the SHAKE method are generated several at a time: four with
* AVX2 (sha3_blocksx4_out_avx2), eight with AVX512 (sha3_blocksx8_out_avx512).
* The one-A-row scratch buffer is widened to hold FRODOKEM_ROW_MULT rows (the
* widest path compiled in); the runtime path is chosen by CPU features. */
#if defined(WOLFSSL_FRODOKEM_SHAKE) && defined(USE_INTEL_SPEEDUP) && \
!defined(WC_SHA3_NO_ASM)
#define FRODOKEM_HAVE_SHAKE_X4
#ifndef NO_AVX512_SUPPORT
#define FRODOKEM_HAVE_SHAKE_X8
#endif
#endif
/* AVX2/AVX512 assembly for the matrix operations: the fused S*A / A*S row
* accumulates, the small nbar x nbar ops (mul_bs, mul_add_sb_plus_e, add) and
* the CDF sampler. Available whenever the Intel assembly is built, independent
* of the matrix-A generation method (AES or SHAKE). */
#if defined(USE_INTEL_SPEEDUP)
#define FRODOKEM_HAVE_MATRIX_ASM
#ifndef NO_AVX512_SUPPORT
#define FRODOKEM_HAVE_MATRIX_ASM_AVX512
#endif
/* VAES (vector AES over YMM/ZMM) matrix-A generation. Follows aes.c: the
* VAES asm is compiled and dispatched unless the build opts out with
* NO_VAES_SUPPORT, in which case the AES-NI kernel is the widest path. */
#ifndef NO_VAES_SUPPORT
#define FRODOKEM_HAVE_MATRIX_ASM_VAES
#endif
#endif
/* AArch64 NEON assembly: a 2-way SHAKE (two matrix-A rows at once) and NEON
* matrix ops. NEON is baseline on AArch64, so no runtime feature check. */
#if defined(WOLFSSL_ARMASM) && defined(__aarch64__)
#define FRODOKEM_HAVE_NEON_ASM
#ifdef WOLFSSL_FRODOKEM_SHAKE
#define FRODOKEM_HAVE_SHAKE_NEON
#endif
/* AArch32 NEON assembly: NEON matrix ops only. There is no 2-way NEON Keccak on
* AArch32 (the single-stream permutation already uses all 32 d-registers), so
* matrix A rows are generated one at a time (FRODOKEM_ROW_MULT is 1). Requires
* NEON (-mfpu=neon) - excludes Thumb2, ARMv6 and other non-NEON ARM targets. */
#elif defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_THUMB2) && \
!defined(WOLFSSL_ARMASM_NO_NEON) && \
(defined(__ARM_NEON) || defined(__ARM_NEON__))
#define FRODOKEM_HAVE_NEON_ASM
/* ARMv7 Thumb2 assembly: matrix ops using the packed dual-16-bit DSP
* instructions (no NEON). Two coefficients per 32-bit register. Requires the
* DSP extension (__ARM_FEATURE_DSP, e.g. Cortex-M4/M7/R) - the CDF sampler
* stays on the C path. Matrix A rows are generated one at a time. */
#elif defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_THUMB2) && \
defined(__ARM_FEATURE_DSP)
#define FRODOKEM_HAVE_THUMB2_ASM
/* AArch32 (A32) scalar assembly: the same packed dual-16-bit matrix ops as the
* Thumb2 path, in A32 encoding, for ARMv7-A without NEON (reached only when the
* NEON branch above did not match, i.e. NEON is absent or disabled via
* WOLFSSL_ARMASM_NO_NEON) when the 32-bit SIMD instructions (SMLAD/SADD16/PKHBT)
* are present. The CDF sampler stays on the C path. Matrix A rows are generated
* one at a time. */
#elif defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
!defined(WOLFSSL_ARMASM_THUMB2) && defined(__ARM_FEATURE_SIMD32)
#define FRODOKEM_HAVE_ARM32_SIMD32_ASM
#endif
/* The ARM asm variants (AArch64 NEON, AArch32 NEON/Thumb2/SIMD32) present the
* same matrix-op interface. Alias them to arch-neutral names so the dispatch
* has a single ARM path; each call generates FRODOKEM_ROW_MULT A rows (four on
* AArch64 NEON, one on AArch32). The CDF sampler is NEON-only. */
#if defined(FRODOKEM_HAVE_NEON_ASM)
#define FRODOKEM_HAVE_ARM_ASM
#define frodokem_add_arm frodokem_add_neon
#define frodokem_sa_accum_arm frodokem_sa_accum_neon
#define frodokem_as_accum_arm frodokem_as_accum_neon
#define frodokem_mul_bs_arm frodokem_mul_bs_neon
#define frodokem_mul_add_sb_plus_e_arm frodokem_mul_add_sb_plus_e_neon
#elif defined(FRODOKEM_HAVE_THUMB2_ASM)
#define FRODOKEM_HAVE_ARM_ASM
#define frodokem_add_arm frodokem_add_thumb2
#define frodokem_sa_accum_arm frodokem_sa_accum_thumb2
#define frodokem_as_accum_arm frodokem_as_accum_thumb2
#define frodokem_mul_bs_arm frodokem_mul_bs_thumb2
#define frodokem_mul_add_sb_plus_e_arm frodokem_mul_add_sb_plus_e_thumb2
#elif defined(FRODOKEM_HAVE_ARM32_SIMD32_ASM)
#define FRODOKEM_HAVE_ARM_ASM
#define frodokem_add_arm frodokem_add_simd32
#define frodokem_sa_accum_arm frodokem_sa_accum_simd32
#define frodokem_as_accum_arm frodokem_as_accum_simd32
#define frodokem_mul_bs_arm frodokem_mul_bs_simd32
#define frodokem_mul_add_sb_plus_e_arm frodokem_mul_add_sb_plus_e_simd32
#endif
/* AArch64 SVE: a length-agnostic scalable-vector S * A accumulate, emitted
* into armv8-frodokem-asm.S alongside NEON. Compiled only when explicitly
* enabled (WOLFSSL_FRODOKEM_SVE) and selected at run time by an AT_HWCAP
* check, since SVE is optional per CPU (NEON is the always-present fallback).
* Not available under inline assembly (WOLFSSL_ARMASM_INLINE): the SVE
* routines are only emitted into the .S file, not the inline C twin, so inline
* builds fall back to NEON. */
#if defined(FRODOKEM_HAVE_NEON_ASM) && defined(__aarch64__) && \
defined(WOLFSSL_FRODOKEM_SVE) && !defined(WOLFSSL_ARMASM_INLINE)
#define FRODOKEM_HAVE_SVE
#endif
/* AArch64 SME: the B * S product via the ZA-tile integer outer product (UMOPA),
* emitted into armv8-frodokem-asm.S alongside NEON. Compiled only when
* explicitly enabled (WOLFSSL_FRODOKEM_SME) and selected at run time by an
* AT_HWCAP2 check. The MOPA needs the B/S matrices in an interleaved layout, so
* the wrapper transposes into a scratch buffer first. Not available under
* inline assembly (see FRODOKEM_HAVE_SVE): the SME routines are only in the .S
* file. */
#if defined(FRODOKEM_HAVE_NEON_ASM) && defined(__aarch64__) && \
defined(WOLFSSL_FRODOKEM_SME) && !defined(WOLFSSL_ARMASM_INLINE)
#define FRODOKEM_HAVE_SME
#endif
/* ARMv8 AES matrix-A generation via the crypto extension (AESE/AESMC), emitted
* into armv8-frodokem-asm.S (AArch64) or armv8-32-frodokem-asm.S (AArch32).
* Available whenever the ARMv8 AES hardware crypto is present and the NEON
* matrix path is compiled (AArch32 also requires NEON) - the crypto condition
* wc_AesEcbEncrypt uses. A single frodokem_gen_a_rows_aes_arm name aliases the
* arch-specific routine so the dispatch has one AES A-gen call. Not available
* under inline assembly (WOLFSSL_ARMASM_INLINE): the generator is only in the
* .S file, not the inline C twin, so inline builds fall back to the per-row C
* AES A-generator (frodokem_gen_a_rows_aes). */
#if defined(FRODOKEM_HAVE_NEON_ASM) && defined(__aarch64__) && \
defined(WOLFSSL_FRODOKEM_AES) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && \
!defined(WOLFSSL_ARMASM_INLINE)
#define FRODOKEM_HAVE_ARM64_AES_ASM
#define FRODOKEM_HAVE_ARM_AES_ASM
#define frodokem_gen_a_rows_aes_arm frodokem_gen_a_rows_aes_arm64
#elif defined(FRODOKEM_HAVE_NEON_ASM) && !defined(__aarch64__) && \
!defined(WOLFSSL_ARMASM_THUMB2) && defined(WOLFSSL_FRODOKEM_AES) && \
!defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && !defined(WOLFSSL_ARMASM_INLINE)
#define FRODOKEM_HAVE_ARM32_AES_ASM
#define FRODOKEM_HAVE_ARM_AES_ASM
#define frodokem_gen_a_rows_aes_arm frodokem_gen_a_rows_aes_arm32
#endif
/* The A-row scratch buffer holds this many rows: the number of A rows generated
* per generator call (also the outer accumulate loop's row step), used by both
* the SHAKE and AES paths; the runtime path is chosen by CPU features. On x86
* this matches the fused accumulate width (8 with AVX512, 4 with AVX2). On
* AArch64 the AES generator batches four rows so its AES-ECB loop keeps enough
* blocks in flight to saturate the crypto unit; the driver then accumulates them
* FRODOKEM_AS_ACCUM_ROWS (two) at a time. */
#if defined(FRODOKEM_HAVE_MATRIX_ASM_AVX512)
#define FRODOKEM_ROW_MULT 8
#elif defined(USE_INTEL_SPEEDUP)
#define FRODOKEM_ROW_MULT 4
#elif defined(FRODOKEM_HAVE_NEON_ASM) && defined(__aarch64__)
#define FRODOKEM_ROW_MULT 4
#else
/* AArch32 NEON and the portable C path both consume one A row per call. */
#define FRODOKEM_ROW_MULT 1
#endif
/* Number of A rows a single fused A * S / S * A accumulate call consumes on the
* ARM paths. The AArch64 accumulate (NEON, and the runtime-interchangeable
* SVE/SME variants) fuses two rows; AArch32 and the portable C path do one.
* FRODOKEM_ROW_MULT is a multiple of this, so a generated batch of rows is
* accumulated this many at a time. */
#if defined(FRODOKEM_HAVE_NEON_ASM) && defined(__aarch64__)
#define FRODOKEM_AS_ACCUM_ROWS 2
#else
#define FRODOKEM_AS_ACCUM_ROWS 1
#endif
/* Run-time parameters for a FrodoKEM parameter set. */
struct FrodoKemParams {
/* Number of rows/columns in the big matrix A. */
int n;
/* Number of bits per coefficient - log2 of the modulus q. */
int d;
/* Mask to reduce a value modulo q (q - 1). */
word16 qMask;
/* Number of bits extracted per coefficient in Encode/Decode. */
int b;
/* Cumulative distribution table for error sampling. */
const word16* cdf;
/* Number of entries in the CDF table. */
int cdfLen;
/* Length of s / pkh / shared secret / message in bytes (lensec / 8). */
int lenSec;
/* Use SHAKE256 (1) or SHAKE128 (0) for the hashing function SHAKE. */
int useShake256;
/* Encoded public key size in bytes (base parameter set only). */
int pkSize;
/* Encoded private key size in bytes (base parameter set only). */
int skSize;
/* Length of seedSE in bytes (lenSE / 8). */
int lenSE;
/* Length of salt in bytes (lensalt / 8). 0 for eFrodoKEM (ephemeral). */
int lenSalt;
/* Ciphertext size in bytes (depends on salt length). */
int ctSize;
/* Generate matrix A with AES-128 (1) or SHAKE-128 (0). */
int useAes;
};
/* Low-level matrix and encoding operations (wc_frodokem_mat.c). */
WOLFSSL_LOCAL void frodokem_init(void);
WOLFSSL_LOCAL void frodokem_pack(byte* out, const word16* in, int nElem, int d);
WOLFSSL_LOCAL void frodokem_unpack(word16* out, const byte* in, int nElem,
int d);
WOLFSSL_LOCAL void frodokem_store_matrix(byte* out, const word16* mat, int cnt);
WOLFSSL_LOCAL void frodokem_load_matrix(word16* mat, const byte* in, int cnt);
WOLFSSL_LOCAL void frodokem_key_encode(word16* c, const byte* msg, int d,
int bits);
WOLFSSL_LOCAL void frodokem_key_decode(byte* msg, const word16* c,
const FrodoKemParams* p);
WOLFSSL_LOCAL int frodokem_shake(const FrodoKemParams* p, wc_Shake* shake,
const byte* in0, word32 len0, const byte* in1, word32 len1, byte* out,
word32 outLen);
WOLFSSL_LOCAL int frodokem_shake_oneshot(const FrodoKemParams* p,
wc_Shake* shake, const byte* in, word32 inLen, byte* out, word32 outLen);
/* seedA = SHAKE(z); z and seedA are both FRODOKEM_SEEDA_SZ bytes, so this is
* just the one-shot path with those fixed lengths. */
#define frodokem_shake_seeda(p, shake, in, out) \
frodokem_shake_oneshot(p, shake, in, FRODOKEM_SEEDA_SZ, out, \
FRODOKEM_SEEDA_SZ)
/* seedSE || k = SHAKE(pkh || u || salt, lenSE + lensec). pkh is lensec bytes;
* uSalt is u (lensec) followed by salt (lensalt). */
#define frodokem_gen_seedse_k(p, shake, pkh, uSalt, out) \
frodokem_shake(p, shake, pkh, (word32)(p)->lenSec, uSalt, \
(word32)((p)->lenSec + (p)->lenSalt), out, \
(word32)((p)->lenSE + (p)->lenSec))
WOLFSSL_LOCAL int frodokem_gen_noise(const FrodoKemParams* p, wc_Shake* shake,
const byte* seInput, byte* tmp, word16* mat0, int cnt0, word16* mat1,
int cnt1);
/* Compute out += A * S + E (keygen) and out += S * A + E (encaps/decaps),
* generating matrix A a row (batch) at a time. seedA, the parameters and the
* SHAKE / AES objects for matrix-A generation are taken from key. */
WOLFSSL_LOCAL int frodokem_mul_add_as_plus_e(FrodoKemKey* key, word16* out,
const word16* s, word16* row);
WOLFSSL_LOCAL int frodokem_mul_add_sa_plus_e(FrodoKemKey* key, word16* out,
const word16* s, word16* row);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_bs(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add(word16* a, const word16* b, int qmask);
#ifdef FRODOKEM_HAVE_MATRIX_ASM
/* Mask cnt contiguous matrix-A coefficients with qmask in one AVX2 pass - the
* mod-q reduction for the 640 SHAKE path (q == 2^15). cnt is a coefficient
* count; any leftover after the 16-wide loop is masked one word at a time. */
WOLFSSL_LOCAL void frodokem_a_rows_reduce_avx2(word16* rows, word32 cnt,
int qmask);
/* Assembly S*A / A*S accumulate for four generated A rows at once (AVX2). */
WOLFSSL_LOCAL void frodokem_sa_accum_avx2(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_avx2(word16* out, const word16* s,
const word16* row, int i, int n);
#ifdef FRODOKEM_HAVE_MATRIX_ASM_VAES
/* Assembly AES-128-ECB matrix-A row generation + mod-q reduction for cnt rows
* (AVX2 + VAES). Builds the counter blocks in registers, ECB-encrypts and
* masks; in is unused. ks is the eleven expanded AES-128 round keys (Aes.key).
* n must be a multiple of 8 (cnt need not be). */
WOLFSSL_LOCAL void frodokem_gen_a_rows_aes_avx2(byte* in, word16* out,
const byte* ks, int i, int cnt, int n, int qmask);
#endif
/* Assembly AES-128-ECB matrix-A row generation + mod-q reduction for cnt rows
* (AVX + AES-NI, no VAES). Builds the AES-ECB counter blocks in registers (no
* memory build pass), encrypts eight at a time and folds the mask into the
* store. Used when AVX2 is present but VAES is not (pre-Ice-Lake Intel,
* pre-Zen4 AMD). in is unused (kept for signature parity); out receives the
* cnt*n coefficients. ks is the eleven expanded AES-128 round keys (Aes.key).
* Handles any n that is a multiple of 8 (cnt and n need not be 8-aligned). */
WOLFSSL_LOCAL void frodokem_gen_a_rows_aes_aesni(byte* in, word16* out,
const byte* ks, int i, int cnt, int n, int qmask);
#endif
#ifdef FRODOKEM_HAVE_MATRIX_ASM_AVX512
/* Assembly S * A / A * S accumulate for eight generated A rows at once
* (AVX512). */
WOLFSSL_LOCAL void frodokem_sa_accum_avx512(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_avx512(word16* out, const word16* s,
const word16* row, int i, int n);
#ifdef FRODOKEM_HAVE_MATRIX_ASM_VAES
/* Assembly AES-128-ECB matrix-A row generation + mod-q reduction for cnt rows
* (AVX512 + VAES). Builds the input blocks, ECB-encrypts and masks; in may
* alias out. ks is the eleven expanded AES-128 round keys (Aes.key). cnt*2*n
* must be a multiple of 256 (holds for cnt == 8). */
WOLFSSL_LOCAL void frodokem_gen_a_rows_aes_avx512(byte* in, word16* out,
const byte* ks, int i, int cnt, int n, int qmask);
#endif
#endif
#ifdef FRODOKEM_HAVE_MATRIX_ASM
/* AVX2 nbar x nbar matrix ops (B*S, S*B+E, add). */
WOLFSSL_LOCAL void frodokem_mul_bs_avx2(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e_avx2(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_avx2(word16* a, const word16* b, int qmask);
WOLFSSL_LOCAL void frodokem_sample_avx2(word16* mat, int cnt,
const word16* cdf, int cdflen);
#endif
#ifdef FRODOKEM_HAVE_MATRIX_ASM_AVX512
/* AVX512 nbar x nbar matrix ops (B*S, S*B+E, add). */
WOLFSSL_LOCAL void frodokem_mul_bs_avx512(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e_avx512(word16* out,
const word16* b, const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_avx512(word16* a, const word16* b, int qmask);
WOLFSSL_LOCAL void frodokem_sample_avx512(word16* mat, int cnt,
const word16* cdf, int cdflen);
#endif
#ifdef FRODOKEM_HAVE_SHAKE_NEON
/* AArch64 NEON Keccak-f[1600] permutation on two interleaved states at once
* (state[0..24] and state[25..49]) - matrix-A SHAKE generates two rows at a
* time. */
WOLFSSL_LOCAL void frodokem_sha3_x2_neon(word64* state);
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
/* SHA3-crypto-extension twin of frodokem_sha3_x2_neon (EOR3/RAX1/XAR/BCAX),
* used at run time when the CPU reports FEAT_SHA3. */
WOLFSSL_LOCAL void frodokem_sha3_x2_crypto(word64* state);
#endif
#endif
#ifdef FRODOKEM_HAVE_NEON_ASM
/* AArch64/AArch32 NEON matrix operations. sa/as accumulate FRODOKEM_ROW_MULT
* generated A rows per call (two on AArch64, one on AArch32); the rest match the
* Intel routines. */
WOLFSSL_LOCAL void frodokem_sa_accum_neon(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_sa_accum_x4_neon(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_neon(word16* out, const word16* s,
const word16* row, int i, int n);
WOLFSSL_LOCAL void frodokem_as_accum_x4_neon(word16* out, const word16* s,
const word16* row, int i, int n);
WOLFSSL_LOCAL void frodokem_mul_bs_neon(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e_neon(word16* out,
const word16* b, const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_neon(word16* a, const word16* b, int qmask);
WOLFSSL_LOCAL void frodokem_sample_neon(word16* mat, int cnt,
const word16* cdf, int cdflen);
#endif
#ifdef FRODOKEM_HAVE_ARM64_AES_ASM
/* AArch64 AES-128-ECB matrix-A row generation + mod-q reduction for cnt rows
* (ARMv8 crypto extension). Builds the input blocks, ECB-encrypts and masks; in
* may alias out. ks is the eleven expanded AES-128 round keys (Aes.key). cnt*2*n
* must be a multiple of 64 (holds for cnt == 2). */
WOLFSSL_LOCAL void frodokem_gen_a_rows_aes_arm64(byte* in, word16* out,
const byte* ks, int i, int cnt, int n, int qmask);
#endif
#ifdef FRODOKEM_HAVE_ARM32_AES_ASM
/* AArch32 AES-128-ECB matrix-A row generation + mod-q reduction for cnt rows
* (ARMv8 crypto extension). Builds the input blocks, ECB-encrypts and masks; in
* may alias out. ks is the eleven expanded AES-128 round keys (Aes.key). cnt*2*n
* must be a multiple of 32 (holds for cnt == 1). */
WOLFSSL_LOCAL void frodokem_gen_a_rows_aes_arm32(byte* in, word16* out,
const byte* ks, int i, int cnt, int n, int qmask);
#endif
#ifdef FRODOKEM_HAVE_THUMB2_ASM
/* ARMv7 Thumb2 packed dual-16-bit matrix operations (no NEON). sa/as accumulate
* one A row per call; the CDF sampler stays on the C path. */
WOLFSSL_LOCAL void frodokem_sa_accum_thumb2(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_thumb2(word16* out, const word16* s,
const word16* row, int i, int n);
WOLFSSL_LOCAL void frodokem_mul_bs_thumb2(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e_thumb2(word16* out,
const word16* b, const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_thumb2(word16* a, const word16* b, int qmask);
#endif
#ifdef FRODOKEM_HAVE_ARM32_SIMD32_ASM
/* AArch32 (A32) packed dual-16-bit matrix operations (no NEON) using the 32-bit
* SIMD instructions (SMLAD/SADD16/PKHBT/...), the A32 encoding of the same
* kernels as the Thumb2 path. sa/as accumulate one A row per call; the CDF
* sampler stays on the C path. */
WOLFSSL_LOCAL void frodokem_sa_accum_simd32(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_simd32(word16* out, const word16* s,
const word16* row, int i, int n);
WOLFSSL_LOCAL void frodokem_mul_bs_simd32(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_mul_add_sb_plus_e_simd32(word16* out,
const word16* b, const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_simd32(word16* a, const word16* b, int qmask);
#endif
#ifdef FRODOKEM_HAVE_SVE
/* AArch64 SVE scalable-vector matrix accumulates (two A rows per call, matching
* the NEON interface). Length-agnostic: run on any SVE vector length. */
WOLFSSL_LOCAL void frodokem_sa_accum_sve(word16* out, const word16* s,
const word16* row, int j, int n);
WOLFSSL_LOCAL void frodokem_as_accum_sve(word16* out, const word16* s,
const word16* row, int i, int n);
WOLFSSL_LOCAL void frodokem_mul_bs_sve(word16* out, const word16* b,
const word16* s, int n, int qmask);
WOLFSSL_LOCAL void frodokem_add_sve(word16* a, const word16* b, int qmask);
#endif
#ifdef FRODOKEM_HAVE_SME
/* AArch64 SME B * S (nbar x nbar) via the ZA-tile UMOPA. bt/st are B and S in
* the interleaved MOPA layout (bt[t*nbar*2 + 2*i + e] = b[i*n + 2*t + e]). */
WOLFSSL_LOCAL void frodokem_mul_bs_sme(word16* out, const word16* bt,
const word16* st, int n, int qmask);
/* AArch64 SME S * A accumulate (two A rows) via the ZA-tile UMOPA tiled over the
* n columns. sc is the S column pair (sc[2*i + e] = s[i*n + j + e], 2*nbar
* word16); row is the natural pair of A rows (the interleave is done in-asm). */
WOLFSSL_LOCAL void frodokem_sa_accum_sme(word16* out, const word16* sc,
const word16* row, int n);
/* AArch64 SME A * S accumulate (two A rows) via the ZA-tile UMOPA. at/st are the
* A rows and S in the interleaved MOPA layout (at[t*4 + 2*r + e] = row[r*n + 2*t
* + e], st[t*nbar*2 + 2*k + e] = s[k*n + 2*t + e]). */
WOLFSSL_LOCAL void frodokem_as_accum_sme(word16* out, const word16* at,
const word16* st, int i, int n);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLFSSL_HAVE_FRODOKEM */
#endif /* WOLF_CRYPT_WC_FRODOKEM_MAT_H */