From 9c22cf1ac4fd8075002f122115d49d830714d5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Mon, 20 Apr 2026 15:12:16 +0200 Subject: [PATCH] Replace liboqs SPHINCS+ with SLH-DSA in certificate layer Replace the liboqs-based pre-standardization SPHINCS+ implementation with the native FIPS 205 SLH-DSA implementation across the certificate/ASN.1/X.509 layers. All liboqs SPHINCS+ code is removed. This enables SLH-DSA for certificate chain authentication (CA certificates signed with SLH-DSA, certificate verification). TLS 1.3 entity authentication via CertificateVerify with SLH-DSA will be added in a follow-up PR. Follows RFC 9909 (X.509 Algorithm Identifiers for SLH-DSA). Changes: - New DER codec for SLH-DSA (PrivateKeyDecode, PublicKeyDecode, KeyToDer, PrivateKeyToDer, PublicKeyToDer) with RFC 9909 compliant encoding (bare OCTET STRING, 4*n bytes = SK.seed || SK.prf || PK.seed || PK.root, no nested wrapper) and OID auto-detection across all six SHAKE parameter sets. - 12 standardized NIST OIDs (6 SHA2 + 6 SHAKE) per RFC 9909. OID collision mechanism cleaned up since NIST OIDs don't collide. - Complete ASN.1 layer replacement (~500 lines in asn.c) and X.509 public-key handling in x509.c. - SHA2-SLH-DSA OIDs are recognized but the native backend is SHAKE-only; Private/PublicKeyDecode and ConfirmSignature return NOT_COMPILED_IN for SHA2 variants so callers get an informative error instead of a generic parse failure. - wc_GetKeyOID selects its placeholder parameter from whatever SHAKE variant is compiled in, so auto-detect works when specific variants (e.g. SHAKE128F) are disabled. - wc_SlhDsaKey_PublicKeyDecode saves and restores key->params and *inOutIdx on ImportPublic failure, matching PrivateKeyDecode. - DER round-trip and on-disk decode tests (bench_slhdsa_shake*_key.der fixtures regenerated with wolfSSL's own encoder, guaranteed RFC 9909 compliant) guard against future encoding drift. - SLH-DSA test cert chain generated with OpenSSL 3.5. - DYNAMIC_TYPE_SPHINCS = 98 kept as RESERVED with a tombstone comment for ABI stability; new code should use DYNAMIC_TYPE_SLHDSA (107). - All build system / IDE project files updated; SPHINCS+ sources, headers, and test data removed. --- .wolfssl_known_macro_extras | 1 - .../template/components/wolfssl/component.mk | 1 - .../components/wolfssl/component.mk | 1 - .../components/wolfssl/component.mk | 1 - .../components/wolfssl/component.mk | 1 - .../components/wolfssl/component.mk | 1 - IDE/INTIME-RTOS/Makefile | 1 - IDE/INTIME-RTOS/libwolfssl.vcxproj | 1 - IDE/INTIME-RTOS/wolfssl-lib.vcxproj | 1 - .../wolfssl.X/nbproject/configurations.xml | 1 - .../e2studio/SK-S7G2/wolfssl_lib/.project | 5 - .../wolfssl-FIPS.xcodeproj/project.pbxproj | 4 - IDE/XCODE/wolfssl.xcodeproj/project.pbxproj | 4 - INSTALL | 2 +- certs/include.am | 2 +- certs/slhdsa/bench_slhdsa_shake128f_key.der | Bin 0 -> 84 bytes certs/slhdsa/bench_slhdsa_shake128s_key.der | Bin 0 -> 84 bytes certs/slhdsa/bench_slhdsa_shake192f_key.der | Bin 0 -> 116 bytes certs/slhdsa/bench_slhdsa_shake192s_key.der | Bin 0 -> 116 bytes certs/slhdsa/bench_slhdsa_shake256f_key.der | Bin 0 -> 150 bytes certs/slhdsa/bench_slhdsa_shake256s_key.der | Bin 0 -> 150 bytes certs/slhdsa/include.am | 11 + .../sphincs/bench_sphincs_fast_level1_key.der | Bin 115 -> 0 bytes .../sphincs/bench_sphincs_fast_level3_key.der | Bin 166 -> 0 bytes .../sphincs/bench_sphincs_fast_level5_key.der | Bin 214 -> 0 bytes .../bench_sphincs_small_level1_key.der | Bin 115 -> 0 bytes .../bench_sphincs_small_level3_key.der | Bin 166 -> 0 bytes .../bench_sphincs_small_level5_key.der | Bin 214 -> 0 bytes certs/sphincs/include.am | 11 - cmake/functions.cmake | 5 - doc/dox_comments/header_files/asn.h | 2 +- gencertbuf.pl | 32 +- rpm/spec.in | 2 - scripts/asn1_oid_sum.pl | 63 +- src/include.am | 1 - src/ssl.c | 3 - src/x509.c | 104 +- tests/api/test_slhdsa.c | 327 ++++- tests/api/test_slhdsa.h | 8 +- wolfcrypt/benchmark/benchmark.c | 230 +-- wolfcrypt/benchmark/benchmark.h | 1 - wolfcrypt/src/asn.c | 1298 ++++++++--------- wolfcrypt/src/asn_orig.c | 136 +- wolfcrypt/src/sphincs.c | 1057 -------------- wolfcrypt/src/wc_slhdsa.c | 394 ++++- wolfssl-VS2022.vcxproj | 1 - wolfssl.vcproj | 4 - wolfssl.vcxproj | 1 - wolfssl/certs_test.h | 142 -- wolfssl/wolfcrypt/asn.h | 37 +- wolfssl/wolfcrypt/asn_public.h | 24 +- wolfssl/wolfcrypt/include.am | 2 +- wolfssl/wolfcrypt/oid_sum.h | 144 +- wolfssl/wolfcrypt/settings.h | 7 +- wolfssl/wolfcrypt/sphincs.h | 167 --- wolfssl/wolfcrypt/types.h | 8 +- wolfssl/wolfcrypt/wc_slhdsa.h | 18 + wrapper/CSharp/wolfssl.vcxproj | 1 - zephyr/CMakeLists.txt | 1 - 59 files changed, 1674 insertions(+), 2595 deletions(-) create mode 100644 certs/slhdsa/bench_slhdsa_shake128f_key.der create mode 100644 certs/slhdsa/bench_slhdsa_shake128s_key.der create mode 100644 certs/slhdsa/bench_slhdsa_shake192f_key.der create mode 100644 certs/slhdsa/bench_slhdsa_shake192s_key.der create mode 100644 certs/slhdsa/bench_slhdsa_shake256f_key.der create mode 100644 certs/slhdsa/bench_slhdsa_shake256s_key.der create mode 100644 certs/slhdsa/include.am delete mode 100644 certs/sphincs/bench_sphincs_fast_level1_key.der delete mode 100644 certs/sphincs/bench_sphincs_fast_level3_key.der delete mode 100644 certs/sphincs/bench_sphincs_fast_level5_key.der delete mode 100644 certs/sphincs/bench_sphincs_small_level1_key.der delete mode 100644 certs/sphincs/bench_sphincs_small_level3_key.der delete mode 100644 certs/sphincs/bench_sphincs_small_level5_key.der delete mode 100644 certs/sphincs/include.am delete mode 100644 wolfcrypt/src/sphincs.c delete mode 100644 wolfssl/wolfcrypt/sphincs.h diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 3943d477390..8fb7261f8bf 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -837,7 +837,6 @@ WOLFSSL_NO_SERVER_GROUPS_EXT WOLFSSL_NO_SESSION_STATS WOLFSSL_NO_SIGALG WOLFSSL_NO_SOCKADDR_UN -WOLFSSL_NO_SPHINCS WOLFSSL_NO_STRICT_CIPHER_SUITE WOLFSSL_NO_TICKET_EXPIRE WOLFSSL_NO_TRUSTED_CERTS_VERIFY diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/component.mk b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/component.mk index 6b1c0529881..a5f4be5e1e2 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/component.mk +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/component.mk @@ -245,7 +245,6 @@ COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/siphash.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm2.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm3.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm4.o -COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sphincs.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm32.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm64.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_armthumb.o diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/component.mk b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/component.mk index 82a56d2a551..e3ff1e3a8ae 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/component.mk +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/component.mk @@ -245,7 +245,6 @@ COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/siphash.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm2.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm3.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm4.o -COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sphincs.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm32.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm64.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_armthumb.o diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/component.mk b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/component.mk index 6b1c0529881..a5f4be5e1e2 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/component.mk +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/component.mk @@ -245,7 +245,6 @@ COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/siphash.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm2.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm3.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm4.o -COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sphincs.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm32.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm64.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_armthumb.o diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/component.mk b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/component.mk index 6b1c0529881..a5f4be5e1e2 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/component.mk +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/component.mk @@ -245,7 +245,6 @@ COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/siphash.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm2.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm3.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm4.o -COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sphincs.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm32.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm64.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_armthumb.o diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/component.mk b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/component.mk index 308aa3d4eb4..9f4450ea1e0 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/component.mk +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/component.mk @@ -245,7 +245,6 @@ COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/siphash.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm2.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm3.o COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sm4.o -COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sphincs.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm32.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_arm64.o # COMPONENT_OBJS += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_armthumb.o diff --git a/IDE/INTIME-RTOS/Makefile b/IDE/INTIME-RTOS/Makefile index 3755c292056..87c0c221556 100644 --- a/IDE/INTIME-RTOS/Makefile +++ b/IDE/INTIME-RTOS/Makefile @@ -320,7 +320,6 @@ INCL_TARGS := wolfssl/callbacks.h \ wolfssl/wolfcrypt/sm4.h \ wolfssl/wolfcrypt/sp.h \ wolfssl/wolfcrypt/sp_int.h \ - wolfssl/wolfcrypt/sphincs.h \ wolfssl/wolfcrypt/srp.h \ wolfssl/wolfcrypt/tfm.h \ wolfssl/wolfcrypt/types.h \ diff --git a/IDE/INTIME-RTOS/libwolfssl.vcxproj b/IDE/INTIME-RTOS/libwolfssl.vcxproj index 87ab3de8f4d..213d16884cb 100644 --- a/IDE/INTIME-RTOS/libwolfssl.vcxproj +++ b/IDE/INTIME-RTOS/libwolfssl.vcxproj @@ -81,7 +81,6 @@ - diff --git a/IDE/INTIME-RTOS/wolfssl-lib.vcxproj b/IDE/INTIME-RTOS/wolfssl-lib.vcxproj index 3c5bd1d8d5c..af39dc6ef68 100644 --- a/IDE/INTIME-RTOS/wolfssl-lib.vcxproj +++ b/IDE/INTIME-RTOS/wolfssl-lib.vcxproj @@ -108,7 +108,6 @@ - diff --git a/IDE/MPLABX16/wolfssl.X/nbproject/configurations.xml b/IDE/MPLABX16/wolfssl.X/nbproject/configurations.xml index bd423ae2c11..562553b4da5 100644 --- a/IDE/MPLABX16/wolfssl.X/nbproject/configurations.xml +++ b/IDE/MPLABX16/wolfssl.X/nbproject/configurations.xml @@ -81,7 +81,6 @@ ../../../wolfcrypt/src/sp_c32.c ../../../wolfcrypt/src/sp_c64.c ../../../wolfcrypt/src/sp_int.c - ../../../wolfcrypt/src/sphincs.c ../../../wolfcrypt/src/srp.c ../../../wolfcrypt/src/tfm.c ../../../wolfcrypt/src/wc_encrypt.c diff --git a/IDE/Renesas/e2studio/SK-S7G2/wolfssl_lib/.project b/IDE/Renesas/e2studio/SK-S7G2/wolfssl_lib/.project index a7ff640024e..bca79c0cf55 100644 --- a/IDE/Renesas/e2studio/SK-S7G2/wolfssl_lib/.project +++ b/IDE/Renesas/e2studio/SK-S7G2/wolfssl_lib/.project @@ -440,11 +440,6 @@ 1 PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_x86_64.c - - src/wolfcrypt/sphincs.c - 1 - PARENT-5-PROJECT_LOC/wolfcrypt/src/sphincs.c - src/wolfcrypt/srp.c 1 diff --git a/IDE/XCODE/wolfssl-FIPS.xcodeproj/project.pbxproj b/IDE/XCODE/wolfssl-FIPS.xcodeproj/project.pbxproj index c96018c5a8c..fdf50b1237b 100644 --- a/IDE/XCODE/wolfssl-FIPS.xcodeproj/project.pbxproj +++ b/IDE/XCODE/wolfssl-FIPS.xcodeproj/project.pbxproj @@ -145,7 +145,6 @@ 700F0D092A2FC11300755BA7 /* siphash.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CD42A2FC0D500755BA7 /* siphash.h */; }; 700F0D0A2A2FC11300755BA7 /* sp_int.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CDF2A2FC0D500755BA7 /* sp_int.h */; }; 700F0D0B2A2FC11300755BA7 /* sp.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CD12A2FC0D500755BA7 /* sp.h */; }; - 700F0D0C2A2FC11300755BA7 /* sphincs.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CEC2A2FC0D500755BA7 /* sphincs.h */; }; 700F0D0D2A2FC11300755BA7 /* srp.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CDC2A2FC0D500755BA7 /* srp.h */; }; 700F0D0E2A2FC11300755BA7 /* wc_mlkem.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CD82A2FC0D500755BA7 /* wc_mlkem.h */; }; 700F0D0F2A2FC11300755BA7 /* wc_pkcs11.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0CE82A2FC0D500755BA7 /* wc_pkcs11.h */; }; @@ -305,7 +304,6 @@ 700F0D092A2FC11300755BA7 /* siphash.h in CopyFiles */, 700F0D0A2A2FC11300755BA7 /* sp_int.h in CopyFiles */, 700F0D0B2A2FC11300755BA7 /* sp.h in CopyFiles */, - 700F0D0C2A2FC11300755BA7 /* sphincs.h in CopyFiles */, 700F0D0D2A2FC11300755BA7 /* srp.h in CopyFiles */, 700F0D0E2A2FC11300755BA7 /* wc_mlkem.h in CopyFiles */, 700F0D0F2A2FC11300755BA7 /* wc_pkcs11.h in CopyFiles */, @@ -593,7 +591,6 @@ 700F0CE82A2FC0D500755BA7 /* wc_pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wc_pkcs11.h; path = ../../wolfssl/wolfcrypt/wc_pkcs11.h; sourceTree = ""; }; 700F0CEA2A2FC0D500755BA7 /* rc2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rc2.h; path = ../../wolfssl/wolfcrypt/rc2.h; sourceTree = ""; }; 700F0CEB2A2FC0D500755BA7 /* wolfmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wolfmath.h; path = ../../wolfssl/wolfcrypt/wolfmath.h; sourceTree = ""; }; - 700F0CEC2A2FC0D500755BA7 /* sphincs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sphincs.h; path = ../../wolfssl/wolfcrypt/sphincs.h; sourceTree = ""; }; 9D2E31D6291CE2190082B941 /* dtls13.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dtls13.c; path = ../../src/dtls13.c; sourceTree = ""; }; 9D2E31D9291CE2370082B941 /* dtls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dtls.c; path = ../../src/dtls.c; sourceTree = ""; }; 9D2E31DC291CE2740082B941 /* quic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quic.c; path = ../../src/quic.c; sourceTree = ""; }; @@ -663,7 +660,6 @@ 700F0CD42A2FC0D500755BA7 /* siphash.h */, 700F0CDF2A2FC0D500755BA7 /* sp_int.h */, 700F0CD12A2FC0D500755BA7 /* sp.h */, - 700F0CEC2A2FC0D500755BA7 /* sphincs.h */, 700F0CDC2A2FC0D500755BA7 /* srp.h */, 700F0CD82A2FC0D500755BA7 /* wc_mlkem.h */, 700F0CE82A2FC0D500755BA7 /* wc_pkcs11.h */, diff --git a/IDE/XCODE/wolfssl.xcodeproj/project.pbxproj b/IDE/XCODE/wolfssl.xcodeproj/project.pbxproj index 1c5d65d1c5d..9aea1c2fe04 100644 --- a/IDE/XCODE/wolfssl.xcodeproj/project.pbxproj +++ b/IDE/XCODE/wolfssl.xcodeproj/project.pbxproj @@ -275,7 +275,6 @@ 700F0C202A2FBC5100755BA7 /* siphash.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BFE2A2FBC1600755BA7 /* siphash.h */; }; 700F0C212A2FBC5100755BA7 /* sp_int.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BE82A2FBC1500755BA7 /* sp_int.h */; }; 700F0C222A2FBC5100755BA7 /* sp.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BE92A2FBC1500755BA7 /* sp.h */; }; - 700F0C232A2FBC5100755BA7 /* sphincs.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BE22A2FBC1500755BA7 /* sphincs.h */; }; 700F0C242A2FBC5100755BA7 /* srp.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BF32A2FBC1600755BA7 /* srp.h */; }; 700F0C252A2FBC5100755BA7 /* wc_mlkem.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BFF2A2FBC1600755BA7 /* wc_mlkem.h */; }; 700F0C262A2FBC5100755BA7 /* wc_pkcs11.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700F0BF52A2FBC1600755BA7 /* wc_pkcs11.h */; }; @@ -641,7 +640,6 @@ 700F0C202A2FBC5100755BA7 /* siphash.h in CopyFiles */, 700F0C212A2FBC5100755BA7 /* sp_int.h in CopyFiles */, 700F0C222A2FBC5100755BA7 /* sp.h in CopyFiles */, - 700F0C232A2FBC5100755BA7 /* sphincs.h in CopyFiles */, 700F0C242A2FBC5100755BA7 /* srp.h in CopyFiles */, 700F0C252A2FBC5100755BA7 /* wc_mlkem.h in CopyFiles */, 700F0C262A2FBC5100755BA7 /* wc_pkcs11.h in CopyFiles */, @@ -975,7 +973,6 @@ 6AC8513B272CB04F00F2B32A /* kdf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kdf.h; path = ../../wolfssl/wolfcrypt/kdf.h; sourceTree = ""; }; 700F0BE02A2FBC1500755BA7 /* rc2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rc2.h; path = ../../wolfssl/wolfcrypt/rc2.h; sourceTree = ""; }; 700F0BE12A2FBC1500755BA7 /* hpke.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hpke.h; path = ../../wolfssl/wolfcrypt/hpke.h; sourceTree = ""; }; - 700F0BE22A2FBC1500755BA7 /* sphincs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sphincs.h; path = ../../wolfssl/wolfcrypt/sphincs.h; sourceTree = ""; }; 700F0BE32A2FBC1500755BA7 /* curve448.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = curve448.h; path = ../../wolfssl/wolfcrypt/curve448.h; sourceTree = ""; }; 700F0BE52A2FBC1500755BA7 /* curve25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = curve25519.h; path = ../../wolfssl/wolfcrypt/curve25519.h; sourceTree = ""; }; 700F0BE62A2FBC1500755BA7 /* wolfevent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wolfevent.h; path = ../../wolfssl/wolfcrypt/wolfevent.h; sourceTree = ""; }; @@ -1172,7 +1169,6 @@ 700F0BFE2A2FBC1600755BA7 /* siphash.h */, 700F0BE82A2FBC1500755BA7 /* sp_int.h */, 700F0BE92A2FBC1500755BA7 /* sp.h */, - 700F0BE22A2FBC1500755BA7 /* sphincs.h */, 700F0BF32A2FBC1600755BA7 /* srp.h */, 700F0BFF2A2FBC1600755BA7 /* wc_mlkem.h */, 700F0BF52A2FBC1600755BA7 /* wc_pkcs11.h */, diff --git a/INSTALL b/INSTALL index dc6e2908c1a..34722257cf1 100644 --- a/INSTALL +++ b/INSTALL @@ -253,13 +253,13 @@ The following NIST Competition winning algorithms are supported: - ML-KEM (CRYSTALS-KYBER) (key encapsulation mechanism) - ML-DSA (CRYSTALS-Dilithium) (signature scheme) + - SLH-DSA (FIPS 205) (signature scheme) The following NIST Competition winning algorithms were supported by our liboqs integration. Support for their standardized specifications will return when we write our own implementations. - FALCON (signature scheme) - - SPHINCS+ (signature scheme) The following NIST Competition Round 3 finalist algorithms were supported, but have been removed after 5.3.3 diff --git a/certs/include.am b/certs/include.am index b19881d31f3..840af3dc306 100644 --- a/certs/include.am +++ b/certs/include.am @@ -159,7 +159,7 @@ include certs/intermediate/include.am include certs/falcon/include.am include certs/rsapss/include.am include certs/dilithium/include.am -include certs/sphincs/include.am +include certs/slhdsa/include.am include certs/rpk/include.am include certs/acert/include.am include certs/mldsa/include.am diff --git a/certs/slhdsa/bench_slhdsa_shake128f_key.der b/certs/slhdsa/bench_slhdsa_shake128f_key.der new file mode 100644 index 0000000000000000000000000000000000000000..935424dd50320177350848c0f0e8736caebd8f37 GIT binary patch literal 84 zcmV-a0IUBnQUU=0Fbf6=V1`HmWdj5Q8w5ZZ$k*CAXzEAOZ|dD(;OqgyIO#3gg=N5p qp)(3(#ocON%{jDuV&6s_G~2YVR^rfbkd7r_m;|OXsviJc-l|?o>Le2Y literal 0 HcmV?d00001 diff --git a/certs/slhdsa/bench_slhdsa_shake128s_key.der b/certs/slhdsa/bench_slhdsa_shake128s_key.der new file mode 100644 index 0000000000000000000000000000000000000000..02ece2175f4aa1e30a4bda70e3d34c372a045324 GIT binary patch literal 84 zcmV-a0IUBnQUU=0Fbf6=V1`HmWdj5Q8U#R(MEtB5t=Jt+BkF8cCP*oPL6Z#YmKV%e qVKrg$7vVpIXWwzpq)9mW^;UOr-8dm-xveYuI3_H{dA2GQQ^e+)M+2PK^69sr+_3$UtAys*h zPPx3T7OhK#!PU5|Ghs+4H1*bVbh7eowevN(WlB3R{urZtG2n1BfW4hHsH?0)9*btv WtQ$c-pgGl|L2{iy2s9>T_+}cOUgu7fT=04$<>b z#;QVHxe-dqTS6y-JebnK;a87zn*qDRp=-U=w=02@e2T&)BCIJuO!?~H!+;*5jfB1H;!kEaDnwu0QS&FEtcVzE+&Ah<0jbB zmK~b*=O=^)u{m)+fe)_(&HQi9OM0^!yfQ|VVh-G16Fkc6dFt9R7hL2; EjE$2&Pyhe` literal 0 HcmV?d00001 diff --git a/certs/slhdsa/bench_slhdsa_shake256s_key.der b/certs/slhdsa/bench_slhdsa_shake256s_key.der new file mode 100644 index 0000000000000000000000000000000000000000..f4233c0eb9ed8791cfbbd4fa7436323cc7105293 GIT binary patch literal 150 zcmV;H0BQd)fs+CO05A&%31Egu0c8UO10Do{fTSDSgq^hzW_8#$vFzQ7^HCaGm=-SEP2TLn~*#Jp4~Hg diff --git a/certs/sphincs/bench_sphincs_fast_level3_key.der b/certs/sphincs/bench_sphincs_fast_level3_key.der deleted file mode 100644 index cd691372bad05482b36b3118742745f2b06acaec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmXqLT+GDCV8Fq~rhSf|jf0D&aWYHegiTiI%e?z`zF#}@iEZkOcjwof*T1(%Fuk|G z*KVd^`dh;+R`-Lqj*5scoZRdZ!P#Ktp6->%3WeD8 c)=SMgS{Cx*on<|_9p@zcmv?y7@RF(?04Xp@M*si- diff --git a/certs/sphincs/bench_sphincs_fast_level5_key.der b/certs/sphincs/bench_sphincs_fast_level5_key.der deleted file mode 100644 index 19f4f4da07ff0310e660127c04c176699b8b54b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmXqLyv)SNV8Fq~rhSf|jgyO|@i0r{fz_A)T8lHBy}Ie$C9|jBW$&DDx*eR=#hZJ{ zMy6(lZ}ExMdaJ4qs2$<0+j4og@Rz)Qd`p)^gfF@~Gim3pL(yt)^Je}Md#-1-me{=T8?@6RQe>yBkJzfL Lv+(6qO7#N(w5nnf diff --git a/certs/sphincs/bench_sphincs_small_level1_key.der b/certs/sphincs/bench_sphincs_small_level1_key.der deleted file mode 100644 index 5133d7bca7ec30a1f028fc03a76b92339fc2203d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmXpgWMX76;9z6ZKF80-F2It+lJH+GEOku|cad)I4oxr7y7!@f_kB6=EML27dP1Pg r=_Y5Fdm^^}&uwHj@1Fl+e*coSJA)1yem~e&SNwZkQFzyN7eev?Z%Q?` diff --git a/certs/sphincs/bench_sphincs_small_level3_key.der b/certs/sphincs/bench_sphincs_small_level3_key.der deleted file mode 100644 index 691d52e5e393fa25ba918fd105b3a45a57fb6239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmXqLT+GDCV8Fq~rhSf|jf01!aWYHegvf&~UGbkkZr<^KMtz%?kK~`g9YXDMg09tH z+pzNcTNkzUht9d*d^}a^nczY5^rfA5&9hz}?wM`3Yh#&L)Vs6O(mn;>>gmkfzyIgb eJ+%!hrYBDbjmY5&O62~$=b`+TW%2V#RSy6mTUBrX diff --git a/certs/sphincs/bench_sphincs_small_level5_key.der b/certs/sphincs/bench_sphincs_small_level5_key.der deleted file mode 100644 index c90cdf68b387edb485cbcf13ac4d48a8fedde4be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmXqLyv)SNV8Fq~rhSf|jgyC^@i0r{f#9dAjxwkF*EjD=aW3$aZTs=-RqAZlJs&H> z+XMA;19tGvn&0zc_KRO~9~RCy)opU6F!;lA*=xM_lM|N$stkXg5 ziH8?m7D_j@zMgJ)_0D}CpH;3aV%Gl}(XF5e&2bvwN(XbF?%Ym-@iZK`Si7gW0M Kn{p_VQvCpl!ejUV diff --git a/certs/sphincs/include.am b/certs/sphincs/include.am deleted file mode 100644 index 2d44e66b7cf..00000000000 --- a/certs/sphincs/include.am +++ /dev/null @@ -1,11 +0,0 @@ -# vim:ft=automake -# All paths should be given relative to the root -# - -EXTRA_DIST += \ - certs/sphincs/bench_sphincs_fast_level1_key.der \ - certs/sphincs/bench_sphincs_fast_level3_key.der \ - certs/sphincs/bench_sphincs_fast_level5_key.der \ - certs/sphincs/bench_sphincs_small_level1_key.der \ - certs/sphincs/bench_sphincs_small_level3_key.der \ - certs/sphincs/bench_sphincs_small_level5_key.der diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 1a5442ddfd2..1e4250b63a6 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -215,7 +215,6 @@ function(generate_build_flags) endif() if(WOLFSSL_OQS OR WOLFSSL_USER_SETTINGS) set(BUILD_FALCON "yes" PARENT_SCOPE) - set(BUILD_SPHINCS "yes" PARENT_SCOPE) set(BUILD_DILITHIUM "yes" PARENT_SCOPE) set(BUILD_EXT_MLKEM "yes" PARENT_SCOPE) set(BUILD_OQS_HELPER "yes" PARENT_SCOPE) @@ -1029,10 +1028,6 @@ function(generate_lib_src_list LIB_SOURCES) list(APPEND LIB_SOURCES wolfcrypt/src/falcon.c) endif() - if(BUILD_SPHINCS) - list(APPEND LIB_SOURCES wolfcrypt/src/sphincs.c) - endif() - if(BUILD_DILITHIUM) list(APPEND LIB_SOURCES wolfcrypt/src/dilithium.c) diff --git a/doc/dox_comments/header_files/asn.h b/doc/dox_comments/header_files/asn.h index b4995dd83ad..03bbe38c038 100644 --- a/doc/dox_comments/header_files/asn.h +++ b/doc/dox_comments/header_files/asn.h @@ -254,7 +254,7 @@ int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, 4. Encodes the signature into the certificate/CSR DER structure NOTE: Only RSA and ECC key types are supported. Ed25519, Ed448, and - post-quantum algorithms (Falcon, Dilithium, SPHINCS+) sign messages + post-quantum algorithms (Falcon, Dilithium, SLH-DSA) sign messages directly rather than hashes, so they cannot use this callback-based API. Use wc_SignCert_ex for those algorithms. diff --git a/gencertbuf.pl b/gencertbuf.pl index 6699c9f2adb..8fd959cd695 100755 --- a/gencertbuf.pl +++ b/gencertbuf.pl @@ -153,15 +153,15 @@ ["certs/falcon/bench_falcon_level5_key.der", "bench_falcon_level5_key" ], ); -#Sphincs+ Post-Quantum Keys -#Used with HAVE_PQC -my @fileList_sphincs = ( - ["certs/sphincs/bench_sphincs_fast_level1_key.der", "bench_sphincs_fast_level1_key" ], - ["certs/sphincs/bench_sphincs_fast_level3_key.der", "bench_sphincs_fast_level3_key" ], - ["certs/sphincs/bench_sphincs_fast_level5_key.der", "bench_sphincs_fast_level5_key" ], - ["certs/sphincs/bench_sphincs_small_level1_key.der", "bench_sphincs_small_level1_key" ], - ["certs/sphincs/bench_sphincs_small_level3_key.der", "bench_sphincs_small_level3_key" ], - ["certs/sphincs/bench_sphincs_small_level5_key.der", "bench_sphincs_small_level5_key" ], +#SLH-DSA Post-Quantum Keys +#Used with WOLFSSL_HAVE_SLHDSA +my @fileList_slhdsa = ( + ["certs/slhdsa/bench_slhdsa_shake128s_key.der", "bench_slhdsa_shake128s_key" ], + ["certs/slhdsa/bench_slhdsa_shake128f_key.der", "bench_slhdsa_shake128f_key" ], + ["certs/slhdsa/bench_slhdsa_shake192s_key.der", "bench_slhdsa_shake192s_key" ], + ["certs/slhdsa/bench_slhdsa_shake192f_key.der", "bench_slhdsa_shake192f_key" ], + ["certs/slhdsa/bench_slhdsa_shake256s_key.der", "bench_slhdsa_shake256s_key" ], + ["certs/slhdsa/bench_slhdsa_shake256f_key.der", "bench_slhdsa_shake256f_key" ], ); # CN-IP test certs (no SAN, CN contains IP literal or wildcard) @@ -184,7 +184,7 @@ my $num_sm2 = @fileList_sm2; my $num_sm2_der = @fileList_sm2_der; my $num_falcon = @fileList_falcon; -my $num_sphincs = @fileList_sphincs; +my $num_slhdsa = @fileList_slhdsa; my $num_cn_ip = @fileList_cn_ip; # open our output file, "+>" creates and/or truncates @@ -2106,12 +2106,12 @@ "; -# convert and print sphincs keys -print OUT_FILE "#if defined(HAVE_SPHINCS)\n\n"; -for (my $i = 0; $i < $num_sphincs; $i++) { +# convert and print SLH-DSA keys +print OUT_FILE "#if defined(WOLFSSL_HAVE_SLHDSA)\n\n"; +for (my $i = 0; $i < $num_slhdsa; $i++) { - my $fname = $fileList_sphincs[$i][0]; - my $sname = $fileList_sphincs[$i][1]; + my $fname = $fileList_slhdsa[$i][0]; + my $sname = $fileList_slhdsa[$i][1]; print OUT_FILE "/* $fname */\n"; print OUT_FILE "static const unsigned char $sname\[] =\n"; @@ -2124,7 +2124,7 @@ print OUT_FILE "#define sizeof_$sname (sizeof($sname))\n\n" } -print OUT_FILE "#endif /* HAVE_SPHINCS */\n\n"; +print OUT_FILE "#endif /* WOLFSSL_HAVE_SLHDSA */\n\n"; # convert and print 256-bit cert/keys print OUT_FILE "#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)\n\n"; diff --git a/rpm/spec.in b/rpm/spec.in index f45998e1fd8..26f0defcc4b 100644 --- a/rpm/spec.in +++ b/rpm/spec.in @@ -98,8 +98,6 @@ fi - Add include of kyber headers * Tue Aug 30 2022 Jacob Barthelmeh - Add include of QUIC documentation -* Wed Aug 17 2022 Anthony Hu -- Add a new header sphincs.h. * Wed Jul 20 2022 Anthony Hu - Add a new header dilithium.h. * Fri Jul 8 2022 Jacob Barthelmeh diff --git a/scripts/asn1_oid_sum.pl b/scripts/asn1_oid_sum.pl index 8c5200d2d38..e16dd242181 100755 --- a/scripts/asn1_oid_sum.pl +++ b/scripts/asn1_oid_sum.pl @@ -298,12 +298,18 @@ sub print_footer { my @mldsa_2 = ( 2, 16, 840, 1, 101, 3, 4, 3, 17 ); my @mldsa_3 = ( 2, 16, 840, 1, 101, 3, 4, 3, 18 ); my @mldsa_5 = ( 2, 16, 840, 1, 101, 3, 4, 3, 19 ); -my @sphincs_fast_1 = ( 1, 3, 9999, 6, 7, 4 ); -my @sphincs_fast_3 = ( 1, 3, 9999, 6, 8, 3 ); -my @sphincs_fast_5 = ( 1, 3, 9999, 6, 9, 3 ); -my @sphincs_small_1 = ( 1, 3, 9999, 6, 7, 10 ); -my @sphincs_small_3 = ( 1, 3, 9999, 6, 8, 7 ); -my @sphincs_small_5 = ( 1, 3, 9999, 6, 9, 7 ); +my @slhdsa_sha2_128s = (2, 16, 840, 1, 101, 3, 4, 3, 20); +my @slhdsa_sha2_128f = (2, 16, 840, 1, 101, 3, 4, 3, 21); +my @slhdsa_sha2_192s = (2, 16, 840, 1, 101, 3, 4, 3, 22); +my @slhdsa_sha2_192f = (2, 16, 840, 1, 101, 3, 4, 3, 23); +my @slhdsa_sha2_256s = (2, 16, 840, 1, 101, 3, 4, 3, 24); +my @slhdsa_sha2_256f = (2, 16, 840, 1, 101, 3, 4, 3, 25); +my @slhdsa_shake_128s = (2, 16, 840, 1, 101, 3, 4, 3, 26); +my @slhdsa_shake_128f = (2, 16, 840, 1, 101, 3, 4, 3, 27); +my @slhdsa_shake_192s = (2, 16, 840, 1, 101, 3, 4, 3, 28); +my @slhdsa_shake_192f = (2, 16, 840, 1, 101, 3, 4, 3, 29); +my @slhdsa_shake_256s = (2, 16, 840, 1, 101, 3, 4, 3, 30); +my @slhdsa_shake_256f = (2, 16, 840, 1, 101, 3, 4, 3, 31); my @keys = ( { name => "ANON", oid => \@anon }, @@ -326,13 +332,18 @@ sub print_footer { { name => "ML_DSA_LEVEL2", oid => \@mldsa_2 }, { name => "ML_DSA_LEVEL3", oid => \@mldsa_3 }, { name => "ML_DSA_LEVEL5", oid => \@mldsa_5 }, - { name => "SPHINCS_FAST_LEVEL1", oid => \@sphincs_fast_1 }, - { name => "SPHINCS_FAST_LEVEL3", oid => \@sphincs_fast_3, - oid_sum => 283 }, - { name => "SPHINCS_FAST_LEVEL5", oid => \@sphincs_fast_5 }, - { name => "SPHINCS_SMALL_LEVEL1", oid => \@sphincs_small_1 }, - { name => "SPHINCS_SMALL_LEVEL3", oid => \@sphincs_small_3 }, - { name => "SPHINCS_SMALL_LEVEL5", oid => \@sphincs_small_5 }, + { name => "SLH_DSA_SHA2_128S", oid => \@slhdsa_sha2_128s }, + { name => "SLH_DSA_SHA2_128F", oid => \@slhdsa_sha2_128f }, + { name => "SLH_DSA_SHA2_192S", oid => \@slhdsa_sha2_192s }, + { name => "SLH_DSA_SHA2_192F", oid => \@slhdsa_sha2_192f }, + { name => "SLH_DSA_SHA2_256S", oid => \@slhdsa_sha2_256s }, + { name => "SLH_DSA_SHA2_256F", oid => \@slhdsa_sha2_256f }, + { name => "SLH_DSA_SHAKE_128S", oid => \@slhdsa_shake_128s }, + { name => "SLH_DSA_SHAKE_128F", oid => \@slhdsa_shake_128f }, + { name => "SLH_DSA_SHAKE_192S", oid => \@slhdsa_shake_192s }, + { name => "SLH_DSA_SHAKE_192F", oid => \@slhdsa_shake_192f }, + { name => "SLH_DSA_SHAKE_256S", oid => \@slhdsa_shake_256s }, + { name => "SLH_DSA_SHAKE_256F", oid => \@slhdsa_shake_256f }, ); print_sum_enum("Key", "k", \@keys); @@ -1122,17 +1133,29 @@ sub print_footer { same => 1 }, { name => "CTC_ML_DSA_LEVEL5", oid => \@mldsa_5, same => 1 }, - { name => "CTC_SPHINCS_FAST_LEVEL1", oid => \@sphincs_fast_1, + { name => "CTC_SLH_DSA_SHA2_128S", oid => \@slhdsa_sha2_128s, same => 1 }, - { name => "CTC_SPHINCS_FAST_LEVEL3", oid => \@sphincs_fast_3, - same => 1, oid_sum => 283 }, - { name => "CTC_SPHINCS_FAST_LEVEL5", oid => \@sphincs_fast_5, + { name => "CTC_SLH_DSA_SHA2_128F", oid => \@slhdsa_sha2_128f, same => 1 }, - { name => "CTC_SPHINCS_SMALL_LEVEL1", oid => \@sphincs_small_1, + { name => "CTC_SLH_DSA_SHA2_192S", oid => \@slhdsa_sha2_192s, same => 1 }, - { name => "CTC_SPHINCS_SMALL_LEVEL3", oid => \@sphincs_small_3, + { name => "CTC_SLH_DSA_SHA2_192F", oid => \@slhdsa_sha2_192f, same => 1 }, - { name => "CTC_SPHINCS_SMALL_LEVEL5", oid => \@sphincs_small_5, + { name => "CTC_SLH_DSA_SHA2_256S", oid => \@slhdsa_sha2_256s, + same => 1 }, + { name => "CTC_SLH_DSA_SHA2_256F", oid => \@slhdsa_sha2_256f, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_128S", oid => \@slhdsa_shake_128s, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_128F", oid => \@slhdsa_shake_128f, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_192S", oid => \@slhdsa_shake_192s, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_192F", oid => \@slhdsa_shake_192f, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_256S", oid => \@slhdsa_shake_256s, + same => 1 }, + { name => "CTC_SLH_DSA_SHAKE_256F", oid => \@slhdsa_shake_256f, same => 1 }, ); diff --git a/src/include.am b/src/include.am index c4f6b8a6739..3bc29220ac9 100644 --- a/src/include.am +++ b/src/include.am @@ -1588,7 +1588,6 @@ endif if BUILD_LIBOQS src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/falcon.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/dilithium.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sphincs.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/ext_mlkem.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/liboqs/liboqs.c endif diff --git a/src/ssl.c b/src/ssl.c index f9b82ac4d0e..7dd9b7a2d22 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -118,9 +118,6 @@ #if defined(HAVE_DILITHIUM) #include #endif /* HAVE_DILITHIUM */ - #if defined(HAVE_SPHINCS) - #include - #endif /* HAVE_SPHINCS */ #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #ifdef HAVE_OCSP #include diff --git a/src/x509.c b/src/x509.c index 8541f999e9a..6f09908374d 100644 --- a/src/x509.c +++ b/src/x509.c @@ -12179,8 +12179,8 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) #if defined(HAVE_DILITHIUM) dilithium_key* dilithium = NULL; #endif - #if defined(HAVE_SPHINCS) - sphincs_key* sphincs = NULL; + #if defined(WOLFSSL_HAVE_SLHDSA) + SlhDsaKey* slhdsa = NULL; #endif WC_RNG rng; word32 idx = 0; @@ -12411,63 +12411,65 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) key = (void*)dilithium; } #endif - #if defined(HAVE_SPHINCS) - if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) || - (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) || - (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) { - sphincs = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL, - DYNAMIC_TYPE_SPHINCS); - if (sphincs == NULL) { - WOLFSSL_MSG("Failed to allocate memory for sphincs_key"); + #if defined(WOLFSSL_HAVE_SLHDSA) + if ((x509->pubKeyOID == SLH_DSA_SHAKE_128Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_192Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_256Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_128Sk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_192Sk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_256Sk)) { + enum SlhDsaParam param = SLHDSA_SHAKE128F; + + slhdsa = (SlhDsaKey*)XMALLOC(sizeof(SlhDsaKey), NULL, + DYNAMIC_TYPE_SLHDSA); + if (slhdsa == NULL) { + WOLFSSL_MSG("Failed to allocate memory for SlhDsaKey"); XFREE(cert, NULL, DYNAMIC_TYPE_CERT); return WOLFSSL_FAILURE; } - ret = wc_sphincs_init(sphincs); - if (ret != 0) { - XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); - XFREE(cert, NULL, DYNAMIC_TYPE_CERT); - return ret; + if (x509->pubKeyOID == SLH_DSA_SHAKE_128Fk) { + type = SLH_DSA_SHAKE_128F_TYPE; + param = SLHDSA_SHAKE128F; } - - if (x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) { - type = SPHINCS_FAST_LEVEL1_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT); + else if (x509->pubKeyOID == SLH_DSA_SHAKE_192Fk) { + type = SLH_DSA_SHAKE_192F_TYPE; + param = SLHDSA_SHAKE192F; } - else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) { - type = SPHINCS_FAST_LEVEL3_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT); + else if (x509->pubKeyOID == SLH_DSA_SHAKE_256Fk) { + type = SLH_DSA_SHAKE_256F_TYPE; + param = SLHDSA_SHAKE256F; } - else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) { - type = SPHINCS_FAST_LEVEL5_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT); + else if (x509->pubKeyOID == SLH_DSA_SHAKE_128Sk) { + type = SLH_DSA_SHAKE_128S_TYPE; + param = SLHDSA_SHAKE128S; } - else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) { - type = SPHINCS_SMALL_LEVEL1_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT); + else if (x509->pubKeyOID == SLH_DSA_SHAKE_192Sk) { + type = SLH_DSA_SHAKE_192S_TYPE; + param = SLHDSA_SHAKE192S; } - else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) { - type = SPHINCS_SMALL_LEVEL3_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT); + else if (x509->pubKeyOID == SLH_DSA_SHAKE_256Sk) { + type = SLH_DSA_SHAKE_256S_TYPE; + param = SLHDSA_SHAKE256S; } - else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) { - type = SPHINCS_SMALL_LEVEL5_TYPE; - wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT); + + ret = wc_SlhDsaKey_Init(slhdsa, param, NULL, INVALID_DEVID); + if (ret != 0) { + XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; } - ret = wc_Sphincs_PublicKeyDecode(x509->pubKey.buffer, &idx, sphincs, - x509->pubKey.length); + ret = wc_SlhDsaKey_PublicKeyDecode(x509->pubKey.buffer, &idx, + slhdsa, x509->pubKey.length); if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); - wc_sphincs_free(sphincs); - XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); + wc_SlhDsaKey_Free(slhdsa); + XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA); XFREE(cert, NULL, DYNAMIC_TYPE_CERT); return ret; } - key = (void*)sphincs; + key = (void*)slhdsa; } #endif if (key == NULL) { @@ -12591,15 +12593,15 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM); } #endif - #if defined(HAVE_SPHINCS) - if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) || - (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) || - (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) || - (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) { - wc_sphincs_free(sphincs); - XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); + #if defined(WOLFSSL_HAVE_SLHDSA) + if ((x509->pubKeyOID == SLH_DSA_SHAKE_128Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_192Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_256Fk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_128Sk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_192Sk) || + (x509->pubKeyOID == SLH_DSA_SHAKE_256Sk)) { + wc_SlhDsaKey_Free(slhdsa); + XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA); } #endif XFREE(cert, NULL, DYNAMIC_TYPE_CERT); diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index fc40bed9c7a..7d8dff540ce 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -152,8 +152,7 @@ int test_wc_slhdsa_sizes(void) ExpectIntEQ(wc_SlhDsaKey_PrivateSize(&key), WC_SLHDSA_SHAKE192S_PRIV_LEN); #endif ExpectIntEQ(wc_SlhDsaKey_PublicSize(&key), WC_SLHDSA_SHAKE192S_PUB_LEN); - /* Verify signature size is positive. */ - ExpectIntGT(wc_SlhDsaKey_SigSize(&key), 0); + ExpectIntEQ(wc_SlhDsaKey_SigSize(&key), WC_SLHDSA_SHAKE192S_SIG_LEN); wc_SlhDsaKey_Free(&key); #ifndef WOLFSSL_SLHDSA_VERIFY_ONLY @@ -162,8 +161,8 @@ int test_wc_slhdsa_sizes(void) #endif ExpectIntEQ(wc_SlhDsaKey_PublicSizeFromParam(SLHDSA_SHAKE192S), WC_SLHDSA_SHAKE192S_PUB_LEN); - /* Verify SigSizeFromParam returns positive value. */ - ExpectIntGT(wc_SlhDsaKey_SigSizeFromParam(SLHDSA_SHAKE192S), 0); + ExpectIntEQ(wc_SlhDsaKey_SigSizeFromParam(SLHDSA_SHAKE192S), + WC_SLHDSA_SHAKE192S_SIG_LEN); #endif #ifdef WOLFSSL_SLHDSA_PARAM_192F @@ -1172,3 +1171,323 @@ int test_wc_slhdsa_check_key(void) #endif /* WOLFSSL_HAVE_SLHDSA */ return EXPECT_RESULT(); } + +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + defined(WC_ENABLE_ASYM_KEY_EXPORT) +/* Round-trip a single SLH-DSA parameter set through the DER codec: + * generate -> KeyToDer -> PrivateKeyDecode -> sign/verify round-trip. + * Also tests PublicKeyToDer -> PublicKeyDecode, and that the decode + * correctly auto-detects the parameter set from the OID. */ +static int slhdsa_der_roundtrip_one(enum SlhDsaParam param) +{ + EXPECT_DECLS; + SlhDsaKey keyGen; + SlhDsaKey keyPriv; + SlhDsaKey keyPub; + WC_RNG rng; + byte* derBuf = NULL; + byte* sig = NULL; + const word32 derBufSz = 16 * 1024; + word32 derLen; + word32 idx; + word32 sigLen; + /* Use the same param as placeholder - the auto-detect overrides it + * anyway, and this avoids failures when FAST or SMALL variants are + * selectively disabled via WOLFSSL_SLHDSA_PARAM_NO_FAST/NO_SMALL. */ + enum SlhDsaParam placeholder = param; + static const byte msg[] = "SLH-DSA DER round-trip"; + + XMEMSET(&rng, 0, sizeof(rng)); + XMEMSET(&keyGen, 0, sizeof(keyGen)); + XMEMSET(&keyPriv, 0, sizeof(keyPriv)); + XMEMSET(&keyPub, 0, sizeof(keyPub)); + + derBuf = (byte*)XMALLOC(derBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(derBuf); + sig = (byte*)XMALLOC(WC_SLHDSA_MAX_SIG_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(sig); + + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_SlhDsaKey_Init(&keyGen, param, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_SlhDsaKey_MakeKey(&keyGen, &rng), 0); + + /* Encode the freshly-generated key to DER (private + public). */ + ExpectIntGT(derLen = (word32)wc_SlhDsaKey_KeyToDer(&keyGen, derBuf, + derBufSz), 0); + + /* Decode into a fresh key. The decode must auto-detect the real + * parameter set from the OID embedded in the DER encoding. */ + ExpectIntEQ(wc_SlhDsaKey_Init(&keyPriv, placeholder, NULL, INVALID_DEVID), + 0); + idx = 0; + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(derBuf, &idx, &keyPriv, derLen), + 0); + /* Verify the decoded key reports the ORIGINAL parameter set. */ + if (keyPriv.params != NULL) { + ExpectIntEQ((int)keyPriv.params->param, (int)param); + } + + /* Sign with the decoded private key and verify with the originally + * generated key. This proves the decoded key material is correct. */ + sigLen = WC_SLHDSA_MAX_SIG_LEN; + ExpectIntEQ(wc_SlhDsaKey_Sign(&keyPriv, NULL, 0, msg, (word32)sizeof(msg), + sig, &sigLen, &rng), 0); + ExpectIntEQ(wc_SlhDsaKey_Verify(&keyGen, NULL, 0, msg, (word32)sizeof(msg), + sig, sigLen), 0); + + /* Also test PrivateKeyToDer -> PrivateKeyDecode round-trip. */ + { + SlhDsaKey keyPriv2; + word32 derLen2; + word32 idx2 = 0; + XMEMSET(&keyPriv2, 0, sizeof(keyPriv2)); + ExpectIntGT(derLen2 = (word32)wc_SlhDsaKey_PrivateKeyToDer(&keyGen, + derBuf, derBufSz), 0); + ExpectIntEQ(wc_SlhDsaKey_Init(&keyPriv2, placeholder, NULL, + INVALID_DEVID), 0); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(derBuf, &idx2, &keyPriv2, + derLen2), 0); + /* Verify the PrivateKeyToDer output matches KeyToDer. */ + sigLen = WC_SLHDSA_MAX_SIG_LEN; + ExpectIntEQ(wc_SlhDsaKey_Sign(&keyPriv2, NULL, 0, msg, + (word32)sizeof(msg), sig, &sigLen, &rng), 0); + ExpectIntEQ(wc_SlhDsaKey_Verify(&keyGen, NULL, 0, msg, + (word32)sizeof(msg), sig, sigLen), 0); + wc_SlhDsaKey_Free(&keyPriv2); + } + + /* Now round-trip the public key alone. */ + ExpectIntGT(derLen = (word32)wc_SlhDsaKey_PublicKeyToDer(&keyGen, derBuf, + derBufSz, 1), 0); + ExpectIntEQ(wc_SlhDsaKey_Init(&keyPub, placeholder, NULL, INVALID_DEVID), + 0); + idx = 0; + ExpectIntEQ(wc_SlhDsaKey_PublicKeyDecode(derBuf, &idx, &keyPub, derLen), 0); + if (keyPub.params != NULL) { + ExpectIntEQ((int)keyPub.params->param, (int)param); + } + /* The decoded public key should verify the signature we just produced. */ + ExpectIntEQ(wc_SlhDsaKey_Verify(&keyPub, NULL, 0, msg, (word32)sizeof(msg), + sig, sigLen), 0); + + wc_SlhDsaKey_Free(&keyPub); + wc_SlhDsaKey_Free(&keyPriv); + wc_SlhDsaKey_Free(&keyGen); + wc_FreeRng(&rng); + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return EXPECT_RESULT(); +} +#endif + +/* + * DER codec round-trip test: encode each compiled-in SLH-DSA parameter set + * to DER, decode it (without telling the decoder which parameter set it is), + * confirm auto-detect produces the right parameter, and verify a signature + * produced with the decoded key. This test would fail if PrivateKeyDecode + * / PublicKeyDecode did not auto-detect the parameter set from the OID. + */ +int test_wc_slhdsa_der_roundtrip(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + defined(WC_ENABLE_ASYM_KEY_EXPORT) + /* Only SHAKE variants are tested; SHA2 SLH-DSA test coverage is pending + * native SHA2 implementation. */ +#ifdef WOLFSSL_SLHDSA_PARAM_128S + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE128S), TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_128F + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE128F), TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_192S + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE192S), TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_192F + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE192F), TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_256S + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE256S), TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_256F + ExpectIntEQ(slhdsa_der_roundtrip_one(SLHDSA_SHAKE256F), TEST_SUCCESS); +#endif +#endif /* WOLFSSL_HAVE_SLHDSA && !VERIFY_ONLY && WC_ENABLE_ASYM_KEY_EXPORT */ + return EXPECT_RESULT(); +} + +/* + * Negative / error-path tests for the DER encode/decode functions. + */ +int test_wc_slhdsa_der_negative(void) +{ + EXPECT_DECLS; +#ifdef WOLFSSL_HAVE_SLHDSA + SlhDsaKey key; + word32 idx; + byte buf[16]; + + XMEMSET(&key, 0, sizeof(key)); + + /* PrivateKeyDecode: NULL parameters */ +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY + idx = 0; + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(NULL, &idx, &key, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(buf, NULL, &key, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(buf, &idx, NULL, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(buf, &idx, &key, 0), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* PrivateKeyDecode: truncated data */ + idx = 0; + XMEMSET(buf, 0, sizeof(buf)); + ExpectIntNE(wc_SlhDsaKey_PrivateKeyDecode(buf, &idx, &key, sizeof(buf)), 0); +#endif + + /* PublicKeyDecode: NULL parameters */ + idx = 0; + ExpectIntEQ(wc_SlhDsaKey_PublicKeyDecode(NULL, &idx, &key, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PublicKeyDecode(buf, NULL, &key, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PublicKeyDecode(buf, &idx, NULL, 10), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PublicKeyDecode(buf, &idx, &key, 0), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + +#if defined(WC_ENABLE_ASYM_KEY_EXPORT) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) + /* KeyToDer / PrivateKeyToDer: NULL key */ + ExpectIntEQ(wc_SlhDsaKey_KeyToDer(NULL, buf, sizeof(buf)), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyToDer(NULL, buf, sizeof(buf)), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* KeyToDer: public-only key should return MISSING_KEY */ + { + SlhDsaKey pubOnly; + XMEMSET(&pubOnly, 0, sizeof(pubOnly)); +#ifdef WOLFSSL_SLHDSA_PARAM_128S + ExpectIntEQ(wc_SlhDsaKey_Init(&pubOnly, SLHDSA_SHAKE128S, NULL, + INVALID_DEVID), 0); + /* Only set the public flag, no private key material. */ + pubOnly.flags = WC_SLHDSA_FLAG_PUBLIC; + ExpectIntEQ(wc_SlhDsaKey_KeyToDer(&pubOnly, NULL, 0), + WC_NO_ERR_TRACE(MISSING_KEY)); + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyToDer(&pubOnly, NULL, 0), + WC_NO_ERR_TRACE(MISSING_KEY)); + wc_SlhDsaKey_Free(&pubOnly); +#endif + } +#endif /* WC_ENABLE_ASYM_KEY_EXPORT && !VERIFY_ONLY */ + + /* PublicKeyToDer: NULL key */ +#ifdef WC_ENABLE_ASYM_KEY_EXPORT + ExpectIntEQ(wc_SlhDsaKey_PublicKeyToDer(NULL, buf, sizeof(buf), 1), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); +#endif + +#endif /* WOLFSSL_HAVE_SLHDSA */ + return EXPECT_RESULT(); +} + +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + !defined(NO_FILESYSTEM) +/* Load an RFC 9909 compliant DER file from disk and confirm that + * wc_SlhDsaKey_PrivateKeyDecode accepts it, auto-detects the parameter + * set from the OID, and produces a usable signing key. This test + * exercises the on-disk certs/slhdsa/ fixtures - any future file-format + * drift (nested wrapper, seed-only, wrong length) will be caught here. */ +static int slhdsa_decode_file_one(const char *path, enum SlhDsaParam expected) +{ + EXPECT_DECLS; + XFILE f = XBADFILE; + byte der[256]; + int derSz = 0; + SlhDsaKey key; + WC_RNG rng; + word32 idx = 0; + byte sig[WC_SLHDSA_MAX_SIG_LEN]; + word32 sigLen = (word32)sizeof(sig); + static const byte msg[] = "slhdsa decode-file test"; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectTrue((f = XFOPEN(path, "rb")) != XBADFILE); + if (f != XBADFILE) { + ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0); + XFCLOSE(f); + } + + /* Seed the decoder with a DIFFERENT parameter than the file; auto-detect + * must overwrite it from the OID. If parameter-set gating disables the + * placeholder, fall back to the expected param (tests still exercise + * auto-detect because that's what the decoder uses). */ + ExpectIntEQ(wc_SlhDsaKey_Init(&key, expected, NULL, INVALID_DEVID), 0); + + ExpectIntEQ(wc_SlhDsaKey_PrivateKeyDecode(der, &idx, &key, (word32)derSz), + 0); + ExpectNotNull(key.params); + if (key.params != NULL) { + ExpectIntEQ((int)key.params->param, (int)expected); + } + + /* Sanity: signing works with the decoded key. */ + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_SlhDsaKey_Sign(&key, NULL, 0, msg, (word32)sizeof(msg), + sig, &sigLen, &rng), 0); + ExpectIntEQ(wc_SlhDsaKey_Verify(&key, NULL, 0, msg, (word32)sizeof(msg), + sig, sigLen), 0); + + wc_SlhDsaKey_Free(&key); + wc_FreeRng(&rng); + return EXPECT_RESULT(); +} +#endif + +/* Load each checked-in bench_slhdsa_shake*_key.der fixture and confirm it + * decodes via wc_SlhDsaKey_PrivateKeyDecode with correct auto-detection. + * These fixtures are RFC 9909 compliant (bare OCTET STRING, 4*n bytes) - + * this test would fail if the files drift to a non-compliant encoding + * (e.g. nested OCTET STRING, seed-only). */ +int test_wc_slhdsa_der_decode_files(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + !defined(NO_FILESYSTEM) +#ifdef WOLFSSL_SLHDSA_PARAM_128S + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake128s_key.der", SLHDSA_SHAKE128S), + TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_128F + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake128f_key.der", SLHDSA_SHAKE128F), + TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_192S + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake192s_key.der", SLHDSA_SHAKE192S), + TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_192F + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake192f_key.der", SLHDSA_SHAKE192F), + TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_256S + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake256s_key.der", SLHDSA_SHAKE256S), + TEST_SUCCESS); +#endif +#ifdef WOLFSSL_SLHDSA_PARAM_256F + ExpectIntEQ(slhdsa_decode_file_one( + "./certs/slhdsa/bench_slhdsa_shake256f_key.der", SLHDSA_SHAKE256F), + TEST_SUCCESS); +#endif +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_slhdsa.h b/tests/api/test_slhdsa.h index c0d909b7aaa..83e95c5cd12 100644 --- a/tests/api/test_slhdsa.h +++ b/tests/api/test_slhdsa.h @@ -33,6 +33,9 @@ int test_wc_slhdsa_sign_vfy(void); int test_wc_slhdsa_sign_hash(void); int test_wc_slhdsa_export_import(void); int test_wc_slhdsa_check_key(void); +int test_wc_slhdsa_der_roundtrip(void); +int test_wc_slhdsa_der_negative(void); +int test_wc_slhdsa_der_decode_files(void); #define TEST_SLHDSA_DECLS \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa), \ @@ -43,6 +46,9 @@ int test_wc_slhdsa_check_key(void); TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sign_vfy), \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sign_hash), \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_export_import), \ - TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_check_key) + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_check_key), \ + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_der_roundtrip), \ + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_der_negative), \ + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_der_decode_files) #endif /* WOLFCRYPT_TEST_SLHDSA_H */ diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 5d8e8efb898..9ffe48f638e 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -209,9 +209,6 @@ #if defined(HAVE_DILITHIUM) #include #endif -#if defined(HAVE_SPHINCS) - #include -#endif #ifdef WOLF_CRYPTO_CB #include @@ -945,13 +942,6 @@ static WC_INLINE void bench_append_memory_info(char* buffer, size_t size, BENCH_ML_DSA_65_SIGN | \ BENCH_ML_DSA_87_SIGN) -/* Post-Quantum Asymmetric algorithms. (Part 2) */ -#define BENCH_SPHINCS_FAST_LEVEL1_SIGN 0x00000001 -#define BENCH_SPHINCS_FAST_LEVEL3_SIGN 0x00000002 -#define BENCH_SPHINCS_FAST_LEVEL5_SIGN 0x00000004 -#define BENCH_SPHINCS_SMALL_LEVEL1_SIGN 0x00000008 -#define BENCH_SPHINCS_SMALL_LEVEL3_SIGN 0x00000010 -#define BENCH_SPHINCS_SMALL_LEVEL5_SIGN 0x00000020 /* Post-Quantum Stateful Hash-Based sig algorithms. */ #define BENCH_LMS_HSS 0x00000001 @@ -1026,8 +1016,6 @@ static word32 bench_kdf_algs = 0; static word32 bench_asym_algs = 0; /* Post-Quantum Asymmetric algorithms to benchmark. */ static word32 bench_pq_asym_algs = 0; -/* Post-Quantum Asymmetric algorithms to benchmark. (Part 2)*/ -static word32 bench_pq_asym_algs2 = 0; /* Other cryptographic algorithms to benchmark. */ static word32 bench_other_algs = 0; /* Post-Quantum Stateful Hash-Based sig algorithms to benchmark. */ @@ -1349,7 +1337,7 @@ static const bench_pq_hash_sig_alg bench_pq_hash_sig_opt[] = { #if !defined(WOLFSSL_BENCHMARK_ALL) && !defined(MAIN_NO_ARGS) #if defined(WOLFSSL_HAVE_MLKEM) || defined(HAVE_FALCON) || \ - defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS) + defined(HAVE_DILITHIUM) /* The post-quantum-specific mapping of command line option to bit values and * OQS name. */ typedef struct bench_pq_alg { @@ -1388,21 +1376,6 @@ static const bench_pq_alg bench_pq_asym_opt[] = { #endif { NULL, 0 } }; - -#if defined(HAVE_SPHINCS) -/* All recognized post-quantum asymmetric algorithm choosing command line - * options. (Part 2) */ -static const bench_pq_alg bench_pq_asym_opt2[] = { - { "-pq", 0xffffffff }, - { "-sphincs_fast_level1", BENCH_SPHINCS_FAST_LEVEL1_SIGN }, - { "-sphincs_fast_level3", BENCH_SPHINCS_FAST_LEVEL3_SIGN }, - { "-sphincs_fast_level5", BENCH_SPHINCS_FAST_LEVEL5_SIGN }, - { "-sphincs_small_level1", BENCH_SPHINCS_SMALL_LEVEL1_SIGN }, - { "-sphincs_small_level3", BENCH_SPHINCS_SMALL_LEVEL3_SIGN }, - { "-sphincs_small_level5", BENCH_SPHINCS_SMALL_LEVEL5_SIGN }, - { NULL, 0, } -}; -#endif /* HAVE_SPHINCS */ #endif #endif @@ -4586,20 +4559,6 @@ static void* benchmarks_do(void* args) bench_dilithiumKeySign(5); #endif #endif -#ifdef HAVE_SPHINCS - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL1_SIGN)) - bench_sphincsKeySign(1, FAST_VARIANT); - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL3_SIGN)) - bench_sphincsKeySign(3, FAST_VARIANT); - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL5_SIGN)) - bench_sphincsKeySign(5, FAST_VARIANT); - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL1_SIGN)) - bench_sphincsKeySign(1, SMALL_VARIANT); - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL3_SIGN)) - bench_sphincsKeySign(3, SMALL_VARIANT); - if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL5_SIGN)) - bench_sphincsKeySign(5, SMALL_VARIANT); -#endif exit: /* free benchmark buffers */ @@ -4625,7 +4584,6 @@ static void* benchmarks_do(void* args) (void)bench_asym_algs; (void)bench_other_algs; (void)bench_pq_asym_algs; - (void)bench_pq_asym_algs2; return NULL; } @@ -15825,165 +15783,6 @@ void bench_dilithiumKeySign(byte level) } #endif /* HAVE_DILITHIUM && !WC_NO_RNG */ -#ifdef HAVE_SPHINCS -void bench_sphincsKeySign(byte level, byte optim) -{ - int ret = 0; - sphincs_key key; - double start; - int i, count; - byte sig[SPHINCS_MAX_SIG_SIZE]; - byte msg[512]; - word32 x = 0; - const char**desc = bench_desc_words[lng_index]; - DECLARE_MULTI_VALUE_STATS_VARS() - - bench_stats_prepare(); - - ret = wc_sphincs_init(&key); - if (ret != 0) { - printf("wc_sphincs_init failed %d\n", ret); - return; - } - - ret = wc_sphincs_set_level_and_optim(&key, level, optim); - if (ret != 0) { - printf("wc_sphincs_set_level_and_optim() failed %d\n", ret); - } - - if (ret == 0) { - ret = -1; - if ((level == 1) && (optim == FAST_VARIANT)) { - ret = wc_sphincs_import_private_key(bench_sphincs_fast_level1_key, - sizeof_bench_sphincs_fast_level1_key, NULL, 0, &key); - } - else if ((level == 3) && (optim == FAST_VARIANT)) { - ret = wc_sphincs_import_private_key(bench_sphincs_fast_level3_key, - sizeof_bench_sphincs_fast_level3_key, NULL, 0, &key); - } - else if ((level == 5) && (optim == FAST_VARIANT)) { - ret = wc_sphincs_import_private_key(bench_sphincs_fast_level5_key, - sizeof_bench_sphincs_fast_level5_key, NULL, 0, &key); - } - else if ((level == 1) && (optim == SMALL_VARIANT)) { - ret = wc_sphincs_import_private_key( - bench_sphincs_small_level1_key, - sizeof_bench_sphincs_small_level1_key, NULL, 0, &key); - } - else if ((level == 3) && (optim == SMALL_VARIANT)) { - ret = wc_sphincs_import_private_key( - bench_sphincs_small_level3_key, - sizeof_bench_sphincs_small_level3_key, NULL, 0, &key); - } - else if ((level == 5) && (optim == SMALL_VARIANT)) { - ret = wc_sphincs_import_private_key( - bench_sphincs_small_level5_key, - sizeof_bench_sphincs_small_level5_key, NULL, 0, &key); - } - - if (ret != 0) { - printf("wc_sphincs_import_private_key failed %d\n", ret); - } - } - - /* make dummy msg */ - for (i = 0; i < (int)sizeof(msg); i++) { - msg[i] = (byte)i; - } - - bench_stats_start(&count, &start); - do { - for (i = 0; i < agreeTimes; i++) { - if (ret == 0) { - if ((level == 1) && (optim == FAST_VARIANT)) { - x = SPHINCS_FAST_LEVEL1_SIG_SIZE; - } - else if ((level == 3) && (optim == FAST_VARIANT)) { - x = SPHINCS_FAST_LEVEL3_SIG_SIZE; - } - else if ((level == 5) && (optim == FAST_VARIANT)) { - x = SPHINCS_FAST_LEVEL5_SIG_SIZE; - } - else if ((level == 1) && (optim == SMALL_VARIANT)) { - x = SPHINCS_SMALL_LEVEL1_SIG_SIZE; - } - else if ((level == 3) && (optim == SMALL_VARIANT)) { - x = SPHINCS_SMALL_LEVEL3_SIG_SIZE; - } - else if ((level == 5) && (optim == SMALL_VARIANT)) { - x = SPHINCS_SMALL_LEVEL5_SIG_SIZE; - } - - ret = wc_sphincs_sign_msg(msg, sizeof(msg), sig, &x, &key, GLOBAL_RNG); - if (ret != 0) { - printf("wc_sphincs_sign_msg failed\n"); - } - } - RECORD_MULTI_VALUE_STATS(); - } - count += i; - } while (bench_stats_check(start) -#ifdef MULTI_VALUE_STATISTICS - || runs < minimum_runs -#endif - ); - - if (ret == 0) { - if (optim == FAST_VARIANT) { - bench_stats_asym_finish("SPHINCS-FAST", level, desc[4], 0, count, - start, ret); - } - else { - bench_stats_asym_finish("SPHINCS-SMALL", level, desc[4], 0, count, - start, ret); - } - #ifdef MULTI_VALUE_STATISTICS - bench_multi_value_stats(max, min, sum, squareSum, runs); - #endif - } - - RESET_MULTI_VALUE_STATS_VARS(); - - bench_stats_start(&count, &start); - do { - for (i = 0; i < agreeTimes; i++) { - if (ret == 0) { - int verify = 0; - ret = wc_sphincs_verify_msg(sig, x, msg, sizeof(msg), &verify, - &key); - - if (ret != 0 || verify != 1) { - printf("wc_sphincs_verify_msg failed %d, verify %d\n", - ret, verify); - ret = -1; - } - } - RECORD_MULTI_VALUE_STATS(); - } - count += i; - } while (bench_stats_check(start) -#ifdef MULTI_VALUE_STATISTICS - || runs < minimum_runs -#endif - ); - - if (ret == 0) { - if (optim == FAST_VARIANT) { - bench_stats_asym_finish("SPHINCS-FAST", level, desc[5], 0, count, - start, ret); - } - else { - bench_stats_asym_finish("SPHINCS-SMALL", level, desc[5], 0, count, - start, ret); - } - #ifdef MULTI_VALUE_STATISTICS - bench_multi_value_stats(max, min, sum, squareSum, runs); - #endif - } - - wc_sphincs_free(&key); -} -#endif /* HAVE_SPHINCS */ #if defined(_WIN32) && !defined(INTIME_RTOS) @@ -16627,13 +16426,9 @@ static void Usage(void) for (i=0; bench_other_opt[i].str != NULL; i++) print_alg(bench_other_opt[i].str, &line); #if defined(WOLFSSL_HAVE_MLKEM) || defined(HAVE_FALCON) || \ - defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS) + defined(HAVE_DILITHIUM) for (i=0; bench_pq_asym_opt[i].str != NULL; i++) print_alg(bench_pq_asym_opt[i].str, &line); -#if defined(HAVE_SPHINCS) - for (i=0; bench_pq_asym_opt2[i].str != NULL; i++) - print_alg(bench_pq_asym_opt2[i].str, &line); -#endif /* HAVE_SPHINCS */ #endif #if defined(BENCH_PQ_STATEFUL_HBS) for (i=0; bench_pq_hash_sig_opt[i].str != NULL; i++) @@ -16932,7 +16727,7 @@ int wolfcrypt_benchmark_main(int argc, char** argv) } } #if defined(WOLFSSL_HAVE_MLKEM) || defined(HAVE_FALCON) || \ - defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS) + defined(HAVE_DILITHIUM) /* Known asymmetric post-quantum algorithms */ for (i=0; !optMatched && bench_pq_asym_opt[i].str != NULL; i++) { if (string_matches(argv[1], bench_pq_asym_opt[i].str)) { @@ -16941,25 +16736,6 @@ int wolfcrypt_benchmark_main(int argc, char** argv) optMatched = 1; } } - #ifdef HAVE_SPHINCS - /* Both bench_pq_asym_opt and bench_pq_asym_opt2 are looking for - * -pq, so we need to do a special case for -pq since optMatched - * was set to 1 just above. */ - if ((bench_pq_asym_opt[0].str != NULL) && - string_matches(argv[1], bench_pq_asym_opt[0].str)) - { - bench_pq_asym_algs2 |= bench_pq_asym_opt2[0].val; - bench_all = 0; - optMatched = 1; - } - for (i=1; !optMatched && bench_pq_asym_opt2[i].str != NULL; i++) { - if (string_matches(argv[1], bench_pq_asym_opt2[i].str)) { - bench_pq_asym_algs2 |= bench_pq_asym_opt2[i].val; - bench_all = 0; - optMatched = 1; - } - } - #endif #endif /* Other known cryptographic algorithms */ for (i=0; !optMatched && bench_other_opt[i].str != NULL; i++) { diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index dc97fe68379..a9406c3d334 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -136,7 +136,6 @@ void bench_ascon_hash(void); void bench_pbkdf2(void); void bench_falconKeySign(byte level); void bench_dilithiumKeySign(byte level); -void bench_sphincsKeySign(byte level, byte optim); void bench_stats_print(void); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 088eb47ea5b..7b53d5e522f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -191,7 +191,7 @@ ASN Options: * WOLFSSL_DILITHIUM_NO_SIGN: Disable Dilithium signing * WOLFSSL_DILITHIUM_NO_VERIFY: Disable Dilithium verify * HAVE_FALCON: Enable Falcon ASN support - * HAVE_SPHINCS: Enable SPHINCS+ ASN support + * WOLFSSL_HAVE_SLHDSA: Enable SLH-DSA ASN support * * Key Import/Export: * WC_ENABLE_ASYM_KEY_IMPORT: Enable asymmetric key import @@ -277,8 +277,8 @@ ASN Options: #if defined(HAVE_DILITHIUM) #include #endif -#if defined(HAVE_SPHINCS) - #include +#if defined(WOLFSSL_HAVE_SLHDSA) + #include #endif #ifdef WOLFSSL_QNX_CAAM @@ -4403,9 +4403,9 @@ static int EncodeName(EncodedName* name, const char* nameStr, byte nameTag, byte #endif #ifdef WOLFSSL_CERT_GEN static int SetValidity(byte* output, int daysValid); -static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, sphincs_key* sphincsKey); +static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey); #ifdef WOLFSSL_CERT_REQ -static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, sphincs_key* sphincsKey); +static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey); #endif #endif #endif @@ -4604,31 +4604,32 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32* inOutI static const byte sigMlDsa_Level5Oid[] = {96, 134, 72, 1, 101, 3, 4, 3, 19}; #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */ - static const byte sigSphincsFast_Level1Oid[] = - {43, 206, 15, 6, 7, 4}; - - /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */ - static const byte sigSphincsFast_Level3Oid[] = - {43, 206, 15, 6, 8, 3}; - - /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */ - static const byte sigSphincsFast_Level5Oid[] = - {43, 206, 15, 6, 9, 3}; - - /* Sphincs Small Level 1: 1 3 9999 6 7 10 */ - static const byte sigSphincsSmall_Level1Oid[] = - {43, 206, 15, 6, 7, 10}; - - /* Sphincs Small Level 3: 1 3 9999 6 8 7 */ - static const byte sigSphincsSmall_Level3Oid[] = - {43, 206, 15, 6, 8, 7}; - - /* Sphincs Small Level 5: 1 3 9999 6 9 7 */ - static const byte sigSphincsSmall_Level5Oid[] = - {43, 206, 15, 6, 9, 7}; -#endif /* HAVE_SPHINCS */ +#ifdef WOLFSSL_HAVE_SLHDSA + /* SLH-DSA-SHA2-128s: 2.16.840.1.101.3.4.3.20 */ + static const byte sigSlhDsa_Sha2_128sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 20}; + /* SLH-DSA-SHA2-128f: 2.16.840.1.101.3.4.3.21 */ + static const byte sigSlhDsa_Sha2_128fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 21}; + /* SLH-DSA-SHA2-192s: 2.16.840.1.101.3.4.3.22 */ + static const byte sigSlhDsa_Sha2_192sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 22}; + /* SLH-DSA-SHA2-192f: 2.16.840.1.101.3.4.3.23 */ + static const byte sigSlhDsa_Sha2_192fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 23}; + /* SLH-DSA-SHA2-256s: 2.16.840.1.101.3.4.3.24 */ + static const byte sigSlhDsa_Sha2_256sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 24}; + /* SLH-DSA-SHA2-256f: 2.16.840.1.101.3.4.3.25 */ + static const byte sigSlhDsa_Sha2_256fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 25}; + /* SLH-DSA-SHAKE-128s: 2.16.840.1.101.3.4.3.26 */ + static const byte sigSlhDsa_Shake_128sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 26}; + /* SLH-DSA-SHAKE-128f: 2.16.840.1.101.3.4.3.27 */ + static const byte sigSlhDsa_Shake_128fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 27}; + /* SLH-DSA-SHAKE-192s: 2.16.840.1.101.3.4.3.28 */ + static const byte sigSlhDsa_Shake_192sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 28}; + /* SLH-DSA-SHAKE-192f: 2.16.840.1.101.3.4.3.29 */ + static const byte sigSlhDsa_Shake_192fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 29}; + /* SLH-DSA-SHAKE-256s: 2.16.840.1.101.3.4.3.30 */ + static const byte sigSlhDsa_Shake_256sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 30}; + /* SLH-DSA-SHAKE-256f: 2.16.840.1.101.3.4.3.31 */ + static const byte sigSlhDsa_Shake_256fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 31}; +#endif /* WOLFSSL_HAVE_SLHDSA */ /* keyType */ #ifndef NO_DSA @@ -4692,31 +4693,32 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32* inOutI static const byte keyMlDsa_Level5Oid[] = {96, 134, 72, 1, 101, 3, 4, 3, 19}; #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */ - static const byte keySphincsFast_Level1Oid[] = - {43, 206, 15, 6, 7, 4}; - - /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */ - static const byte keySphincsFast_Level3Oid[] = - {43, 206, 15, 6, 8, 3}; - - /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */ - static const byte keySphincsFast_Level5Oid[] = - {43, 206, 15, 6, 9, 3}; - - /* Sphincs Small Level 1: 1 3 9999 6 7 10 */ - static const byte keySphincsSmall_Level1Oid[] = - {43, 206, 15, 6, 7, 10}; - - /* Sphincs Small Level 3: 1 3 9999 6 8 7 */ - static const byte keySphincsSmall_Level3Oid[] = - {43, 206, 15, 6, 8, 7}; - - /* Sphincs Small Level 5: 1 3 9999 6 9 7 */ - static const byte keySphincsSmall_Level5Oid[] = - {43, 206, 15, 6, 9, 7}; -#endif /* HAVE_SPHINCS */ +#ifdef WOLFSSL_HAVE_SLHDSA + /* SLH-DSA-SHA2-128s: 2.16.840.1.101.3.4.3.20 */ + static const byte keySlhDsa_Sha2_128sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 20}; + /* SLH-DSA-SHA2-128f: 2.16.840.1.101.3.4.3.21 */ + static const byte keySlhDsa_Sha2_128fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 21}; + /* SLH-DSA-SHA2-192s: 2.16.840.1.101.3.4.3.22 */ + static const byte keySlhDsa_Sha2_192sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 22}; + /* SLH-DSA-SHA2-192f: 2.16.840.1.101.3.4.3.23 */ + static const byte keySlhDsa_Sha2_192fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 23}; + /* SLH-DSA-SHA2-256s: 2.16.840.1.101.3.4.3.24 */ + static const byte keySlhDsa_Sha2_256sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 24}; + /* SLH-DSA-SHA2-256f: 2.16.840.1.101.3.4.3.25 */ + static const byte keySlhDsa_Sha2_256fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 25}; + /* SLH-DSA-SHAKE-128s: 2.16.840.1.101.3.4.3.26 */ + static const byte keySlhDsa_Shake_128sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 26}; + /* SLH-DSA-SHAKE-128f: 2.16.840.1.101.3.4.3.27 */ + static const byte keySlhDsa_Shake_128fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 27}; + /* SLH-DSA-SHAKE-192s: 2.16.840.1.101.3.4.3.28 */ + static const byte keySlhDsa_Shake_192sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 28}; + /* SLH-DSA-SHAKE-192f: 2.16.840.1.101.3.4.3.29 */ + static const byte keySlhDsa_Shake_192fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 29}; + /* SLH-DSA-SHAKE-256s: 2.16.840.1.101.3.4.3.30 */ + static const byte keySlhDsa_Shake_256sOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 30}; + /* SLH-DSA-SHAKE-256f: 2.16.840.1.101.3.4.3.31 */ + static const byte keySlhDsa_Shake_256fOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 31}; +#endif /* WOLFSSL_HAVE_SLHDSA */ /* curveType */ #ifdef HAVE_ECC @@ -5547,32 +5549,56 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) *oidSz = sizeof(sigMlDsa_Level5Oid); break; #endif /* HAVE_DILITHIUM */ - #ifdef HAVE_SPHINCS - case CTC_SPHINCS_FAST_LEVEL1: - oid = sigSphincsFast_Level1Oid; - *oidSz = sizeof(sigSphincsFast_Level1Oid); + #ifdef WOLFSSL_HAVE_SLHDSA + case CTC_SLH_DSA_SHA2_128S: + oid = sigSlhDsa_Sha2_128sOid; + *oidSz = sizeof(sigSlhDsa_Sha2_128sOid); + break; + case CTC_SLH_DSA_SHA2_128F: + oid = sigSlhDsa_Sha2_128fOid; + *oidSz = sizeof(sigSlhDsa_Sha2_128fOid); + break; + case CTC_SLH_DSA_SHA2_192S: + oid = sigSlhDsa_Sha2_192sOid; + *oidSz = sizeof(sigSlhDsa_Sha2_192sOid); + break; + case CTC_SLH_DSA_SHA2_192F: + oid = sigSlhDsa_Sha2_192fOid; + *oidSz = sizeof(sigSlhDsa_Sha2_192fOid); + break; + case CTC_SLH_DSA_SHA2_256S: + oid = sigSlhDsa_Sha2_256sOid; + *oidSz = sizeof(sigSlhDsa_Sha2_256sOid); break; - case CTC_SPHINCS_FAST_LEVEL3: - oid = sigSphincsFast_Level3Oid; - *oidSz = sizeof(sigSphincsFast_Level3Oid); + case CTC_SLH_DSA_SHA2_256F: + oid = sigSlhDsa_Sha2_256fOid; + *oidSz = sizeof(sigSlhDsa_Sha2_256fOid); break; - case CTC_SPHINCS_FAST_LEVEL5: - oid = sigSphincsFast_Level5Oid; - *oidSz = sizeof(sigSphincsFast_Level5Oid); + case CTC_SLH_DSA_SHAKE_128S: + oid = sigSlhDsa_Shake_128sOid; + *oidSz = sizeof(sigSlhDsa_Shake_128sOid); break; - case CTC_SPHINCS_SMALL_LEVEL1: - oid = sigSphincsSmall_Level1Oid; - *oidSz = sizeof(sigSphincsSmall_Level1Oid); + case CTC_SLH_DSA_SHAKE_128F: + oid = sigSlhDsa_Shake_128fOid; + *oidSz = sizeof(sigSlhDsa_Shake_128fOid); break; - case CTC_SPHINCS_SMALL_LEVEL3: - oid = sigSphincsSmall_Level3Oid; - *oidSz = sizeof(sigSphincsSmall_Level3Oid); + case CTC_SLH_DSA_SHAKE_192S: + oid = sigSlhDsa_Shake_192sOid; + *oidSz = sizeof(sigSlhDsa_Shake_192sOid); break; - case CTC_SPHINCS_SMALL_LEVEL5: - oid = sigSphincsSmall_Level5Oid; - *oidSz = sizeof(sigSphincsSmall_Level5Oid); + case CTC_SLH_DSA_SHAKE_192F: + oid = sigSlhDsa_Shake_192fOid; + *oidSz = sizeof(sigSlhDsa_Shake_192fOid); break; - #endif /* HAVE_SPHINCS */ + case CTC_SLH_DSA_SHAKE_256S: + oid = sigSlhDsa_Shake_256sOid; + *oidSz = sizeof(sigSlhDsa_Shake_256sOid); + break; + case CTC_SLH_DSA_SHAKE_256F: + oid = sigSlhDsa_Shake_256fOid; + *oidSz = sizeof(sigSlhDsa_Shake_256fOid); + break; + #endif /* WOLFSSL_HAVE_SLHDSA */ default: break; } @@ -5672,32 +5698,56 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) *oidSz = sizeof(keyMlDsa_Level5Oid); break; #endif /* HAVE_DILITHIUM */ - #ifdef HAVE_SPHINCS - case SPHINCS_FAST_LEVEL1k: - oid = keySphincsFast_Level1Oid; - *oidSz = sizeof(keySphincsFast_Level1Oid); + #ifdef WOLFSSL_HAVE_SLHDSA + case SLH_DSA_SHA2_128Sk: + oid = keySlhDsa_Sha2_128sOid; + *oidSz = sizeof(keySlhDsa_Sha2_128sOid); + break; + case SLH_DSA_SHA2_128Fk: + oid = keySlhDsa_Sha2_128fOid; + *oidSz = sizeof(keySlhDsa_Sha2_128fOid); + break; + case SLH_DSA_SHA2_192Sk: + oid = keySlhDsa_Sha2_192sOid; + *oidSz = sizeof(keySlhDsa_Sha2_192sOid); + break; + case SLH_DSA_SHA2_192Fk: + oid = keySlhDsa_Sha2_192fOid; + *oidSz = sizeof(keySlhDsa_Sha2_192fOid); + break; + case SLH_DSA_SHA2_256Sk: + oid = keySlhDsa_Sha2_256sOid; + *oidSz = sizeof(keySlhDsa_Sha2_256sOid); + break; + case SLH_DSA_SHA2_256Fk: + oid = keySlhDsa_Sha2_256fOid; + *oidSz = sizeof(keySlhDsa_Sha2_256fOid); break; - case SPHINCS_FAST_LEVEL3k: - oid = keySphincsFast_Level3Oid; - *oidSz = sizeof(keySphincsFast_Level3Oid); + case SLH_DSA_SHAKE_128Sk: + oid = keySlhDsa_Shake_128sOid; + *oidSz = sizeof(keySlhDsa_Shake_128sOid); break; - case SPHINCS_FAST_LEVEL5k: - oid = keySphincsFast_Level5Oid; - *oidSz = sizeof(keySphincsFast_Level5Oid); + case SLH_DSA_SHAKE_128Fk: + oid = keySlhDsa_Shake_128fOid; + *oidSz = sizeof(keySlhDsa_Shake_128fOid); break; - case SPHINCS_SMALL_LEVEL1k: - oid = keySphincsSmall_Level1Oid; - *oidSz = sizeof(keySphincsSmall_Level1Oid); + case SLH_DSA_SHAKE_192Sk: + oid = keySlhDsa_Shake_192sOid; + *oidSz = sizeof(keySlhDsa_Shake_192sOid); break; - case SPHINCS_SMALL_LEVEL3k: - oid = keySphincsSmall_Level3Oid; - *oidSz = sizeof(keySphincsSmall_Level3Oid); + case SLH_DSA_SHAKE_192Fk: + oid = keySlhDsa_Shake_192fOid; + *oidSz = sizeof(keySlhDsa_Shake_192fOid); break; - case SPHINCS_SMALL_LEVEL5k: - oid = keySphincsSmall_Level5Oid; - *oidSz = sizeof(keySphincsSmall_Level5Oid); + case SLH_DSA_SHAKE_256Sk: + oid = keySlhDsa_Shake_256sOid; + *oidSz = sizeof(keySlhDsa_Shake_256sOid); break; - #endif /* HAVE_SPHINCS */ + case SLH_DSA_SHAKE_256Fk: + oid = keySlhDsa_Shake_256fOid; + *oidSz = sizeof(keySlhDsa_Shake_256fOid); + break; + #endif /* WOLFSSL_HAVE_SLHDSA */ default: break; } @@ -7244,7 +7294,7 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid, word32 checkOidSz; #endif /* NO_VERIFY_OID */ #ifdef WOLFSSL_OLD_OID_SUM -#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI) +#if defined(WOLFSSL_FPKI) word32 found_collision = 0; #endif #endif @@ -7257,24 +7307,6 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid, actualOidSz = (word32)length; #endif /* NO_VERIFY_OID */ -#ifdef WOLFSSL_OLD_OID_SUM -#if defined(HAVE_SPHINCS) - /* Since we are summing it up, there could be collisions...and indeed there - * are: SPHINCS_FAST_LEVEL1 and SPHINCS_FAST_LEVEL3. - * - * We will look for the special case of SPHINCS_FAST_LEVEL3 and set *oid to - * 283 instead of 281; 282 is taken. - * - * These hacks will hopefully disappear when new standardized OIDs appear. - */ - if (idx + (word32)sizeof(sigSphincsFast_Level3Oid) < (word32)length && - XMEMCMP(&input[idx], sigSphincsFast_Level3Oid, - sizeof(sigSphincsFast_Level3Oid)) == 0) { - found_collision = SPHINCS_FAST_LEVEL3k; - } -#endif /* HAVE_SPHINCS */ -#endif - *oid = wc_oid_sum(actualOid, (int)actualOidSz); idx += actualOidSz; @@ -7288,11 +7320,11 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid, } #endif -#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI) +#if defined(WOLFSSL_FPKI) if (found_collision) { *oid = found_collision; } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_FPKI */ #endif /* Return the index after the OID data. */ @@ -8577,7 +8609,7 @@ int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx, word32 sz, break; #endif /* DSAk not supported. */ - /* Falcon, Dilithium and Sphincs not supported. */ + /* Falcon, Dilithium and SLH-DSA not supported. */ /* Ignore OID lookup failures. */ default: break; @@ -9109,63 +9141,67 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, } else #endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_VERIFY_ONLY */ - #if defined(HAVE_SPHINCS) - if ((ks == SPHINCS_FAST_LEVEL1k) || - (ks == SPHINCS_FAST_LEVEL3k) || - (ks == SPHINCS_FAST_LEVEL5k) || - (ks == SPHINCS_SMALL_LEVEL1k) || - (ks == SPHINCS_SMALL_LEVEL3k) || - (ks == SPHINCS_SMALL_LEVEL5k)) { - WC_DECLARE_VAR(key_pair, sphincs_key, 1, 0); +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) + if ((ks == SLH_DSA_SHAKE_128Fk) || + (ks == SLH_DSA_SHAKE_192Fk) || + (ks == SLH_DSA_SHAKE_256Fk) || + (ks == SLH_DSA_SHAKE_128Sk) || + (ks == SLH_DSA_SHAKE_192Sk) || + (ks == SLH_DSA_SHAKE_256Sk)) { + WC_DECLARE_VAR(key_pair, SlhDsaKey, 1, 0); word32 keyIdx = 0; + int slhDsaParam = -1; - WC_ALLOC_VAR_EX(key_pair, sphincs_key, 1, NULL, DYNAMIC_TYPE_SPHINCS, + WC_ALLOC_VAR_EX(key_pair, SlhDsaKey, 1, NULL, DYNAMIC_TYPE_SLHDSA, return MEMORY_E); - ret = wc_sphincs_init(key_pair); - if (ret < 0) { - WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SPHINCS); - return ret; - } - if (ks == SPHINCS_FAST_LEVEL1k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 1, FAST_VARIANT); + if (ks == SLH_DSA_SHAKE_128Fk) { + slhDsaParam = SLHDSA_SHAKE128F; + } + else if (ks == SLH_DSA_SHAKE_192Fk) { + slhDsaParam = SLHDSA_SHAKE192F; } - else if (ks == SPHINCS_FAST_LEVEL3k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 3, FAST_VARIANT); + else if (ks == SLH_DSA_SHAKE_256Fk) { + slhDsaParam = SLHDSA_SHAKE256F; } - else if (ks == SPHINCS_FAST_LEVEL5k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 5, FAST_VARIANT); + else if (ks == SLH_DSA_SHAKE_128Sk) { + slhDsaParam = SLHDSA_SHAKE128S; } - else if (ks == SPHINCS_SMALL_LEVEL1k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 1, SMALL_VARIANT); + else if (ks == SLH_DSA_SHAKE_192Sk) { + slhDsaParam = SLHDSA_SHAKE192S; } - else if (ks == SPHINCS_SMALL_LEVEL3k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 3, SMALL_VARIANT); + else if (ks == SLH_DSA_SHAKE_256Sk) { + slhDsaParam = SLHDSA_SHAKE256S; } - else if (ks == SPHINCS_SMALL_LEVEL5k) { - ret = wc_sphincs_set_level_and_optim(key_pair, 5, SMALL_VARIANT); + + if (slhDsaParam < 0) { + WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SLHDSA); + return NOT_COMPILED_IN; } + ret = wc_SlhDsaKey_Init(key_pair, (enum SlhDsaParam)slhDsaParam, + NULL, INVALID_DEVID); if (ret < 0) { - WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SPHINCS); + WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SLHDSA); return ret; } - if ((ret = wc_Sphincs_PrivateKeyDecode(privKey, &keyIdx, key_pair, + + if ((ret = wc_SlhDsaKey_PrivateKeyDecode(privKey, &keyIdx, key_pair, privKeySz)) == 0) { - WOLFSSL_MSG("Checking Sphincs key pair"); + WOLFSSL_MSG("Checking SLH-DSA key pair"); keyIdx = 0; - if ((ret = wc_sphincs_import_public(pubKey, pubKeySz, - key_pair)) == 0) { + if ((ret = wc_SlhDsaKey_ImportPublic(key_pair, pubKey, + pubKeySz)) == 0) { /* Public and private extracted successfully. Sanity check. */ - if ((ret = wc_sphincs_check_key(key_pair)) == 0) + if ((ret = wc_SlhDsaKey_CheckKey(key_pair)) == 0) ret = 1; } } - wc_sphincs_free(key_pair); - WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SPHINCS); + wc_SlhDsaKey_Free(key_pair); + WC_FREE_VAR_EX(key_pair, NULL, DYNAMIC_TYPE_SLHDSA); } else - #endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA && !WOLFSSL_SLHDSA_VERIFY_ONLY */ { ret = 0; } @@ -9609,83 +9645,73 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, XFREE(dilithium, heap, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_VERIFY_ONLY */ -#if defined(HAVE_SPHINCS) +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) if (*algoID == 0) { - sphincs_key *sphincs = (sphincs_key *)XMALLOC(sizeof(*sphincs), + enum SlhDsaParam placeholder; + SlhDsaKey *slhDsa = (SlhDsaKey *)XMALLOC(sizeof(*slhDsa), heap, DYNAMIC_TYPE_TMP_BUFFER); - if (sphincs == NULL) + if (slhDsa == NULL) return MEMORY_E; - if (wc_sphincs_init(sphincs) == 0) { + /* wc_SlhDsaKey_PrivateKeyDecode auto-detects the parameter set from + * the OID in the DER encoding, so a single call handles all six + * SHAKE variants. SHA2 variants are not supported by the native + * implementation. The initial parameter is only a placeholder; it is + * overwritten by the decoder. Pick whichever variant is compiled in + * so wc_SlhDsaKey_Init does not fail with NOT_COMPILED_IN when a + * specific variant (like 128F) is disabled. */ + #if defined(WOLFSSL_SLHDSA_PARAM_128F) + placeholder = SLHDSA_SHAKE128F; + #elif defined(WOLFSSL_SLHDSA_PARAM_128S) + placeholder = SLHDSA_SHAKE128S; + #elif defined(WOLFSSL_SLHDSA_PARAM_192F) + placeholder = SLHDSA_SHAKE192F; + #elif defined(WOLFSSL_SLHDSA_PARAM_192S) + placeholder = SLHDSA_SHAKE192S; + #elif defined(WOLFSSL_SLHDSA_PARAM_256F) + placeholder = SLHDSA_SHAKE256F; + #else + placeholder = SLHDSA_SHAKE256S; + #endif + if (wc_SlhDsaKey_Init(slhDsa, placeholder, NULL, INVALID_DEVID) == 0) { tmpIdx = 0; - if (wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, - keySz) == 0) { - *algoID = SPHINCS_FAST_LEVEL1k; - } - else { - WOLFSSL_MSG("Not Sphincs-fast Level 1 DER key"); - } - } - else if (wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, - keySz) == 0) { - *algoID = SPHINCS_FAST_LEVEL3k; - } - else { - WOLFSSL_MSG("Not Sphincs-fast Level 3 DER key"); - } - } - else if (wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, + if (wc_SlhDsaKey_PrivateKeyDecode(key, &tmpIdx, slhDsa, keySz) == 0) { - *algoID = SPHINCS_FAST_LEVEL5k; - } - else { - WOLFSSL_MSG("Not Sphincs-fast Level 5 DER key"); - } - } - else if (wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, - keySz) == 0) { - *algoID = SPHINCS_SMALL_LEVEL1k; - } - else { - WOLFSSL_MSG("Not Sphincs-small Level 1 DER key"); - } - } - else if (wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, - keySz) == 0) { - *algoID = SPHINCS_SMALL_LEVEL3k; - } - else { - WOLFSSL_MSG("Not Sphincs-small Level 3 DER key"); - } - } - else if (wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT) - == 0) { - if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs, - keySz) == 0) { - *algoID = SPHINCS_SMALL_LEVEL5k; - } - else { - WOLFSSL_MSG("Not Sphincs-small Level 5 DER key"); + switch (slhDsa->params->param) { + case SLHDSA_SHAKE128S: + *algoID = SLH_DSA_SHAKE_128Sk; + break; + case SLHDSA_SHAKE128F: + *algoID = SLH_DSA_SHAKE_128Fk; + break; + case SLHDSA_SHAKE192S: + *algoID = SLH_DSA_SHAKE_192Sk; + break; + case SLHDSA_SHAKE192F: + *algoID = SLH_DSA_SHAKE_192Fk; + break; + case SLHDSA_SHAKE256S: + *algoID = SLH_DSA_SHAKE_256Sk; + break; + case SLHDSA_SHAKE256F: + *algoID = SLH_DSA_SHAKE_256Fk; + break; + default: + WOLFSSL_MSG("Unexpected SLH-DSA parameter set"); + break; } } else { - WOLFSSL_MSG("GetKeyOID sphincs initialization failed"); + WOLFSSL_MSG("Not an SLH-DSA DER key"); } - wc_sphincs_free(sphincs); + wc_SlhDsaKey_Free(slhDsa); } - XFREE(sphincs, heap, DYNAMIC_TYPE_TMP_BUFFER); + else { + WOLFSSL_MSG("GetKeyOID SLH-DSA initialization failed"); + } + XFREE(slhDsa, heap, DYNAMIC_TYPE_TMP_BUFFER); } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA && !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* if flag is not set then this is not a key that we understand. */ if (*algoID == 0) { @@ -12148,7 +12174,7 @@ void wc_FreeDecodedCert(DecodedCert* cert) } #if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_FALCON) || \ - defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS) + defined(HAVE_DILITHIUM) || defined(WOLFSSL_HAVE_SLHDSA) /* Store the key data under the BIT_STRING in dynamically allocated data. * * @param [in, out] cert Certificate object. @@ -12447,7 +12473,7 @@ int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve) #ifdef WOLFSSL_ASN_TEMPLATE #if defined(WC_ENABLE_ASYM_KEY_EXPORT) || defined(WC_ENABLE_ASYM_KEY_IMPORT) /* ASN.1 template for the SubjectPublicKeyInfo of a general asymmetric key. - * Used with Ed448/Ed25519, Curve448/Curve25519, SPHINCS+, falcon, dilithium, + * Used with Ed448/Ed25519, Curve448/Curve25519, SLH-DSA, falcon, dilithium, * etc. * * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo @@ -13052,32 +13078,23 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx, ret = StoreKey(cert, source, &srcIdx, maxIdx); break; #endif /* HAVE_DILITHIUM */ - #ifdef HAVE_SPHINCS - case SPHINCS_FAST_LEVEL1k: - cert->pkCurveOID = SPHINCS_FAST_LEVEL1k; - ret = StoreKey(cert, source, &srcIdx, maxIdx); - break; - case SPHINCS_FAST_LEVEL3k: - cert->pkCurveOID = SPHINCS_FAST_LEVEL3k; - ret = StoreKey(cert, source, &srcIdx, maxIdx); - break; - case SPHINCS_FAST_LEVEL5k: - cert->pkCurveOID = SPHINCS_FAST_LEVEL5k; - ret = StoreKey(cert, source, &srcIdx, maxIdx); - break; - case SPHINCS_SMALL_LEVEL1k: - cert->pkCurveOID = SPHINCS_SMALL_LEVEL1k; - ret = StoreKey(cert, source, &srcIdx, maxIdx); - break; - case SPHINCS_SMALL_LEVEL3k: - cert->pkCurveOID = SPHINCS_SMALL_LEVEL3k; - ret = StoreKey(cert, source, &srcIdx, maxIdx); - break; - case SPHINCS_SMALL_LEVEL5k: - cert->pkCurveOID = SPHINCS_SMALL_LEVEL5k; + #ifdef WOLFSSL_HAVE_SLHDSA + case SLH_DSA_SHAKE_128Fk: + case SLH_DSA_SHAKE_192Fk: + case SLH_DSA_SHAKE_256Fk: + case SLH_DSA_SHAKE_128Sk: + case SLH_DSA_SHAKE_192Sk: + case SLH_DSA_SHAKE_256Sk: + case SLH_DSA_SHA2_128Fk: + case SLH_DSA_SHA2_192Fk: + case SLH_DSA_SHA2_256Fk: + case SLH_DSA_SHA2_128Sk: + case SLH_DSA_SHA2_192Sk: + case SLH_DSA_SHA2_256Sk: + cert->pkCurveOID = cert->keyOID; ret = StoreKey(cert, source, &srcIdx, maxIdx); break; - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ #ifndef NO_DSA case DSAk: cert->publicKey = source + pubIdx; @@ -15541,13 +15558,19 @@ static WC_INLINE int IsSigAlgoECC(word32 algoOID) || (algoOID == ML_DSA_LEVEL3k) || (algoOID == ML_DSA_LEVEL5k) #endif - #ifdef HAVE_SPHINCS - || (algoOID == SPHINCS_FAST_LEVEL1k) - || (algoOID == SPHINCS_FAST_LEVEL3k) - || (algoOID == SPHINCS_FAST_LEVEL5k) - || (algoOID == SPHINCS_SMALL_LEVEL1k) - || (algoOID == SPHINCS_SMALL_LEVEL3k) - || (algoOID == SPHINCS_SMALL_LEVEL5k) + #ifdef WOLFSSL_HAVE_SLHDSA + || (algoOID == SLH_DSA_SHAKE_128Fk) + || (algoOID == SLH_DSA_SHAKE_192Fk) + || (algoOID == SLH_DSA_SHAKE_256Fk) + || (algoOID == SLH_DSA_SHAKE_128Sk) + || (algoOID == SLH_DSA_SHAKE_192Sk) + || (algoOID == SLH_DSA_SHAKE_256Sk) + || (algoOID == SLH_DSA_SHA2_128Fk) + || (algoOID == SLH_DSA_SHA2_192Fk) + || (algoOID == SLH_DSA_SHA2_256Fk) + || (algoOID == SLH_DSA_SHA2_128Sk) + || (algoOID == SLH_DSA_SHA2_192Sk) + || (algoOID == SLH_DSA_SHA2_256Sk) #endif ); } @@ -15882,20 +15905,26 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) #endif break; #endif /* HAVE_DILITHIUM */ - #if defined(HAVE_SPHINCS) - case SPHINCS_FAST_LEVEL1k: - case SPHINCS_FAST_LEVEL3k: - case SPHINCS_FAST_LEVEL5k: - case SPHINCS_SMALL_LEVEL1k: - case SPHINCS_SMALL_LEVEL3k: - case SPHINCS_SMALL_LEVEL5k: - wc_sphincs_free(sigCtx->key.sphincs); + #if defined(WOLFSSL_HAVE_SLHDSA) + case SLH_DSA_SHAKE_128Fk: + case SLH_DSA_SHAKE_192Fk: + case SLH_DSA_SHAKE_256Fk: + case SLH_DSA_SHAKE_128Sk: + case SLH_DSA_SHAKE_192Sk: + case SLH_DSA_SHAKE_256Sk: + case SLH_DSA_SHA2_128Fk: + case SLH_DSA_SHA2_192Fk: + case SLH_DSA_SHA2_256Fk: + case SLH_DSA_SHA2_128Sk: + case SLH_DSA_SHA2_192Sk: + case SLH_DSA_SHA2_256Sk: + wc_SlhDsaKey_Free(sigCtx->key.slhdsa); #ifndef WOLFSSL_NO_MALLOC - XFREE(sigCtx->key.sphincs, sigCtx->heap, DYNAMIC_TYPE_SPHINCS); - sigCtx->key.sphincs = NULL; + XFREE(sigCtx->key.slhdsa, sigCtx->heap, DYNAMIC_TYPE_SLHDSA); + sigCtx->key.slhdsa = NULL; #endif break; - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ default: break; } /* switch (keyOID) */ @@ -16078,13 +16107,19 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, /* Hashes done in signing operation. */ break; #endif - #ifdef HAVE_SPHINCS - case CTC_SPHINCS_FAST_LEVEL1: - case CTC_SPHINCS_FAST_LEVEL3: - case CTC_SPHINCS_FAST_LEVEL5: - case CTC_SPHINCS_SMALL_LEVEL1: - case CTC_SPHINCS_SMALL_LEVEL3: - case CTC_SPHINCS_SMALL_LEVEL5: + #ifdef WOLFSSL_HAVE_SLHDSA + case CTC_SLH_DSA_SHA2_128S: + case CTC_SLH_DSA_SHA2_128F: + case CTC_SLH_DSA_SHA2_192S: + case CTC_SLH_DSA_SHA2_192F: + case CTC_SLH_DSA_SHA2_256S: + case CTC_SLH_DSA_SHA2_256F: + case CTC_SLH_DSA_SHAKE_128S: + case CTC_SLH_DSA_SHAKE_128F: + case CTC_SLH_DSA_SHAKE_192S: + case CTC_SLH_DSA_SHAKE_192F: + case CTC_SLH_DSA_SHAKE_256S: + case CTC_SLH_DSA_SHAKE_256F: /* Hashes done in signing operation. */ break; #endif @@ -16259,19 +16294,31 @@ static int SigOidMatchesKeyOid(word32 sigOID, word32 keyOID) case ML_DSA_LEVEL5k: return (sigOID == CTC_ML_DSA_LEVEL5); #endif - #if defined(HAVE_SPHINCS) - case SPHINCS_FAST_LEVEL1k: - return (sigOID == CTC_SPHINCS_FAST_LEVEL1); - case SPHINCS_FAST_LEVEL3k: - return (sigOID == CTC_SPHINCS_FAST_LEVEL3); - case SPHINCS_FAST_LEVEL5k: - return (sigOID == CTC_SPHINCS_FAST_LEVEL5); - case SPHINCS_SMALL_LEVEL1k: - return (sigOID == CTC_SPHINCS_SMALL_LEVEL1); - case SPHINCS_SMALL_LEVEL3k: - return (sigOID == CTC_SPHINCS_SMALL_LEVEL3); - case SPHINCS_SMALL_LEVEL5k: - return (sigOID == CTC_SPHINCS_SMALL_LEVEL5); + #if defined(WOLFSSL_HAVE_SLHDSA) + case SLH_DSA_SHAKE_128Fk: + return (sigOID == CTC_SLH_DSA_SHAKE_128F); + case SLH_DSA_SHAKE_192Fk: + return (sigOID == CTC_SLH_DSA_SHAKE_192F); + case SLH_DSA_SHAKE_256Fk: + return (sigOID == CTC_SLH_DSA_SHAKE_256F); + case SLH_DSA_SHAKE_128Sk: + return (sigOID == CTC_SLH_DSA_SHAKE_128S); + case SLH_DSA_SHAKE_192Sk: + return (sigOID == CTC_SLH_DSA_SHAKE_192S); + case SLH_DSA_SHAKE_256Sk: + return (sigOID == CTC_SLH_DSA_SHAKE_256S); + case SLH_DSA_SHA2_128Fk: + return (sigOID == CTC_SLH_DSA_SHA2_128F); + case SLH_DSA_SHA2_192Fk: + return (sigOID == CTC_SLH_DSA_SHA2_192F); + case SLH_DSA_SHA2_256Fk: + return (sigOID == CTC_SLH_DSA_SHA2_256F); + case SLH_DSA_SHA2_128Sk: + return (sigOID == CTC_SLH_DSA_SHA2_128S); + case SLH_DSA_SHA2_192Sk: + return (sigOID == CTC_SLH_DSA_SHA2_192S); + case SLH_DSA_SHA2_256Sk: + return (sigOID == CTC_SLH_DSA_SHA2_256S); #endif } @@ -16728,177 +16775,71 @@ int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* HAVE_DILITHIUM */ - #if defined(HAVE_SPHINCS) - case SPHINCS_FAST_LEVEL1k: + #if defined(WOLFSSL_HAVE_SLHDSA) + case SLH_DSA_SHA2_128Fk: + case SLH_DSA_SHA2_192Fk: + case SLH_DSA_SHA2_256Fk: + case SLH_DSA_SHA2_128Sk: + case SLH_DSA_SHA2_192Sk: + case SLH_DSA_SHA2_256Sk: + /* SHA2-SLH-DSA OIDs are recognized by the ASN layer but + * not implemented by the native backend. Return a + * specific error instead of falling through to the + * generic unknown-OID path so callers can distinguish + * "unsupported variant" from "malformed DER". */ + WOLFSSL_MSG("SHA2-SLH-DSA not supported by native backend"); + ERROR_OUT(NOT_COMPILED_IN, exit_cs); + case SLH_DSA_SHAKE_128Fk: + case SLH_DSA_SHAKE_192Fk: + case SLH_DSA_SHAKE_256Fk: + case SLH_DSA_SHAKE_128Sk: + case SLH_DSA_SHAKE_192Sk: + case SLH_DSA_SHAKE_256Sk: { word32 idx = 0; + int slhDsaParam = -1; sigCtx->verify = 0; - #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), - sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { - ERROR_OUT(MEMORY_E, exit_cs); - } - #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 1, FAST_VARIANT)) - < 0) { - goto exit_cs; - } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1"); - goto exit_cs; - } - break; - } - case SPHINCS_FAST_LEVEL3k: - { - word32 idx = 0; - sigCtx->verify = 0; - #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), - sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { - ERROR_OUT(MEMORY_E, exit_cs); - } - #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 3, FAST_VARIANT)) - < 0) { - goto exit_cs; - } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3"); - goto exit_cs; - } - break; - } - case SPHINCS_FAST_LEVEL5k: - { - word32 idx = 0; - sigCtx->verify = 0; - #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), - sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { - ERROR_OUT(MEMORY_E, exit_cs); - } - #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 5, FAST_VARIANT)) - < 0) { - goto exit_cs; - } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5"); - goto exit_cs; - } - break; - } - case SPHINCS_SMALL_LEVEL1k: - { - word32 idx = 0; - sigCtx->verify = 0; - #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), - sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { - ERROR_OUT(MEMORY_E, exit_cs); - } - #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 1, SMALL_VARIANT)) - < 0) { - goto exit_cs; - } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1"); - goto exit_cs; - } - break; - } - case SPHINCS_SMALL_LEVEL3k: - { - word32 idx = 0; - sigCtx->verify = 0; - #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), - sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { - ERROR_OUT(MEMORY_E, exit_cs); - } - #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 3, SMALL_VARIANT)) - < 0) { - goto exit_cs; + if (keyOID == SLH_DSA_SHAKE_128Fk) + slhDsaParam = SLHDSA_SHAKE128F; + else if (keyOID == SLH_DSA_SHAKE_192Fk) + slhDsaParam = SLHDSA_SHAKE192F; + else if (keyOID == SLH_DSA_SHAKE_256Fk) + slhDsaParam = SLHDSA_SHAKE256F; + else if (keyOID == SLH_DSA_SHAKE_128Sk) + slhDsaParam = SLHDSA_SHAKE128S; + else if (keyOID == SLH_DSA_SHAKE_192Sk) + slhDsaParam = SLHDSA_SHAKE192S; + else if (keyOID == SLH_DSA_SHAKE_256Sk) + slhDsaParam = SLHDSA_SHAKE256S; + + if (slhDsaParam < 0) { + ERROR_OUT(ASN_UNKNOWN_OID_E, exit_cs); } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3"); - goto exit_cs; - } - break; - } - case SPHINCS_SMALL_LEVEL5k: - { - word32 idx = 0; - sigCtx->verify = 0; + #ifndef WOLFSSL_NO_MALLOC - sigCtx->key.sphincs = - (sphincs_key*)XMALLOC(sizeof(sphincs_key), + sigCtx->key.slhdsa = + (SlhDsaKey*)XMALLOC(sizeof(SlhDsaKey), sigCtx->heap, - DYNAMIC_TYPE_SPHINCS); - if (sigCtx->key.sphincs == NULL) { + DYNAMIC_TYPE_SLHDSA); + if (sigCtx->key.slhdsa == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } #endif - if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) { - goto exit_cs; - } - if ((ret = wc_sphincs_set_level_and_optim( - sigCtx->key.sphincs, 5, SMALL_VARIANT)) - < 0) { + if ((ret = wc_SlhDsaKey_Init(sigCtx->key.slhdsa, + (enum SlhDsaParam)slhDsaParam, + NULL, INVALID_DEVID)) < 0) { + WOLFSSL_MSG("ASN Key init err: SLH-DSA"); goto exit_cs; } - if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx, - sigCtx->key.sphincs, keySz)) < 0) { - WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5"); + if ((ret = wc_SlhDsaKey_PublicKeyDecode(key, &idx, + sigCtx->key.slhdsa, keySz)) < 0) { + WOLFSSL_MSG("ASN Key import err: SLH-DSA"); goto exit_cs; } break; } - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ default: WOLFSSL_MSG("Verify Key type unknown"); ret = ASN_UNKNOWN_OID_E; @@ -17086,20 +17027,23 @@ int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* HAVE_DILITHIUM */ - #if defined(HAVE_SPHINCS) - case SPHINCS_FAST_LEVEL1k: - case SPHINCS_FAST_LEVEL3k: - case SPHINCS_FAST_LEVEL5k: - case SPHINCS_SMALL_LEVEL1k: - case SPHINCS_SMALL_LEVEL3k: - case SPHINCS_SMALL_LEVEL5k: + #if defined(WOLFSSL_HAVE_SLHDSA) + case SLH_DSA_SHAKE_128Fk: + case SLH_DSA_SHAKE_192Fk: + case SLH_DSA_SHAKE_256Fk: + case SLH_DSA_SHAKE_128Sk: + case SLH_DSA_SHAKE_192Sk: + case SLH_DSA_SHAKE_256Sk: { - ret = wc_sphincs_verify_msg(sig, sigSz, buf, bufSz, - &sigCtx->verify, - sigCtx->key.sphincs); + ret = wc_SlhDsaKey_Verify(sigCtx->key.slhdsa, + NULL, 0, buf, bufSz, + sig, sigSz); + if (ret == 0) { + sigCtx->verify = 1; + } break; } - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ default: break; } /* switch (keyOID) */ @@ -17296,74 +17240,24 @@ int ConfirmSignature(SignatureCtx* sigCtx, } break; #endif /* HAVE_DILITHIUM */ - #ifdef HAVE_SPHINCS - case SPHINCS_FAST_LEVEL1k: - { - if (sigCtx->verify == 1) { - ret = 0; - } - else { - WOLFSSL_MSG("SPHINCS_FAST_LEVEL1 Verify didn't match"); - ret = ASN_SIG_CONFIRM_E; - } - break; - } - case SPHINCS_FAST_LEVEL3k: - { - if (sigCtx->verify == 1) { - ret = 0; - } - else { - WOLFSSL_MSG("SPHINCS_FAST_LEVEL3 Verify didn't match"); - ret = ASN_SIG_CONFIRM_E; - } - break; - } - case SPHINCS_FAST_LEVEL5k: - { - if (sigCtx->verify == 1) { - ret = 0; - } - else { - WOLFSSL_MSG("SPHINCS_FAST_LEVEL5 Verify didn't match"); - ret = ASN_SIG_CONFIRM_E; - } - break; - } - case SPHINCS_SMALL_LEVEL1k: - { - if (sigCtx->verify == 1) { - ret = 0; - } - else { - WOLFSSL_MSG("SPHINCS_SMALL_LEVEL1 Verify didn't match"); - ret = ASN_SIG_CONFIRM_E; - } - break; - } - case SPHINCS_SMALL_LEVEL3k: - { - if (sigCtx->verify == 1) { - ret = 0; - } - else { - WOLFSSL_MSG("SPHINCS_SMALL_LEVEL3 Verify didn't match"); - ret = ASN_SIG_CONFIRM_E; - } - break; - } - case SPHINCS_SMALL_LEVEL5k: + #ifdef WOLFSSL_HAVE_SLHDSA + case SLH_DSA_SHAKE_128Fk: + case SLH_DSA_SHAKE_192Fk: + case SLH_DSA_SHAKE_256Fk: + case SLH_DSA_SHAKE_128Sk: + case SLH_DSA_SHAKE_192Sk: + case SLH_DSA_SHAKE_256Sk: { if (sigCtx->verify == 1) { ret = 0; } else { - WOLFSSL_MSG("SPHINCS_SMALL_LEVEL5 Verify didn't match"); + WOLFSSL_MSG("SLH-DSA Verify didn't match"); ret = ASN_SIG_CONFIRM_E; } break; } - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ default: break; } /* switch (keyOID) */ @@ -23244,21 +23138,21 @@ static wcchar END_PUB_KEY = "-----END PUBLIC KEY-----"; static wcchar BEGIN_ML_DSA_LEVEL5_PRIV = "-----BEGIN ML_DSA_LEVEL5 PRIVATE KEY-----"; static wcchar END_ML_DSA_LEVEL5_PRIV = "-----END ML_DSA_LEVEL5 PRIVATE KEY-----"; #endif /* HAVE_DILITHIUM */ -#if defined(HAVE_SPHINCS) - static wcchar BEGIN_SPHINCS_FAST_LEVEL1_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL1 PRIVATE KEY-----"; - static wcchar END_SPHINCS_FAST_LEVEL1_PRIV = "-----END SPHINCS_FAST_LEVEL1 PRIVATE KEY-----"; - static wcchar BEGIN_SPHINCS_FAST_LEVEL3_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL3 PRIVATE KEY-----"; - static wcchar END_SPHINCS_FAST_LEVEL3_PRIV = "-----END SPHINCS_FAST_LEVEL3 PRIVATE KEY-----"; - static wcchar BEGIN_SPHINCS_FAST_LEVEL5_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL5 PRIVATE KEY-----"; - static wcchar END_SPHINCS_FAST_LEVEL5_PRIV = "-----END SPHINCS_FAST_LEVEL5 PRIVATE KEY-----"; - - static wcchar BEGIN_SPHINCS_SMALL_LEVEL1_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----"; - static wcchar END_SPHINCS_SMALL_LEVEL1_PRIV = "-----END SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----"; - static wcchar BEGIN_SPHINCS_SMALL_LEVEL3_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----"; - static wcchar END_SPHINCS_SMALL_LEVEL3_PRIV = "-----END SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----"; - static wcchar BEGIN_SPHINCS_SMALL_LEVEL5_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----"; - static wcchar END_SPHINCS_SMALL_LEVEL5_PRIV = "-----END SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----"; -#endif /* HAVE_SPHINCS */ +#if defined(WOLFSSL_HAVE_SLHDSA) + static wcchar BEGIN_SLH_DSA_SHAKE_128F_PRIV = "-----BEGIN SLH_DSA_SHAKE_128F PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_128F_PRIV = "-----END SLH_DSA_SHAKE_128F PRIVATE KEY-----"; + static wcchar BEGIN_SLH_DSA_SHAKE_192F_PRIV = "-----BEGIN SLH_DSA_SHAKE_192F PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_192F_PRIV = "-----END SLH_DSA_SHAKE_192F PRIVATE KEY-----"; + static wcchar BEGIN_SLH_DSA_SHAKE_256F_PRIV = "-----BEGIN SLH_DSA_SHAKE_256F PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_256F_PRIV = "-----END SLH_DSA_SHAKE_256F PRIVATE KEY-----"; + + static wcchar BEGIN_SLH_DSA_SHAKE_128S_PRIV = "-----BEGIN SLH_DSA_SHAKE_128S PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_128S_PRIV = "-----END SLH_DSA_SHAKE_128S PRIVATE KEY-----"; + static wcchar BEGIN_SLH_DSA_SHAKE_192S_PRIV = "-----BEGIN SLH_DSA_SHAKE_192S PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_192S_PRIV = "-----END SLH_DSA_SHAKE_192S PRIVATE KEY-----"; + static wcchar BEGIN_SLH_DSA_SHAKE_256S_PRIV = "-----BEGIN SLH_DSA_SHAKE_256S PRIVATE KEY-----"; + static wcchar END_SLH_DSA_SHAKE_256S_PRIV = "-----END SLH_DSA_SHAKE_256S PRIVATE KEY-----"; +#endif /* WOLFSSL_HAVE_SLHDSA */ const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----" "-----END X509 CRL-----"); @@ -23426,38 +23320,38 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) ret = 0; break; #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - case SPHINCS_FAST_LEVEL1_TYPE: - if (header) *header = BEGIN_SPHINCS_FAST_LEVEL1_PRIV; - if (footer) *footer = END_SPHINCS_FAST_LEVEL1_PRIV; +#ifdef WOLFSSL_HAVE_SLHDSA + case SLH_DSA_SHAKE_128F_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_128F_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_128F_PRIV; ret = 0; break; - case SPHINCS_FAST_LEVEL3_TYPE: - if (header) *header = BEGIN_SPHINCS_FAST_LEVEL3_PRIV; - if (footer) *footer = END_SPHINCS_FAST_LEVEL3_PRIV; + case SLH_DSA_SHAKE_192F_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_192F_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_192F_PRIV; ret = 0; break; - case SPHINCS_FAST_LEVEL5_TYPE: - if (header) *header = BEGIN_SPHINCS_FAST_LEVEL5_PRIV; - if (footer) *footer = END_SPHINCS_FAST_LEVEL5_PRIV; + case SLH_DSA_SHAKE_256F_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_256F_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_256F_PRIV; ret = 0; break; - case SPHINCS_SMALL_LEVEL1_TYPE: - if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL1_PRIV; - if (footer) *footer = END_SPHINCS_SMALL_LEVEL1_PRIV; + case SLH_DSA_SHAKE_128S_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_128S_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_128S_PRIV; ret = 0; break; - case SPHINCS_SMALL_LEVEL3_TYPE: - if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL3_PRIV; - if (footer) *footer = END_SPHINCS_SMALL_LEVEL3_PRIV; + case SLH_DSA_SHAKE_192S_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_192S_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_192S_PRIV; ret = 0; break; - case SPHINCS_SMALL_LEVEL5_TYPE: - if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL5_PRIV; - if (footer) *footer = END_SPHINCS_SMALL_LEVEL5_PRIV; + case SLH_DSA_SHAKE_256S_TYPE: + if (header) *header = BEGIN_SLH_DSA_SHAKE_256S_PRIV; + if (footer) *footer = END_SLH_DSA_SHAKE_256S_PRIV; ret = 0; break; -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA */ case PUBLICKEY_TYPE: case ECC_PUBLICKEY_TYPE: if (header) *header = BEGIN_PUB_KEY; @@ -26298,7 +26192,7 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, DsaKey* dsaKey, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey) + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey) { int ret = 0; @@ -26310,7 +26204,7 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, (void)dsaKey; (void)falconKey; (void)dilithiumKey; - (void)sphincsKey; + (void)slhDsaKey; switch (keyType) { #ifndef NO_RSA @@ -26372,20 +26266,20 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, } break; #endif /* HAVE_DILITHIUM */ - #if defined(HAVE_SPHINCS) - case SPHINCS_FAST_LEVEL1_KEY: - case SPHINCS_FAST_LEVEL3_KEY: - case SPHINCS_FAST_LEVEL5_KEY: - case SPHINCS_SMALL_LEVEL1_KEY: - case SPHINCS_SMALL_LEVEL3_KEY: - case SPHINCS_SMALL_LEVEL5_KEY: - ret = wc_Sphincs_PublicKeyToDer(sphincsKey, output, + #if defined(WOLFSSL_HAVE_SLHDSA) + case SLH_DSA_SHAKE_128F_KEY: + case SLH_DSA_SHAKE_192F_KEY: + case SLH_DSA_SHAKE_256F_KEY: + case SLH_DSA_SHAKE_128S_KEY: + case SLH_DSA_SHAKE_192S_KEY: + case SLH_DSA_SHAKE_256S_KEY: + ret = wc_SlhDsaKey_PublicKeyToDer(slhDsaKey, output, (word32)outLen, 1); if (ret <= 0) { ret = PUBLIC_KEY_E; } break; - #endif /* HAVE_SPHINCS */ + #endif /* WOLFSSL_HAVE_SLHDSA */ default: ret = PUBLIC_KEY_E; break; @@ -27126,16 +27020,16 @@ static int InternalSignCb(const byte* in, word32 inLen, } else #endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_NO_SIGN */ -#if defined(HAVE_SPHINCS) - if ((keyType == SPHINCS_FAST_LEVEL1_TYPE || keyType == SPHINCS_FAST_LEVEL3_TYPE || - keyType == SPHINCS_FAST_LEVEL5_TYPE || keyType == SPHINCS_SMALL_LEVEL1_TYPE || - keyType == SPHINCS_SMALL_LEVEL3_TYPE || keyType == SPHINCS_SMALL_LEVEL5_TYPE) && +#if defined(WOLFSSL_HAVE_SLHDSA) + if ((keyType == SLH_DSA_SHAKE_128F_TYPE || keyType == SLH_DSA_SHAKE_192F_TYPE || + keyType == SLH_DSA_SHAKE_256F_TYPE || keyType == SLH_DSA_SHAKE_128S_TYPE || + keyType == SLH_DSA_SHAKE_192S_TYPE || keyType == SLH_DSA_SHAKE_256S_TYPE) && signCtx->key) { - /* Sphincs signs messages, not hashes - cannot use callback path */ + /* SLH-DSA signs messages, not hashes - cannot use callback path */ ret = SIG_TYPE_E; } else -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA */ { /* Unhandled key type */ (void)in; @@ -27158,7 +27052,7 @@ static int InternalSignCb(const byte* in, word32 inLen, static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz, byte* sig, word32 sigSz, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey, WC_RNG* rng, + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey, WC_RNG* rng, word32 sigAlgoType, void* heap) { int ret = 0; @@ -27171,7 +27065,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz, (void)ed448Key; (void)falconKey; (void)dilithiumKey; - (void)sphincsKey; + (void)slhDsaKey; (void)rng; (void)heap; @@ -27256,14 +27150,14 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz, } #endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_NO_SIGN */ -#if defined(HAVE_SPHINCS) - if (sphincsKey) { +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) + if (slhDsaKey) { word32 outSz = sigSz; - ret = wc_sphincs_sign_msg(buf, sz, sig, &outSz, sphincsKey, rng); + ret = wc_SlhDsaKey_Sign(slhDsaKey, NULL, 0, buf, sz, sig, &outSz, rng); if (ret == 0) ret = outSz; } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA && !WOLFSSL_SLHDSA_VERIFY_ONLY */ if (ret == -1) ret = ALGO_ID_E; @@ -27412,7 +27306,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey) + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey) { /* TODO: issRaw and sbjRaw should be NUL terminated. */ DECL_ASNSETDATA(dataASN, x509CertASN_Length); @@ -27425,10 +27319,10 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, word32 issRawLen = 0; word32 sbjRawLen = 0; - /* Unused without OQS */ + /* Unused without PQC */ (void)falconKey; (void)dilithiumKey; - (void)sphincsKey; + (void)slhDsaKey; CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap); @@ -27485,32 +27379,32 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, cert->keyType = ML_DSA_LEVEL5_KEY; } #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL1_KEY; +#ifdef WOLFSSL_HAVE_SLHDSA + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128F)) { + cert->keyType = SLH_DSA_SHAKE_128F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL3_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192F)) { + cert->keyType = SLH_DSA_SHAKE_192F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL5_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256F)) { + cert->keyType = SLH_DSA_SHAKE_256F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL1_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128S)) { + cert->keyType = SLH_DSA_SHAKE_128S_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL3_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192S)) { + cert->keyType = SLH_DSA_SHAKE_192S_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL5_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256S)) { + cert->keyType = SLH_DSA_SHAKE_256S_KEY; } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA */ else { ret = BAD_FUNC_ARG; } @@ -27559,7 +27453,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, /* Calculate public key encoding size. */ ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey, - dilithiumKey, sphincsKey); + dilithiumKey, slhDsaKey); publicKeySz = (word32)ret; } if (ret >= 0) { @@ -27746,7 +27640,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, (int)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ] .data.buffer.length, rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, - falconKey, dilithiumKey, sphincsKey); + falconKey, dilithiumKey, slhDsaKey); } if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) { /* Encode extensions into buffer. */ @@ -27790,7 +27684,7 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -27820,22 +27714,22 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, dilithiumKey = (dilithium_key*)key; else if (keyType == ML_DSA_LEVEL5_TYPE) dilithiumKey = (dilithium_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; + else if (keyType == SLH_DSA_SHAKE_128F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_128S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256S_TYPE) + slhDsaKey = (SlhDsaKey*)key; return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey, ed25519Key, ed448Key, falconKey, dilithiumKey, - sphincsKey); + slhDsaKey); } /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ @@ -27912,7 +27806,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, - sphincs_key* sphincsKey) + SlhDsaKey* slhDsaKey) { DECL_ASNSETDATA(dataASN, certReqBodyASN_Length); word32 publicKeySz = 0; @@ -27924,10 +27818,10 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, word32 sbjRawSz = 0; #endif - /* Unused without OQS */ + /* Unused without PQC */ (void)falconKey; (void)dilithiumKey; - (void)sphincsKey; + (void)slhDsaKey; CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap); @@ -27984,32 +27878,32 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, cert->keyType = ML_DSA_LEVEL5_KEY; } #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL1_KEY; +#ifdef WOLFSSL_HAVE_SLHDSA + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128F)) { + cert->keyType = SLH_DSA_SHAKE_128F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL3_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192F)) { + cert->keyType = SLH_DSA_SHAKE_192F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == FAST_VARIANT)) { - cert->keyType = SPHINCS_FAST_LEVEL5_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256F)) { + cert->keyType = SLH_DSA_SHAKE_256F_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL1_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128S)) { + cert->keyType = SLH_DSA_SHAKE_128S_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL3_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192S)) { + cert->keyType = SLH_DSA_SHAKE_192S_KEY; } - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == SMALL_VARIANT)) { - cert->keyType = SPHINCS_SMALL_LEVEL5_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256S)) { + cert->keyType = SLH_DSA_SHAKE_256S_KEY; } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA */ else { ret = BAD_FUNC_ARG; } @@ -28032,7 +27926,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, /* Determine encode public key size. */ ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey, - dilithiumKey, sphincsKey); + dilithiumKey, slhDsaKey); publicKeySz = (word32)ret; } if (ret >= 0) { @@ -28152,7 +28046,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data, (int)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length, rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey, - dilithiumKey, sphincsKey); + dilithiumKey, slhDsaKey); } if ((ret >= 0 && derBuffer != NULL) && (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) { @@ -28185,7 +28079,7 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -28215,22 +28109,22 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, dilithiumKey = (dilithium_key*)key; else if (keyType == ML_DSA_LEVEL5_TYPE) dilithiumKey = (dilithium_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; + else if (keyType == SLH_DSA_SHAKE_128F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_128S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256S_TYPE) + slhDsaKey = (SlhDsaKey*)key; return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key, falconKey, dilithiumKey, - sphincsKey); + slhDsaKey); } WOLFSSL_ABI @@ -28384,7 +28278,7 @@ static int MakeSignatureCb(CertSignCtx* certSignCtx, const byte* buf, static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey, + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey, WC_RNG* rng) { int sigSz = 0; @@ -28430,7 +28324,7 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, sigSz = MakeSignature(certSignCtx, buf, (word32)requestSz, certSignCtx->sig, MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key, - falconKey, dilithiumKey, sphincsKey, rng, (word32)sType, heap); + falconKey, dilithiumKey, slhDsaKey, rng, (word32)sType, heap); #ifdef WOLFSSL_ASYNC_CRYPT if (sigSz == WC_NO_ERR_TRACE(WC_PENDING_E)) { /* Not free'ing certSignCtx->sig here because it could still be in use @@ -28480,7 +28374,7 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; int ret = 0; int headerSz; void* heap = NULL; @@ -28523,13 +28417,13 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, case ML_DSA_LEVEL5_TYPE: dilithiumKey = (dilithium_key*)key; break; - case SPHINCS_FAST_LEVEL1_TYPE: - case SPHINCS_FAST_LEVEL3_TYPE: - case SPHINCS_FAST_LEVEL5_TYPE: - case SPHINCS_SMALL_LEVEL1_TYPE: - case SPHINCS_SMALL_LEVEL3_TYPE: - case SPHINCS_SMALL_LEVEL5_TYPE: - sphincsKey = (sphincs_key*)key; + case SLH_DSA_SHAKE_128F_TYPE: + case SLH_DSA_SHAKE_192F_TYPE: + case SLH_DSA_SHAKE_256F_TYPE: + case SLH_DSA_SHAKE_128S_TYPE: + case SLH_DSA_SHAKE_192S_TYPE: + case SLH_DSA_SHAKE_256S_TYPE: + slhDsaKey = (SlhDsaKey*)key; break; default: return BAD_FUNC_ARG; @@ -28568,7 +28462,7 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, ret = MakeSignature(certSignCtx, buf, (word32)bufSz, certSignCtx->sig, MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key, - falconKey, dilithiumKey, sphincsKey, rng, (word32)sType, heap); + falconKey, dilithiumKey, slhDsaKey, rng, (word32)sType, heap); #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) { /* Not free'ing certSignCtx->sig here because it could still be in use @@ -28627,7 +28521,7 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -28655,21 +28549,21 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, dilithiumKey = (dilithium_key*)key; else if (keyType == ML_DSA_LEVEL5_TYPE) dilithiumKey = (dilithium_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; + else if (keyType == SLH_DSA_SHAKE_128F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_128S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256S_TYPE) + slhDsaKey = (SlhDsaKey*)key; return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key, - ed448Key, falconKey, dilithiumKey, sphincsKey, rng); + ed448Key, falconKey, dilithiumKey, slhDsaKey, rng); } int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz, @@ -28825,7 +28719,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, - sphincs_key *sphincsKey, int kid_type) + SlhDsaKey *slhDsaKey, int kid_type) { byte *buf; int bufferSz, ret; @@ -28833,7 +28727,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, if (cert == NULL || (rsakey == NULL && eckey == NULL && ed25519Key == NULL && ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL && - sphincsKey == NULL) || + slhDsaKey == NULL) || (kid_type != SKID_TYPE && kid_type != AKID_TYPE)) return BAD_FUNC_ARG; @@ -28878,9 +28772,9 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, MAX_PUBLIC_KEY_SZ, 0); } #endif -#if defined(HAVE_SPHINCS) - if (sphincsKey != NULL) { - bufferSz = wc_Sphincs_PublicKeyToDer(sphincsKey, buf, +#if defined(WOLFSSL_HAVE_SLHDSA) + if (slhDsaKey != NULL) { + bufferSz = wc_SlhDsaKey_PublicKeyToDer(slhDsaKey, buf, MAX_PUBLIC_KEY_SZ, 0); } #endif @@ -28922,7 +28816,7 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -28950,21 +28844,21 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) dilithiumKey = (dilithium_key*)key; else if (keyType == ML_DSA_LEVEL5_TYPE) dilithiumKey = (dilithium_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; + else if (keyType == SLH_DSA_SHAKE_128F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_128S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256S_TYPE) + slhDsaKey = (SlhDsaKey*)key; return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key, - falconKey, dilithiumKey, sphincsKey, + falconKey, dilithiumKey, slhDsaKey, SKID_TYPE); } @@ -28983,7 +28877,7 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) ed448_key* ed448Key = NULL; falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; - sphincs_key* sphincsKey = NULL; + SlhDsaKey* slhDsaKey = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -29011,21 +28905,21 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) dilithiumKey = (dilithium_key*)key; else if (keyType == ML_DSA_LEVEL5_TYPE) dilithiumKey = (dilithium_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_FAST_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE) - sphincsKey = (sphincs_key*)key; - else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE) - sphincsKey = (sphincs_key*)key; + else if (keyType == SLH_DSA_SHAKE_128F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256F_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_128S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_192S_TYPE) + slhDsaKey = (SlhDsaKey*)key; + else if (keyType == SLH_DSA_SHAKE_256S_TYPE) + slhDsaKey = (SlhDsaKey*)key; return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key, - falconKey, dilithiumKey, sphincsKey, + falconKey, dilithiumKey, slhDsaKey, AKID_TYPE); } @@ -30968,7 +30862,7 @@ enum { || (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \ || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \ || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \ - || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS)) + || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(WOLFSSL_HAVE_SLHDSA)) int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz, @@ -31328,7 +31222,7 @@ int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz, return ret; } -#endif /* HAVE_ED25519 || etc... || HAVE_DILITHIUM || HAVE_SPHINCS */ +#endif /* HAVE_ED25519 || etc... || HAVE_DILITHIUM || WOLFSSL_HAVE_SLHDSA */ #endif /* WC_ENABLE_ASYM_KEY_IMPORT */ #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) diff --git a/wolfcrypt/src/asn_orig.c b/wolfcrypt/src/asn_orig.c index d6568aa5d11..3363921aacd 100644 --- a/wolfcrypt/src/asn_orig.c +++ b/wolfcrypt/src/asn_orig.c @@ -5956,7 +5956,7 @@ static int SetValidity(byte* output, int daysValid) static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey) + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey) { int ret; @@ -5966,7 +5966,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, /* make sure at least one key type is provided */ if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && dsaKey == NULL && ed448Key == NULL && falconKey == NULL && - dilithiumKey == NULL && sphincsKey == NULL) { + dilithiumKey == NULL && slhDsaKey == NULL) { return PUBLIC_KEY_E; } @@ -6072,21 +6072,21 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, (word32)sizeof(der->publicKey), 1); } #endif /* HAVE_DILITHIUM */ -#if defined(HAVE_SPHINCS) - if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) || - (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) || - (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) { - if (sphincsKey == NULL) +#if defined(WOLFSSL_HAVE_SLHDSA) + if ((cert->keyType == SLH_DSA_SHAKE_128F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_192F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_256F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_128S_KEY) || + (cert->keyType == SLH_DSA_SHAKE_192S_KEY) || + (cert->keyType == SLH_DSA_SHAKE_256S_KEY)) { + if (slhDsaKey == NULL) return PUBLIC_KEY_E; der->publicKeySz = - wc_Sphincs_PublicKeyToDer(sphincsKey, der->publicKey, + wc_SlhDsaKey_PublicKeyToDer(slhDsaKey, der->publicKey, (word32)sizeof(der->publicKey), 1); } -#endif /* HAVE_SPHINCS */ +#endif /* WOLFSSL_HAVE_SLHDSA */ if (der->publicKeySz <= 0) return PUBLIC_KEY_E; @@ -6519,7 +6519,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, - dilithium_key* dilithiumKey, sphincs_key* sphincsKey) + dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey) { int ret; WC_DECLARE_VAR(der, DerCert, 1, 0); @@ -6571,26 +6571,26 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, cert->keyType = ML_DSA_LEVEL5_KEY; } #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL1_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL3_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL5_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL1_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL3_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL5_KEY; -#endif /* HAVE_SPHINCS */ +#ifdef WOLFSSL_HAVE_SLHDSA + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128F)) + cert->keyType = SLH_DSA_SHAKE_128F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192F)) + cert->keyType = SLH_DSA_SHAKE_192F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256F)) + cert->keyType = SLH_DSA_SHAKE_256F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128S)) + cert->keyType = SLH_DSA_SHAKE_128S_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192S)) + cert->keyType = SLH_DSA_SHAKE_192S_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256S)) + cert->keyType = SLH_DSA_SHAKE_256S_KEY; +#endif /* WOLFSSL_HAVE_SLHDSA */ else return BAD_FUNC_ARG; @@ -6598,7 +6598,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, return MEMORY_E); ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key, - ed448Key, falconKey, dilithiumKey, sphincsKey); + ed448Key, falconKey, dilithiumKey, slhDsaKey); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) ret = BUFFER_E; @@ -6774,7 +6774,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, - sphincs_key* sphincsKey) + SlhDsaKey* slhDsaKey) { int ret; @@ -6783,14 +6783,14 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, (void)ed448Key; (void)falconKey; (void)dilithiumKey; - (void)sphincsKey; + (void)slhDsaKey; if (cert == NULL || der == NULL) return BAD_FUNC_ARG; if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && dsaKey == NULL && ed448Key == NULL && falconKey == NULL && - dilithiumKey == NULL && sphincsKey == NULL) { + dilithiumKey == NULL && slhDsaKey == NULL) { return PUBLIC_KEY_E; } @@ -6897,16 +6897,16 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, der->publicKey, (word32)sizeof(der->publicKey), 1); } #endif -#if defined(HAVE_SPHINCS) - if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) || - (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) || - (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) || - (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) { - if (sphincsKey == NULL) +#if defined(WOLFSSL_HAVE_SLHDSA) + if ((cert->keyType == SLH_DSA_SHAKE_128F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_192F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_256F_KEY) || + (cert->keyType == SLH_DSA_SHAKE_128S_KEY) || + (cert->keyType == SLH_DSA_SHAKE_192S_KEY) || + (cert->keyType == SLH_DSA_SHAKE_256S_KEY)) { + if (slhDsaKey == NULL) return PUBLIC_KEY_E; - der->publicKeySz = wc_Sphincs_PublicKeyToDer(sphincsKey, + der->publicKeySz = wc_SlhDsaKey_PublicKeyToDer(slhDsaKey, der->publicKey, (word32)sizeof(der->publicKey), 1); } #endif @@ -7157,7 +7157,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey, dilithium_key* dilithiumKey, - sphincs_key* sphincsKey) + SlhDsaKey* slhDsaKey) { int ret; WC_DECLARE_VAR(der, DerCert, 1, 0); @@ -7206,26 +7206,26 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, cert->keyType = ML_DSA_LEVEL5_KEY; } #endif /* HAVE_DILITHIUM */ -#ifdef HAVE_SPHINCS - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL1_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL3_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == FAST_VARIANT)) - cert->keyType = SPHINCS_FAST_LEVEL5_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 1) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL1_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 3) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL3_KEY; - else if ((sphincsKey != NULL) && (sphincsKey->level == 5) - && (sphincsKey->optim == SMALL_VARIANT)) - cert->keyType = SPHINCS_SMALL_LEVEL5_KEY; -#endif /* HAVE_SPHINCS */ +#ifdef WOLFSSL_HAVE_SLHDSA + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128F)) + cert->keyType = SLH_DSA_SHAKE_128F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192F)) + cert->keyType = SLH_DSA_SHAKE_192F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256F)) + cert->keyType = SLH_DSA_SHAKE_256F_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE128S)) + cert->keyType = SLH_DSA_SHAKE_128S_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE192S)) + cert->keyType = SLH_DSA_SHAKE_192S_KEY; + else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) && + (slhDsaKey->params->param == SLHDSA_SHAKE256S)) + cert->keyType = SLH_DSA_SHAKE_256S_KEY; +#endif /* WOLFSSL_HAVE_SLHDSA */ else return BAD_FUNC_ARG; @@ -7233,7 +7233,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, return MEMORY_E); ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key, - falconKey, dilithiumKey, sphincsKey); + falconKey, dilithiumKey, slhDsaKey); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) diff --git a/wolfcrypt/src/sphincs.c b/wolfcrypt/src/sphincs.c deleted file mode 100644 index 587b99375e8..00000000000 --- a/wolfcrypt/src/sphincs.c +++ /dev/null @@ -1,1057 +0,0 @@ -/* sphincs.c - * - * 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 - */ - -#include - -/* Based on dilithium.c and Reworked for Sphincs by Anthony Hu. */ - -#include - -#if defined(HAVE_PQC) && defined(HAVE_SPHINCS) - -#ifdef HAVE_LIBOQS -#include -#endif - -#include -#ifdef NO_INLINE - #include -#else - #define WOLFSSL_MISC_INCLUDED - #include -#endif - -/* Sign the message using the sphincs private key. - * - * in [in] Message to sign. - * inLen [in] Length of the message in bytes. - * out [in] Buffer to write signature into. - * outLen [in/out] On in, size of buffer. - * On out, the length of the signature in bytes. - * key [in] Sphincs key to use when signing - * returns BAD_FUNC_ARG when a parameter is NULL or public key not set, - * BUFFER_E when outLen is less than SPHINCS_FAST_LEVEL1_SIG_SIZE, - * 0 otherwise. - */ -int wc_sphincs_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, - sphincs_key* key, WC_RNG* rng) -{ - int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - size_t localOutLen = 0; - - /* sanity check on arguments */ - if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) { - ret = BAD_FUNC_ARG; - } - - if ((ret == 0) && (!key->prvKeySet)) { - ret = BAD_FUNC_ARG; - } - - if (ret == 0) { - if ((key->optim == FAST_VARIANT) && (key->level == 1)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_128f_simple); - } - else if ((key->optim == FAST_VARIANT) && (key->level == 3)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_192f_simple); - } - else if ((key->optim == FAST_VARIANT) && (key->level == 5)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_256f_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 1)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_128s_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 3)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_192s_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 5)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_256s_simple); - } - - if (oqssig == NULL) { - ret = SIG_TYPE_E; - } - } - - /* check and set up out length */ - if (ret == 0) { - if ((key->level == 1) && (key->optim == FAST_VARIANT) && - (*outLen < SPHINCS_FAST_LEVEL1_SIG_SIZE)) { - *outLen = SPHINCS_FAST_LEVEL1_SIG_SIZE; - ret = BUFFER_E; - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT) && - (*outLen < SPHINCS_FAST_LEVEL3_SIG_SIZE)) { - *outLen = SPHINCS_FAST_LEVEL3_SIG_SIZE; - ret = BUFFER_E; - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT) && - (*outLen < SPHINCS_FAST_LEVEL5_SIG_SIZE)) { - *outLen = SPHINCS_FAST_LEVEL5_SIG_SIZE; - ret = BUFFER_E; - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT) && - (*outLen < SPHINCS_SMALL_LEVEL1_SIG_SIZE)) { - *outLen = SPHINCS_SMALL_LEVEL1_SIG_SIZE; - ret = BUFFER_E; - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT) && - (*outLen < SPHINCS_SMALL_LEVEL3_SIG_SIZE)) { - *outLen = SPHINCS_SMALL_LEVEL3_SIG_SIZE; - ret = BUFFER_E; - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT) && - (*outLen < SPHINCS_SMALL_LEVEL5_SIG_SIZE)) { - *outLen = SPHINCS_SMALL_LEVEL5_SIG_SIZE; - ret = BUFFER_E; - } - - localOutLen = *outLen; - } - - if (ret == 0) { - ret = wolfSSL_liboqsRngMutexLock(rng); - if (ret == 0) { - if (OQS_SIG_sign(oqssig, out, &localOutLen, in, inLen, key->k) - == OQS_ERROR) { - ret = BAD_FUNC_ARG; - } - } - if (ret == 0) { - *outLen = (word32)localOutLen; - } - wolfSSL_liboqsRngMutexUnlock(); - } - - if (oqssig != NULL) { - OQS_SIG_free(oqssig); - } -#else - ret = NOT_COMPILED_IN; -#endif - return ret; -} - -/* Verify the message using the sphincs public key. - * - * sig [in] Signature to verify. - * sigLen [in] Size of signature in bytes. - * msg [in] Message to verify. - * msgLen [in] Length of the message in bytes. - * res [out] *res is set to 1 on successful verification. - * key [in] Sphincs key to use to verify. - * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and - * BUFFER_E when sigLen is less than SPHINCS_FAST_LEVEL1_SIG_SIZE, - * 0 otherwise. - */ -int wc_sphincs_verify_msg(const byte* sig, word32 sigLen, const byte* msg, - word32 msgLen, int* res, sphincs_key* key) -{ - int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - - if (key == NULL || sig == NULL || msg == NULL || res == NULL) { - ret = BAD_FUNC_ARG; - } - - if ((ret == 0) && (!key->pubKeySet)) { - ret = BAD_FUNC_ARG; - } - - if (ret == 0) { - if ((key->optim == FAST_VARIANT) && (key->level == 1)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_128f_simple); - } - else if ((key->optim == FAST_VARIANT) && (key->level == 3)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_192f_simple); - } - else if ((key->optim == FAST_VARIANT) && (key->level == 5)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_256f_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 1)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_128s_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 3)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_192s_simple); - } - else if ((key->optim == SMALL_VARIANT) && (key->level == 5)) { - oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake_256s_simple); - } - - if (oqssig == NULL) { - ret = SIG_TYPE_E; - } - } - - if ((ret == 0) && - (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p) - == OQS_ERROR)) { - ret = SIG_VERIFY_E; - } - - if (ret == 0) { - *res = 1; - } - - if (oqssig != NULL) { - OQS_SIG_free(oqssig); - } -#else - ret = NOT_COMPILED_IN; -#endif - - return ret; -} - -/* Initialize the sphincs private/public key. - * - * key [in] Sphincs key. - * returns BAD_FUNC_ARG when key is NULL - */ -int wc_sphincs_init(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - ForceZero(key, sizeof(*key)); - return 0; -} - -/* Set the level of the sphincs private/public key. - * - * key [out] Sphincs key. - * level [in] Either 1, 3 or 5. - * optim [in] Either FAST_VARIANT or SMALL_VARIANT. - * returns BAD_FUNC_ARG when key is NULL or level or optim are bad values. - */ -int wc_sphincs_set_level_and_optim(sphincs_key* key, byte level, byte optim) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if (level != 1 && level != 3 && level != 5) { - return BAD_FUNC_ARG; - } - - if (optim != FAST_VARIANT && optim != SMALL_VARIANT) { - return BAD_FUNC_ARG; - } - - key->level = level; - key->optim = optim; - key->pubKeySet = 0; - key->prvKeySet = 0; - return 0; -} - -/* Get the level and optimization variant of the sphincs private/public key. - * - * key [in] Sphincs key. - * level [out] The level. - * optim [out] The optimization variant. FAST_VARIANT or SMALL_VARIANT. - * returns BAD_FUNC_ARG when key is NULL or level has not been set. - */ -int wc_sphincs_get_level_and_optim(sphincs_key* key, byte* level, byte* optim) -{ - if (key == NULL || level == NULL) { - return BAD_FUNC_ARG; - } - - if (key->level != 1 && key->level != 3 && key->level != 5) { - return BAD_FUNC_ARG; - } - - if (key->optim != FAST_VARIANT && key->optim != SMALL_VARIANT) { - return BAD_FUNC_ARG; - } - - *level = key->level; - *optim = key->optim; - return 0; -} - -/* Clears the sphincs key data - * - * key [in] Sphincs key. - */ -void wc_sphincs_free(sphincs_key* key) -{ - if (key != NULL) { - ForceZero(key, sizeof(*key)); - } -} - -/* Export the sphincs public key. - * - * key [in] Sphincs public key. - * out [in] Array to hold public key. - * outLen [in/out] On in, the number of bytes in array. - * On out, the number bytes put into array. - * returns BAD_FUNC_ARG when a parameter is NULL, - * BUFFER_E when outLen is less than SPHINCS_FAST_LEVEL1_PUB_KEY_SIZE, - * 0 otherwise. - */ -int wc_sphincs_export_public(sphincs_key* key, - byte* out, word32* outLen) -{ - /* sanity check on arguments */ - if ((key == NULL) || (out == NULL) || (outLen == NULL)) { - return BAD_FUNC_ARG; - } - - if ((key->level != 1) && (key->level != 5)) { - return BAD_FUNC_ARG; - } - - if (!key->pubKeySet) { - return BAD_FUNC_ARG; - } - - /* check and set up out length */ - if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_PUB_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL1_PUB_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_PUB_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL3_PUB_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_PUB_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL5_PUB_KEY_SIZE; - return BUFFER_E; - } - - if (key->level == 1) { - *outLen = SPHINCS_LEVEL1_PUB_KEY_SIZE; - XMEMCPY(out, key->p, SPHINCS_LEVEL1_PUB_KEY_SIZE); - } - else if (key->level == 3) { - *outLen = SPHINCS_LEVEL3_PUB_KEY_SIZE; - XMEMCPY(out, key->p, SPHINCS_LEVEL3_PUB_KEY_SIZE); - } - else if (key->level == 5) { - *outLen = SPHINCS_LEVEL5_PUB_KEY_SIZE; - XMEMCPY(out, key->p, SPHINCS_LEVEL5_PUB_KEY_SIZE); - } - - return 0; -} - -/* Import a sphincs public key from a byte array. - * Public key encoded in big-endian. - * - * in [in] Array holding public key. - * inLen [in] Number of bytes of data in array. - * key [in] Sphincs public key. - * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported, - * 0 otherwise. - */ -int wc_sphincs_import_public(const byte* in, word32 inLen, - sphincs_key* key) -{ - /* sanity check on arguments */ - if ((in == NULL) || (key == NULL)) { - return BAD_FUNC_ARG; - } - - if ((key->level != 1) && (key->level != 3) && (key->level != 5)) { - return BAD_FUNC_ARG; - } - - if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (inLen != SPHINCS_LEVEL1_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - else if ((key->level == 3) && (inLen != SPHINCS_LEVEL3_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - else if ((key->level == 5) && (inLen != SPHINCS_LEVEL5_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - - XMEMCPY(key->p, in, inLen); - key->pubKeySet = 1; - - return 0; -} - -static int parse_private_key(const byte* priv, word32 privSz, - byte** out, word32 *outSz, - sphincs_key* key) { - word32 idx = 0; - int ret = 0; - int length = 0; - - /* sanity check on arguments */ - if ((priv == NULL) || (key == NULL)) { - return BAD_FUNC_ARG; - } - - if ((key->level != 1) && (key->level != 3) && (key->level != 5)) { - return BAD_FUNC_ARG; - } - - if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) { - return BAD_FUNC_ARG; - } - - /* At this point, it is still a PKCS8 private key. */ - if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) { - /* ignore error, did not have PKCS8 header */ - (void)ret; - } - - /* Now it is a octet_string(concat(priv,pub)) */ - if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) { - return ret; - } - - *out = (byte *)priv + idx; - *outSz = privSz - idx; - - /* And finally it is concat(priv,pub). Key size check. */ - if ((key->level == 1) && (*outSz != SPHINCS_LEVEL1_KEY_SIZE + - SPHINCS_LEVEL1_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - else if ((key->level == 3) && (*outSz != SPHINCS_LEVEL3_KEY_SIZE + - SPHINCS_LEVEL3_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - else if ((key->level == 5) && (*outSz != SPHINCS_LEVEL5_KEY_SIZE + - SPHINCS_LEVEL5_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - - return 0; -} - -/* Import a sphincs private key from a byte array. - * - * priv [in] Array holding private key. - * privSz [in] Number of bytes of data in array. - * key [in] Sphincs private key. - * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than - * SPHINCS_LEVEL1_KEY_SIZE, - * 0 otherwise. - */ -int wc_sphincs_import_private_only(const byte* priv, word32 privSz, - sphincs_key* key) -{ - int ret = 0; - byte *newPriv = NULL; - word32 newPrivSz = 0; - - if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key)) - != 0) { - return ret; - } - - if (key->level == 1) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL1_KEY_SIZE); - } - else if (key->level == 3) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL3_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL5_KEY_SIZE); - } - key->prvKeySet = 1; - - return 0; -} - -/* Import a sphincs private and public keys from byte array(s). - * - * priv [in] Array holding private key or private+public keys - * privSz [in] Number of bytes of data in private key array. - * pub [in] Array holding public key (or NULL). - * pubSz [in] Number of bytes of data in public key array (or 0). - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid - * combination of keys/lengths is supplied, 0 otherwise. - */ -int wc_sphincs_import_private_key(const byte* priv, word32 privSz, - const byte* pub, word32 pubSz, - sphincs_key* key) -{ - int ret = 0; - byte *newPriv = NULL; - word32 newPrivSz = 0; - - if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key)) - != 0) { - return ret; - } - - if (pub == NULL) { - if (pubSz != 0) { - return BAD_FUNC_ARG; - } - - if ((newPrivSz != SPHINCS_LEVEL1_PRV_KEY_SIZE) && - (newPrivSz != SPHINCS_LEVEL3_PRV_KEY_SIZE) && - (newPrivSz != SPHINCS_LEVEL5_PRV_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - - if (key->level == 1) { - pub = newPriv + SPHINCS_LEVEL1_KEY_SIZE; - pubSz = SPHINCS_LEVEL1_PUB_KEY_SIZE; - } - else if (key->level == 3) { - pub = newPriv + SPHINCS_LEVEL3_KEY_SIZE; - pubSz = SPHINCS_LEVEL3_PUB_KEY_SIZE; - } - else if (key->level == 5) { - pub = newPriv + SPHINCS_LEVEL5_KEY_SIZE; - pubSz = SPHINCS_LEVEL5_PUB_KEY_SIZE; - } - } - else if ((pubSz != SPHINCS_LEVEL1_PUB_KEY_SIZE) && - (pubSz != SPHINCS_LEVEL3_PUB_KEY_SIZE) && - (pubSz != SPHINCS_LEVEL5_PUB_KEY_SIZE)) { - return BAD_FUNC_ARG; - } - - /* import public key */ - ret = wc_sphincs_import_public(pub, pubSz, key); - - if (ret == 0) { - /* make the private key (priv + pub) */ - if (key->level == 1) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL1_KEY_SIZE); - } - else if (key->level == 3) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL3_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, SPHINCS_LEVEL5_KEY_SIZE); - } - key->prvKeySet = 1; - } - - return ret; -} - -/* Export the sphincs private key. - * - * key [in] Sphincs private key. - * out [in] Array to hold private key. - * outLen [in/out] On in, the number of bytes in array. - * On out, the number bytes put into array. - * returns BAD_FUNC_ARG when a parameter is NULL, - * BUFFER_E when outLen is less than SPHINCS_LEVEL1_KEY_SIZE, - * 0 otherwise. - */ -int wc_sphincs_export_private_only(sphincs_key* key, byte* out, word32* outLen) -{ - /* sanity checks on arguments */ - if ((key == NULL) || (out == NULL) || (outLen == NULL)) { - return BAD_FUNC_ARG; - } - - if ((key->level != 1) && (key->level != 3) && (key->level != 5)) { - return BAD_FUNC_ARG; - } - - if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) { - return BAD_FUNC_ARG; - } - - /* check and set up out length */ - if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL1_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL3_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL5_KEY_SIZE; - return BUFFER_E; - } - - if (key->level == 1) { - *outLen = SPHINCS_LEVEL1_KEY_SIZE; - } - else if (key->level == 3) { - *outLen = SPHINCS_LEVEL3_KEY_SIZE; - } - else if (key->level == 5) { - *outLen = SPHINCS_LEVEL5_KEY_SIZE; - } - - XMEMCPY(out, key->k, *outLen); - - return 0; -} - -/* Export the sphincs private and public key. - * - * key [in] Sphincs private/public key. - * out [in] Array to hold private and public key. - * outLen [in/out] On in, the number of bytes in array. - * On out, the number bytes put into array. - * returns BAD_FUNC_ARG when a parameter is NULL, - * BUFFER_E when outLen is less than required, 0 otherwise. - */ -int wc_sphincs_export_private(sphincs_key* key, byte* out, word32* outLen) -{ - /* sanity checks on arguments */ - if ((key == NULL) || (out == NULL) || (outLen == NULL)) { - return BAD_FUNC_ARG; - } - - if ((key->level != 1) && (key->level != 3) && (key->level != 5)) { - return BAD_FUNC_ARG; - } - - if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_PRV_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL1_PRV_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_PRV_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL3_PRV_KEY_SIZE; - return BUFFER_E; - } - else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_PRV_KEY_SIZE)) { - *outLen = SPHINCS_LEVEL5_PRV_KEY_SIZE; - return BUFFER_E; - } - - - if (key->level == 1) { - *outLen = SPHINCS_LEVEL1_PRV_KEY_SIZE; - XMEMCPY(out, key->k, SPHINCS_LEVEL1_PRV_KEY_SIZE); - XMEMCPY(out + SPHINCS_LEVEL1_PRV_KEY_SIZE, key->p, - SPHINCS_LEVEL1_PUB_KEY_SIZE); - } - else if (key->level == 3) { - *outLen = SPHINCS_LEVEL3_PRV_KEY_SIZE; - XMEMCPY(out, key->k, SPHINCS_LEVEL3_PRV_KEY_SIZE); - XMEMCPY(out + SPHINCS_LEVEL3_PRV_KEY_SIZE, key->p, - SPHINCS_LEVEL3_PUB_KEY_SIZE); - } - else if (key->level == 5) { - *outLen = SPHINCS_LEVEL5_PRV_KEY_SIZE; - XMEMCPY(out, key->k, SPHINCS_LEVEL5_PRV_KEY_SIZE); - XMEMCPY(out + SPHINCS_LEVEL5_PRV_KEY_SIZE, key->p, - SPHINCS_LEVEL5_PUB_KEY_SIZE); - } - - return 0; -} - -/* Export the sphincs private and public key. - * - * key [in] Sphincs private/public key. - * priv [in] Array to hold private key. - * privSz [in/out] On in, the number of bytes in private key array. - * pub [in] Array to hold public key. - * pubSz [in/out] On in, the number of bytes in public key array. - * On out, the number bytes put into array. - * returns BAD_FUNC_ARG when a parameter is NULL, - * BUFFER_E when privSz is or pubSz is less than required, - * 0 otherwise. - */ -int wc_sphincs_export_key(sphincs_key* key, byte* priv, word32 *privSz, - byte* pub, word32 *pubSz) -{ - int ret = 0; - - /* export private part */ - ret = wc_sphincs_export_private(key, priv, privSz); - if (ret == 0) { - /* export public part */ - ret = wc_sphincs_export_public(key, pub, pubSz); - } - - return ret; -} - -/* Check the public key of the sphincs key matches the private key. - * - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when key is NULL, - * PUBLIC_KEY_E when the public key is not set or doesn't match, - * other -ve value on hash failure, - * 0 otherwise. - */ -int wc_sphincs_check_key(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - /* Assume everything is fine. */ - return 0; -} - -/* Returns the size of a sphincs private key. - * - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when key is NULL, - * SPHINCS_LEVELn_KEY_SIZE otherwise. - */ -int wc_sphincs_size(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if (key->level == 1) { - return SPHINCS_LEVEL1_KEY_SIZE; - } - else if (key->level == 3) { - return SPHINCS_LEVEL3_KEY_SIZE; - } - else if (key->level == 5) { - return SPHINCS_LEVEL5_KEY_SIZE; - } - - return BAD_FUNC_ARG; -} - -/* Returns the size of a sphincs private plus public key. - * - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when key is NULL, - * SPHINCS_LEVELn_PRV_KEY_SIZE otherwise. - */ -int wc_sphincs_priv_size(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if (key->level == 1) { - return SPHINCS_LEVEL1_PRV_KEY_SIZE; - } - else if (key->level == 3) { - return SPHINCS_LEVEL3_PRV_KEY_SIZE; - } - else if (key->level == 5) { - return SPHINCS_LEVEL5_PRV_KEY_SIZE; - } - - return BAD_FUNC_ARG; -} - -/* Returns the size of a sphincs public key. - * - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when key is NULL, - * SPHINCS_FAST_LEVEL1_PUB_KEY_SIZE otherwise. - */ -int wc_sphincs_pub_size(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if (key->level == 1) { - return SPHINCS_LEVEL1_PUB_KEY_SIZE; - } - else if (key->level == 3) { - return SPHINCS_LEVEL3_PUB_KEY_SIZE; - } - else if (key->level == 5) { - return SPHINCS_LEVEL5_PUB_KEY_SIZE; - } - - return BAD_FUNC_ARG; -} - -/* Returns the size of a sphincs signature. - * - * key [in] Sphincs private/public key. - * returns BAD_FUNC_ARG when key is NULL, - * SPHINCS_FAST_LEVEL1_SIG_SIZE otherwise. - */ -int wc_sphincs_sig_size(sphincs_key* key) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - return SPHINCS_FAST_LEVEL1_SIG_SIZE; - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - return SPHINCS_FAST_LEVEL3_SIG_SIZE; - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - return SPHINCS_FAST_LEVEL5_SIG_SIZE; - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - return SPHINCS_SMALL_LEVEL1_SIG_SIZE; - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - return SPHINCS_SMALL_LEVEL3_SIG_SIZE; - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - return SPHINCS_SMALL_LEVEL5_SIG_SIZE; - } - - return BAD_FUNC_ARG; -} - -int wc_Sphincs_PrivateKeyDecode(const byte* input, word32* inOutIdx, - sphincs_key* key, word32 inSz) -{ - int ret = 0; - byte privKey[SPHINCS_MAX_KEY_SIZE], pubKey[SPHINCS_MAX_PUB_KEY_SIZE]; - word32 privKeyLen = (word32)sizeof(privKey); - word32 pubKeyLen = (word32)sizeof(pubKey); - int keytype = 0; - - if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL5k; - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL5k; - } - else { - return BAD_FUNC_ARG; - } - - ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen, - pubKey, &pubKeyLen, keytype); - if (ret == 0) { - if (pubKeyLen == 0) { - ret = wc_sphincs_import_private_only(input, inSz, key); - } - else { - ret = wc_sphincs_import_private_key(privKey, privKeyLen, - pubKey, pubKeyLen, key); - } - } - return ret; -} - -int wc_Sphincs_PublicKeyDecode(const byte* input, word32* inOutIdx, - sphincs_key* key, word32 inSz) -{ - int ret = 0; - byte pubKey[SPHINCS_MAX_PUB_KEY_SIZE]; - word32 pubKeyLen = (word32)sizeof(pubKey); - int keytype = 0; - - if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) { - return BAD_FUNC_ARG; - } - - ret = wc_sphincs_import_public(input, inSz, key); - if (ret == 0) { - return 0; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL5k; - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL5k; - } - else { - return BAD_FUNC_ARG; - } - - ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen, - keytype); - if (ret == 0) { - ret = wc_sphincs_import_public(pubKey, pubKeyLen, key); - } - return ret; -} - -#ifdef WC_ENABLE_ASYM_KEY_EXPORT -/* Encode the public part of an Sphincs key in DER. - * - * Pass NULL for output to get the size of the encoding. - * - * @param [in] key Sphincs key object. - * @param [out] output Buffer to put encoded data in. - * @param [in] outLen Size of buffer in bytes. - * @param [in] withAlg Whether to use SubjectPublicKeyInfo format. - * @return Size of encoded data in bytes on success. - * @return BAD_FUNC_ARG when key is NULL. - * @return MEMORY_E when dynamic memory allocation failed. - */ -int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output, word32 inLen, - int withAlg) -{ - int ret; - byte pubKey[SPHINCS_MAX_PUB_KEY_SIZE]; - word32 pubKeyLen = (word32)sizeof(pubKey); - int keytype = 0; - - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - keytype = SPHINCS_FAST_LEVEL5k; - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL1k; - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL3k; - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - keytype = SPHINCS_SMALL_LEVEL5k; - } - else { - return BAD_FUNC_ARG; - } - - ret = wc_sphincs_export_public(key, pubKey, &pubKeyLen); - if (ret == 0) { - ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen, keytype, - withAlg); - } - - return ret; -} -#endif - -int wc_Sphincs_KeyToDer(sphincs_key* key, byte* output, word32 inLen) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, key->p, - SPHINCS_LEVEL1_KEY_SIZE, output, inLen, - SPHINCS_FAST_LEVEL1k); - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, key->p, - SPHINCS_LEVEL3_KEY_SIZE, output, inLen, - SPHINCS_FAST_LEVEL3k); - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, key->p, - SPHINCS_LEVEL5_KEY_SIZE, output, inLen, - SPHINCS_FAST_LEVEL5k); - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, key->p, - SPHINCS_LEVEL1_KEY_SIZE, output, inLen, - SPHINCS_SMALL_LEVEL1k); - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, key->p, - SPHINCS_LEVEL3_KEY_SIZE, output, inLen, - SPHINCS_SMALL_LEVEL3k); - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, key->p, - SPHINCS_LEVEL5_KEY_SIZE, output, inLen, - SPHINCS_SMALL_LEVEL5k); - } - - return BAD_FUNC_ARG; -} - -int wc_Sphincs_PrivateKeyToDer(sphincs_key* key, byte* output, word32 inLen) -{ - if (key == NULL) { - return BAD_FUNC_ARG; - } - - if ((key->level == 1) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_FAST_LEVEL1k); - } - else if ((key->level == 3) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_FAST_LEVEL3k); - } - else if ((key->level == 5) && (key->optim == FAST_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_FAST_LEVEL5k); - } - else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_SMALL_LEVEL1k); - } - else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_SMALL_LEVEL3k); - } - else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) { - return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, NULL, 0, output, - inLen, SPHINCS_SMALL_LEVEL5k); - } - - return BAD_FUNC_ARG; -} -#endif /* HAVE_PQC && HAVE_SPHINCS */ diff --git a/wolfcrypt/src/wc_slhdsa.c b/wolfcrypt/src/wc_slhdsa.c index 65926a43349..402047247c2 100644 --- a/wolfcrypt/src/wc_slhdsa.c +++ b/wolfcrypt/src/wc_slhdsa.c @@ -25,6 +25,7 @@ #ifdef WOLFSSL_HAVE_SLHDSA +#include #include #include #ifdef NO_INLINE @@ -7019,7 +7020,7 @@ int wc_SlhDsaKey_ImportPublic(SlhDsaKey* key, const byte* pub, word32 pubLen) else { /* Copy public key data into SLH-DSA key object. */ XMEMCPY(key->sk + 2 * key->params->n, pub, 2 * key->params->n); - key->flags = WC_SLHDSA_FLAG_PUBLIC; + key->flags |= WC_SLHDSA_FLAG_PUBLIC; } return ret; @@ -7317,5 +7318,396 @@ int wc_SlhDsaKey_SigSizeFromParam(enum SlhDsaParam param) return ret; } + +/* Map SLH-DSA parameter set to OID key type for DER encoding. + * Only SHAKE variants are supported; SHA2 SLH-DSA OIDs are defined in + * oid_sum.h but not handled here pending native SHA2 implementation. */ +static int slhdsa_param_to_keytype(enum SlhDsaParam param) +{ + switch (param) { +#ifndef WOLFSSL_SLHDSA_NO_128 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLHDSA_SHAKE128S: return SLH_DSA_SHAKE_128Sk; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLHDSA_SHAKE128F: return SLH_DSA_SHAKE_128Fk; + #endif +#endif +#ifndef WOLFSSL_SLHDSA_NO_192 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLHDSA_SHAKE192S: return SLH_DSA_SHAKE_192Sk; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLHDSA_SHAKE192F: return SLH_DSA_SHAKE_192Fk; + #endif +#endif +#ifndef WOLFSSL_SLHDSA_NO_256 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLHDSA_SHAKE256S: return SLH_DSA_SHAKE_256Sk; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLHDSA_SHAKE256F: return SLH_DSA_SHAKE_256Fk; + #endif +#endif + default: + return BAD_FUNC_ARG; + } +} + +/* Map OID key type back to SlhDsaParam. Returns NOT_COMPILED_IN for + * SHA2-SLH-DSA OIDs - the wolfCrypt SLH-DSA backend is SHAKE-only + * today, so SHA2-SLH-DSA certs/keys are rejected loudly at decode + * rather than getting an uninformative BAD_FUNC_ARG. */ +static int slhdsa_keytype_to_param(int keytype) +{ + switch (keytype) { +#ifndef WOLFSSL_SLHDSA_NO_128 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLH_DSA_SHAKE_128Sk: return SLHDSA_SHAKE128S; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLH_DSA_SHAKE_128Fk: return SLHDSA_SHAKE128F; + #endif +#endif +#ifndef WOLFSSL_SLHDSA_NO_192 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLH_DSA_SHAKE_192Sk: return SLHDSA_SHAKE192S; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLH_DSA_SHAKE_192Fk: return SLHDSA_SHAKE192F; + #endif +#endif +#ifndef WOLFSSL_SLHDSA_NO_256 + #ifndef WOLFSSL_SLHDSA_PARAM_NO_SMALL + case SLH_DSA_SHAKE_256Sk: return SLHDSA_SHAKE256S; + #endif + #ifndef WOLFSSL_SLHDSA_PARAM_NO_FAST + case SLH_DSA_SHAKE_256Fk: return SLHDSA_SHAKE256F; + #endif +#endif + case SLH_DSA_SHA2_128Sk: + case SLH_DSA_SHA2_128Fk: + case SLH_DSA_SHA2_192Sk: + case SLH_DSA_SHA2_192Fk: + case SLH_DSA_SHA2_256Sk: + case SLH_DSA_SHA2_256Fk: + return NOT_COMPILED_IN; + default: + return BAD_FUNC_ARG; + } +} + +/* Find SlhDsaParameters entry for a given param enum. */ +static const SlhDsaParameters* slhdsa_find_params(enum SlhDsaParam param) +{ + int i; + for (i = 0; i < SLHDSA_PARAM_LEN; i++) { + if (SlhDsaParams[i].param == param) { + return &SlhDsaParams[i]; + } + } + return NULL; +} + +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY +/* Decode a DER-encoded SLH-DSA private key (PKCS#8 / OneAsymmetricKey). + * + * RFC 9909 Section 6: The privateKey OCTET STRING contains the raw + * concatenation SK.seed || SK.prf || PK.seed || PK.root (4*n bytes) + * directly, without a nested OCTET STRING wrapper. This differs from + * Ed25519/Ed448 which wrap the key in an additional OCTET STRING. + * + * The parameter set is detected from the AlgorithmIdentifier OID. + * On success, key->params is updated to match the detected parameter set. + * + * @param [in] input DER-encoded key data. + * @param [in, out] inOutIdx Index into input, updated on return. + * @param [in, out] key SLH-DSA key. Parameter set is auto-detected. + * @param [in] inSz Size of input in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when input, inOutIdx, or key is NULL. + * @return ASN_PARSE_E when the DER cannot be parsed as an SLH-DSA key. + */ +int wc_SlhDsaKey_PrivateKeyDecode(const byte* input, word32* inOutIdx, + SlhDsaKey* key, word32 inSz) +{ + int ret = 0; + int length; + int version; + word32 oid = 0; + word32 seqEnd; + int privSz; + int paramId; + const SlhDsaParameters* params; + + if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) { + return BAD_FUNC_ARG; + } + + /* Parse PKCS#8 OneAsymmetricKey wrapper: + * SEQUENCE { version, AlgorithmIdentifier { OID }, OCTET STRING { key }, + * [0] attributes OPTIONAL, [1] publicKey OPTIONAL } + */ + if (GetSequence(input, inOutIdx, &length, inSz) < 0) { + return ASN_PARSE_E; + } + seqEnd = *inOutIdx + (word32)length; + + if (GetMyVersion(input, inOutIdx, &version, inSz) < 0) { + return ASN_PARSE_E; + } + if (version != 0 && version != 1) { + return ASN_PARSE_E; + } + + if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0) { + return ASN_PARSE_E; + } + + /* Map the OID to an SLH-DSA parameter set. Pass through NOT_COMPILED_IN + * so callers can distinguish "SHA2-SLH-DSA present but unsupported" from + * "malformed DER". */ + paramId = slhdsa_keytype_to_param((int)oid); + if (paramId == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { + return NOT_COMPILED_IN; + } + if (paramId < 0) { + return ASN_PARSE_E; + } + params = slhdsa_find_params((enum SlhDsaParam)paramId); + if (params == NULL) { + return ASN_PARSE_E; + } + + /* RFC 9909: privateKey is a single OCTET STRING containing the raw key + * (4*n bytes). Unlike Ed25519/Ed448, there is no nested inner OCTET + * STRING wrapping. */ + if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) { + return ASN_PARSE_E; + } + + if (privSz != params->n * 4) { + return ASN_PARSE_E; + } + + { + const SlhDsaParameters* oldParams = key->params; + + /* Update the key's parameter set to the detected one. */ + key->params = params; + + /* Import the raw private key: SK.seed || SK.prf || PK.seed || PK.root */ + ret = wc_SlhDsaKey_ImportPrivate(key, input + *inOutIdx, + (word32)privSz); + if (ret == 0) { + /* Skip past any optional trailing fields (attributes, publicKey) + * per RFC 5958 OneAsymmetricKey. */ + *inOutIdx = seqEnd; + } + else { + /* Restore original params on failure. */ + key->params = oldParams; + } + } + + return ret; +} +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ + +/* Decode a DER-encoded SLH-DSA public key (SubjectPublicKeyInfo). + * + * The parameter set is detected from the AlgorithmIdentifier OID. + * On success, key->params is updated to match the detected parameter set. + * + * @param [in] input DER-encoded key data. + * @param [in, out] inOutIdx Index into input, updated on return. + * @param [in, out] key SLH-DSA key. Parameter set is auto-detected. + * @param [in] inSz Size of input in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when input, inOutIdx, or key is NULL. + * @return ASN_PARSE_E when the DER cannot be parsed as an SLH-DSA key. + */ +int wc_SlhDsaKey_PublicKeyDecode(const byte* input, word32* inOutIdx, + SlhDsaKey* key, word32 inSz) +{ + int ret; + int keytype = ANONk; + int paramId; + const SlhDsaParameters* params; + const SlhDsaParameters* oldParams; + const byte* pubKeyPtr = NULL; + word32 pubKeyLen = 0; + word32 savedIdx; + + if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) { + return BAD_FUNC_ARG; + } + + savedIdx = *inOutIdx; + + /* Use ANONk to auto-detect the OID from the SPKI AlgorithmIdentifier + * in a single parse. (PrivateKeyDecode parses each DER element + * manually because the PKCS#8 OneAsymmetricKey layout differs from + * SPKI and has no matching helper.) */ + ret = DecodeAsymKeyPublic_Assign(input, inOutIdx, inSz, &pubKeyPtr, + &pubKeyLen, &keytype); + if (ret != 0) { + return ret; + } + + /* Map the detected OID key type to an SLH-DSA parameter set. Pass + * through NOT_COMPILED_IN for SHA2-SLH-DSA so callers see the specific + * reason (unsupported variant) rather than a generic parse error. */ + paramId = slhdsa_keytype_to_param(keytype); + if (paramId == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { + *inOutIdx = savedIdx; + return NOT_COMPILED_IN; + } + if (paramId < 0) { + *inOutIdx = savedIdx; + return ASN_PARSE_E; + } + params = slhdsa_find_params((enum SlhDsaParam)paramId); + if (params == NULL) { + return ASN_PARSE_E; + } + + oldParams = key->params; + + key->params = params; + ret = wc_SlhDsaKey_ImportPublic(key, pubKeyPtr, pubKeyLen); + if (ret != 0) { + /* Restore original params and inOutIdx so the caller sees a + * clean failure, matching wc_SlhDsaKey_PrivateKeyDecode. */ + key->params = oldParams; + *inOutIdx = savedIdx; + } + + return ret; +} + +#ifdef WC_ENABLE_ASYM_KEY_EXPORT +/* Encode an SLH-DSA public key to DER. + * + * Pass NULL for output to get the size of the encoding. + * + * @param [in] key SLH-DSA key object. + * @param [out] output Buffer to put encoded data in. + * @param [in] inLen Size of buffer in bytes. + * @param [in] withAlg Whether to use SubjectPublicKeyInfo format. + * @return Size of encoded data in bytes on success. + * @return BAD_FUNC_ARG when key is NULL. + */ +int wc_SlhDsaKey_PublicKeyToDer(SlhDsaKey* key, byte* output, word32 inLen, + int withAlg) +{ + int ret; + byte pubKey[WC_SLHDSA_MAX_PUB_LEN]; + word32 pubKeyLen = (word32)sizeof(pubKey); + int keytype; + + if ((key == NULL) || (key->params == NULL)) { + return BAD_FUNC_ARG; + } + + keytype = slhdsa_param_to_keytype(key->params->param); + if (keytype < 0) { + return BAD_FUNC_ARG; + } + + ret = wc_SlhDsaKey_ExportPublic(key, pubKey, &pubKeyLen); + if (ret == 0) { + ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen, keytype, + withAlg); + } + + return ret; +} + +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY +/* Encode an SLH-DSA private key to DER (PKCS#8 / OneAsymmetricKey). + * + * RFC 9909: The privateKey OCTET STRING contains the raw 4*n bytes + * (SK.seed || SK.prf || PK.seed || PK.root) directly, without a nested + * OCTET STRING wrapper. This differs from Ed25519/Ed448 which use a + * double OCTET STRING wrapping. + * + * Pass NULL for output to get the required buffer size. + * + * @param [in] key SLH-DSA key object. + * @param [out] output Buffer to put encoded data in (or NULL for size). + * @param [in] inLen Size of buffer in bytes. + * @return Size of encoded data in bytes on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MISSING_KEY when private key not set. + * @return BUFFER_E when output buffer is too small. + */ +int wc_SlhDsaKey_KeyToDer(SlhDsaKey* key, byte* output, word32 inLen) +{ + int keytype; + int n; + word32 privSz, algoSz, verSz, seqSz, sz; + + if ((key == NULL) || (key->params == NULL)) { + return BAD_FUNC_ARG; + } + if ((key->flags & WC_SLHDSA_FLAG_PRIVATE) == 0) { + return MISSING_KEY; + } + + keytype = slhdsa_param_to_keytype(key->params->param); + if (keytype < 0) { + return BAD_FUNC_ARG; + } + + n = key->params->n; + /* RFC 9909: bare OCTET STRING containing 4*n raw key bytes */ + privSz = SetOctetString((word32)(n * 4), NULL) + (word32)(n * 4); + algoSz = SetAlgoID(keytype, NULL, oidKeyType, 0); + verSz = 3; /* ASN_INTEGER(1) + length(1) + version_byte(1) */ + seqSz = SetSequence(verSz + algoSz + privSz, NULL); + sz = seqSz + verSz + algoSz + privSz; + + if (output == NULL) { + return (int)sz; + } + if (sz > inLen) { + return BUFFER_E; + } + + { + word32 idx = 0; + idx += SetSequence(verSz + algoSz + privSz, output + idx); + idx += (word32)SetMyVersion(0, output + idx, FALSE); + idx += SetAlgoID(keytype, output + idx, oidKeyType, 0); + idx += SetOctetString((word32)(n * 4), output + idx); + XMEMCPY(output + idx, key->sk, (word32)(n * 4)); + idx += (word32)(n * 4); + return (int)idx; + } +} + +/* Encode an SLH-DSA private key to DER (PKCS#8 / OneAsymmetricKey). + * + * For SLH-DSA, RFC 9909 packs SK.seed || SK.prf || PK.seed || PK.root into + * a single OCTET STRING, so there is no separate "private-only" encoding. + * This function is intentionally an alias of wc_SlhDsaKey_KeyToDer, kept + * for API parity with Ed25519/Ed448 which do have a distinct private form. + * + * @param [in] key SLH-DSA key object. + * @param [out] output Buffer to put encoded data in (or NULL for size). + * @param [in] inLen Size of buffer in bytes. + * @return Size of encoded data in bytes on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MISSING_KEY when private key not set. + * @return BUFFER_E when output buffer is too small. + */ +int wc_SlhDsaKey_PrivateKeyToDer(SlhDsaKey* key, byte* output, word32 inLen) +{ + return wc_SlhDsaKey_KeyToDer(key, output, inLen); +} +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ +#endif /* WC_ENABLE_ASYM_KEY_EXPORT */ + #endif /* WOLFSSL_HAVE_SLHDSA */ diff --git a/wolfssl-VS2022.vcxproj b/wolfssl-VS2022.vcxproj index d5e13a39645..0bccef768b6 100644 --- a/wolfssl-VS2022.vcxproj +++ b/wolfssl-VS2022.vcxproj @@ -460,7 +460,6 @@ - diff --git a/wolfssl.vcproj b/wolfssl.vcproj index 02554722d2a..0303a254181 100644 --- a/wolfssl.vcproj +++ b/wolfssl.vcproj @@ -375,10 +375,6 @@ RelativePath=".\wolfcrypt\src\sha512.c" > - - diff --git a/wolfssl.vcxproj b/wolfssl.vcxproj index 58410b144a7..afd78c4175d 100644 --- a/wolfssl.vcxproj +++ b/wolfssl.vcxproj @@ -460,7 +460,6 @@ - diff --git a/wolfssl/certs_test.h b/wolfssl/certs_test.h index efd4c1bd288..000f384f2f5 100644 --- a/wolfssl/certs_test.h +++ b/wolfssl/certs_test.h @@ -5911,148 +5911,6 @@ static const unsigned char bench_dilithium_level5_pubkey[] = { #endif /* HAVE_DILITHIUM */ -#if defined(HAVE_SPHINCS) - -/* certs/sphincs/bench_sphincs_fast_level1_key.der */ -static const unsigned char bench_sphincs_fast_level1_key[] = -{ - 0x30, 0x71, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, 0x2B, - 0xCE, 0x0F, 0x06, 0x07, 0x0D, 0x04, 0x62, 0x04, 0x60, 0xD8, - 0xC4, 0x6E, 0x8D, 0x3B, 0xB7, 0xE7, 0x48, 0x8D, 0x6F, 0x0C, - 0x3D, 0xDF, 0xAB, 0x79, 0xB6, 0x62, 0xAE, 0x89, 0x19, 0x6F, - 0x5E, 0xF9, 0xD3, 0x3A, 0x69, 0xBA, 0xFF, 0x4C, 0x46, 0xDE, - 0xAA, 0x7C, 0x40, 0x79, 0x8C, 0xE1, 0xE5, 0x30, 0xE6, 0xDF, - 0x4E, 0x23, 0x5E, 0x14, 0xDB, 0x0A, 0x48, 0x4E, 0xF6, 0x57, - 0xCE, 0x45, 0x8F, 0x8B, 0x1D, 0x68, 0x63, 0xAA, 0x24, 0xA4, - 0xE1, 0x0D, 0xFB, 0x7C, 0x40, 0x79, 0x8C, 0xE1, 0xE5, 0x30, - 0xE6, 0xDF, 0x4E, 0x23, 0x5E, 0x14, 0xDB, 0x0A, 0x48, 0x4E, - 0xF6, 0x57, 0xCE, 0x45, 0x8F, 0x8B, 0x1D, 0x68, 0x63, 0xAA, - 0x24, 0xA4, 0xE1, 0x0D, 0xFB -}; -#define sizeof_bench_sphincs_fast_level1_key (sizeof(bench_sphincs_fast_level1_key)) - -/* certs/sphincs/bench_sphincs_fast_level3_key.der */ -static const unsigned char bench_sphincs_fast_level3_key[] = -{ - 0x30, 0x81, 0xA3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, - 0x2B, 0xCE, 0x0F, 0x06, 0x08, 0x0A, 0x04, 0x81, 0x93, 0x04, - 0x81, 0x90, 0xB2, 0x3A, 0x67, 0xA6, 0x4B, 0x8E, 0xB9, 0xEF, - 0xAD, 0x99, 0xE4, 0x3D, 0x65, 0xE8, 0xEE, 0xCF, 0xAC, 0xCF, - 0x2F, 0xDE, 0xBC, 0x11, 0x67, 0x8D, 0x8F, 0x8D, 0x3E, 0x99, - 0x31, 0x67, 0xED, 0x31, 0x6A, 0x05, 0x47, 0xC1, 0xDA, 0xC5, - 0x14, 0x17, 0xA1, 0x93, 0x83, 0x44, 0x58, 0x09, 0x80, 0x3A, - 0x47, 0x67, 0x42, 0x6D, 0x4C, 0xB7, 0xC8, 0x7D, 0x37, 0xF3, - 0x90, 0xF7, 0x46, 0x92, 0xB6, 0x26, 0xF7, 0x4E, 0x0D, 0x8D, - 0xB8, 0xCA, 0x8B, 0xA8, 0x20, 0x5D, 0x67, 0x85, 0xD2, 0x83, - 0x2C, 0x2A, 0x38, 0x1F, 0x57, 0x89, 0x76, 0x8C, 0x6D, 0x88, - 0xCE, 0x18, 0x4F, 0xA7, 0x88, 0x48, 0x7C, 0x0D, 0x47, 0x67, - 0x42, 0x6D, 0x4C, 0xB7, 0xC8, 0x7D, 0x37, 0xF3, 0x90, 0xF7, - 0x46, 0x92, 0xB6, 0x26, 0xF7, 0x4E, 0x0D, 0x8D, 0xB8, 0xCA, - 0x8B, 0xA8, 0x20, 0x5D, 0x67, 0x85, 0xD2, 0x83, 0x2C, 0x2A, - 0x38, 0x1F, 0x57, 0x89, 0x76, 0x8C, 0x6D, 0x88, 0xCE, 0x18, - 0x4F, 0xA7, 0x88, 0x48, 0x7C, 0x0D -}; -#define sizeof_bench_sphincs_fast_level3_key (sizeof(bench_sphincs_fast_level3_key)) - -/* certs/sphincs/bench_sphincs_fast_level5_key.der */ -static const unsigned char bench_sphincs_fast_level5_key[] = -{ - 0x30, 0x81, 0xD3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, - 0x2B, 0xCE, 0x0F, 0x06, 0x09, 0x0A, 0x04, 0x81, 0xC3, 0x04, - 0x81, 0xC0, 0xAB, 0xD3, 0xFD, 0x3B, 0x17, 0x00, 0xCD, 0xD5, - 0xB2, 0xEE, 0xD2, 0x36, 0xE5, 0xF7, 0x1D, 0xDC, 0xC8, 0x42, - 0xDB, 0x53, 0x6A, 0x8A, 0x0D, 0x6D, 0xD2, 0x3C, 0x1C, 0x7C, - 0x98, 0x4D, 0x73, 0xC8, 0xAB, 0x2E, 0xAA, 0x7A, 0xC0, 0x26, - 0xC4, 0x0D, 0x7E, 0xB4, 0xD3, 0xBB, 0x13, 0xF4, 0x6E, 0xFE, - 0x0E, 0xA5, 0xA4, 0x58, 0x57, 0xA2, 0xDD, 0x99, 0x62, 0xB9, - 0xBA, 0xC2, 0x5B, 0x26, 0xED, 0x6E, 0x99, 0xFA, 0x11, 0x0E, - 0xCF, 0x33, 0x54, 0x85, 0x56, 0x0C, 0xEB, 0x2A, 0xB0, 0xAA, - 0xEB, 0x74, 0x14, 0x89, 0x1A, 0xB9, 0x38, 0xF5, 0x29, 0x66, - 0x28, 0x28, 0x17, 0xF5, 0x72, 0x42, 0xEE, 0xC0, 0x14, 0x59, - 0xA0, 0x72, 0x9B, 0x9B, 0x1E, 0x7F, 0x70, 0x70, 0xBB, 0x89, - 0x0C, 0x7E, 0x87, 0x8B, 0x83, 0x80, 0x2B, 0x66, 0x58, 0x64, - 0x1D, 0x94, 0xAF, 0x58, 0xB5, 0x23, 0x2C, 0xA1, 0xE9, 0x95, - 0x99, 0xFA, 0x11, 0x0E, 0xCF, 0x33, 0x54, 0x85, 0x56, 0x0C, - 0xEB, 0x2A, 0xB0, 0xAA, 0xEB, 0x74, 0x14, 0x89, 0x1A, 0xB9, - 0x38, 0xF5, 0x29, 0x66, 0x28, 0x28, 0x17, 0xF5, 0x72, 0x42, - 0xEE, 0xC0, 0x14, 0x59, 0xA0, 0x72, 0x9B, 0x9B, 0x1E, 0x7F, - 0x70, 0x70, 0xBB, 0x89, 0x0C, 0x7E, 0x87, 0x8B, 0x83, 0x80, - 0x2B, 0x66, 0x58, 0x64, 0x1D, 0x94, 0xAF, 0x58, 0xB5, 0x23, - 0x2C, 0xA1, 0xE9, 0x95 -}; -#define sizeof_bench_sphincs_fast_level5_key (sizeof(bench_sphincs_fast_level5_key)) - -/* certs/sphincs/bench_sphincs_small_level1_key.der */ -static const unsigned char bench_sphincs_small_level1_key[] = -{ - 0x30, 0x71, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, 0x2B, - 0xCE, 0x0F, 0x06, 0x07, 0x10, 0x04, 0x62, 0x04, 0x60, 0xFF, - 0x26, 0x56, 0x65, 0xAC, 0x6C, 0x0B, 0x72, 0x2D, 0x8D, 0xB8, - 0x29, 0x4A, 0x15, 0x7E, 0xEF, 0x55, 0xFD, 0xBE, 0xF4, 0xC0, - 0xE6, 0x6F, 0x2B, 0x7A, 0x97, 0x60, 0x51, 0x1C, 0xCB, 0x82, - 0x43, 0x44, 0xDE, 0x14, 0x3D, 0x4F, 0xE7, 0x3C, 0x1C, 0xB3, - 0xBB, 0x9F, 0xE8, 0x9F, 0x8F, 0xA4, 0xAD, 0xB9, 0x52, 0xC1, - 0x31, 0xF7, 0xC1, 0x86, 0x7E, 0x73, 0xFB, 0x9E, 0x72, 0x57, - 0x8A, 0xD7, 0x44, 0x44, 0xDE, 0x14, 0x3D, 0x4F, 0xE7, 0x3C, - 0x1C, 0xB3, 0xBB, 0x9F, 0xE8, 0x9F, 0x8F, 0xA4, 0xAD, 0xB9, - 0x52, 0xC1, 0x31, 0xF7, 0xC1, 0x86, 0x7E, 0x73, 0xFB, 0x9E, - 0x72, 0x57, 0x8A, 0xD7, 0x44 -}; -#define sizeof_bench_sphincs_small_level1_key (sizeof(bench_sphincs_small_level1_key)) - -/* certs/sphincs/bench_sphincs_small_level3_key.der */ -static const unsigned char bench_sphincs_small_level3_key[] = -{ - 0x30, 0x81, 0xA3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, - 0x2B, 0xCE, 0x0F, 0x06, 0x08, 0x0C, 0x04, 0x81, 0x93, 0x04, - 0x81, 0x90, 0x59, 0xC1, 0x44, 0x8A, 0x5F, 0xF3, 0xF1, 0xB3, - 0xB8, 0xFF, 0x98, 0x7F, 0x86, 0x4A, 0x4C, 0x19, 0xFC, 0x51, - 0xB8, 0x12, 0x87, 0x9C, 0x52, 0xD6, 0x7F, 0xD6, 0xB0, 0xA9, - 0xF7, 0xED, 0x44, 0x26, 0xAF, 0xC2, 0xCE, 0x47, 0xD9, 0xE3, - 0x95, 0x1A, 0xE6, 0x11, 0xC1, 0x37, 0x67, 0xA5, 0x89, 0xDD, - 0x37, 0x6A, 0xE9, 0xC3, 0x8C, 0x9B, 0x3E, 0xBA, 0xB1, 0x76, - 0x4A, 0x5A, 0xEE, 0xCD, 0x96, 0x66, 0xF2, 0x53, 0xDA, 0x8C, - 0x89, 0x69, 0xBF, 0xBF, 0xF9, 0xA5, 0xBC, 0x7D, 0x80, 0xA8, - 0x97, 0x63, 0x90, 0x55, 0x58, 0x6C, 0x0A, 0x52, 0x61, 0x0B, - 0xF3, 0xBC, 0xE1, 0x1F, 0xB4, 0xA6, 0x5F, 0x9F, 0x37, 0x6A, - 0xE9, 0xC3, 0x8C, 0x9B, 0x3E, 0xBA, 0xB1, 0x76, 0x4A, 0x5A, - 0xEE, 0xCD, 0x96, 0x66, 0xF2, 0x53, 0xDA, 0x8C, 0x89, 0x69, - 0xBF, 0xBF, 0xF9, 0xA5, 0xBC, 0x7D, 0x80, 0xA8, 0x97, 0x63, - 0x90, 0x55, 0x58, 0x6C, 0x0A, 0x52, 0x61, 0x0B, 0xF3, 0xBC, - 0xE1, 0x1F, 0xB4, 0xA6, 0x5F, 0x9F -}; -#define sizeof_bench_sphincs_small_level3_key (sizeof(bench_sphincs_small_level3_key)) - -/* certs/sphincs/bench_sphincs_small_level5_key.der */ -static const unsigned char bench_sphincs_small_level5_key[] = -{ - 0x30, 0x81, 0xD3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, - 0x2B, 0xCE, 0x0F, 0x06, 0x09, 0x0C, 0x04, 0x81, 0xC3, 0x04, - 0x81, 0xC0, 0x53, 0xE5, 0x25, 0x41, 0x1C, 0xCB, 0x8F, 0xAF, - 0x83, 0xBE, 0x64, 0x43, 0x70, 0x4E, 0x1D, 0x86, 0xF8, 0xFA, - 0xEA, 0x65, 0x9B, 0x45, 0xBC, 0xF1, 0x79, 0x57, 0x87, 0x51, - 0x2F, 0x6D, 0x50, 0xB8, 0x0D, 0x9A, 0x9F, 0x8C, 0xE8, 0x9B, - 0xE8, 0xFA, 0x1E, 0xF0, 0xA1, 0x98, 0xCA, 0x8B, 0x34, 0xD4, - 0x71, 0x53, 0xF0, 0xA7, 0x1D, 0xD6, 0x0D, 0xDF, 0x63, 0x61, - 0xA7, 0x12, 0x80, 0x64, 0xF7, 0x73, 0x14, 0x03, 0xD4, 0x54, - 0x01, 0x9D, 0x9D, 0x5D, 0x42, 0xC1, 0x2B, 0x91, 0xC3, 0xA2, - 0xD3, 0x12, 0x67, 0x35, 0x3B, 0xD7, 0x67, 0x31, 0xD5, 0xDC, - 0xDF, 0x4C, 0x4C, 0xAA, 0x45, 0xA8, 0x5D, 0x1E, 0xFB, 0x9E, - 0x34, 0x5D, 0x4B, 0x83, 0x77, 0xBF, 0x52, 0x8A, 0xDB, 0x67, - 0x7A, 0x52, 0xA4, 0x02, 0x29, 0xEB, 0x34, 0x9A, 0x4E, 0x86, - 0x25, 0x66, 0xFF, 0xA0, 0x79, 0x47, 0xBE, 0x94, 0xC2, 0x69, - 0x14, 0x03, 0xD4, 0x54, 0x01, 0x9D, 0x9D, 0x5D, 0x42, 0xC1, - 0x2B, 0x91, 0xC3, 0xA2, 0xD3, 0x12, 0x67, 0x35, 0x3B, 0xD7, - 0x67, 0x31, 0xD5, 0xDC, 0xDF, 0x4C, 0x4C, 0xAA, 0x45, 0xA8, - 0x5D, 0x1E, 0xFB, 0x9E, 0x34, 0x5D, 0x4B, 0x83, 0x77, 0xBF, - 0x52, 0x8A, 0xDB, 0x67, 0x7A, 0x52, 0xA4, 0x02, 0x29, 0xEB, - 0x34, 0x9A, 0x4E, 0x86, 0x25, 0x66, 0xFF, 0xA0, 0x79, 0x47, - 0xBE, 0x94, 0xC2, 0x69 -}; -#define sizeof_bench_sphincs_small_level5_key (sizeof(bench_sphincs_small_level5_key)) - -#endif /* HAVE_SPHINCS */ - #if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) /* ./certs/ecc-client-key.der, ECC */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index b3028c9c99d..51981abad3a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -67,8 +67,8 @@ that can be serialized and deserialized in a cross-platform way. #ifdef HAVE_ED448 #include #endif -#ifdef HAVE_SPHINCS - #include +#ifdef WOLFSSL_HAVE_SLHDSA + #include #endif #ifdef HAVE_FALCON #include @@ -1538,7 +1538,7 @@ struct SignatureCtx { #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ !defined(NO_DSA) || defined(HAVE_DILITHIUM) || defined(HAVE_FALCON) || \ - defined(HAVE_SPHINCS) + defined(WOLFSSL_HAVE_SLHDSA) int verify; #endif union { @@ -1591,11 +1591,11 @@ struct SignatureCtx { struct dilithium_key* dilithium; #endif #endif - #ifdef HAVE_SPHINCS + #ifdef WOLFSSL_HAVE_SLHDSA #ifdef WOLFSSL_NO_MALLOC - struct sphincs_key sphincs[1]; + SlhDsaKey slhdsa[1]; #else - struct sphincs_key* sphincs; + SlhDsaKey* slhdsa; #endif #endif #ifndef WOLFSSL_NO_MALLOC @@ -1852,13 +1852,14 @@ struct DecodedCert { #endif /* WOLFSSL_SUBJ_INFO_ACC */ #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ - defined(HAVE_DILITHIUM) || defined(HAVE_FALCON) || defined(HAVE_SPHINCS) + defined(HAVE_DILITHIUM) || defined(HAVE_FALCON) || \ + defined(WOLFSSL_HAVE_SLHDSA) word32 pkCurveOID; /* Public Key's curve OID */ #ifdef WOLFSSL_CUSTOM_CURVES int pkCurveSize; /* Public Key's curve size */ #endif #endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 || HAVE_DILITHIUM || - * HAVE_FALCON || HAVE_SPHINCS */ + * HAVE_FALCON || WOLFSSL_HAVE_SLHDSA */ const byte* beforeDate; int beforeDateLen; const byte* afterDate; @@ -2680,12 +2681,18 @@ enum cert_enums { ML_DSA_LEVEL2_KEY = 21, ML_DSA_LEVEL3_KEY = 22, ML_DSA_LEVEL5_KEY = 23, - SPHINCS_FAST_LEVEL1_KEY = 24, - SPHINCS_FAST_LEVEL3_KEY = 25, - SPHINCS_FAST_LEVEL5_KEY = 26, - SPHINCS_SMALL_LEVEL1_KEY = 27, - SPHINCS_SMALL_LEVEL3_KEY = 28, - SPHINCS_SMALL_LEVEL5_KEY = 29 + SLH_DSA_SHA2_128S_KEY = 24, + SLH_DSA_SHA2_128F_KEY = 25, + SLH_DSA_SHA2_192S_KEY = 26, + SLH_DSA_SHA2_192F_KEY = 27, + SLH_DSA_SHA2_256S_KEY = 28, + SLH_DSA_SHA2_256F_KEY = 29, + SLH_DSA_SHAKE_128S_KEY = 30, + SLH_DSA_SHAKE_128F_KEY = 31, + SLH_DSA_SHAKE_192S_KEY = 32, + SLH_DSA_SHAKE_192F_KEY = 33, + SLH_DSA_SHAKE_256S_KEY = 34, + SLH_DSA_SHAKE_256F_KEY = 35 }; #endif /* WOLFSSL_CERT_GEN */ @@ -3123,7 +3130,7 @@ WOLFSSL_TEST_VIS int wolfssl_local_MatchIpSubnet(const byte* ip, int ipSz, || (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \ || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \ || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \ - || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS)) + || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(WOLFSSL_HAVE_SLHDSA)) WOLFSSL_LOCAL int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz, const byte** seed, word32* seedLen, const byte** privKey, word32* privKeyLen, const byte** pubKey, word32* pubKeyLen, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 3d4a78b598c..3d12d337d7a 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -78,9 +78,9 @@ This library defines the interface APIs for X509 certificates. typedef struct dilithium_key dilithium_key; #define WC_DILITHIUMKEY_TYPE_DEFINED #endif -#ifndef WC_SPHINCSKEY_TYPE_DEFINED - typedef struct sphincs_key sphincs_key; - #define WC_SPHINCSKEY_TYPE_DEFINED +#ifndef WC_SLHDSAKEY_TYPE_DEFINED + typedef struct SlhDsaKey SlhDsaKey; + #define WC_SLHDSAKEY_TYPE_DEFINED #endif enum EncPkcs8Types { @@ -140,12 +140,18 @@ enum CertType { ML_DSA_LEVEL2_TYPE, ML_DSA_LEVEL3_TYPE, ML_DSA_LEVEL5_TYPE, - SPHINCS_FAST_LEVEL1_TYPE, - SPHINCS_FAST_LEVEL3_TYPE, - SPHINCS_FAST_LEVEL5_TYPE, - SPHINCS_SMALL_LEVEL1_TYPE, - SPHINCS_SMALL_LEVEL3_TYPE, - SPHINCS_SMALL_LEVEL5_TYPE, + SLH_DSA_SHA2_128S_TYPE, + SLH_DSA_SHA2_128F_TYPE, + SLH_DSA_SHA2_192S_TYPE, + SLH_DSA_SHA2_192F_TYPE, + SLH_DSA_SHA2_256S_TYPE, + SLH_DSA_SHA2_256F_TYPE, + SLH_DSA_SHAKE_128S_TYPE, + SLH_DSA_SHAKE_128F_TYPE, + SLH_DSA_SHAKE_192S_TYPE, + SLH_DSA_SHAKE_192F_TYPE, + SLH_DSA_SHAKE_256S_TYPE, + SLH_DSA_SHAKE_256F_TYPE, ECC_PARAM_TYPE, CHAIN_CERT_TYPE, PKCS7_TYPE, diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 1c23469d206..7f4edb7073f 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -25,7 +25,7 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/ed448.h \ wolfssl/wolfcrypt/falcon.h \ wolfssl/wolfcrypt/dilithium.h \ - wolfssl/wolfcrypt/sphincs.h \ + wolfssl/wolfcrypt/wc_slhdsa.h \ wolfssl/wolfcrypt/fe_448.h \ wolfssl/wolfcrypt/ge_448.h \ wolfssl/wolfcrypt/eccsi.h \ diff --git a/wolfssl/wolfcrypt/oid_sum.h b/wolfssl/wolfcrypt/oid_sum.h index e1fbee5f44c..effd564ed2f 100644 --- a/wolfssl/wolfcrypt/oid_sum.h +++ b/wolfssl/wolfcrypt/oid_sum.h @@ -196,18 +196,30 @@ enum Key_Sum { ML_DSA_LEVEL3k = 432, /* 2.16.840.1.101.3.4.3.18 */ /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x13 */ ML_DSA_LEVEL5k = 433, /* 2.16.840.1.101.3.4.3.19 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x04 */ - SPHINCS_FAST_LEVEL1k = 281, /* 1.3.9999.6.7.4 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x03 */ - SPHINCS_FAST_LEVEL3k = 283, /* 1.3.9999.6.8.3 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x03 */ - SPHINCS_FAST_LEVEL5k = 282, /* 1.3.9999.6.9.3 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x0a */ - SPHINCS_SMALL_LEVEL1k = 287, /* 1.3.9999.6.7.10 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x07 */ - SPHINCS_SMALL_LEVEL3k = 285, /* 1.3.9999.6.8.7 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x07 */ - SPHINCS_SMALL_LEVEL5k = 286 /* 1.3.9999.6.9.7 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x14 */ + SLH_DSA_SHA2_128Sk = 434, /* 2.16.840.1.101.3.4.3.20 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x15 */ + SLH_DSA_SHA2_128Fk = 435, /* 2.16.840.1.101.3.4.3.21 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x16 */ + SLH_DSA_SHA2_192Sk = 436, /* 2.16.840.1.101.3.4.3.22 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x17 */ + SLH_DSA_SHA2_192Fk = 437, /* 2.16.840.1.101.3.4.3.23 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x18 */ + SLH_DSA_SHA2_256Sk = 438, /* 2.16.840.1.101.3.4.3.24 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x19 */ + SLH_DSA_SHA2_256Fk = 439, /* 2.16.840.1.101.3.4.3.25 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1a */ + SLH_DSA_SHAKE_128Sk = 440, /* 2.16.840.1.101.3.4.3.26 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1b */ + SLH_DSA_SHAKE_128Fk = 441, /* 2.16.840.1.101.3.4.3.27 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1c */ + SLH_DSA_SHAKE_192Sk = 442, /* 2.16.840.1.101.3.4.3.28 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1d */ + SLH_DSA_SHAKE_192Fk = 443, /* 2.16.840.1.101.3.4.3.29 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1e */ + SLH_DSA_SHAKE_256Sk = 444, /* 2.16.840.1.101.3.4.3.30 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1f */ + SLH_DSA_SHAKE_256Fk = 445 /* 2.16.840.1.101.3.4.3.31 */ #else /* 0x00 */ ANONk = 0x7fffffff, /* 0.0 */ @@ -249,18 +261,30 @@ enum Key_Sum { ML_DSA_LEVEL3k = 0x7db37ae8, /* 2.16.840.1.101.3.4.3.18 */ /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x13 */ ML_DSA_LEVEL5k = 0x7db37ae9, /* 2.16.840.1.101.3.4.3.19 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x04 */ - SPHINCS_FAST_LEVEL1k = 0x06f0ca2c, /* 1.3.9999.6.7.4 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x03 */ - SPHINCS_FAST_LEVEL3k = 0x06f0cd23, /* 1.3.9999.6.8.3 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x03 */ - SPHINCS_FAST_LEVEL5k = 0x06f0cd22, /* 1.3.9999.6.9.3 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x0a */ - SPHINCS_SMALL_LEVEL1k = 0x06f0c42c, /* 1.3.9999.6.7.10 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x07 */ - SPHINCS_SMALL_LEVEL3k = 0x06f0c923, /* 1.3.9999.6.8.7 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x07 */ - SPHINCS_SMALL_LEVEL5k = 0x06f0c922 /* 1.3.9999.6.9.7 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x14 */ + SLH_DSA_SHA2_128Sk = 0x7db37aee, /* 2.16.840.1.101.3.4.3.20 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x15 */ + SLH_DSA_SHA2_128Fk = 0x7db37aef, /* 2.16.840.1.101.3.4.3.21 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x16 */ + SLH_DSA_SHA2_192Sk = 0x7db37aec, /* 2.16.840.1.101.3.4.3.22 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x17 */ + SLH_DSA_SHA2_192Fk = 0x7db37aed, /* 2.16.840.1.101.3.4.3.23 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x18 */ + SLH_DSA_SHA2_256Sk = 0x7db37ae2, /* 2.16.840.1.101.3.4.3.24 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x19 */ + SLH_DSA_SHA2_256Fk = 0x7db37ae3, /* 2.16.840.1.101.3.4.3.25 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1a */ + SLH_DSA_SHAKE_128Sk = 0x7db37ae0, /* 2.16.840.1.101.3.4.3.26 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1b */ + SLH_DSA_SHAKE_128Fk = 0x7db37ae1, /* 2.16.840.1.101.3.4.3.27 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1c */ + SLH_DSA_SHAKE_192Sk = 0x7db37ae6, /* 2.16.840.1.101.3.4.3.28 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1d */ + SLH_DSA_SHAKE_192Fk = 0x7db37ae7, /* 2.16.840.1.101.3.4.3.29 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1e */ + SLH_DSA_SHAKE_256Sk = 0x7db37ae4, /* 2.16.840.1.101.3.4.3.30 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1f */ + SLH_DSA_SHAKE_256Fk = 0x7db37ae5 /* 2.16.840.1.101.3.4.3.31 */ #endif }; @@ -1572,18 +1596,30 @@ enum Ctc_SigType { CTC_ML_DSA_LEVEL3 = 432, /* 2.16.840.1.101.3.4.3.18 */ /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x13 */ CTC_ML_DSA_LEVEL5 = 433, /* 2.16.840.1.101.3.4.3.19 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x04 */ - CTC_SPHINCS_FAST_LEVEL1 = 281, /* 1.3.9999.6.7.4 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x03 */ - CTC_SPHINCS_FAST_LEVEL3 = 283, /* 1.3.9999.6.8.3 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x03 */ - CTC_SPHINCS_FAST_LEVEL5 = 282, /* 1.3.9999.6.9.3 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x0a */ - CTC_SPHINCS_SMALL_LEVEL1 = 287, /* 1.3.9999.6.7.10 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x07 */ - CTC_SPHINCS_SMALL_LEVEL3 = 285, /* 1.3.9999.6.8.7 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x07 */ - CTC_SPHINCS_SMALL_LEVEL5 = 286 /* 1.3.9999.6.9.7 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x14 */ + CTC_SLH_DSA_SHA2_128S = 434, /* 2.16.840.1.101.3.4.3.20 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x15 */ + CTC_SLH_DSA_SHA2_128F = 435, /* 2.16.840.1.101.3.4.3.21 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x16 */ + CTC_SLH_DSA_SHA2_192S = 436, /* 2.16.840.1.101.3.4.3.22 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x17 */ + CTC_SLH_DSA_SHA2_192F = 437, /* 2.16.840.1.101.3.4.3.23 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x18 */ + CTC_SLH_DSA_SHA2_256S = 438, /* 2.16.840.1.101.3.4.3.24 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x19 */ + CTC_SLH_DSA_SHA2_256F = 439, /* 2.16.840.1.101.3.4.3.25 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1a */ + CTC_SLH_DSA_SHAKE_128S = 440, /* 2.16.840.1.101.3.4.3.26 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1b */ + CTC_SLH_DSA_SHAKE_128F = 441, /* 2.16.840.1.101.3.4.3.27 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1c */ + CTC_SLH_DSA_SHAKE_192S = 442, /* 2.16.840.1.101.3.4.3.28 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1d */ + CTC_SLH_DSA_SHAKE_192F = 443, /* 2.16.840.1.101.3.4.3.29 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1e */ + CTC_SLH_DSA_SHAKE_256S = 444, /* 2.16.840.1.101.3.4.3.30 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1f */ + CTC_SLH_DSA_SHAKE_256F = 445 /* 2.16.840.1.101.3.4.3.31 */ #else /* 0x2a,0x86,0x48,0xce,0x38,0x04,0x03 */ CTC_SHAwDSA = 0x314b8212, /* 1.2.840.10040.4.3 */ @@ -1653,18 +1689,30 @@ enum Ctc_SigType { CTC_ML_DSA_LEVEL3 = 0x7db37ae8, /* 2.16.840.1.101.3.4.3.18 */ /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x13 */ CTC_ML_DSA_LEVEL5 = 0x7db37ae9, /* 2.16.840.1.101.3.4.3.19 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x04 */ - CTC_SPHINCS_FAST_LEVEL1 = 0x06f0ca2c, /* 1.3.9999.6.7.4 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x03 */ - CTC_SPHINCS_FAST_LEVEL3 = 0x06f0cd23, /* 1.3.9999.6.8.3 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x03 */ - CTC_SPHINCS_FAST_LEVEL5 = 0x06f0cd22, /* 1.3.9999.6.9.3 */ - /* 0x2b,0xce,0x0f,0x06,0x07,0x0a */ - CTC_SPHINCS_SMALL_LEVEL1 = 0x06f0c42c, /* 1.3.9999.6.7.10 */ - /* 0x2b,0xce,0x0f,0x06,0x08,0x07 */ - CTC_SPHINCS_SMALL_LEVEL3 = 0x06f0c923, /* 1.3.9999.6.8.7 */ - /* 0x2b,0xce,0x0f,0x06,0x09,0x07 */ - CTC_SPHINCS_SMALL_LEVEL5 = 0x06f0c922 /* 1.3.9999.6.9.7 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x14 */ + CTC_SLH_DSA_SHA2_128S = 0x7db37aee, /* 2.16.840.1.101.3.4.3.20 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x15 */ + CTC_SLH_DSA_SHA2_128F = 0x7db37aef, /* 2.16.840.1.101.3.4.3.21 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x16 */ + CTC_SLH_DSA_SHA2_192S = 0x7db37aec, /* 2.16.840.1.101.3.4.3.22 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x17 */ + CTC_SLH_DSA_SHA2_192F = 0x7db37aed, /* 2.16.840.1.101.3.4.3.23 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x18 */ + CTC_SLH_DSA_SHA2_256S = 0x7db37ae2, /* 2.16.840.1.101.3.4.3.24 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x19 */ + CTC_SLH_DSA_SHA2_256F = 0x7db37ae3, /* 2.16.840.1.101.3.4.3.25 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1a */ + CTC_SLH_DSA_SHAKE_128S = 0x7db37ae0, /* 2.16.840.1.101.3.4.3.26 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1b */ + CTC_SLH_DSA_SHAKE_128F = 0x7db37ae1, /* 2.16.840.1.101.3.4.3.27 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1c */ + CTC_SLH_DSA_SHAKE_192S = 0x7db37ae6, /* 2.16.840.1.101.3.4.3.28 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1d */ + CTC_SLH_DSA_SHAKE_192F = 0x7db37ae7, /* 2.16.840.1.101.3.4.3.29 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1e */ + CTC_SLH_DSA_SHAKE_256S = 0x7db37ae4, /* 2.16.840.1.101.3.4.3.30 */ + /* 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1f */ + CTC_SLH_DSA_SHAKE_256F = 0x7db37ae5 /* 2.16.840.1.101.3.4.3.31 */ #endif }; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index d01ab3cd465..c55e2240819 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3280,7 +3280,7 @@ extern void uITRON4_free(void *p) ; (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)) || \ (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)) || \ defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || \ - defined(HAVE_SPHINCS) || defined(HAVE_LIBOQS)) + defined(WOLFSSL_HAVE_SLHDSA) || defined(HAVE_LIBOQS)) #define WC_ENABLE_ASYM_KEY_EXPORT #endif @@ -3290,7 +3290,7 @@ extern void uITRON4_free(void *p) ; (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) || \ (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) || \ defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || \ - defined(HAVE_SPHINCS) || defined(HAVE_LIBOQS)) + defined(WOLFSSL_HAVE_SLHDSA) || defined(HAVE_LIBOQS)) #define WC_ENABLE_ASYM_KEY_IMPORT #endif @@ -4554,9 +4554,6 @@ extern void uITRON4_free(void *p) ; #ifndef HAVE_DILITHIUM #define HAVE_DILITHIUM #endif -#ifndef WOLFSSL_NO_SPHINCS - #define HAVE_SPHINCS -#endif #ifndef WOLFSSL_HAVE_MLKEM #define WOLFSSL_HAVE_MLKEM #define WOLFSSL_KYBER512 diff --git a/wolfssl/wolfcrypt/sphincs.h b/wolfssl/wolfcrypt/sphincs.h deleted file mode 100644 index a14252278ef..00000000000 --- a/wolfssl/wolfcrypt/sphincs.h +++ /dev/null @@ -1,167 +0,0 @@ -/* sphincs.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/sphincs.h -*/ - -/* Interfaces for Sphincs: - * - SPHINCS_FAST_LEVEL1 (AKA SPHINCS+-SHAKE-128f-simple) - * - SPHINCS_FAST_LEVEL3 (AKA SPHINCS+-SHAKE-192f-simple) - * - SPHINCS_FAST_LEVEL5 (AKA SPHINCS+-SHAKE-256f-simple) - * - SPHINCS_SMALL_LEVEL1 (AKA SPHINCS+-SHAKE-128s-simple) - * - SPHINCS_SMALL_LEVEL3 (AKA SPHINCS+-SHAKE-192s-simple) - * - SPHINCS_SMALL_LEVEL5 (AKA SPHINCS+-SHAKE-256s-simple) - */ - -#ifndef WOLF_CRYPT_SPHINCS_H -#define WOLF_CRYPT_SPHINCS_H - -#include - -#if defined(HAVE_PQC) && defined(HAVE_SPHINCS) - -#ifdef HAVE_LIBOQS -#include -#include -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -/* Macros Definitions */ - -#ifdef HAVE_LIBOQS - -#define SPHINCS_FAST_LEVEL1_SIG_SIZE OQS_SIG_sphincs_shake_128f_simple_length_signature -#define SPHINCS_FAST_LEVEL3_SIG_SIZE OQS_SIG_sphincs_shake_192f_simple_length_signature -#define SPHINCS_FAST_LEVEL5_SIG_SIZE OQS_SIG_sphincs_shake_256f_simple_length_signature -#define SPHINCS_SMALL_LEVEL1_SIG_SIZE OQS_SIG_sphincs_shake_128s_simple_length_signature -#define SPHINCS_SMALL_LEVEL3_SIG_SIZE OQS_SIG_sphincs_shake_192s_simple_length_signature -#define SPHINCS_SMALL_LEVEL5_SIG_SIZE OQS_SIG_sphincs_shake_256s_simple_length_signature - -#define SPHINCS_LEVEL1_KEY_SIZE OQS_SIG_sphincs_shake_128f_simple_length_secret_key -#define SPHINCS_LEVEL1_PUB_KEY_SIZE OQS_SIG_sphincs_shake_128f_simple_length_public_key -#define SPHINCS_LEVEL1_PRV_KEY_SIZE (SPHINCS_LEVEL1_PUB_KEY_SIZE+SPHINCS_LEVEL1_KEY_SIZE) - -#define SPHINCS_LEVEL3_KEY_SIZE OQS_SIG_sphincs_shake_192f_simple_length_secret_key -#define SPHINCS_LEVEL3_PUB_KEY_SIZE OQS_SIG_sphincs_shake_192f_simple_length_public_key -#define SPHINCS_LEVEL3_PRV_KEY_SIZE (SPHINCS_LEVEL3_PUB_KEY_SIZE+SPHINCS_LEVEL3_KEY_SIZE) - -#define SPHINCS_LEVEL5_KEY_SIZE OQS_SIG_sphincs_shake_256f_simple_length_secret_key -#define SPHINCS_LEVEL5_PUB_KEY_SIZE OQS_SIG_sphincs_shake_256f_simple_length_public_key -#define SPHINCS_LEVEL5_PRV_KEY_SIZE (SPHINCS_LEVEL5_PUB_KEY_SIZE+SPHINCS_LEVEL5_KEY_SIZE) -#endif - -#define SPHINCS_MAX_SIG_SIZE SPHINCS_FAST_LEVEL5_SIG_SIZE -#define SPHINCS_MAX_KEY_SIZE SPHINCS_LEVEL5_PRV_KEY_SIZE -#define SPHINCS_MAX_PUB_KEY_SIZE SPHINCS_LEVEL5_PUB_KEY_SIZE -#define SPHINCS_MAX_PRV_KEY_SIZE SPHINCS_LEVEL5_PRV_KEY_SIZE - -#define FAST_VARIANT 1 -#define SMALL_VARIANT 2 - -/* Structs */ - -struct sphincs_key { - WC_BITFIELD pubKeySet:1; - WC_BITFIELD prvKeySet:1; - byte level; /* 1,3 or 5 */ - byte optim; /* FAST_VARIANT or SMALL_VARIANT */ - byte p[SPHINCS_MAX_PUB_KEY_SIZE]; - byte k[SPHINCS_MAX_PRV_KEY_SIZE]; -}; - -#ifndef WC_SPHINCSKEY_TYPE_DEFINED - typedef struct sphincs_key sphincs_key; - #define WC_SPHINCSKEY_TYPE_DEFINED -#endif - -/* Functions */ - -WOLFSSL_API -int wc_sphincs_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, - sphincs_key* key, WC_RNG* rng); -WOLFSSL_API -int wc_sphincs_verify_msg(const byte* sig, word32 sigLen, const byte* msg, - word32 msgLen, int* res, sphincs_key* key); - -WOLFSSL_API -int wc_sphincs_init(sphincs_key* key); -WOLFSSL_API -int wc_sphincs_set_level_and_optim(sphincs_key* key, byte level, byte optim); -WOLFSSL_API -int wc_sphincs_get_level_and_optim(sphincs_key* key, byte* level, byte *optim); -WOLFSSL_API -void wc_sphincs_free(sphincs_key* key); - -WOLFSSL_API -int wc_sphincs_import_public(const byte* in, word32 inLen, sphincs_key* key); -WOLFSSL_API -int wc_sphincs_import_private_only(const byte* priv, word32 privSz, - sphincs_key* key); -WOLFSSL_API -int wc_sphincs_import_private_key(const byte* priv, word32 privSz, - const byte* pub, word32 pubSz, - sphincs_key* key); - -WOLFSSL_API -int wc_sphincs_export_public(sphincs_key* key, byte* out, word32* outLen); -WOLFSSL_API -int wc_sphincs_export_private_only(sphincs_key* key, byte* out, word32* outLen); -WOLFSSL_API -int wc_sphincs_export_private(sphincs_key* key, byte* out, word32* outLen); -WOLFSSL_API -int wc_sphincs_export_key(sphincs_key* key, byte* priv, word32 *privSz, - byte* pub, word32 *pubSz); - -WOLFSSL_API -int wc_sphincs_check_key(sphincs_key* key); - -WOLFSSL_API -int wc_sphincs_size(sphincs_key* key); -WOLFSSL_API -int wc_sphincs_priv_size(sphincs_key* key); -WOLFSSL_API -int wc_sphincs_pub_size(sphincs_key* key); -WOLFSSL_API -int wc_sphincs_sig_size(sphincs_key* key); - -WOLFSSL_API int wc_Sphincs_PrivateKeyDecode(const byte* input, - word32* inOutIdx, - sphincs_key* key, word32 inSz); -WOLFSSL_API int wc_Sphincs_PublicKeyDecode(const byte* input, - word32* inOutIdx, - sphincs_key* key, word32 inSz); -WOLFSSL_API int wc_Sphincs_KeyToDer(sphincs_key* key, byte* output, - word32 inLen); -WOLFSSL_API int wc_Sphincs_PrivateKeyToDer(sphincs_key* key, byte* output, - word32 inLen); -WOLFSSL_API int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output, - word32 inLen, int withAlg); - -#ifdef __cplusplus - } /* extern "C" */ -#endif - -#endif /* HAVE_PQC && HAVE_SPHINCS */ -#endif /* WOLF_CRYPT_SPHINCS_H */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index e8c24855be1..8f803155fbe 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1370,7 +1370,7 @@ enum { DYNAMIC_TYPE_FALCON = 95, DYNAMIC_TYPE_SESSION = 96, DYNAMIC_TYPE_DILITHIUM = 97, - DYNAMIC_TYPE_SPHINCS = 98, + DYNAMIC_TYPE_SPHINCS = 98, /* deprecated: kept for ABI compat */ DYNAMIC_TYPE_SM4_BUFFER = 99, DYNAMIC_TYPE_DEBUG_TAG = 100, DYNAMIC_TYPE_LMS = 101, @@ -2316,8 +2316,8 @@ enum Max_ASN { DSA_INTS = 5, /* DSA ints in private key */ MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */ MAX_IV_SIZE = 64, /* MAX PKCS Iv length */ -#ifdef HAVE_SPHINCS - MAX_ENCODED_SIG_SZ = 51200, +#ifdef WOLFSSL_HAVE_SLHDSA + MAX_ENCODED_SIG_SZ = 49856, #elif defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) MAX_ENCODED_SIG_SZ = 5120, #elif !defined(NO_RSA) @@ -2369,7 +2369,7 @@ enum Max_ASN { /* Maximum DER digest ASN header size */ /* Max X509 header length indicates the * max length + 2 ('\n', '\0') */ -#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS) +#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(WOLFSSL_HAVE_SLHDSA) MAX_X509_HEADER_SZ = (48 + 2), /* Maximum PEM Header/Footer Size */ #else MAX_X509_HEADER_SZ = (37 + 2), /* Maximum PEM Header/Footer Size */ diff --git a/wolfssl/wolfcrypt/wc_slhdsa.h b/wolfssl/wolfcrypt/wc_slhdsa.h index 19ee86fbb28..3e2e867da06 100644 --- a/wolfssl/wolfcrypt/wc_slhdsa.h +++ b/wolfssl/wolfcrypt/wc_slhdsa.h @@ -375,6 +375,24 @@ WOLFSSL_API int wc_SlhDsaKey_PrivateSizeFromParam(enum SlhDsaParam param); WOLFSSL_API int wc_SlhDsaKey_PublicSizeFromParam(enum SlhDsaParam param); WOLFSSL_API int wc_SlhDsaKey_SigSizeFromParam(enum SlhDsaParam param); +/* DER encode/decode */ +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY +WOLFSSL_API int wc_SlhDsaKey_PrivateKeyDecode(const byte* input, + word32* inOutIdx, SlhDsaKey* key, word32 inSz); +#endif +WOLFSSL_API int wc_SlhDsaKey_PublicKeyDecode(const byte* input, + word32* inOutIdx, SlhDsaKey* key, word32 inSz); +#ifdef WC_ENABLE_ASYM_KEY_EXPORT +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY +WOLFSSL_API int wc_SlhDsaKey_KeyToDer(SlhDsaKey* key, byte* output, + word32 inLen); +WOLFSSL_API int wc_SlhDsaKey_PrivateKeyToDer(SlhDsaKey* key, byte* output, + word32 inLen); +#endif +WOLFSSL_API int wc_SlhDsaKey_PublicKeyToDer(SlhDsaKey* key, byte* output, + word32 inLen, int withAlg); +#endif + #endif /* WOLFSSL_HAVE_SLHDSA */ #endif /* WOLF_CRYPT_WC_SLHDSA_H */ diff --git a/wrapper/CSharp/wolfssl.vcxproj b/wrapper/CSharp/wolfssl.vcxproj index a01d55d5a49..0b7c27aaea2 100644 --- a/wrapper/CSharp/wolfssl.vcxproj +++ b/wrapper/CSharp/wolfssl.vcxproj @@ -342,7 +342,6 @@ - diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 35b8a765652..8dcf6e6227c 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -112,7 +112,6 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sp_dsp32.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sp_int.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sp_x86_64.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sphincs.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/srp.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/tfm.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_dsp.c)