From e2424e67444a360eab615b53fd5649ff355ad68b Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 10 Feb 2023 11:48:59 +1000 Subject: [PATCH] SM2/SM3/SM4: Chinese cipher support Add support for: - SM2 elliptic curve and SM2 sign/verify - SM3 digest - SM4 cipher with modes ECB/CBC/CTR/GCM/CCM Add APIs for SM3 and SM4. Add SM2 sign and verify APIs. Add support for SM3 in wc_Hash and wc_Hmac API. Add support for SM3 and SM4 through EVP layer. Add support for SM2-SM3 certificates. Support key ID and name hash being with SHA-1/256 or SM3. Add support for TLS 1.3 cipher suites: TLS-SM4-GCM-SM3, TLS-SM4-CCM-SM3 Add support for TLS 1.2 SM cipher suite: ECDHE-ECDSA-SM4-CBC-SM3 Add support for SM3 in wc_PRF_TLS. Add SM2-SM3 certificates and keys. Generated with GmSSL-3.0.0 and OpenSSL. --- certs/include.am | 1 + certs/sm2/ca-sm2-key.der | Bin 0 -> 92 bytes certs/sm2/ca-sm2-key.pem | 4 + certs/sm2/ca-sm2-priv.der | Bin 0 -> 121 bytes certs/sm2/ca-sm2-priv.pem | 5 + certs/sm2/ca-sm2.der | Bin 0 -> 666 bytes certs/sm2/ca-sm2.pem | 51 + certs/sm2/client-sm2-key.der | Bin 0 -> 92 bytes certs/sm2/client-sm2-key.pem | 4 + certs/sm2/client-sm2-priv.der | Bin 0 -> 121 bytes certs/sm2/client-sm2-priv.pem | 5 + certs/sm2/client-sm2.der | Bin 0 -> 973 bytes certs/sm2/client-sm2.pem | 63 + certs/sm2/gen-sm2-certs.sh | 105 ++ certs/sm2/gen-sm2-keys.sh | 16 + certs/sm2/include.am | 37 + certs/sm2/root-sm2-key.der | Bin 0 -> 92 bytes certs/sm2/root-sm2-key.pem | 4 + certs/sm2/root-sm2-priv.der | Bin 0 -> 121 bytes certs/sm2/root-sm2-priv.pem | 5 + certs/sm2/root-sm2.der | Bin 0 -> 661 bytes certs/sm2/root-sm2.pem | 52 + certs/sm2/self-sm2-cert.pem | 13 + certs/sm2/self-sm2-key.pem | 4 + certs/sm2/self-sm2-priv.pem | 6 + certs/sm2/server-sm2-cert.pem | 57 + certs/sm2/server-sm2-key.der | Bin 0 -> 92 bytes certs/sm2/server-sm2-key.pem | 4 + certs/sm2/server-sm2-priv.der | Bin 0 -> 121 bytes certs/sm2/server-sm2-priv.pem | 5 + certs/sm2/server-sm2.der | Bin 0 -> 732 bytes certs/sm2/server-sm2.pem | 108 ++ configure.ac | 177 ++- examples/client/client.c | 13 + mcapi/crypto.h | 4 +- src/dtls.c | 4 +- src/include.am | 21 + src/internal.c | 2187 +++++++++++++++++++-------- src/keys.c | 379 +++++ src/pk.c | 4 + src/sniffer.c | 5 + src/ssl.c | 153 +- src/tls.c | 150 +- src/tls13.c | 339 ++++- tests/api.c | 2234 +++++++++++++++++++++++++++- tests/include.am | 1 + tests/suites.c | 12 + tests/test-sm2.conf | 189 +++ tests/unit.h | 8 +- wolfcrypt/benchmark/benchmark.c | 594 ++++++++ wolfcrypt/benchmark/benchmark.h | 5 + wolfcrypt/src/aes.c | 250 ++-- wolfcrypt/src/asn.c | 359 ++++- wolfcrypt/src/ecc.c | 272 +++- wolfcrypt/src/error.c | 6 + wolfcrypt/src/evp.c | 1193 ++++++++++++--- wolfcrypt/src/hash.c | 110 +- wolfcrypt/src/hmac.c | 74 + wolfcrypt/src/integer.c | 9 + wolfcrypt/src/kdf.c | 14 + wolfcrypt/src/misc.c | 8 +- wolfcrypt/src/pkcs7.c | 112 +- wolfcrypt/src/port/arm/armv8-aes.c | 95 +- wolfcrypt/src/rsa.c | 3 + wolfcrypt/src/sm2.c | 13 + wolfcrypt/src/sm3.c | 13 + wolfcrypt/src/sm3_asm.S | 3 + wolfcrypt/src/sm4.c | 13 + wolfcrypt/src/sp_int.c | 79 +- wolfcrypt/src/tfm.c | 40 +- wolfcrypt/test/test.c | 1348 ++++++++++++++++- wolfssl/internal.h | 121 +- wolfssl/openssl/evp.h | 155 +- wolfssl/ssl.h | 11 +- wolfssl/wolfcrypt/aes.h | 46 +- wolfssl/wolfcrypt/asn.h | 27 +- wolfssl/wolfcrypt/asn_public.h | 3 + wolfssl/wolfcrypt/ecc.h | 3 + wolfssl/wolfcrypt/error-crypt.h | 5 +- wolfssl/wolfcrypt/hash.h | 16 +- wolfssl/wolfcrypt/hmac.h | 3 + wolfssl/wolfcrypt/include.am | 5 +- wolfssl/wolfcrypt/integer.h | 2 + wolfssl/wolfcrypt/sm2.h | 7 + wolfssl/wolfcrypt/sm3.h | 7 + wolfssl/wolfcrypt/sm4.h | 7 + wolfssl/wolfcrypt/sp.h | 33 + wolfssl/wolfcrypt/sp_int.h | 3 + wolfssl/wolfcrypt/tfm.h | 3 +- wolfssl/wolfcrypt/types.h | 10 +- 90 files changed, 10185 insertions(+), 1324 deletions(-) create mode 100644 certs/sm2/ca-sm2-key.der create mode 100644 certs/sm2/ca-sm2-key.pem create mode 100644 certs/sm2/ca-sm2-priv.der create mode 100644 certs/sm2/ca-sm2-priv.pem create mode 100644 certs/sm2/ca-sm2.der create mode 100644 certs/sm2/ca-sm2.pem create mode 100644 certs/sm2/client-sm2-key.der create mode 100644 certs/sm2/client-sm2-key.pem create mode 100644 certs/sm2/client-sm2-priv.der create mode 100644 certs/sm2/client-sm2-priv.pem create mode 100644 certs/sm2/client-sm2.der create mode 100644 certs/sm2/client-sm2.pem create mode 100755 certs/sm2/gen-sm2-certs.sh create mode 100755 certs/sm2/gen-sm2-keys.sh create mode 100644 certs/sm2/include.am create mode 100644 certs/sm2/root-sm2-key.der create mode 100644 certs/sm2/root-sm2-key.pem create mode 100644 certs/sm2/root-sm2-priv.der create mode 100644 certs/sm2/root-sm2-priv.pem create mode 100644 certs/sm2/root-sm2.der create mode 100644 certs/sm2/root-sm2.pem create mode 100644 certs/sm2/self-sm2-cert.pem create mode 100644 certs/sm2/self-sm2-key.pem create mode 100644 certs/sm2/self-sm2-priv.pem create mode 100644 certs/sm2/server-sm2-cert.pem create mode 100644 certs/sm2/server-sm2-key.der create mode 100644 certs/sm2/server-sm2-key.pem create mode 100644 certs/sm2/server-sm2-priv.der create mode 100644 certs/sm2/server-sm2-priv.pem create mode 100644 certs/sm2/server-sm2.der create mode 100644 certs/sm2/server-sm2.pem create mode 100644 tests/test-sm2.conf create mode 100644 wolfcrypt/src/sm2.c create mode 100644 wolfcrypt/src/sm3.c create mode 100644 wolfcrypt/src/sm3_asm.S create mode 100644 wolfcrypt/src/sm4.c create mode 100644 wolfssl/wolfcrypt/sm2.h create mode 100644 wolfssl/wolfcrypt/sm3.h create mode 100644 wolfssl/wolfcrypt/sm4.h diff --git a/certs/include.am b/certs/include.am index b82d520be..69db67898 100644 --- a/certs/include.am +++ b/certs/include.am @@ -129,6 +129,7 @@ include certs/ecc/include.am include certs/ed25519/include.am include certs/ed448/include.am include certs/p521/include.am +include certs/sm2/include.am include certs/external/include.am include certs/ocsp/include.am include certs/statickeys/include.am diff --git a/certs/sm2/ca-sm2-key.der b/certs/sm2/ca-sm2-key.der new file mode 100644 index 0000000000000000000000000000000000000000..56b92e5ac32977767e5c46cf77af390fa312f3a1 GIT binary patch literal 92 zcmXqrG7w?o&}x)9AIjLIi(oN3F|a63`hHsFev0p|)oInur7Ja`|4&KYcGamtVeg|y qOhVRuTNtKtHk=N7>wT&>{MkCz%Vp}xg_fP$GoN`hth>0l2z>q6p#_tqH7wD9}zBwXuuB=<>uiC z%Fi#+1qn$Qh=GKddHBoA%k@Bti;HvglJj#7uBjmqK)D8uYpCJw;#?y`egj^JyV;x_bwL8;yV_9PK$MM( zbCO!;sT+BsV5g&c5csn=Fzb3;z|#p#mNSVz|dq4 zmE~g*V-a!Z@~GR*v?59^Tw8Kwbz*mY?94m^d62X+3(#i`A||qxE~1qSHzv<~{5G{F zrL*DxjyK?_lNDxU{LjK_zzn3osX&$=B)|epHf_jhhS`I`z?DhC-H(BJwaLQuk(T`l zX8SukoE+5;-VHxld0IX!Mr^CbUM59`Zavl4inCX0FUyL)z5KYg;QeCJwNH*7KJ7Ek{Byzk9z|K@l6hh<4Y!BznJHYb7r literal 0 HcmV?d00001 diff --git a/certs/sm2/client-sm2-key.pem b/certs/sm2/client-sm2-key.pem new file mode 100644 index 000000000..63e70e3db --- /dev/null +++ b/certs/sm2/client-sm2-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABDod6MtL0y4/Swc/sCH+xZ7ZyjqT +k5V2HTDZC/VW7Rlg7QFM9mcd8ayodA2yd8hJOOT/TO+NbYf2Tsf4OXRwcLU= +-----END PUBLIC KEY----- diff --git a/certs/sm2/client-sm2-priv.der b/certs/sm2/client-sm2-priv.der new file mode 100644 index 0000000000000000000000000000000000000000..e1ab54fd6f9d1b4603e1fae91fcdd46c0361ab16 GIT binary patch literal 121 zcmV-<0EYiCcLD(c1R&6&-${Bc-vY_bxAHdv4c+_*xZV_#dQ&Dz)&2t6^KqaG1_&yF z9M4q&f-Rv$13~}ujX&dE&8E71iBN*IWN1etmG%gf94K+21YbM%t)a}DJU zWZ5{i+C196^D=TWiV0-qrR6&yD-bsjW#i(Uq}Dn4lTHdFBM&>&G6OkrUL#`zBSTXI zGazjq1>~9<0s)je6ulH>AOee%CS3%J*@=P0O7_KR@5_4j-t6`p6#pHack`6hXC<3B7*3JSI^ZemO{Xkv^7 z1~+r4EFX&)i^vnjO-G+znb&mcNBSp?ncrGpd<=bW(D(r)uguc;!l3bK16DN)8@DZK z+&l!sw+VYb-~stqn1$7VnUV3ofeeTz$RcVW+{B$)k(gVMlL|_x?JV^S42+P_Q)LkY zMU*xhBP%OAGb5bEgq)?AJsAw#m=qcMH*KBTU->Pr^y$%;vxF}3SIj>k+bgp#o9E-# t@PykF{eeo_<7%H=v)WxfL%sE0)d$5#X$$A8J-FMZyye6Jx2R8^y#N{^CV>C| literal 0 HcmV?d00001 diff --git a/certs/sm2/client-sm2.pem b/certs/sm2/client-sm2.pem new file mode 100644 index 000000000..2f3f49ef8 --- /dev/null +++ b/certs/sm2/client-sm2.pem @@ -0,0 +1,63 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 60:a0:4a:0b:36:eb:7d:e1:3f:74:29:a9:29:b4:05:6c:17:f7:a6:d4 + Signature Algorithm: SM2-with-SM3 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = Client-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Validity + Not Before: Feb 15 06:23:07 2023 GMT + Not After : Nov 11 06:23:07 2025 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = Client-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Subject Public Key Info: + Public Key Algorithm: sm2 + Public-Key: (256 bit) + pub: + 04:3a:1d:e8:cb:4b:d3:2e:3f:4b:07:3f:b0:21:fe: + c5:9e:d9:ca:3a:93:93:95:76:1d:30:d9:0b:f5:56: + ed:19:60:ed:01:4c:f6:67:1d:f1:ac:a8:74:0d:b2: + 77:c8:49:38:e4:ff:4c:ef:8d:6d:87:f6:4e:c7:f8: + 39:74:70:70:b5 + ASN1 OID: SM2 + X509v3 extensions: + X509v3 Subject Key Identifier: + E4:21:B2:C5:E5:D4:9E:82:CA:F8:67:F2:28:99:F6:85:E8:F1:55:EF + X509v3 Authority Key Identifier: + keyid:E4:21:B2:C5:E5:D4:9E:82:CA:F8:67:F2:28:99:F6:85:E8:F1:55:EF + DirName:/C=US/ST=Montana/L=Bozeman/O=wolfSSL_sm2/OU=Client-sm2/CN=www.wolfssl.com/emailAddress=info@wolfssl.com/UID=wolfSSL + serial:60:A0:4A:0B:36:EB:7D:E1:3F:74:29:A9:29:B4:05:6C:17:F7:A6:D4 + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Alternative Name: + DNS:example.com, IP Address:127.0.0.1 + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + Signature Algorithm: SM2-with-SM3 + Signature Value: + 30:46:02:21:00:8f:b2:b5:95:8f:79:f6:5e:75:e5:c5:e9:9a: + 12:d2:0f:78:9f:c0:1d:8d:1c:be:6b:0c:f1:f5:57:60:db:91: + 4f:02:21:00:87:5e:7d:e4:d6:3a:bb:7b:98:27:85:de:7a:f0: + 21:e2:66:a1:9f:26:e0:dd:86:23:b4:c8:c0:46:5a:f2:49:8d +-----BEGIN CERTIFICATE----- +MIIDyTCCA26gAwIBAgIUYKBKCzbrfeE/dCmpKbQFbBf3ptQwCgYIKoEcz1UBg3Uw +gbAxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3pl +bWFuMRQwEgYDVQQKDAt3b2xmU1NMX3NtMjETMBEGA1UECwwKQ2xpZW50LXNtMjEY +MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv +bGZzc2wuY29tMRcwFQYKCZImiZPyLGQBAQwHd29sZlNTTDAeFw0yMzAyMTUwNjIz +MDdaFw0yNTExMTEwNjIzMDdaMIGwMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9u +dGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEUMBIGA1UECgwLd29sZlNTTF9zbTIxEzAR +BgNVBAsMCkNsaWVudC1zbTIxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0G +CSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTEXMBUGCgmSJomT8ixkAQEMB3dv +bGZTU0wwWjAUBggqgRzPVQGCLQYIKoEcz1UBgi0DQgAEOh3oy0vTLj9LBz+wIf7F +ntnKOpOTlXYdMNkL9VbtGWDtAUz2Zx3xrKh0DbJ3yEk45P9M741th/ZOx/g5dHBw +taOCAWEwggFdMB0GA1UdDgQWBBTkIbLF5dSegsr4Z/IomfaF6PFV7zCB8AYDVR0j +BIHoMIHlgBTkIbLF5dSegsr4Z/IomfaF6PFV76GBtqSBszCBsDELMAkGA1UEBhMC +VVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFDASBgNVBAoM +C3dvbGZTU0xfc20yMRMwEQYDVQQLDApDbGllbnQtc20yMRgwFgYDVQQDDA93d3cu +d29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20xFzAV +BgoJkiaJk/IsZAEBDAd3b2xmU1NMghRgoEoLNut94T90KakptAVsF/em1DAMBgNV +HRMEBTADAQH/MBwGA1UdEQQVMBOCC2V4YW1wbGUuY29thwR/AAABMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAKBggqgRzPVQGDdQNJADBGAiEAj7K1lY95 +9l515cXpmhLSD3ifwB2NHL5rDPH1V2DbkU8CIQCHXn3k1jq7e5gnhd568CHiZqGf +JuDdhiO0yMBGWvJJjQ== +-----END CERTIFICATE----- diff --git a/certs/sm2/gen-sm2-certs.sh b/certs/sm2/gen-sm2-certs.sh new file mode 100755 index 000000000..d5d7cd568 --- /dev/null +++ b/certs/sm2/gen-sm2-certs.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +check_result(){ + if [ $1 -ne 0 ]; then + echo "Failed at \"$2\", Abort" + exit 1 + else + echo "Step Succeeded!" + fi +} + +openssl pkey -in root-sm2-priv.pem -noout >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "OpenSSL does not support SM2" + echo "Skipping SM2 certificate renewal" + exit 0 +fi + +############################################################ +###### update the self-signed root-sm2.pem ############# +############################################################ +echo "Updating root-sm2.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_SM2\\nRoot-SM2\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | \ +openssl req -new -key root-sm2-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out root-sm2.csr +check_result $? "Generate request" + +openssl x509 -req -in root-sm2.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions ca_ecc_cert -signkey root-sm2-priv.pem -out root-sm2.pem +check_result $? "Generate certificate" +rm root-sm2.csr + +openssl x509 -in root-sm2.pem -outform DER > root-sm2.der +check_result $? "Convert to DER" +openssl x509 -in root-sm2.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem root-sm2.pem +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update ca-sm2.pem signed by root ################ +############################################################ +echo "Updating ca-sm2.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_sm2\\nCA-sm2\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key ca-sm2-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out ca-sm2.csr +check_result $? "Generate request" + +openssl x509 -req -in ca-sm2.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions ca_ecc_cert -CA root-sm2.pem -CAkey root-sm2-priv.pem -set_serial 01 -out ca-sm2.pem +check_result $? "Generate certificate" +rm ca-sm2.csr + +openssl x509 -in ca-sm2.pem -outform DER > ca-sm2.der +check_result $? "Convert to DER" +openssl x509 -in ca-sm2.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem ca-sm2.pem +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update server-sm2.pem signed by ca ############## +############################################################ +echo "Updating server-sm2.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_sm2\\nServer-sm2\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key server-sm2-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out server-sm2.csr +check_result $? "Generate request" + +openssl x509 -req -in server-sm2.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions server_ecc -CA ca-sm2.pem -CAkey ca-sm2-priv.pem -set_serial 01 -out server-sm2-cert.pem +check_result $? "Generate certificate" +rm server-sm2.csr + +openssl x509 -in server-sm2-cert.pem -outform DER > server-sm2.der +check_result $? "Convert to DER" +openssl x509 -in server-sm2-cert.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem server-sm2-cert.pem +cat server-sm2-cert.pem ca-sm2.pem > server-sm2.pem +check_result $? "Add CA into server cert" +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update the self-signed client-sm2.pem ########### +############################################################ +echo "Updating client-sm2.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_sm2\\nClient-sm2\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key client-sm2-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out client-sm2.csr +check_result $? "Generate request" + +openssl x509 -req -in client-sm2.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions wolfssl_opts -signkey client-sm2-priv.pem -out client-sm2.pem +check_result $? "Generate certificate" +rm client-sm2.csr + +openssl x509 -in client-sm2.pem -outform DER > client-sm2.der +check_result $? "Convert to DER" +openssl x509 -in client-sm2.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem client-sm2.pem +echo "End of section" +echo "---------------------------------------------------------------------" + diff --git a/certs/sm2/gen-sm2-keys.sh b/certs/sm2/gen-sm2-keys.sh new file mode 100755 index 000000000..503c25818 --- /dev/null +++ b/certs/sm2/gen-sm2-keys.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +for key in root ca server client +do + + openssl genpkey -algorithm sm2 > ${key}-sm2-priv.pem + + openssl pkey -in ${key}-sm2-priv.pem -outform DER -out ${key}-sm2-priv.der + + openssl pkey -in ${key}-sm2-priv.pem -outform PEM -pubout -out ${key}-sm2-key.pem + + openssl pkey -in ${key}-sm2-priv.pem -outform DER -pubout -out ${key}-sm2-key.der + +done + + diff --git a/certs/sm2/include.am b/certs/sm2/include.am new file mode 100644 index 000000000..9028b5ade --- /dev/null +++ b/certs/sm2/include.am @@ -0,0 +1,37 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +EXTRA_DIST += \ + certs/sm2/ca-sm2.der \ + certs/sm2/ca-sm2.pem \ + certs/sm2/ca-sm2-key.der \ + certs/sm2/ca-sm2-key.pem \ + certs/sm2/ca-sm2-priv.der \ + certs/sm2/ca-sm2-priv.pem \ + certs/sm2/client-sm2.der \ + certs/sm2/client-sm2.pem \ + certs/sm2/client-sm2-key.der \ + certs/sm2/client-sm2-key.pem \ + certs/sm2/client-sm2-priv.der \ + certs/sm2/client-sm2-priv.pem \ + certs/sm2/root-sm2.der \ + certs/sm2/root-sm2.pem \ + certs/sm2/root-sm2-key.der \ + certs/sm2/root-sm2-key.pem \ + certs/sm2/root-sm2-priv.der \ + certs/sm2/root-sm2-priv.pem \ + certs/sm2/server-sm2.der \ + certs/sm2/server-sm2.pem \ + certs/sm2/server-sm2-cert.pem \ + certs/sm2/server-sm2-key.der \ + certs/sm2/server-sm2-key.pem \ + certs/sm2/server-sm2-priv.der \ + certs/sm2/server-sm2-priv.pem \ + certs/sm2/self-sm2-cert.pem \ + certs/sm2/self-sm2-key.pem \ + certs/sm2/self-sm2-priv.pem + +EXTRA_DIST += \ + certs/sm2/gen-sm2-certs.sh \ + certs/sm2/gen-sm2-keys.sh diff --git a/certs/sm2/root-sm2-key.der b/certs/sm2/root-sm2-key.der new file mode 100644 index 0000000000000000000000000000000000000000..e2d9adcdc893b105effc0710dd5fa30899e2635f GIT binary patch literal 92 zcmXqrG7w?o&}x)9AIjLIi(oN3F|h2OQ`+-g{D;Tt@853o&gz|i=%V}dsoZ|g!rvVI r5gt-#X;b;o!G2rd%bMf2bl+ckQQ26%dU1TVR?c*(xW1bg&aeOgtQ;yK literal 0 HcmV?d00001 diff --git a/certs/sm2/root-sm2-key.pem b/certs/sm2/root-sm2-key.pem new file mode 100644 index 000000000..45b4a332d --- /dev/null +++ b/certs/sm2/root-sm2-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABLucdYz3F/hIq/f22w2ajZ/C0UeX +lQtO5lfsxfhXVHE5PHnhQD+2Uel8x9ot79LoeYF7q6NfaypslxpejtnQzAQ= +-----END PUBLIC KEY----- diff --git a/certs/sm2/root-sm2-priv.der b/certs/sm2/root-sm2-priv.der new file mode 100644 index 0000000000000000000000000000000000000000..efc18f96cefc06810e8b44eb45bf86f1fcd5cd6e GIT binary patch literal 121 zcmV-<0EYiCcLD(c1R%z1G)yx$TVxhme+2pbhcM9$Jb2bdrx;RcOSiYTB81_&yF z9M4q&f-Rv$13~}Ul?zVhSM0_3S5$F1JbB?jKekcn be8<`?@6zabfqSc?Uu!CCml|G<+0e`cb%{1R literal 0 HcmV?d00001 diff --git a/certs/sm2/root-sm2-priv.pem b/certs/sm2/root-sm2-priv.pem new file mode 100644 index 000000000..b8e708568 --- /dev/null +++ b/certs/sm2/root-sm2-priv.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGIAgEAMBQGCCqBHM9VAYItBggqgRzPVQGCLQRtMGsCAQEEIMZrNEwzN1tkFlp/ +BPn8hzDRFbpYeO4HmCAm4QaNUYoooUQDQgAEu5x1jPcX+Eir9/bbDZqNn8LRR5eV +C07mV+zF+FdUcTk8eeFAP7ZR6XzH2i3v0uh5gXuro19rKmyXGl6O2dDMBA== +-----END PRIVATE KEY----- diff --git a/certs/sm2/root-sm2.der b/certs/sm2/root-sm2.der new file mode 100644 index 0000000000000000000000000000000000000000..63c0407713d05b25e21a6a0d22b3382492362c39 GIT binary patch literal 661 zcmXqLVwz~s#ALC6nTe5!Nu*@X-6fmS)xtG@zZ4F6V8X$yU9i%Ci;Y98QRaLoV{@rN z<5WX#15P&PP!={}rqEzR0Ruh|hl7XRH$Sf=F)tA&!p_6)lwXyao0w-PVju)k!^Oj0 zo}ZHz9PASx>}zBwXuuB=<>uiC%Fi#+1qn$Qh=GKddHBoA%k@Bti;HvglJj#7uBjmqK)Hj~-BAW2u+VMN zMX;Ei7+7}CDed_#{=;MS_iwj(XZ6lMbkTkKRBpd#;ct%q2oEW=w5fdPV81Q!WzF$h zy6-Q&sBElWy*NHwD`&b?T;I(LXIK^|8zcgQjX6}7k420{#6-5zMYM9^#^jlg-=@~2 zbT<6o@y0+NB(2N>4EP4@3P5orE6m9FpM}+c8AySnTb3UrzyeG%ZODm(*`2|_g-L-~ zUGu~H3bln&S#lkX&zpID!kc$2`YhtIX@TMe0J|5+C;$Ke literal 0 HcmV?d00001 diff --git a/certs/sm2/root-sm2.pem b/certs/sm2/root-sm2.pem new file mode 100644 index 000000000..91b149af5 --- /dev/null +++ b/certs/sm2/root-sm2.pem @@ -0,0 +1,52 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 74:9c:dd:a4:b2:67:26:57:29:fb:e9:13:54:e0:34:08:03:2b:70:a9 + Signature Algorithm: SM2-with-SM3 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_SM2, OU = Root-SM2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 15 06:23:07 2023 GMT + Not After : Nov 11 06:23:07 2025 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_SM2, OU = Root-SM2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: sm2 + Public-Key: (256 bit) + pub: + 04:bb:9c:75:8c:f7:17:f8:48:ab:f7:f6:db:0d:9a: + 8d:9f:c2:d1:47:97:95:0b:4e:e6:57:ec:c5:f8:57: + 54:71:39:3c:79:e1:40:3f:b6:51:e9:7c:c7:da:2d: + ef:d2:e8:79:81:7b:ab:a3:5f:6b:2a:6c:97:1a:5e: + 8e:d9:d0:cc:04 + ASN1 OID: SM2 + X509v3 extensions: + X509v3 Subject Key Identifier: + 34:1D:79:44:15:79:A1:B1:63:99:E3:ED:65:7C:64:89:80:FF:B8:EC + X509v3 Authority Key Identifier: + 34:1D:79:44:15:79:A1:B1:63:99:E3:ED:65:7C:64:89:80:FF:B8:EC + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: SM2-with-SM3 + Signature Value: + 30:44:02:20:03:27:29:f0:ef:78:26:a1:1a:6a:1e:88:81:e7: + 83:72:5f:3e:e6:08:e8:14:68:bf:4b:0f:68:52:92:aa:8f:a1: + 02:20:0b:fe:1b:14:ba:51:82:65:06:bb:22:d8:1a:a7:9f:54: + 62:eb:8d:b2:d5:13:b3:b8:a2:f3:14:44:b2:a0:21:d0 +-----BEGIN CERTIFICATE----- +MIICkTCCAjigAwIBAgIUdJzdpLJnJlcp++kTVOA0CAMrcKkwCgYIKoEcz1UBg3Uw +gZUxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3pl +bWFuMRQwEgYDVQQKDAt3b2xmU1NMX1NNMjERMA8GA1UECwwIUm9vdC1TTTIxGDAW +BgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xm +c3NsLmNvbTAeFw0yMzAyMTUwNjIzMDdaFw0yNTExMTEwNjIzMDdaMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEUMBIG +A1UECgwLd29sZlNTTF9TTTIxETAPBgNVBAsMCFJvb3QtU00yMRgwFgYDVQQDDA93 +d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20w +WjAUBggqgRzPVQGCLQYIKoEcz1UBgi0DQgAEu5x1jPcX+Eir9/bbDZqNn8LRR5eV +C07mV+zF+FdUcTk8eeFAP7ZR6XzH2i3v0uh5gXuro19rKmyXGl6O2dDMBKNjMGEw +HQYDVR0OBBYEFDQdeUQVeaGxY5nj7WV8ZImA/7jsMB8GA1UdIwQYMBaAFDQdeUQV +eaGxY5nj7WV8ZImA/7jsMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG +MAoGCCqBHM9VAYN1A0cAMEQCIAMnKfDveCahGmoeiIHng3JfPuYI6BRov0sPaFKS +qo+hAiAL/hsUulGCZQa7Itgap59UYuuNstUTs7ii8xREsqAh0A== +-----END CERTIFICATE----- diff --git a/certs/sm2/self-sm2-cert.pem b/certs/sm2/self-sm2-cert.pem new file mode 100644 index 000000000..5e13ab90d --- /dev/null +++ b/certs/sm2/self-sm2-cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAaSgAwIBAgIMGSJGj94zOf2VJ8V7MAwGCCqBHM9VAYN1BQAwWTELMAkG +A1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEQMA4GA1UEChMHd29sZlNTTDEQMA4GA1UE +CxMHVGVzdGluZzEYMBYGA1UEAxMPd29sZnNzbC1kZXYtc20yMB4XDTIzMDIxNDAz +NDYyMFoXDTI0MDIxMzE3NDYyMFowWTELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM +RDEQMA4GA1UEChMHd29sZlNTTDEQMA4GA1UECxMHVGVzdGluZzEYMBYGA1UEAxMP +d29sZnNzbC1kZXYtc20yMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE2MSh8QuL +jcR93NRluaVVTvusM6ubQ5RMSEAbM9kbzDHBglY/sMBrlUBR/YgCAbGwlGwG66fa +ju5wtuW7tB7ntKNQME4wDgYDVR0PAQH/BAQDAgKEMA8GA1UdEwEB/wQFMAMBAf8w +KwYDVR0jBCQwIoAg58sNBkW7bGpWBXDo6zbHrieKTvcwnKWSidVvnSzhPkIwDAYI +KoEcz1UBg3UFAANJADBGAiEAm/cByfeknMZJ4NF/a0gu/RqeG/tFouvXKKtbYzqN +8/8CIQCJV/RNKQkp8zKZU+sMOGvGk7c3otMNy4B4OOJorD00rw== +-----END CERTIFICATE----- diff --git a/certs/sm2/self-sm2-key.pem b/certs/sm2/self-sm2-key.pem new file mode 100644 index 000000000..f4ec65253 --- /dev/null +++ b/certs/sm2/self-sm2-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE2MSh8QuLjcR93NRluaVVTvusM6ub +Q5RMSEAbM9kbzDHBglY/sMBrlUBR/YgCAbGwlGwG66faju5wtuW7tB7ntA== +-----END PUBLIC KEY----- diff --git a/certs/sm2/self-sm2-priv.pem b/certs/sm2/self-sm2-priv.pem new file mode 100644 index 000000000..35798c0a6 --- /dev/null +++ b/certs/sm2/self-sm2-priv.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg0JwoWhXWJQ22X9Gh +AW60DtA2+hX8qQTlF6HQLynW/mqgCgYIKoEcz1UBgi2hRANCAATYxKHxC4uNxH3c +1GW5pVVO+6wzq5tDlExIQBsz2RvMMcGCVj+wwGuVQFH9iAIBsbCUbAbrp9qO7nC2 +5bu0Hue0 +-----END PRIVATE KEY----- diff --git a/certs/sm2/server-sm2-cert.pem b/certs/sm2/server-sm2-cert.pem new file mode 100644 index 000000000..23c49c911 --- /dev/null +++ b/certs/sm2/server-sm2-cert.pem @@ -0,0 +1,57 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: SM2-with-SM3 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = CA-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Validity + Not Before: Feb 15 06:23:07 2023 GMT + Not After : Nov 11 06:23:07 2025 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = Server-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Subject Public Key Info: + Public Key Algorithm: sm2 + Public-Key: (256 bit) + pub: + 04:94:70:2b:46:e4:5e:0f:41:fb:8f:2d:34:0a:41: + 40:19:5e:fb:d4:1d:11:ac:fa:f5:93:37:c6:fa:87: + 08:f7:16:1f:2c:ce:30:40:9d:4f:a6:2a:0a:a1:d6: + 95:33:c3:a6:03:98:e6:8d:05:34:b0:97:0c:de:a4: + c7:cf:53:8f:d1 + ASN1 OID: SM2 + X509v3 extensions: + X509v3 Subject Key Identifier: + 67:AE:60:FF:7E:1B:0F:95:AE:1F:82:59:F2:6C:56:2D:93:EF:17:32 + X509v3 Authority Key Identifier: + 47:0A:48:7E:BB:02:A8:5A:26:57:2B:19:A9:7B:61:8B:7F:5D:99:6E + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + Netscape Cert Type: + SSL Server + Signature Algorithm: SM2-with-SM3 + Signature Value: + 30:45:02:20:1b:ca:94:28:7f:f6:b2:0d:31:43:50:e1:d5:34: + 17:dd:af:3a:de:81:06:67:9a:b3:06:22:7e:64:ec:fd:0e:b9: + 02:21:00:a1:48:a8:32:d1:05:09:6b:1c:eb:89:12:66:d8:38: + a1:c4:5c:89:09:0f:fd:e9:c0:3b:1d:fb:cd:b5:4c:31:68 +-----BEGIN CERTIFICATE----- +MIIC2DCCAn6gAwIBAgIBATAKBggqgRzPVQGDdTCBrDELMAkGA1UEBhMCVVMxEDAO +BgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFDASBgNVBAoMC3dvbGZT +U0xfc20yMQ8wDQYDVQQLDAZDQS1zbTIxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNv +bTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTEXMBUGCgmSJomT8ixk +AQEMB3dvbGZTU0wwHhcNMjMwMjE1MDYyMzA3WhcNMjUxMTExMDYyMzA3WjCBsDEL +MAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4x +FDASBgNVBAoMC3dvbGZTU0xfc20yMRMwEQYDVQQLDApTZXJ2ZXItc20yMRgwFgYD +VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz +bC5jb20xFzAVBgoJkiaJk/IsZAEBDAd3b2xmU1NMMFowFAYIKoEcz1UBgi0GCCqB +HM9VAYItA0IABJRwK0bkXg9B+48tNApBQBle+9QdEaz69ZM3xvqHCPcWHyzOMECd +T6YqCqHWlTPDpgOY5o0FNLCXDN6kx89Tj9GjgYkwgYYwHQYDVR0OBBYEFGeuYP9+ +Gw+Vrh+CWfJsVi2T7xcyMB8GA1UdIwQYMBaAFEcKSH67AqhaJlcrGal7YYt/XZlu +MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUF +BwMBMBEGCWCGSAGG+EIBAQQEAwIGQDAKBggqgRzPVQGDdQNIADBFAiAbypQof/ay +DTFDUOHVNBfdrzregQZnmrMGIn5k7P0OuQIhAKFIqDLRBQlrHOuJEmbYOKHEXIkJ +D/3pwDsd+821TDFo +-----END CERTIFICATE----- diff --git a/certs/sm2/server-sm2-key.der b/certs/sm2/server-sm2-key.der new file mode 100644 index 0000000000000000000000000000000000000000..bbc58b15a4a5804ed7aeadff7da6d1559a5fcdbd GIT binary patch literal 92 zcmXqrG7w?o&}x)9AIjLIi(oN3F|bT2&~|$g$M5*NU)O}o(Lplq_Z3;eHNU=2Hb3^O qo#VThyv{iThq?aCw73>tn`(S`8S{*1y{sl1rt{oea{PR7|3v_kb|iQJ literal 0 HcmV?d00001 diff --git a/certs/sm2/server-sm2-key.pem b/certs/sm2/server-sm2-key.pem new file mode 100644 index 000000000..b0c34dc10 --- /dev/null +++ b/certs/sm2/server-sm2-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABJRwK0bkXg9B+48tNApBQBle+9Qd +Eaz69ZM3xvqHCPcWHyzOMECdT6YqCqHWlTPDpgOY5o0FNLCXDN6kx89Tj9E= +-----END PUBLIC KEY----- diff --git a/certs/sm2/server-sm2-priv.der b/certs/sm2/server-sm2-priv.der new file mode 100644 index 0000000000000000000000000000000000000000..0ff08cecd4c8e03686f284079424b3ac453a5848 GIT binary patch literal 121 zcmV-<0EYiCcLD(c1R&Ql!J%=O+Cza2a6*V<&`f?0ikmIk6{-$e`t5f*L#Ut%1_&yF z9M4q&f-Rv$13~}!@<>p~? zcGLw4NEnEL1ekgF%gf94KuU{?bM%t)a}DJUWZ5{i+C196^D=TWiV0-qrR6&yD-bsj zW#i(Uq}Dn4lTHdFBM&>&A_F;bUL#`zBSTXIGazjq1>~9<0s)k3(71tG-Vrtsgm{N5 zIJKxOwTNb3iZT#^#YdAag2n8_z%r#k+wDmlzvJ(IT@x-x2g$hKS7Zg({Q5fC{MfH{ zj_+dfI_C@==K3$w;#zoZs`24v%rl<#vYKp|&U0_c@$61DiQimXAe@ zMI?P)!v8vH{;BKan<78ugy~LxFK%QY50X}90Y+DYh&z`@-EO88QEK7Zk}IndyX#|T z<{9vS6bLgi{%2t_U;w8NS$+_Yg_((Yg@G_gR+WVZl&rMb7+G1_nHhm$$C=RP!Pxf0 ziIEYcj?Do%)iHZ87`QSiNS~UbQU7fduc33m!>cCZch_6pYh+8GwV6$+F6GT%zMV{p n3=2J07+qxL%$9lGDU^1@V&RdPPEP*6FArGD{yw|a$1no`7dFXU literal 0 HcmV?d00001 diff --git a/certs/sm2/server-sm2.pem b/certs/sm2/server-sm2.pem new file mode 100644 index 000000000..95877f0d4 --- /dev/null +++ b/certs/sm2/server-sm2.pem @@ -0,0 +1,108 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: SM2-with-SM3 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = CA-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Validity + Not Before: Feb 15 06:23:07 2023 GMT + Not After : Nov 11 06:23:07 2025 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = Server-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Subject Public Key Info: + Public Key Algorithm: sm2 + Public-Key: (256 bit) + pub: + 04:94:70:2b:46:e4:5e:0f:41:fb:8f:2d:34:0a:41: + 40:19:5e:fb:d4:1d:11:ac:fa:f5:93:37:c6:fa:87: + 08:f7:16:1f:2c:ce:30:40:9d:4f:a6:2a:0a:a1:d6: + 95:33:c3:a6:03:98:e6:8d:05:34:b0:97:0c:de:a4: + c7:cf:53:8f:d1 + ASN1 OID: SM2 + X509v3 extensions: + X509v3 Subject Key Identifier: + 67:AE:60:FF:7E:1B:0F:95:AE:1F:82:59:F2:6C:56:2D:93:EF:17:32 + X509v3 Authority Key Identifier: + 47:0A:48:7E:BB:02:A8:5A:26:57:2B:19:A9:7B:61:8B:7F:5D:99:6E + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + Netscape Cert Type: + SSL Server + Signature Algorithm: SM2-with-SM3 + Signature Value: + 30:45:02:20:1b:ca:94:28:7f:f6:b2:0d:31:43:50:e1:d5:34: + 17:dd:af:3a:de:81:06:67:9a:b3:06:22:7e:64:ec:fd:0e:b9: + 02:21:00:a1:48:a8:32:d1:05:09:6b:1c:eb:89:12:66:d8:38: + a1:c4:5c:89:09:0f:fd:e9:c0:3b:1d:fb:cd:b5:4c:31:68 +-----BEGIN CERTIFICATE----- +MIIC2DCCAn6gAwIBAgIBATAKBggqgRzPVQGDdTCBrDELMAkGA1UEBhMCVVMxEDAO +BgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFDASBgNVBAoMC3dvbGZT +U0xfc20yMQ8wDQYDVQQLDAZDQS1zbTIxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNv +bTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTEXMBUGCgmSJomT8ixk +AQEMB3dvbGZTU0wwHhcNMjMwMjE1MDYyMzA3WhcNMjUxMTExMDYyMzA3WjCBsDEL +MAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4x +FDASBgNVBAoMC3dvbGZTU0xfc20yMRMwEQYDVQQLDApTZXJ2ZXItc20yMRgwFgYD +VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz +bC5jb20xFzAVBgoJkiaJk/IsZAEBDAd3b2xmU1NMMFowFAYIKoEcz1UBgi0GCCqB +HM9VAYItA0IABJRwK0bkXg9B+48tNApBQBle+9QdEaz69ZM3xvqHCPcWHyzOMECd +T6YqCqHWlTPDpgOY5o0FNLCXDN6kx89Tj9GjgYkwgYYwHQYDVR0OBBYEFGeuYP9+ +Gw+Vrh+CWfJsVi2T7xcyMB8GA1UdIwQYMBaAFEcKSH67AqhaJlcrGal7YYt/XZlu +MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUF +BwMBMBEGCWCGSAGG+EIBAQQEAwIGQDAKBggqgRzPVQGDdQNIADBFAiAbypQof/ay +DTFDUOHVNBfdrzregQZnmrMGIn5k7P0OuQIhAKFIqDLRBQlrHOuJEmbYOKHEXIkJ +D/3pwDsd+821TDFo +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: SM2-with-SM3 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_SM2, OU = Root-SM2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 15 06:23:07 2023 GMT + Not After : Nov 11 06:23:07 2025 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_sm2, OU = CA-sm2, CN = www.wolfssl.com, emailAddress = info@wolfssl.com, UID = wolfSSL + Subject Public Key Info: + Public Key Algorithm: sm2 + Public-Key: (256 bit) + pub: + 04:21:92:f7:cb:24:df:64:4d:ba:ab:66:7b:83:75: + a9:29:e7:ff:64:63:b6:d5:42:80:20:bd:e2:e2:02: + 12:3b:8e:b4:00:95:09:80:cb:56:ed:4b:ca:8d:57: + e6:ae:05:d3:76:27:63:71:39:89:b7:69:e6:48:80: + ae:d1:a9:48:12 + ASN1 OID: SM2 + X509v3 extensions: + X509v3 Subject Key Identifier: + 47:0A:48:7E:BB:02:A8:5A:26:57:2B:19:A9:7B:61:8B:7F:5D:99:6E + X509v3 Authority Key Identifier: + 34:1D:79:44:15:79:A1:B1:63:99:E3:ED:65:7C:64:89:80:FF:B8:EC + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: SM2-with-SM3 + Signature Value: + 30:45:02:20:47:4e:00:03:ab:34:a1:af:59:39:8f:60:36:bf: + 89:88:42:41:27:c1:dd:57:c9:79:cb:1f:56:5c:16:b5:28:bd: + 02:21:00:8b:2e:25:eb:21:9b:a9:2b:a6:6a:5b:db:a7:c7:2b: + 11:df:73:15:ad:e4:c5:c3:c2:f3:b4:b4:67:af:d7:51:1c +-----BEGIN CERTIFICATE----- +MIICljCCAjygAwIBAgIBATAKBggqgRzPVQGDdTCBlTELMAkGA1UEBhMCVVMxEDAO +BgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFDASBgNVBAoMC3dvbGZT +U0xfU00yMREwDwYDVQQLDAhSb290LVNNMjEYMBYGA1UEAwwPd3d3LndvbGZzc2wu +Y29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTIzMDIxNTA2 +MjMwN1oXDTI1MTExMTA2MjMwN1owgawxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdN +b250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRQwEgYDVQQKDAt3b2xmU1NMX3NtMjEP +MA0GA1UECwwGQ0Etc20yMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkq +hkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20xFzAVBgoJkiaJk/IsZAEBDAd3b2xm +U1NMMFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABCGS98sk32RNuqtme4N1qSnn +/2RjttVCgCC94uICEjuOtACVCYDLVu1Lyo1X5q4F03YnY3E5ibdp5kiArtGpSBKj +YzBhMB0GA1UdDgQWBBRHCkh+uwKoWiZXKxmpe2GLf12ZbjAfBgNVHSMEGDAWgBQ0 +HXlEFXmhsWOZ4+1lfGSJgP+47DAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBhjAKBggqgRzPVQGDdQNIADBFAiBHTgADqzShr1k5j2A2v4mIQkEnwd1XyXnL +H1ZcFrUovQIhAIsuJeshm6krpmpb26fHKxHfcxWt5MXDwvO0tGev11Ec +-----END CERTIFICATE----- diff --git a/configure.ac b/configure.ac index fd3e5fa9b..50eda24d6 100644 --- a/configure.ac +++ b/configure.ac @@ -184,7 +184,6 @@ AS_IF([test "$ax_enable_debug" = "yes"], [AM_CCASFLAGS="$DEBUG_CFLAGS $AM_CCASFLAGS"], [AM_CCASFLAGS="$AM_CCASFLAGS -DNDEBUG"]) - # Start without certificates enabled and enable if a certificate algorithm is # enabled ENABLED_CERTS="no" @@ -2255,8 +2254,97 @@ then fi +# SM4 +ENABLED_SM4="no" +AC_ARG_ENABLE([sm4-ecb], + [AS_HELP_STRING([--enable-sm4-ecb],[Enable wolfSSL SM4-ECB support (default: disabled)])], + [ ENABLED_SM4_ECB=$enableval ], + [ ENABLED_SM4_ECB=no ] + ) + +if test "$ENABLED_SM4_ECB" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_SMALL" +fi +if test "$ENABLED_SM4_ECB" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_ECB" + ENABLED_SM4="yes" +fi + +AC_ARG_ENABLE([sm4-cbc], + [AS_HELP_STRING([--enable-sm4-cbc],[Enable wolfSSL SM4-CBC support (default: disabled)])], + [ ENABLED_SM4_CBC=$enableval ], + [ ENABLED_SM4_CBC=no ] + ) + +if test "$ENABLED_SM4_CBC" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_SMALL" +fi +if test "$ENABLED_SM4_CBC" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_CBC" + ENABLED_SM4="yes" +fi + +AC_ARG_ENABLE([sm4-ctr], + [AS_HELP_STRING([--enable-sm4-ctr],[Enable wolfSSL SM4-CTR support (default: disabled)])], + [ ENABLED_SM4_CTR=$enableval ], + [ ENABLED_SM4_CTR=no ] + ) + +if test "$ENABLED_SM4_CTR" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_SMALL" +fi +if test "$ENABLED_SM4_CTR" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_CTR" + ENABLED_SM4="yes" +fi + +AC_ARG_ENABLE([sm4-gcm], + [AS_HELP_STRING([--enable-sm4-gcm],[Enable wolfSSL SM4-GCM support (default: enabled)])], + [ ENABLED_SM4_GCM=$enableval ], + [ ENABLED_SM4_GCM=no ] + ) + +if test "$ENABLED_SM4_GCM" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_SMALL" +fi +if test "$ENABLED_SM4_GCM" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_GCM" + ENABLED_SM4="yes" +fi + +AC_ARG_ENABLE([sm4-ccm], + [AS_HELP_STRING([--enable-sm4-ccm],[Enable wolfSSL SM4-CCM support (default: enabled)])], + [ ENABLED_SM4_CCM=$enableval ], + [ ENABLED_SM4_CCM=no ] + ) + +if test "$ENABLED_SM4_CCM" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_SMALL" +fi +if test "$ENABLED_SM4_CCM" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4_CCM" + ENABLED_SM4="yes" +fi + +if test "$ENABLED_SM4" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM4" +fi + + ENABLED_ARMASM_INLINE="no" ENABLED_ARMASM_SHA3="no" +ENABLED_ARMASM_CRYPTO_SM4="no" # ARM Assembly # Both SHA3 and SHA512 instructions available with ARMV8.2-a AC_ARG_ENABLE([armasm], @@ -2284,6 +2372,33 @@ then break;; esac ENABLED_ARMASM_SHA3=yes + ENABLED_ARMASM_PLUS=yes + ;; + sm4) + case $host_cpu in + *aarch64*) + ;; + *) + AC_MSG_ERROR([SM4 instructions only available on Aarch64 CPU.]) + break;; + esac + ENABLED_ARMASM_SM4=yes + # gcc requires -march=...+sm4 to enable SM4 instructions + ENABLED_ARMASM_CRYPTO_SM4=yes + ENABLED_ARMASM_PLUS=yes + ;; + sm3) + case $host_cpu in + *aarch64*) + ;; + *) + AC_MSG_ERROR([SM3 instructions only available on Aarch64 CPU.]) + break;; + esac + ENABLED_ARMASM_SM3=yes + # gcc requires -march=...+sm4 to enable SM3 instructions + ENABLED_ARMASM_CRYPTO_SM4=yes + ENABLED_ARMASM_PLUS=yes ;; *) AC_MSG_ERROR([Invalid choice of ARM asm inclusions (yes, sha512-crypto, sha3-crypto): $ENABLED_ARMASM.]) @@ -2308,8 +2423,14 @@ then ;; *) # +crypto needed for hardware acceleration - if test "$ENABLED_ARMASM_SHA3" = "yes"; then - AM_CPPFLAGS="$AM_CPPFLAGS -march=armv8.2-a+crypto+sha3" + if test "$ENABLED_ARMASM_PLUS" = "yes"; then + AM_CPPFLAGS="$AM_CPPFLAGS -march=armv8.2-a+crypto" + if test "$ENABLED_ARMASM_SHA3" = "yes"; then + AM_CPPFLAGS="$AM_CPPFLAGS+sha3" + fi + if test "$ENABLED_ARMASM_CRYPTO_SM4" = "yes"; then + AM_CPPFLAGS="$AM_CPPFLAGS+sm4" + fi else AM_CPPFLAGS="$AM_CPPFLAGS -mcpu=generic+crypto" fi @@ -2359,6 +2480,12 @@ if test "$ENABLED_ARMASM_SHA3" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ARMASM_CRYPTO_SHA512 -DWOLFSSL_ARMASM_CRYPTO_SHA3" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ARMASM_CRYPTO_SHA512 -DWOLFSSL_ARMASM_CRYPTO_SHA3" fi +if test "$ENABLED_ARMASM_SM3" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ARMASM_CRYPTO_SM3" +fi +if test "$ENABLED_ARMASM_SM4" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ARMASM_CRYPTO_SM4" +fi # Xilinx hardened crypto AC_ARG_ENABLE([xilinx], @@ -2957,6 +3084,22 @@ then fi +# SM3 +AC_ARG_ENABLE([sm3], + [AS_HELP_STRING([--enable-sm3],[Enable wolfSSL SM3 support (default: disabled)])], + [ ENABLED_SM3=$enableval ], + [ ENABLED_SM3=no ] + ) + +if test "$ENABLED_SM3" = "small" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM3_SMALL" +fi +if test "$ENABLED_SM3" != "no" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM3" +fi + # SESSION CERTS AC_ARG_ENABLE([sessioncerts], [AS_HELP_STRING([--enable-sessioncerts],[Enable session cert storing (default: disabled)])], @@ -3170,6 +3313,24 @@ then fi +# SM2 +AC_ARG_ENABLE([sm2], + [AS_HELP_STRING([--enable-sm2],[Enable wolfSSL SM2 support (default: disabled)])], + [ ENABLED_SM2=$enableval ], + [ ENABLED_SM2=no ] + ) + +if test "$ENABLED_SM2" = "yes" +then + if test "$ENABLED_ECC" = "no" + then + AC_MSG_ERROR([Cannot enable SM2 without enabling ecc.]) + fi + + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SM2 -DWOLFSSL_BASE16" +fi + + # ECC Custom Curves AC_ARG_ENABLE([ecccustcurves], [AS_HELP_STRING([--enable-ecccustcurves],[Enable ECC custom curves (default: disabled)])], @@ -8532,6 +8693,9 @@ AM_CONDITIONAL([BUILD_SHA3],[test "x$ENABLED_SHA3" != "xno" || test "x$ENABLED_U AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes" || test "x$ENABLED_CHACHA" = "xnoasm" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_XCHACHA],[test "x$ENABLED_XCHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SM2],[test "x$ENABLED_SM2" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SM3],[test "x$ENABLED_SM3" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SM4],[test "x$ENABLED_SM4" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_INLINE],[test "x$ENABLED_INLINE" = "xyes"]) AM_CONDITIONAL([BUILD_OCSP],[test "x$ENABLED_OCSP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_OCSP_STAPLING],[test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes"]) @@ -8927,6 +9091,11 @@ echo " * AES-OFB: $ENABLED_AESOFB" echo " * AES-SIV: $ENABLED_AESSIV" echo " * DES3: $ENABLED_DES3" echo " * Camellia: $ENABLED_CAMELLIA" +echo " * SM4-ECB: $ENABLED_SM4_ECB" +echo " * SM4-CBC: $ENABLED_SM4_CBC" +echo " * SM4-CTR: $ENABLED_SM4_CTR" +echo " * SM4-GCM: $ENABLED_SM4_GCM" +echo " * SM4-CCM: $ENABLED_SM4_CCM" echo " * NULL Cipher: $ENABLED_NULL_CIPHER" echo " * MD2: $ENABLED_MD2" echo " * MD4: $ENABLED_MD4" @@ -8939,6 +9108,7 @@ echo " * SHA-512: $ENABLED_SHA512" echo " * SHA3: $ENABLED_SHA3" echo " * SHAKE128: $ENABLED_SHAKE128" echo " * SHAKE256: $ENABLED_SHAKE256" +echo " * SM3: $ENABLED_SM3" echo " * BLAKE2: $ENABLED_BLAKE2" echo " * BLAKE2S: $ENABLED_BLAKE2S" echo " * SipHash: $ENABLED_SIPHASH" @@ -9081,6 +9251,7 @@ then fi echo " * ARM ASM: $ENABLED_ARMASM" echo " * ARM ASM SHA512/SHA3 Crypto $ENABLED_ARMASM_SHA3" +echo " * ARM ASM SM3/SM4 Crypto $ENABLED_ARMASM_CRYPTO_SM4" echo " * AES Key Wrap: $ENABLED_AESKEYWRAP" echo " * Write duplicate: $ENABLED_WRITEDUP" echo " * Xilinx Hardware Acc.: $ENABLED_XILINX" diff --git a/examples/client/client.c b/examples/client/client.c index 2eb36b9d7..3c4aebc40 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -350,6 +350,19 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, err_sys("unable to use curve secp256r1"); } while (ret == WC_PENDING_E); #endif + #ifdef WOLFSSL_SM2 + do { + ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SM2P256V1); + if (ret == WOLFSSL_SUCCESS) + groups[count++] = WOLFSSL_ECC_SM2P256V1; + #ifdef WOLFSSL_ASYNC_CRYPT + else if (ret == WC_PENDING_E) + wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + #endif + else + err_sys("unable to use curve sm2p256v1"); + } while (ret == WC_PENDING_E); + #endif #endif } } diff --git a/mcapi/crypto.h b/mcapi/crypto.h index 979d65007..451119307 100644 --- a/mcapi/crypto.h +++ b/mcapi/crypto.h @@ -173,9 +173,9 @@ enum { typedef struct CRYPT_AES_CTX { /* big enough to hold internal, but check on init */ #ifdef WOLF_PRIVATE_KEY_ID - int holder[108]; + int holder[110]; #else - int holder[90]; + int holder[92]; #endif } CRYPT_AES_CTX; diff --git a/src/dtls.c b/src/dtls.c index d604b5a2f..97cfae7ea 100644 --- a/src/dtls.c +++ b/src/dtls.c @@ -718,8 +718,8 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch) #ifdef HAVE_SUPPORTED_CURVES if (doKE) { byte searched = 0; - ret = TLSX_KeyShare_Choose(ssl, parsedExts, &cs.clientKSE, - &searched); + ret = TLSX_KeyShare_Choose(ssl, parsedExts, cs.cipherSuite0, + cs.cipherSuite, &cs.clientKSE, &searched); if (ret != 0) goto dtls13_cleanup; if (cs.clientKSE == NULL && searched) diff --git a/src/include.am b/src/include.am index d2c40e6de..174be8483 100644 --- a/src/include.am +++ b/src/include.am @@ -473,6 +473,27 @@ endif endif endif !BUILD_FIPS_CURRENT +if !BUILD_FIPS_CURRENT +if BUILD_SM2 +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sm2.c +endif BUILD_SM2 +endif !BUILD_FIPS_CURRENT + +if !BUILD_FIPS_CURRENT +if BUILD_SM3 +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sm3.c +if BUILD_INTELASM +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sm3_asm.S +endif +endif BUILD_SM3 +endif !BUILD_FIPS_CURRENT + +if !BUILD_FIPS_CURRENT +if BUILD_SM4 +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sm4.c +endif BUILD_SM4 +endif !BUILD_FIPS_CURRENT + endif !BUILD_FIPS_RAND if BUILD_SIPHASH diff --git a/src/internal.c b/src/internal.c index 9d3cf0117..41f610437 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2755,17 +2755,23 @@ void FreeCiphers(WOLFSSL* ssl) * check (enc->aes, dec->aes) */ wc_AesFree(ssl->encrypt.aes); wc_AesFree(ssl->decrypt.aes); - #if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \ - !defined(WOLFSSL_NO_TLS12) - XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); - XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); - #endif XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif +#if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + wc_Sm4Free(ssl->encrypt.sm4); + wc_Sm4Free(ssl->decrypt.sm4); + XFREE(ssl->encrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +#if (defined(BUILD_AESGCM) || defined(BUILD_AESCCM)) && \ + !defined(WOLFSSL_NO_TLS12) + XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif #ifdef CIPHER_NONCE - XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); - XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif #ifdef HAVE_CAMELLIA XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER); @@ -2847,13 +2853,17 @@ static int GetMacDigestSize(byte macAlgo) #ifdef WOLFSSL_SHA512 case sha512_mac: return WC_SHA512_DIGEST_SIZE; + #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + return WC_SM3_DIGEST_SIZE; #endif default: break; } return NOT_COMPILED_IN; } -#endif /* USE_ECDSA_KEYSZ_HASH_ALGO */ +#endif /* USE_ECDSA_KEYSZ_HASH_ALGO || (WOLFSSL_TLS13 && HAVE_ECC) */ #define ADD_HASH_SIG_ALGO(out, inOutIdx, major, minor) \ do { \ @@ -2882,6 +2892,13 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo, #endif /* USE_ECDSA_KEYSZ_HASH_ALGO */ if (addSigAlgo) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigAlgo == sm2_sa_algo) { + ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, + SM2_SA_MAJOR, SM2_SA_MINOR); + } + else + #endif #ifdef HAVE_ED25519 if (sigAlgo == ed25519_sa_algo) { ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, @@ -2945,18 +2962,8 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo, } } -void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, - int haveFalconSig, int haveDilithiumSig, int haveAnon, int tls1_2, - int keySz) -{ - InitSuitesHashSigAlgo_ex(suites->hashSigAlgo, haveECDSAsig, haveRSAsig, - haveFalconSig, haveDilithiumSig, haveAnon, tls1_2, keySz, - &suites->hashSigAlgoSz); -} - -void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, - int haveRSAsig, int haveFalconSig, int haveDilithiumSig, int haveAnon, - int tls1_2, int keySz, word16* len) +void InitSuitesHashSigAlgo_ex2(byte* hashSigAlgo, int haveSig, int tls1_2, + int keySz, word16* len) { word16 idx = 0; @@ -2964,7 +2971,7 @@ void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, (void)keySz; #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) - if (haveECDSAsig) { + if (haveSig & SIG_ECDSA) { #ifdef HAVE_ECC #ifdef WOLFSSL_SHA512 AddSuiteHashSigAlgo(hashSigAlgo, sha512_mac, ecc_dsa_sa_algo, keySz, @@ -2991,29 +2998,33 @@ void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, #endif } #endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */ - if (haveFalconSig) { +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (haveSig & SIG_SM2) { + AddSuiteHashSigAlgo(hashSigAlgo, sm3_mac, sm2_sa_algo, keySz, + &idx); + } +#endif #if defined(HAVE_PQC) #ifdef HAVE_FALCON + if (haveSig & SIG_FALCON) { AddSuiteHashSigAlgo(hashSigAlgo, no_mac, falcon_level1_sa_algo, keySz, &idx); AddSuiteHashSigAlgo(hashSigAlgo, no_mac, falcon_level5_sa_algo, keySz, &idx); -#endif /* HAVE_FALCON */ -#endif /* HAVE_PQC */ } - if (haveDilithiumSig) { -#if defined(HAVE_PQC) +#endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM + if (haveSig & SIG_DILITHIUM) { AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level2_sa_algo, keySz, &idx); AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level3_sa_algo, keySz, &idx); AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level5_sa_algo, keySz, &idx); + } #endif /* HAVE_DILITHIUM */ #endif /* HAVE_PQC */ - } - if (haveRSAsig) { + if (haveSig & SIG_RSA) { #ifdef WC_RSA_PSS if (tls1_2) { #ifdef WOLFSSL_SHA512 @@ -3049,17 +3060,39 @@ void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, } #ifdef HAVE_ANON - if (haveAnon) { + if (haveSig & SIG_ANON) { AddSuiteHashSigAlgo(hashSigAlgo, sha_mac, anonymous_sa_algo, keySz, &idx); } #endif - (void)haveAnon; - (void)haveECDSAsig; *len = idx; } +void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, + int haveFalconSig, int haveDilithiumSig, int haveAnon, int tls1_2, + int keySz) +{ + InitSuitesHashSigAlgo_ex(suites->hashSigAlgo, haveECDSAsig, haveRSAsig, + haveFalconSig, haveDilithiumSig, haveAnon, tls1_2, keySz, + &suites->hashSigAlgoSz); +} + +void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, + int haveRSAsig, int haveFalconSig, int haveDilithiumSig, int haveAnon, + int tls1_2, int keySz, word16* len) +{ + int have = 0; + + if (haveECDSAsig) have |= SIG_ECDSA; + if (haveRSAsig) have |= SIG_RSA; + if (haveFalconSig) have |= SIG_FALCON; + if (haveDilithiumSig) have |= SIG_DILITHIUM; + if (haveAnon) have |= SIG_ANON; + + InitSuitesHashSigAlgo_ex2(hashSigAlgo, have, tls1_2, keySz, len); +} + int AllocateCtxSuites(WOLFSSL_CTX* ctx) { if (ctx->suites == NULL) { @@ -3174,6 +3207,19 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, } #endif +#ifdef BUILD_TLS_SM4_GCM_SM3 + if (tls1_3) { + suites->suites[idx++] = CIPHER_BYTE; + suites->suites[idx++] = TLS_SM4_GCM_SM3; + } +#endif +#ifdef BUILD_TLS_SM4_CCM_SM3 + if (tls1_3) { + suites->suites[idx++] = CIPHER_BYTE; + suites->suites[idx++] = TLS_SM4_CCM_SM3; + } +#endif + #ifdef HAVE_NULL_CIPHER #ifdef BUILD_TLS_SHA256_SHA256 if (tls1_3 && haveNull) { @@ -4054,14 +4100,41 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, } #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + if (tls && haveECC) { + suites->suites[idx++] = SM_BYTE; + suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3; + } +#endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + if (tls && haveECC) { + suites->suites[idx++] = SM_BYTE; + suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3; + } +#endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + if (tls && haveECC) { + suites->suites[idx++] = SM_BYTE; + suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3; + } +#endif + #endif /* !WOLFSSL_NO_TLS12 */ suites->suiteSz = idx; if (suites->hashSigAlgoSz == 0) { - InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC, - haveRSAsig | haveRSA, haveFalconSig, - haveDilithiumSig, 0, tls1_2, keySz); + int haveSig = 0; + haveSig |= (haveRSAsig | haveRSA) ? SIG_RSA : 0; + haveSig |= (haveECDSAsig | haveECC) ? SIG_ECDSA : 0; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + haveSig |= (haveECDSAsig | haveECC) ? SIG_SM2 : 0; + #endif + haveSig |= haveFalconSig ? SIG_FALCON : 0; + haveSig |= haveDilithiumSig ? SIG_DILITHIUM : 0; + haveSig &= ~SIG_ANON; + InitSuitesHashSigAlgo_ex2(suites->hashSigAlgo, haveSig, tls1_2, keySz, + &suites->hashSigAlgoSz); } } @@ -4110,6 +4183,16 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy *hashAlgo = input[1]; } break; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2_SA_MAJOR: + /* SM2: 0x0708 */ + if (input[1] == SM2_SA_MINOR) { + *hsType = sm2_sa_algo; + /* Hash performed as part of sign/verify operation. */ + *hashAlgo = sm3_mac; + } + break; + #endif #ifdef HAVE_PQC case PQC_SA_MAJOR: /* Hash performed as part of sign/verify operation. */ @@ -4163,6 +4246,10 @@ static enum wc_HashType HashAlgoToType(int hashAlgo) case sha384_mac: return WC_HASH_TYPE_SHA384; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + return WC_HASH_TYPE_SM3; + #endif #ifndef NO_SHA256 case sha256_mac: return WC_HASH_TYPE_SHA256; @@ -4393,6 +4480,13 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) (void)hashAlgo; break; #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + output[0] = SM2_SA_MAJOR; + output[1] = SM2_SA_MINOR; + (void)hashAlgo; + break; +#endif #ifndef NO_RSA case rsa_sa_algo: output[0] = hashAlgo; @@ -4432,6 +4526,13 @@ static void SetDigest(WOLFSSL* ssl, int hashAlgo) ssl->buffers.digest.length = WC_SHA256_DIGEST_SIZE; break; #endif /* !NO_SHA256 */ + #ifdef WOLFSSL_SM3 + case sm3_mac: + ssl->options.dontFreeDigest = 1; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sm3; + ssl->buffers.digest.length = WC_SM3_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SM2 */ #ifdef WOLFSSL_SHA384 case sha384_mac: ssl->options.dontFreeDigest = 1; @@ -5184,6 +5285,24 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) if (ssl->ecdhCurveOID > 0) { ecc_curve = wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL); } + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \ + (defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_GCM) || \ + defined(WOLFSSL_SM4_CCM)) + if ((ssl->options.cipherSuite0 == SM_BYTE) && (0 + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + || (ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3) + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + || (ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3) + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + || (ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3) + #endif + )) { + keySz = 32; + ecc_curve = ECC_SM2P256V1; + } + #endif } else { keySz = peer->dp->size; @@ -5222,6 +5341,63 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) } #endif /* HAVE_ECC */ +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + +int Sm2wSm3Sign(WOLFSSL* ssl, const byte* id, word32 idSz, const byte* in, + word32 inSz, byte* out, word32* outSz, ecc_key* key, DerBuffer* keyBufInfo) +{ + int ret; + byte hash[WC_SM3_DIGEST_SIZE]; + + (void)ssl; + (void)keyBufInfo; + + WOLFSSL_ENTER("Sm2wSm3Sign"); + + ret = wc_ecc_sm2_create_digest(id, idSz, in, inSz, WC_HASH_TYPE_SM3, hash, + sizeof(hash), key); + if (ret == 0) { + ret = wc_ecc_sm2_sign_hash(hash, sizeof(hash), out, outSz, ssl->rng, + key); + } + + WOLFSSL_LEAVE("Sm2wSm3Sign", ret); + + return ret; +} + +int Sm2wSm3Verify(WOLFSSL* ssl, const byte* id, word32 idSz, const byte* sig, + word32 sigSz, const byte* msg, word32 msgSz, ecc_key* key, + buffer* keyBufInfo) +{ + int ret = SIG_VERIFY_E; + byte hash[WC_SM3_DIGEST_SIZE]; + + (void)ssl; + (void)keyBufInfo; + + WOLFSSL_ENTER("Sm2wSm3Verify"); + + ret = wc_ecc_sm2_create_digest(id, idSz, msg, msgSz, WC_HASH_TYPE_SM3, hash, + sizeof(hash), key); + if (ret == 0) { + ret = wc_ecc_sm2_verify_hash(sig, sigSz, hash, sizeof(hash), + &ssl->eccVerifyRes, key); + if (ret == 0 && ssl->eccVerifyRes == 0) { + ret = VERIFY_SIGN_ERROR; + } + } + if (ret != 0) { + WOLFSSL_ERROR_VERBOSE(ret); + } + + WOLFSSL_LEAVE("Sm2wSm3Verify", ret); + + return ret; +} + +#endif /* WOLFSSL_SM2 */ + #ifdef HAVE_ED25519 /* Check whether the key contains a public key. * If not then pull it out of the leaf certificate. @@ -6133,11 +6309,13 @@ int InitSSL_Suites(WOLFSSL* ssl) ssl->options.maxEarlyDataSz = ssl->ctx->maxEarlyDataSz; #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END || ssl->buffers.keyType == ed25519_sa_algo || - ssl->buffers.keyType == ed448_sa_algo; + ssl->buffers.keyType == ed448_sa_algo || + ssl->buffers.keyType == sm2_sa_algo; #endif #ifndef NO_CERTS @@ -6437,11 +6615,13 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->buffers.keyDevId = ctx->privateKeyDevId; #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END || ssl->buffers.keyType == ed25519_sa_algo || - ssl->buffers.keyType == ed448_sa_algo; + ssl->buffers.keyType == ed448_sa_algo || + ssl->buffers.keyType == sm2_sa_algo; #endif @@ -6567,6 +6747,14 @@ int InitHandshakeHashes(WOLFSSL* ssl) wc_Sha512SetFlags(&ssl->hsHashes->hashSha512, WC_HASH_FLAG_WILLCOPY); #endif #endif +#ifdef WOLFSSL_SM3 + ret = wc_InitSm3(&ssl->hsHashes->hashSm3, ssl->heap, ssl->devId); + if (ret != 0) + return ret; + #ifdef WOLFSSL_HASH_FLAGS + wc_Sm3SetFlags(&ssl->hsHashes->hashSm3, WC_HASH_FLAG_WILLCOPY); + #endif +#endif return ret; } @@ -6591,8 +6779,12 @@ void FreeHandshakeHashes(WOLFSSL* ssl) #ifdef WOLFSSL_SHA512 wc_Sha512Free(&ssl->hsHashes->hashSha512); #endif - #if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) + #ifdef WOLFSSL_SM3 + wc_Sm3Free(&ssl->hsHashes->hashSm3); + #endif + #if (defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + (defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3))) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) if (ssl->hsHashes->messages != NULL) { ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length); XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES); @@ -6649,8 +6841,14 @@ int InitHandshakeHashesAndCopy(WOLFSSL* ssl, HS_Hashes* source, ret = wc_Sha512Copy(&source->hashSha512, &(*destination)->hashSha512); #endif - #if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) + #ifdef WOLFSSL_SM3 + if (ret == 0) + ret = wc_Sm3Copy(&source->hashSm3, + &(*destination)->hashSm3); + #endif + #if (defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + (defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3))) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) if (ret == 0 && source->messages != NULL) { (*destination)->messages = (byte*)XMALLOC(source->length, ssl->heap, DYNAMIC_TYPE_HASHES); @@ -8201,7 +8399,8 @@ void FreeSSL(WOLFSSL* ssl, void* heap) #if !defined(NO_OLD_TLS) || defined(WOLFSSL_DTLS) || \ !defined(WOLFSSL_NO_TLS12) || \ - ((defined(HAVE_CHACHA) || defined(HAVE_AESCCM) || defined(HAVE_AESGCM)) \ + ((defined(HAVE_CHACHA) || defined(HAVE_AESCCM) || defined(HAVE_AESGCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) \ && defined(HAVE_AEAD)) #if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) @@ -8325,7 +8524,8 @@ void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) } #endif /* WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 */ #endif /* !NO_OLD_TLS || WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 || - * ((HAVE_CHACHA || HAVE_AESCCM || HAVE_AESGCM) && HAVE_AEAD) */ + * ((HAVE_CHACHA || HAVE_AESCCM || HAVE_AESGCM || WOLFSSL_SM4_GCM || + * WOLFSSL_SM4_CCM) && HAVE_AEAD) */ #ifdef WOLFSSL_DTLS @@ -9388,7 +9588,8 @@ ProtocolVersion MakeDTLSv1_3(void) #endif /* !NO_ASN_TIME */ #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) /* Store the message for use with CertificateVerify using EdDSA. * @@ -9494,8 +9695,19 @@ int HashRaw(WOLFSSL* ssl, const byte* data, int sz) WOLFSSL_BUFFER(digest, WC_SHA512_DIGEST_SIZE); #endif #endif + #ifdef WOLFSSL_SM3 + ret = wc_Sm3Update(&ssl->hsHashes->hashSm3, data, sz); + if (ret != 0) + return ret; + #ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("SM3"); + wc_Sm3GetHash(&ssl->hsHashes->hashSm3, digest); + WOLFSSL_BUFFER(digest, WC_SM3_DIGEST_SIZE); + #endif + #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) ret = EdDSA_Update(ssl, data, sz); if (ret != 0) @@ -10874,31 +11086,31 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #endif /* WOLFSSL_NO_TLS12 */ #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) - /* cipher requirements */ - enum { - REQUIRES_RSA, - REQUIRES_DHE, - REQUIRES_ECC, - REQUIRES_ECC_STATIC, - REQUIRES_PSK, - REQUIRES_RSA_SIG, - REQUIRES_AEAD - }; +/* cipher requirements */ +enum { + REQUIRES_RSA, + REQUIRES_DHE, + REQUIRES_ECC, + REQUIRES_ECC_STATIC, + REQUIRES_PSK, + REQUIRES_RSA_SIG, + REQUIRES_AEAD +}; - /* Does this cipher suite (first, second) have the requirement - an ephemeral key exchange will still require the key for signing - the key exchange so ECDHE_RSA requires an rsa key thus rsa_kea */ - static int CipherRequires(byte first, byte second, int requirement) - { +/* Does this cipher suite (first, second) have the requirement + an ephemeral key exchange will still require the key for signing + the key exchange so ECDHE_RSA requires an rsa key thus rsa_kea */ +static int CipherRequires(byte first, byte second, int requirement) +{ - (void)requirement; + (void)requirement; #ifndef WOLFSSL_NO_TLS12 #ifdef HAVE_CHACHA - if (first == CHACHA_BYTE) { + if (first == CHACHA_BYTE) { switch (second) { case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : @@ -10952,527 +11164,580 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_DHE) return 1; break; + + default: + WOLFSSL_MSG("Unsupported cipher suite, CipherRequires CHACHA"); + return 0; } if (requirement == REQUIRES_AEAD) return 1; - } + } #endif /* HAVE_CHACHA */ - /* ECC extensions */ - if (first == ECC_BYTE) { + /* ECC extensions */ + if (first == ECC_BYTE) { switch (second) { #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) #ifndef NO_RSA - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; - #ifndef NO_DES3 - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + #ifndef NO_DES3 + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - #endif /* !NO_DES3 */ + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + #endif /* !NO_DES3 */ - #ifndef NO_RC4 - case TLS_ECDHE_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + #ifndef NO_RC4 + case TLS_ECDHE_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDH_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - #endif /* !NO_RC4 */ + case TLS_ECDH_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + #endif /* !NO_RC4 */ #endif /* NO_RSA */ - #ifndef NO_DES3 - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC) - return 1; - break; + #ifndef NO_DES3 + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - #endif /* !NO_DES3 */ - #ifndef NO_RC4 - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + #endif /* !NO_DES3 */ + #ifndef NO_RC4 + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; - #endif /* !NO_RC4 */ - #ifndef NO_RSA - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + #endif /* !NO_RC4 */ + #ifndef NO_RSA + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - break; - #endif /* !NO_RSA */ + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + #endif /* !NO_RSA */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_RSA #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_ECC_STATIC) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_ECC_STATIC) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifdef HAVE_AESCCM - case TLS_RSA_WITH_AES_128_CCM_8 : - case TLS_RSA_WITH_AES_256_CCM_8 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_RSA_WITH_AES_128_CCM_8 : + case TLS_RSA_WITH_AES_256_CCM_8 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; #endif /* HAVE_AESCCM */ #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #endif /* !NO_RSA */ -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM : - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : - case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : - if (requirement == REQUIRES_ECC) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM : + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : + case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : + if (requirement == REQUIRES_ECC) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 : + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 : - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 : - if (requirement == REQUIRES_ECC) - return 1; - if (requirement == REQUIRES_ECC_STATIC) - return 1; - break; -#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 : + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 : + if (requirement == REQUIRES_ECC) + return 1; + if (requirement == REQUIRES_ECC_STATIC) + return 1; + break; + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ -#ifndef NO_PSK - case TLS_PSK_WITH_AES_128_CCM: - case TLS_PSK_WITH_AES_256_CCM: - case TLS_PSK_WITH_AES_128_CCM_8: - case TLS_PSK_WITH_AES_256_CCM_8: - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + #ifndef NO_PSK + case TLS_PSK_WITH_AES_128_CCM: + case TLS_PSK_WITH_AES_256_CCM: + case TLS_PSK_WITH_AES_128_CCM_8: + case TLS_PSK_WITH_AES_256_CCM_8: + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_DHE_PSK_WITH_AES_128_CCM: - case TLS_DHE_PSK_WITH_AES_256_CCM: - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; -#endif /* !NO_PSK */ -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_ECDSA_WITH_NULL_SHA : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_DHE_PSK_WITH_AES_128_CCM: + case TLS_DHE_PSK_WITH_AES_256_CCM: + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; + #endif /* !NO_PSK */ + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + case TLS_ECDHE_ECDSA_WITH_NULL_SHA : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_ECDHE_PSK_WITH_NULL_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - break; + case TLS_ECDHE_PSK_WITH_NULL_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + break; - case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - break; -#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ + case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + break; + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ -#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) - case TLS_SHA256_SHA256: - break; - case TLS_SHA384_SHA384: - break; -#endif + #if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) + case TLS_SHA256_SHA256: + break; + case TLS_SHA384_SHA384: + break; + #endif - default: - WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC"); - return 0; + default: + WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC"); + return 0; } /* switch */ - } /* if */ + } /* if */ - /* ECC extensions */ - if (first == ECDHE_PSK_BYTE) { + /* ECC extensions */ + if (first == ECDHE_PSK_BYTE) { switch (second) { -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) - case TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - break; -#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ - default: - WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC PSK"); - return 0; + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + case TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + break; + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ + default: + WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC PSK"); + return 0; } /* switch */ - } /* if */ + } /* if */ #endif /* !WOLFSSL_NO_TLS12 */ - /* Distinct TLS v1.3 cipher suites with cipher and digest only. */ - if (first == TLS13_BYTE) { - - switch (second) { #ifdef WOLFSSL_TLS13 + /* Distinct TLS v1.3 cipher suites with cipher and digest only. */ + if (first == TLS13_BYTE) { + + switch (second) { case TLS_AES_128_GCM_SHA256: case TLS_AES_256_GCM_SHA384: case TLS_CHACHA20_POLY1305_SHA256: case TLS_AES_128_CCM_SHA256: case TLS_AES_128_CCM_8_SHA256: + if (requirement == REQUIRES_AEAD) + return 1; + return 0; break; -#endif default: WOLFSSL_MSG("Unsupported cipher suite, CipherRequires " "TLS v1.3"); return 0; - } } + } + +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && defined(WOLFSSL_SM4) + if (first == CIPHER_BYTE) { + /* Other cipher suites for TLS 1.2 below. */ + switch (second) { + #if defined(WOLFSSL_SM4_GCM) + case TLS_SM4_GCM_SM3: + return 0; + break; + #endif + #if defined(WOLFSSL_SM4_CCM) + case TLS_SM4_CCM_SM3: + return 0; + break; + #endif + } + } +#endif /* WOLFSSL_SM2 && WOLFSSL_SM3 && WOLFSSL_SM4 */ +#endif /* WOLFSSL_TLS13 */ #ifndef WOLFSSL_NO_TLS12 - if (first != ECC_BYTE && first != CHACHA_BYTE && - first != TLS13_BYTE && first != ECDHE_PSK_BYTE) { +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && defined(WOLFSSL_SM4) + if (first == SM_BYTE) { + switch (second) { + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3: + if (requirement == REQUIRES_ECC) + return 1; + break; + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3: + if (requirement == REQUIRES_ECC) + return 1; + break; + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3: + if (requirement == REQUIRES_ECC) + return 1; + break; + #endif + + default: + WOLFSSL_MSG("Unsupported cipher suite, CipherRequires SM"); + return 0; + } + } +#endif + + if (first == CIPHER_BYTE) { /* normal suites */ switch (second) { -#ifndef NO_RSA - #ifndef NO_RC4 - case SSL_RSA_WITH_RC4_128_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + #ifndef NO_RSA + #ifndef NO_RC4 + case SSL_RSA_WITH_RC4_128_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case SSL_RSA_WITH_RC4_128_MD5 : - if (requirement == REQUIRES_RSA) - return 1; - break; - #endif /* NO_RC4 */ + case SSL_RSA_WITH_RC4_128_MD5 : + if (requirement == REQUIRES_RSA) + return 1; + break; + #endif /* NO_RC4 */ - case SSL_RSA_WITH_3DES_EDE_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_RSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_RSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_RSA_WITH_AES_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_RSA_WITH_AES_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_RSA_WITH_NULL_MD5 : - case TLS_RSA_WITH_NULL_SHA : - case TLS_RSA_WITH_NULL_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_RSA_WITH_NULL_MD5 : + case TLS_RSA_WITH_NULL_SHA : + case TLS_RSA_WITH_NULL_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; -#endif /* !NO_RSA */ + #endif /* !NO_RSA */ -#ifndef NO_PSK - case TLS_PSK_WITH_AES_128_GCM_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + #ifndef NO_PSK + case TLS_PSK_WITH_AES_128_GCM_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_PSK_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_PSK_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_PSK_WITH_AES_128_CBC_SHA256 : - case TLS_PSK_WITH_AES_256_CBC_SHA384 : - case TLS_PSK_WITH_AES_128_CBC_SHA : - case TLS_PSK_WITH_AES_256_CBC_SHA : - case TLS_PSK_WITH_NULL_SHA384 : - case TLS_PSK_WITH_NULL_SHA256 : - case TLS_PSK_WITH_NULL_SHA : - if (requirement == REQUIRES_PSK) - return 1; - break; + case TLS_PSK_WITH_AES_128_CBC_SHA256 : + case TLS_PSK_WITH_AES_256_CBC_SHA384 : + case TLS_PSK_WITH_AES_128_CBC_SHA : + case TLS_PSK_WITH_AES_256_CBC_SHA : + case TLS_PSK_WITH_NULL_SHA384 : + case TLS_PSK_WITH_NULL_SHA256 : + case TLS_PSK_WITH_NULL_SHA : + if (requirement == REQUIRES_PSK) + return 1; + break; - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_DHE) - return 1; - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : - case TLS_DHE_PSK_WITH_NULL_SHA384 : - case TLS_DHE_PSK_WITH_NULL_SHA256 : - if (requirement == REQUIRES_DHE) - return 1; - if (requirement == REQUIRES_PSK) - return 1; - break; -#endif /* NO_PSK */ + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : + case TLS_DHE_PSK_WITH_NULL_SHA384 : + case TLS_DHE_PSK_WITH_NULL_SHA256 : + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_PSK) + return 1; + break; + #endif /* NO_PSK */ -#ifndef NO_RSA - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + #ifndef NO_RSA + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_RSA_WITH_AES_128_GCM_SHA256 : - case TLS_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; -#ifdef HAVE_CAMELLIA - case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA : - case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA : - case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 : - case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + #ifdef HAVE_CAMELLIA + case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA : + case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA : + case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 : + case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA : - case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA : - case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 : - case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; -#endif /* HAVE_CAMELLIA */ + case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA : + case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA : + case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 : + case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + #endif /* HAVE_CAMELLIA */ - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_RSA_SIG) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; -#endif -#ifdef HAVE_ANON - case TLS_DH_anon_WITH_AES_128_CBC_SHA : - if (requirement == REQUIRES_DHE) - return 1; - break; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: - if (requirement == REQUIRES_DHE) - return 1; - if (requirement == REQUIRES_AEAD) - return 1; - break; -#endif -#ifdef WOLFSSL_MULTICAST - case WDM_WITH_NULL_SHA256 : - break; -#endif + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + #endif /* !NO_RSA */ + #ifdef HAVE_ANON + case TLS_DH_anon_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_DHE) + return 1; + break; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + if (requirement == REQUIRES_DHE) + return 1; + if (requirement == REQUIRES_AEAD) + return 1; + break; + #endif + #ifdef WOLFSSL_MULTICAST + case WDM_WITH_NULL_SHA256 : + break; + #endif - default: - WOLFSSL_MSG("Unsupported cipher suite, CipherRequires"); - return 0; + default: + WOLFSSL_MSG("Unsupported cipher suite, CipherRequires"); + return 0; } /* switch */ - } /* if ECC / Normal suites else */ + } /* if ECC / Normal suites else */ #endif /* !WOLFSSL_NO_TLS12 */ - return 0; - } + return 0; +} #endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */ @@ -13978,8 +14243,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* compare against previous time */ if (ssl->secure_renegotiation->subject_hash_set) { if (XMEMCMP(args->dCert->subjectHash, - ssl->secure_renegotiation->subject_hash, - KEYID_SIZE) != 0) { + ssl->secure_renegotiation->subject_hash, + KEYID_SIZE) != 0) { WOLFSSL_MSG( "Peer sent different cert during scr, fatal"); args->fatal = 1; @@ -14370,6 +14635,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } #endif /* NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + #endif case ECDSAk: { int keyRet = 0; @@ -15809,7 +16077,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("processing server hello"); ret = DoServerHello(ssl, input, inOutIdx, size); #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { @@ -15891,7 +16160,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("processing client hello"); ret = DoClientHello(ssl, input, inOutIdx, size); #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) if (ssl->options.resuming || !ssl->options.verifyPeer || \ !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { @@ -17406,6 +17676,25 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, #endif +#if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + +/* The following type is used to share code between SM4-GCM and SM4-CCM. */ +typedef int (*Sm4AuthEncryptFunc)(wc_Sm4* sm4, byte* out, const byte* in, + word32 sz, const byte* nonce, word32 nonceSz, byte* tag, word32 tagSz, + const byte* aad, word32 aadSz); +typedef int (*Sm4AuthDecryptFunc)(wc_Sm4* sm4, byte* out, const byte* in, + word32 sz, const byte* nonce, word32 nonceSz, const byte* tag, word32 tagSz, + const byte* aad, word32 aadSz); + +#define SM4_AUTH_ENCRYPT_FUNC Sm4AuthEncryptFunc +#define SM4_AUTH_DECRYPT_FUNC Sm4AuthDecryptFunc +#define SM4_GCM_ENCRYPT_FUNC wc_Sm4GcmEncrypt +#define SM4_CCM_ENCRYPT_FUNC wc_Sm4CcmEncrypt +#define SM4_GCM_DECRYPT_FUNC wc_Sm4GcmDecrypt +#define SM4_CCM_DECRYPT_FUNC wc_Sm4CcmDecrypt + +#endif + static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, word16 sz, int asyncOkay) @@ -17574,6 +17863,95 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, break; #endif + #ifdef WOLFSSL_SM4_CBC + case wolfssl_sm4_cbc: + #ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + asyncDev = &ssl->encrypt.sm4->asyncDev; + ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags); + if (ret != 0) + break; + #endif + ret = wc_Sm4CbcEncrypt(ssl->encrypt.sm4, out, input, sz); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E && asyncOkay) { + ret = wolfSSL_AsyncPush(ssl, asyncDev); + } + #endif + break; + #endif + + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + case wolfssl_sm4_gcm: + case wolfssl_sm4_ccm:/* GCM AEAD macros use same size as CCM */ + { + SM4_AUTH_ENCRYPT_FUNC sm4_auth_fn; + const byte* additionalSrc; + + #ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + asyncDev = &ssl->encrypt.sm4->asyncDev; + ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags); + if (ret != 0) + break; + #endif + + #if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_SM4_CCM) + sm4_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) + ? SM4_GCM_ENCRYPT_FUNC : SM4_CCM_ENCRYPT_FUNC; + #elif defined(WOLFSSL_SM4_GCM) + sm4_auth_fn = SM4_GCM_ENCRYPT_FUNC; + #else + sm4_auth_fn = SM4_CCM_ENCRYPT_FUNC; + #endif + additionalSrc = input - 5; + + XMEMSET(ssl->encrypt.additional, 0, AEAD_AUTH_DATA_SZ); + + /* sequence number field is 64-bits */ + WriteSEQ(ssl, CUR_ORDER, ssl->encrypt.additional); + + /* Store the type, version. Unfortunately, they are in + * the input buffer ahead of the plaintext. */ + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + additionalSrc -= DTLS_HANDSHAKE_EXTRA; + } + #endif + XMEMCPY(ssl->encrypt.additional + AEAD_TYPE_OFFSET, + additionalSrc, 3); + + /* Store the length of the plain text minus the explicit + * IV length minus the authentication tag size. */ + c16toa(sz - GCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->encrypt.additional + AEAD_LEN_OFFSET); + XMEMCPY(ssl->encrypt.nonce, + ssl->keys.aead_enc_imp_IV, GCM_IMP_IV_SZ); + XMEMCPY(ssl->encrypt.nonce + GCM_IMP_IV_SZ, + ssl->keys.aead_exp_IV, GCM_EXP_IV_SZ); + ret = sm4_auth_fn(ssl->encrypt.sm4, + out + GCM_EXP_IV_SZ, input + GCM_EXP_IV_SZ, + sz - GCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->encrypt.nonce, GCM_NONCE_SZ, + out + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size, + ssl->encrypt.additional, AEAD_AUTH_DATA_SZ); + + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E && asyncOkay) { + ret = wolfSSL_AsyncPush(ssl, asyncDev); + } + #endif +#if !defined(NO_PUBLIC_GCM_SET_IV) && \ + ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) + XMEMCPY(out, + ssl->encrypt.nonce + GCM_IMP_IV_SZ, GCM_EXP_IV_SZ); +#endif + } + break; + #endif /* WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM */ + #ifdef HAVE_NULL_CIPHER case wolfssl_cipher_null: if (input != out) { @@ -17638,10 +18016,10 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, /* make sure auth iv and auth are allocated */ if (ssl->encrypt.additional == NULL) ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, - ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + ssl->heap, DYNAMIC_TYPE_CIPHER); if (ssl->encrypt.nonce == NULL) { ssl->encrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ, - ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + ssl->heap, DYNAMIC_TYPE_CIPHER); #ifdef WOLFSSL_CHECK_MEM_ZERO if (ssl->encrypt.nonce != NULL) { wc_MemZero_Add("Encrypt nonce", ssl->encrypt.nonce, @@ -17656,6 +18034,32 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, } #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + /* make sure SM4 GCM/CCM memory is allocated */ + /* free for these happens in FreeCiphers */ + if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || + ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) { + /* make sure auth iv and auth are allocated */ + if (ssl->encrypt.additional == NULL) + ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, + ssl->heap, DYNAMIC_TYPE_CIPHER); + if (ssl->encrypt.nonce == NULL) { + ssl->encrypt.nonce = (byte*)XMALLOC(GCM_NONCE_SZ, + ssl->heap, DYNAMIC_TYPE_CIPHER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->encrypt.nonce != NULL) { + wc_MemZero_Add("Encrypt nonce", ssl->encrypt.nonce, + GCM_NONCE_SZ); + } + #endif + } + if (ssl->encrypt.additional == NULL || + ssl->encrypt.nonce == NULL) { + return MEMORY_E; + } + } + #endif /* WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM */ + /* Advance state and proceed */ ssl->encrypt.state = CIPHER_STATE_DO; } @@ -17706,6 +18110,16 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ); } #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || + ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) + { + /* finalize authentication cipher */ + AeadIncrementExpIV(ssl); + if (ssl->encrypt.nonce) + ForceZero(ssl->encrypt.nonce, GCM_NONCE_SZ); + } + #endif /* WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM */ #ifdef WOLFSSL_CHECK_MEM_ZERO if ((ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) && (out != input) && (ret == 0)) { @@ -17875,6 +18289,88 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, break; #endif + #ifdef WOLFSSL_SM4_CBC + case wolfssl_sm4_cbc: + #ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + if (ret != 0) + break; + #endif + ret = wc_Sm4CbcDecrypt(ssl->decrypt.sm4, plain, input, sz); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.aes->asyncDev); + } + #endif + break; + #endif + + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + case wolfssl_sm4_gcm: + case wolfssl_sm4_ccm: /* GCM AEAD macros use same size as CCM */ + { + SM4_AUTH_DECRYPT_FUNC sm4_auth_fn; + + #ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.sm4->asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + if (ret != 0) + break; + #endif + + #if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_SM4_CCM) + sm4_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) + ? SM4_GCM_DECRYPT_FUNC : SM4_CCM_DECRYPT_FUNC; + #elif defined(WOLFSSL_SM4_GCM) + sm4_auth_fn = SM4_GCM_DECRYPT_FUNC; + #else + sm4_auth_fn = SM4_CCM_DECRYPT_FUNC; + #endif + + XMEMSET(ssl->decrypt.additional, 0, AEAD_AUTH_DATA_SZ); + + /* sequence number field is 64-bits */ + WriteSEQ(ssl, PEER_ORDER, ssl->decrypt.additional); + + ssl->decrypt.additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; + ssl->decrypt.additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; + ssl->decrypt.additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; + + c16toa(sz - GCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->decrypt.additional + AEAD_LEN_OFFSET); + + #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + if (ssl->options.dtls && IsDtlsMsgSCRKeys(ssl)) + XMEMCPY(ssl->decrypt.nonce, + ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, + GCM_IMP_IV_SZ); + else + #endif + XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, + GCM_IMP_IV_SZ); + XMEMCPY(ssl->decrypt.nonce + GCM_IMP_IV_SZ, input, GCM_EXP_IV_SZ); + if ((ret = sm4_auth_fn(ssl->decrypt.sm4, + plain + GCM_EXP_IV_SZ, + input + GCM_EXP_IV_SZ, + sz - GCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + ssl->decrypt.nonce, GCM_NONCE_SZ, + input + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size, + ssl->decrypt.additional, AEAD_AUTH_DATA_SZ)) < 0) { + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, + &ssl->decrypt.sm4->asyncDev); + } + #endif + } + } + break; + #endif /* WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM */ + #ifdef HAVE_NULL_CIPHER case wolfssl_cipher_null: if (input != plain) { @@ -17939,10 +18435,10 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) /* make sure auth iv and auth are allocated */ if (ssl->decrypt.additional == NULL) ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, - ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + ssl->heap, DYNAMIC_TYPE_CIPHER); if (ssl->decrypt.nonce == NULL) { ssl->decrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ, - ssl->heap, DYNAMIC_TYPE_AES_BUFFER); + ssl->heap, DYNAMIC_TYPE_CIPHER); #ifdef WOLFSSL_CHECK_MEM_ZERO if (ssl->decrypt.nonce != NULL) { wc_MemZero_Add("DecryptTls nonce", ssl->decrypt.nonce, @@ -17957,6 +18453,32 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) } #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + /* make sure SM4 GCM/CCM memory is allocated */ + /* free for these happens in FreeCiphers */ + if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || + ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) { + /* make sure auth iv and auth are allocated */ + if (ssl->decrypt.additional == NULL) + ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ, + ssl->heap, DYNAMIC_TYPE_CIPHER); + if (ssl->decrypt.nonce == NULL) { + ssl->decrypt.nonce = (byte*)XMALLOC(GCM_NONCE_SZ, + ssl->heap, DYNAMIC_TYPE_CIPHER); + #ifdef WOLFSSL_CHECK_MEM_ZERO + if (ssl->decrypt.nonce != NULL) { + wc_MemZero_Add("DecryptTls nonce", ssl->decrypt.nonce, + GCM_NONCE_SZ); + } + #endif + } + if (ssl->decrypt.additional == NULL || + ssl->decrypt.nonce == NULL) { + return MEMORY_E; + } + } + #endif /* WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM */ + /* Advance state and proceed */ ssl->decrypt.state = CIPHER_STATE_DO; } @@ -18016,6 +18538,19 @@ static int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) } } #endif /* BUILD_AESGCM || HAVE_AESCCM */ + #if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + /* make sure SM4 GCM/CCM nonce is cleared */ + if (ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_ccm || + ssl->specs.bulk_cipher_algorithm == wolfssl_sm4_gcm) { + if (ssl->decrypt.nonce) + ForceZero(ssl->decrypt.nonce, GCM_NONCE_SZ); + + if (ret < 0) { + ret = VERIFY_MAC_ERROR; + WOLFSSL_ERROR_VERBOSE(ret); + } + } + #endif /* BUILD_AESGCM || HAVE_AESCCM */ break; } @@ -20727,6 +21262,12 @@ int BuildCertHashes(const WOLFSSL* ssl, Hashes* hashes) if (ret != 0) return ret; #endif + #ifdef WOLFSSL_SM3 + ret = wc_Sm3GetHash(&ssl->hsHashes->hashSm3, + hashes->sm3); + if (ret != 0) + return ret; + #endif } } else { @@ -21947,7 +22488,26 @@ int SendCertificateRequest(WOLFSSL* ssl) ssl->options.cipherSuite0 == CHACHA_BYTE) && ssl->specs.sig_algo == ecc_dsa_sa_algo) { output[i++] = ecdsa_sign; - } else + } + else +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \ + (defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_GCM) || \ + defined(WOLFSSL_SM4_CCM)) + if (ssl->options.cipherSuite0 == SM_BYTE && (0 + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + || ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + || ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + || ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + #endif + )) { + output[i++] = ecdsa_sign; + } + else +#endif #endif /* HAVE_ECC */ { output[i++] = rsa_sign; @@ -22487,6 +23047,18 @@ static int CheckTLS13AEADSendLimit(WOLFSSL* ssl) #endif limit = AEAD_AES_LIMIT; /* Limit is 2^24.5 */ break; +#endif +#ifdef WOLFSSL_SM4_GCM + case wolfssl_sm4_gcm: + /* Limit is 2^22 - 1 */ + limit = AEAD_SM4_GCM_LIMIT; + break; +#endif +#ifdef WOLFSSL_SM4_CCM + case wolfssl_sm4_ccm: + /* Limit is 2^10 - 1 */ + limit = AEAD_SM4_CCM_LIMIT; + break; #endif case wolfssl_cipher_null: /* No encryption being done */ @@ -23761,6 +24333,14 @@ static const CipherSuiteInfo cipher_names[] = SUITE_ALIAS("TLS13-AES128-CCM8-SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256,TLSv1_3_MINOR, SSLv3_MAJOR) #endif +#ifdef BUILD_TLS_SM4_GCM_SM3 + SUITE_INFO("TLS13-SM4-GCM-SM3","TLS_SM4_GCM_SM3",CIPHER_BYTE,TLS_SM4_GCM_SM3, TLSv1_3_MINOR, SSLv3_MAJOR), +#endif + +#ifdef BUILD_TLS_SM4_CCM_SM3 + SUITE_INFO("TLS13-SM4-CCM-SM3","TLS_SM4_GCM_SM3",CIPHER_BYTE,TLS_SM4_CCM_SM3, TLSv1_3_MINOR, SSLv3_MAJOR), +#endif + #ifdef BUILD_TLS_SHA256_SHA256 SUITE_INFO("TLS13-SHA256-SHA256","TLS_SHA256_SHA256",ECC_BYTE,TLS_SHA256_SHA256,TLSv1_3_MINOR, SSLv3_MAJOR), #endif @@ -24137,6 +24717,18 @@ static const CipherSuiteInfo cipher_names[] = SUITE_INFO("DHE-RSA-CHACHA20-POLY1305-OLD","TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256",CHACHA_BYTE,TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256, TLSv1_2_MINOR, SSLv3_MAJOR), #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + SUITE_INFO("ECDHE-ECDSA-SM4-CBC-SM3","TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3",SM_BYTE,TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3, TLSv1_2_MINOR, SSLv3_MAJOR), +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + SUITE_INFO("ECDHE-ECDSA-SM4-GCM-SM3","TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3",SM_BYTE,TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3, TLSv1_2_MINOR, SSLv3_MAJOR), +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + SUITE_INFO("ECDHE-ECDSA-SM4-CCM-SM3","TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3",SM_BYTE,TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3, TLSv1_2_MINOR, SSLv3_MAJOR), +#endif + #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA SUITE_INFO("ADH-AES128-SHA","TLS_DH_anon_WITH_AES_128_CBC_SHA",CIPHER_BYTE,TLS_DH_anon_WITH_AES_128_CBC_SHA, TLSv1_2_MINOR, SSLv3_MAJOR), #endif @@ -24386,6 +24978,23 @@ const char* GetCipherEncStr(char n[][MAX_SEGMENT_SZ]) { else if ((XSTRCMP(n[0],"CAMELLIA128") == 0) || (XSTRCMP(n[2],"CAMELLIA128") == 0)) encStr = "CAMELLIA(128)"; +#ifdef WOLFSSL_SM4_GCM + else if ((XSTRCMP(n[0],"SM4") == 0 && XSTRCMP(n[1],"GCM") == 0) || + (XSTRCMP(n[1],"SM4") == 0 && XSTRCMP(n[2],"GCM") == 0) || + (XSTRCMP(n[2],"SM4") == 0 && XSTRCMP(n[3],"GCM") == 0)) + encStr = "SM4-GCM"; +#endif +#ifdef WOLFSSL_SM4_CCM + else if ((XSTRCMP(n[0],"SM4") == 0 && XSTRCMP(n[1],"CCM") == 0) || + (XSTRCMP(n[1],"SM4") == 0 && XSTRCMP(n[2],"CCM") == 0) || + (XSTRCMP(n[2],"SM4") == 0 && XSTRCMP(n[3],"CCM") == 0)) + encStr = "SM4-CCM"; +#endif +#ifdef WOLFSSL_SM4_CBC + else if ((XSTRCMP(n[0],"SM4") == 0) || + (XSTRCMP(n[2],"SM4") == 0)) + encStr = "SM4"; +#endif else if ((XSTRCMP(n[0],"RC4") == 0) || (XSTRCMP(n[1],"RC4") == 0) || (XSTRCMP(n[2],"RC4") == 0)) encStr = "RC4"; @@ -24442,6 +25051,13 @@ const char* GetCipherMacStr(char n[][MAX_SEGMENT_SZ]) { (XSTRCMP(n[2],"SHA384") == 0) || (XSTRCMP(n[1],"SHA384") == 0)) macStr = "SHA384"; +#ifdef WOLFSSL_SM3 + else if ((XSTRCMP(n[4],"SM3") == 0) || + (XSTRCMP(n[3],"SM3") == 0) || + (XSTRCMP(n[2],"SM3") == 0) || + (XSTRCMP(n[1],"SM3") == 0)) + macStr = "SM3"; +#endif else if ((XSTRCMP(n[4],"SHA") == 0) || (XSTRCMP(n[3],"SHA") == 0) || (XSTRCMP(n[2],"SHA") == 0) || (XSTRCMP(n[1],"SHA") == 0) || (XSTRCMP(n[1],"MD5") == 0)) @@ -24581,11 +25197,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) { int ret = 0; int idx = 0; - word16 haveRSAsig = 0; - word16 haveECDSAsig = 0; - word16 haveFalconSig = 0; - word16 haveDilithiumSig = 0; - word16 haveAnon = 0; + int haveSig = 0; word16 haveRSA = 0; #ifdef OPENSSL_EXTRA word16 haveDH = 0; @@ -24599,8 +25211,6 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) const int suiteSz = GetCipherNamesSize(); const char* next = list; - (void)haveRSA; - if (suites == NULL || list == NULL) { WOLFSSL_MSG("SetCipherList parameter error"); return 0; @@ -24693,11 +25303,11 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) if (XSTRCMP(name, "DEFAULT") == 0 || XSTRCMP(name, "ALL") == 0) { if (XSTRCMP(name, "ALL") == 0) - haveAnon = 1; + haveSig |= SIG_ANON; else - haveAnon = 0; + haveSig &= ~SIG_ANON; #ifdef HAVE_ANON - ctx->haveAnon = haveAnon; + ctx->haveAnon = (haveSig & SIG_ANON) == SIG_ANON; #endif haveRSA = 1; haveDH = 1; @@ -24707,7 +25317,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) * static ECC suites here * haveStaticECC = 1; */ haveStaticRSA = 1; - haveRSAsig = 1; + haveSig |= SIG_RSA; havePSK = 1; haveNull = 0; @@ -24720,7 +25330,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) * ciphersuites. */ if (XSTRCMP(name, "HIGH") == 0 && allowing) { /* Disable static, anonymous, and null ciphers */ - haveAnon = 0; + haveSig &= ~SIG_ANON; #ifdef HAVE_ANON ctx->haveAnon = 0; #endif @@ -24729,7 +25339,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) haveECC = 1; haveStaticECC = 0; haveStaticRSA = 0; - haveRSAsig = 1; + haveSig |= SIG_RSA; havePSK = 1; haveNull = 0; @@ -24739,7 +25349,10 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) } if (XSTRCMP(name, "aNULL") == 0) { - haveAnon = allowing; + if (allowing) + haveSig |= SIG_ANON; + else + haveSig &= ~SIG_ANON; #ifdef HAVE_ANON ctx->haveAnon = allowing; #endif @@ -24747,8 +25360,8 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) /* Allow RSA by default. */ if (!haveECC) haveRSA = 1; - if (!haveECDSAsig) - haveRSAsig = 1; + if ((haveSig & SIG_ECDSA) == 0) + haveSig |= SIG_RSA; callInitSuites = 1; ret = 1; } @@ -24761,8 +25374,8 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) /* Allow RSA by default. */ if (!haveECC) haveRSA = 1; - if (!haveECDSAsig) - haveRSAsig = 1; + if ((haveSig & SIG_ECDSA) == 0) + haveSig |= SIG_RSA; callInitSuites = 1; ret = 1; } @@ -24773,7 +25386,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) haveStaticECC = allowing; if (allowing) { haveECC = 1; - haveECDSAsig = 1; + haveSig |= SIG_ECDSA; callInitSuites = 1; ret = 1; } @@ -24783,7 +25396,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) if (XSTRCMP(name, "ECDHE") == 0) { if (allowing) { haveECC = 1; - haveECDSAsig = 1; + haveSig |= SIG_ECDSA; callInitSuites = 1; ret = 1; } @@ -24794,7 +25407,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) haveStaticRSA = allowing; if (allowing) { haveRSA = 1; - haveRSAsig = 1; + haveSig |= SIG_RSA; callInitSuites = 1; ret = 1; } @@ -24803,13 +25416,13 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) if (XSTRCMP(name, "PSK") == 0) { havePSK = allowing; - haveRSAsig = 1; + haveSig |= SIG_RSA; if (allowing) { /* Allow RSA by default. */ if (!haveECC) haveRSA = 1; - if (!haveECDSAsig) - haveRSAsig = 1; + if ((haveSig & SIG_ECDSA) == 0) + haveSig |= SIG_RSA; callInitSuites = 1; ret = 1; } @@ -24821,7 +25434,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) if (allowing) { /* Allow RSA by default */ haveRSA = 1; - haveRSAsig = 1; + haveSig |= SIG_RSA; callInitSuites = 1; ret = 1; } @@ -24879,46 +25492,81 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) suites->suites[idx++] = cipher_names[i].cipherSuite; /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA * suites don't necessarily have RSA in the name. */ - #ifdef WOLFSSL_TLS13 + #ifdef WOLFSSL_TLS13 if (cipher_names[i].cipherSuite0 == TLS13_BYTE || (cipher_names[i].cipherSuite0 == ECC_BYTE && (cipher_names[i].cipherSuite == TLS_SHA256_SHA256 || cipher_names[i].cipherSuite == TLS_SHA384_SHA384))) { #ifndef NO_RSA - haveRSAsig = 1; + haveSig |= SIG_RSA; #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ defined(HAVE_ED448) - haveECDSAsig = 1; + haveSig |= SIG_ECDSA; #endif #if defined(HAVE_PQC) #ifdef HAVE_FALCON - haveFalconSig = 1; + haveSig |= SIG_FALCON; #endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM - haveDilithiumSig = 1; + haveSig |= SIG_DILITHIUM; #endif /* HAVE_DILITHIUM */ #endif /* HAVE_PQC */ } else + #ifdef BUILD_TLS_SM4_GCM_SM3 + if ((cipher_names[i].cipherSuite0 == CIPHER_BYTE) && + (cipher_names[i].cipherSuite == TLS_SM4_GCM_SM3)) { + haveSig |= SIG_SM2; + } + else + #endif + #ifdef BUILD_TLS_SM4_CCM_SM3 + if ((cipher_names[i].cipherSuite0 == CIPHER_BYTE) && + (cipher_names[i].cipherSuite == TLS_SM4_CCM_SM3)) { + haveSig |= SIG_SM2; + } + else + #endif + #endif /* WOLFSSL_TLS13 */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \ + (defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_GCM) || \ + defined(WOLFSSL_SM4_CCM)) + if ((cipher_names[i].cipherSuite0 == SM_BYTE) && (0 + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + || (cipher_names[i].cipherSuite == + TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3) + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + || (cipher_names[i].cipherSuite == + TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3) + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + || (cipher_names[i].cipherSuite == + TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3) + #endif + )) { + haveSig |= SIG_SM2; + } + else #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ defined(HAVE_ED448) - if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA")) - haveECDSAsig = 1; + if (((haveSig && SIG_ECDSA) == 0) && XSTRSTR(name, "ECDSA")) + haveSig |= SIG_ECDSA; else #endif #ifdef HAVE_ANON if (XSTRSTR(name, "ADH")) - haveAnon = 1; + haveSig |= SIG_ANON; else #endif - if (haveRSAsig == 0 + if (((haveSig & SIG_RSA) == 0) #ifndef NO_PSK && (XSTRSTR(name, "PSK") == NULL) #endif ) { - haveRSAsig = 1; + haveSig |= SIG_RSA; } ret = 1; /* found at least one */ @@ -24940,12 +25588,15 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) suites->setSuites = 0; /* Force InitSuites */ suites->hashSigAlgoSz = 0; /* Force InitSuitesHashSigAlgo call * inside InitSuites */ - InitSuites(suites, ctx->method->version, keySz, haveRSA, - havePSK, haveDH, haveECDSAsig, - haveECC, haveStaticRSA, - haveStaticECC, haveFalconSig, - haveDilithiumSig, haveAnon, - haveNull, ctx->method->side); + InitSuites(suites, ctx->method->version, keySz, (word16)haveRSA, + (word16)havePSK, (word16)haveDH, + (word16)((haveSig & SIG_ECDSA) != 0), + (word16)haveECC, (word16)haveStaticRSA, + (word16)haveStaticECC, + (word16)((haveSig & SIG_FALCON) != 0), + (word16)((haveSig & SIG_DILITHIUM) != 0), + (word16)((haveSig & SIG_ANON) != 0), + (word16)haveNull, ctx->method->side); /* Restore user ciphers ahead of defaults */ XMEMMOVE(suites->suites + idx, suites->suites, min(suites->suiteSz, WOLFSSL_MAX_SUITE_SZ-idx)); @@ -24955,9 +25606,8 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) #endif { suites->suiteSz = (word16)idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, - haveFalconSig, haveDilithiumSig, haveAnon, - 1, keySz); + InitSuitesHashSigAlgo_ex2(suites->hashSigAlgo, haveSig, 1, keySz, + &suites->hashSigAlgoSz); } suites->setSuites = 1; } @@ -25035,8 +25685,10 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, * suites don't necessarily have RSA in the name. */ #ifdef WOLFSSL_TLS13 if (firstByte == TLS13_BYTE || (firstByte == ECC_BYTE && - (secondByte == TLS_SHA256_SHA256 || - secondByte == TLS_SHA384_SHA384))) { + (secondByte == TLS_SHA256_SHA256 || + secondByte == TLS_SHA384_SHA384)) || + (firstByte == CIPHER_BYTE && (secondByte == TLS_SM4_GCM_SM3 || + secondByte == TLS_SM4_CCM_SM3))) { #ifndef NO_RSA haveRSAsig = 1; #endif @@ -25077,13 +25729,21 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, if (ret) { int keySz = 0; + int haveSig = 0; #ifndef NO_CERTS keySz = ctx->privateKeySz; #endif suites->suiteSz = (word16)idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, - haveFalconSig, haveDilithiumSig, haveAnon, 1, - keySz); + haveSig |= haveECDSAsig ? SIG_ECDSA : 0; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + haveSig |= haveECDSAsig ? SIG_SM2 : 0; + #endif + haveSig |= haveRSAsig ? SIG_RSA : 0; + haveSig |= haveFalconSig ? SIG_FALCON : 0; + haveSig |= haveDilithiumSig ? SIG_DILITHIUM : 0; + haveSig |= haveAnon ? SIG_ANON : 0; + InitSuitesHashSigAlgo_ex2(suites->hashSigAlgo, haveSig, 1, keySz, + &suites->hashSigAlgoSz); suites->setSuites = 1; } @@ -25112,6 +25772,9 @@ struct mac_algs { #ifdef WOLFSSL_SHA224 { sha224_mac, "SHA224" }, #endif +#ifdef WOLFSSL_SM3 + { sm3_mac, "SM3" }, +#endif #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ defined(WOLFSSL_ALLOW_TLS_SHA1)) { sha_mac, "SHA1" }, @@ -25159,6 +25822,9 @@ struct sig_algs { #ifndef NO_DSA { dsa_sa_algo, "DSA" }, #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + { sm2_sa_algo, "SM2" }, +#endif }; #define SIG_NAMES_SZ (int)(sizeof(sig_names)/sizeof(*sig_names)) @@ -25324,9 +25990,15 @@ static int CmpEccStrength(int hashAlgo, int curveSz) static byte MinHashAlgo(WOLFSSL* ssl) { #ifdef WOLFSSL_TLS13 +#ifndef NO_SHA256 if (IsAtLeastTLSv1_3(ssl->version)) { return sha256_mac; } +#elif defined(WOLFSSL_SM3) + if (IsAtLeastTLSv1_3(ssl->version)) { + return sm3_mac; + } +#endif #endif #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_ALLOW_TLS_SHA1) if (IsAtLeastTLSv1_2(ssl)) { @@ -25427,6 +26099,23 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) #if defined(HAVE_ECC) && (defined(WOLFSSL_TLS13) || \ defined(WOLFSSL_ECDSA_MATCH_HASH)) + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigAlgo == sm2_sa_algo && hashAlgo == sm3_mac + #ifndef WOLFSSL_ECDSA_MATCH_HASH + && IsAtLeastTLSv1_3(ssl->version) + #endif + ) { + /* Must be exact match. */ + if (CmpEccStrength(hashAlgo, ssl->buffers.keySz) != 0) + continue; + /* Matched SM2-SM3 - set chosen and finished. */ + ssl->options.sigAlgo = sigAlgo; + ssl->options.hashAlgo = hashAlgo; + ret = 0; + break; + } + else + #endif if (sigAlgo == ecc_dsa_sa_algo #ifndef WOLFSSL_ECDSA_MATCH_HASH && IsAtLeastTLSv1_3(ssl->version) @@ -25490,6 +26179,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) #endif #ifdef WOLFSSL_SHA512 case sha512_mac: + #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: #endif #ifdef WOLFSSL_STRONGEST_HASH_SIG /* Is hash algorithm weaker than chosen/min? */ @@ -25517,6 +26209,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) #endif #ifdef WOLFSSL_SHA512 && (hashAlgo != sha512_mac) + #endif + #ifdef WOLFSSL_SM3 + && (hashAlgo != sm3_mac) #endif ) { @@ -25968,7 +26663,11 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); #endif /* !NO_RSA */ - if (ssl->buffers.keyType == ecc_dsa_sa_algo || ssl->buffers.keyType == 0) { + if (ssl->buffers.keyType == ecc_dsa_sa_algo || ssl->buffers.keyType == 0 + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + || ssl->buffers.keyType == sm2_sa_algo + #endif + ) { ssl->hsType = DYNAMIC_TYPE_ECC; ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); if (ret != 0) { @@ -26307,6 +27006,43 @@ exit_dpk: ((defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) && \ (defined(HAVE_ED25519) || defined(HAVE_ED448) || !defined(NO_RSA)))) || \ (!defined(NO_DH) && (!defined(NO_RSA) || defined(HAVE_ANON)))) +/* Returns whether the signature algorithm requires caching of messages. + * + * @param [in] sigAlgo Signature algorithm. + * @return 1 when caching required. + * @return 0 when cacheing not required. + */ +static int SigAlgoCachesMsgs(int sigAlgo) +{ + int ret; + + (void)sigAlgo; + +#ifdef HAVE_ED25519 + if (sigAlgo == ed25519_sa_algo) { + ret = 1; + } + else +#endif +#ifdef HAVE_ED448 + if (sigAlgo == ed448_sa_algo) { + ret = 1; + } + else +#endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigAlgo == sm2_sa_algo) { + ret = 1; + } + else +#endif + { + ret = 0; + } + + return ret; +} + static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, const byte* data, int sz, byte sigAlgo) { @@ -26335,8 +27071,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, /* message */ XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN * 2], data, sz); } - if (ret == 0 && sigAlgo != ed25519_sa_algo && sigAlgo != ed448_sa_algo) { - ssl->buffers.digest.length = (unsigned int)digest_sz; + if (ret == 0 && !SigAlgoCachesMsgs(sigAlgo)) { + ssl->buffers.digest.length = (unsigned int)digest_sz; /* buffer for hash */ if (!ssl->buffers.digest.buffer) { @@ -26353,7 +27089,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, ret = MEMORY_E; } } - if (ret == 0 && sigAlgo != ed25519_sa_algo && sigAlgo != ed448_sa_algo) { + if (ret == 0 && !SigAlgoCachesMsgs(sigAlgo)) { /* Perform hash. Only wc_Hash supports MD5_SHA1. */ ret = wc_Hash(hashType, ssl->buffers.sig.buffer, ssl->buffers.sig.length, @@ -27531,6 +28267,9 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP256R1: return ECC_BRAINPOOLP256R1_OID; #endif /* HAVE_ECC_BRAINPOOL */ + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: return ECC_SM2P256V1_OID; + #endif /* WOLFSSL_SM2 */ #endif #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 case WOLFSSL_ECC_X448: return ECC_X448_OID; @@ -28355,6 +29094,13 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } else #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigAlgo == sm2_sa_algo && + args->sigAlgo == ecc_dsa_sa_algo) { + args->sigAlgo = sigAlgo; + } + else + #endif #ifdef HAVE_ED25519 if (sigAlgo == ed25519_sa_algo && args->sigAlgo == ecc_dsa_sa_algo) { @@ -28425,6 +29171,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } #endif /* !NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + #endif case ecc_dsa_sa_algo: { if (!ssl->peerEccDsaKeyPresent) { @@ -28546,6 +29295,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } #endif /* !NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + #endif case ecc_dsa_sa_algo: { ret = NOT_COMPILED_IN; @@ -28560,17 +29312,36 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } #endif /* HAVE_PK_CALLBACKS */ if (ret == NOT_COMPILED_IN) { - ret = EccVerify(ssl, - args->verifySig, args->verifySigSz, - ssl->buffers.digest.buffer, - ssl->buffers.digest.length, - ssl->peerEccDsaKey, - #ifdef HAVE_PK_CALLBACKS - &ssl->buffers.peerEccDsaKey - #else - NULL - #endif - ); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo == sm2_sa_algo) { + ret = Sm2wSm3Verify(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + args->verifySig, args->verifySigSz, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + } + else + #endif + { + ret = EccVerify(ssl, + args->verifySig, args->verifySigSz, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + } } #ifdef WOLFSSL_ASYNC_CRYPT @@ -28782,6 +29553,11 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, /* Nothing to do in this algo */ break; #endif /* HAVE_ECC */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + /* Nothing to do in this algo */ + break; + #endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */ #if defined(HAVE_ED25519) case ed25519_sa_algo: /* Nothing to do in this algo */ @@ -30322,7 +31098,15 @@ int SendCertificateVerify(WOLFSSL* ssl) args->sigAlgo = rsa_sa_algo; } else if (ssl->hsType == DYNAMIC_TYPE_ECC) - args->sigAlgo = ecc_dsa_sa_algo; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType == sm2_sa_algo) { + args->sigAlgo = sm2_sa_algo; + } + else + #endif + { + args->sigAlgo = ecc_dsa_sa_algo; + } else if (ssl->hsType == DYNAMIC_TYPE_ED25519) args->sigAlgo = ed25519_sa_algo; else if (ssl->hsType == DYNAMIC_TYPE_ED448) @@ -30396,17 +31180,36 @@ int SendCertificateVerify(WOLFSSL* ssl) if (ssl->hsType == DYNAMIC_TYPE_ECC) { ecc_key* key = (ecc_key*)ssl->hsKey; - ret = EccSign(ssl, - ssl->buffers.digest.buffer, ssl->buffers.digest.length, - ssl->buffers.sig.buffer, - (word32*)&ssl->buffers.sig.length, - key, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key - #else - NULL + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo == sm2_sa_algo) { + ret = Sm2wSm3Sign(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + ssl->hsHashes->messages, ssl->hsHashes->length, + ssl->buffers.sig.buffer, + (word32*)&ssl->buffers.sig.length, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } + else #endif - ); + { + ret = EccSign(ssl, + ssl->buffers.digest.buffer, ssl->buffers.digest.length, + ssl->buffers.sig.buffer, + (word32*)&ssl->buffers.sig.length, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } } #endif /* HAVE_ECC */ #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) @@ -30480,16 +31283,34 @@ int SendCertificateVerify(WOLFSSL* ssl) { ecc_key* key = (ecc_key*)ssl->hsKey; - ret = EccVerify(ssl, - ssl->buffers.sig.buffer, ssl->buffers.sig.length, - ssl->buffers.digest.buffer, ssl->buffers.digest.length, - key, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key - #else - NULL - #endif - ); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType == sm2_sa_algo) { + ret = Sm3wSm2Verify(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } + else + #endif + { + ret = EccVerify(ssl, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } if (ret != 0) { WOLFSSL_MSG("Failed to verify ECC signature"); goto exit_scv; @@ -30842,6 +31663,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case ECC_BRAINPOOLP256R1_OID: return WOLFSSL_ECC_BRAINPOOLP256R1; #endif /* HAVE_ECC_BRAINPOOL */ + #ifdef WOLFSSL_SM2 + case ECC_SM2P256V1_OID: + return WOLFSSL_ECC_SM2P256V1; + #endif /* WOLFSSL_SM2 */ #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -31923,6 +32748,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif /* !NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + #endif case ecc_dsa_sa_algo: { word16 keySz; @@ -32115,6 +32943,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; #endif #endif /* !NO_RSA */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + #endif case ecc_dsa_sa_algo: { break; @@ -32394,6 +33225,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif /* !NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + { + ecc_key* key = (ecc_key*)ssl->hsKey; + + ret = Sm2wSm3Sign(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + args->output + LENGTH_SZ + args->idx, + &args->sigSz, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + break; + } + #endif case ecc_dsa_sa_algo: { ecc_key* key = (ecc_key*)ssl->hsKey; @@ -32575,23 +33427,46 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + #endif /* WOLFSSL_SM2 */ case ecc_dsa_sa_algo: #ifdef WOLFSSL_CHECK_SIG_FAULTS { ecc_key* key = (ecc_key*)ssl->hsKey; - ret = EccVerify(ssl, - args->output + LENGTH_SZ + args->idx, - args->sigSz, - ssl->buffers.digest.buffer, - ssl->buffers.digest.length, - key, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key - #else - NULL - #endif - ); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->options.sigAlgo == sm2_sa_algo) { + ret = Sm2wSm3Verify(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + args->output + LENGTH_SZ + args->idx, + args->sigSz, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } + else + #endif /* WOLFSSL_SM2 */ + { + ret = EccVerify(ssl, + args->output + LENGTH_SZ + args->idx, + args->sigSz, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } if (ret != 0) { WOLFSSL_MSG( "Failed to verify ECC signature"); @@ -32888,8 +33763,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.side == WOLFSSL_SERVER_END) { #ifdef HAVE_SUPPORTED_CURVES byte searched = 0; - int ret = TLSX_KeyShare_Choose(ssl, extensions, &cs->clientKSE, - &searched); + int ret = TLSX_KeyShare_Choose(ssl, extensions, first, second, + &cs->clientKSE, &searched); if (ret == MEMORY_E) { WOLFSSL_MSG("TLSX_KeyShare_Choose() failed in " @@ -32906,8 +33781,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return 0; /* not found */ #endif /* HAVE_SUPPORTED_CURVES */ } - else if (first == TLS13_BYTE || (first == ECC_BYTE && - (second == TLS_SHA256_SHA256 || second == TLS_SHA384_SHA384))) { + else if ((first == TLS13_BYTE) || ((first == ECC_BYTE) && + ((second == TLS_SHA256_SHA256) || + (second == TLS_SHA384_SHA384))) || + ((first == CIPHER_BYTE) && ((second == TLS_SM4_GCM_SM3) || + (second == TLS_SM4_CCM_SM3)))) { /* Can't negotiate TLS 1.3 cipher suites with lower protocol * version. */ return 0; @@ -34081,8 +34959,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, args->sigAlgo = rsa_sa_algo; #endif #ifdef HAVE_ECC - else if (ssl->peerEccDsaKeyPresent) - args->sigAlgo = ecc_dsa_sa_algo; + else if (ssl->peerEccDsaKeyPresent) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) { + args->sigAlgo = sm2_sa_algo; + } + else + #endif + { + args->sigAlgo = ecc_dsa_sa_algo; + } + } #endif #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) else if (ssl->peerEd25519KeyPresent) @@ -34115,6 +35002,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, SetDigest(ssl, sha_mac); #elif !defined(NO_SHA256) SetDigest(ssl, sha256_mac); + #elif defined(WOLFSSL_SM3) + SetDigest(ssl, sm3_mac); #elif defined(WOLFSSL_SHA384) SetDigest(ssl, sha384_mac); #elif defined(WOLFSSL_SHA512) @@ -34124,7 +35013,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif if (IsAtLeastTLSv1_2(ssl)) { - if (args->sigAlgo != ecc_dsa_sa_algo) { + if (args->sigAlgo != ecc_dsa_sa_algo + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + && args->sigAlgo != sm2_sa_algo + #endif + ) { WOLFSSL_MSG("Oops, peer sent ECC key but not in verify"); } @@ -34191,16 +35084,35 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->peerEccDsaKeyPresent) { WOLFSSL_MSG("Doing ECC peer cert verify"); - ret = EccVerify(ssl, - input + args->idx, args->sz, - ssl->buffers.digest.buffer, ssl->buffers.digest.length, - ssl->peerEccDsaKey, - #ifdef HAVE_PK_CALLBACKS - &ssl->buffers.peerEccDsaKey - #else - NULL - #endif - ); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo == sm2_sa_algo) { + ret = Sm2wSm3Verify(ssl, + TLS12_SM2_SIG_ID, TLS12_SM2_SIG_ID_SZ, + input + args->idx, args->sz, + ssl->hsHashes->messages, ssl->hsHashes->prevLen, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + } + else + #endif + { + ret = EccVerify(ssl, + input + args->idx, args->sz, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + } /* SERVER: Data verified with certificate's public key. */ ssl->options.peerAuthGood = ssl->options.havePeerCert && (ret == 0); @@ -35576,6 +36488,75 @@ static int TicketEncDec(byte* key, int keyLen, byte* iv, byte* aad, int aadSz, return ret; } +#elif defined(WOLFSSL_SM4_GCM) +/* Ticket encryption/decryption implementation. + * + * @param [in] key Key for encryption/decryption. + * @param [in] keyLen Length of key in bytes. + * @param [in] iv IV/Nonce for encryption/decryption. + * @param [in] aad Additional authentication data. + * @param [in] aadSz Length of additional authentication data. + * @param [in] in Data to encrypt/decrypt. + * @param [in] inLen Length of encrypted data. + * @param [out] out Resulting data from encrypt/decrypt. + * @param [out] outLen Size of resulting data. + * @param [in] tag Authentication tag for encrypted data. + * @param [in] heap Dynamic memory allocation data hint. + * @param [in] enc 1 when encrypting, 0 when decrypting. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other value when encryption/decryption fails. + */ +static int TicketEncDec(byte* key, int keyLen, byte* iv, byte* aad, int aadSz, + byte* in, int inLen, byte* out, int* outLen, byte* tag, + void* heap, int enc) +{ + int ret; +#ifdef WOLFSSL_SMALL_STACK + wc_Sm4* sm4; +#else + wc_Sm4 sm4[1]; +#endif + + (void)heap; + +#ifdef WOLFSSL_SMALL_STACK + sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, DYNAMIC_TYPE_TMP_BUFFER); + if (sm4 == NULL) + return MEMORY_E; +#endif + + if (enc) { + ret = wc_Sm4Init(sm4, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Sm4GcmSetKey(sm4, key, keyLen); + } + if (ret == 0) { + ret = wc_Sm4GcmEncrypt(sm4, in, out, inLen, iv, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, aadSz); + } + wc_Sm4Free(sm4); + } + else { + ret = wc_Sm4Init(sm4, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Sm4GcmSetKey(sm4, key, keyLen); + } + if (ret == 0) { + ret = wc_Sm4GcmDecrypt(sm4, in, out, inLen, iv, GCM_NONCE_MID_SZ, + tag, SM$_BLOCK_SIZE, aad, aadSz); + } + wc_Sm4Free(sm4); + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(sm4, heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + *outLen = inLen; + + return ret; +} #else #error "No encryption algorithm available for default ticket encryption." #endif @@ -35638,7 +36619,7 @@ static int TicketEncCbCtx_ChooseKey(TicketEncCbCtx* keyCtx, int ticketHint, /* Default Session Ticket encryption/decryption callback. * - * Use ChaCha20-Poly1305 or AES-GCM to encrypt/decrypt the ticket. + * Use ChaCha20-Poly1305, AES-GCM or SM4-GCM to encrypt/decrypt the ticket. * Two keys are used: * - When the first expires for encryption, then use the other. * - Don't encrypt with key if the ticket lifetime will go beyond expirary. diff --git a/src/keys.c b/src/keys.c index 825127936..e240faa60 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1354,13 +1354,114 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite, } } + if (cipherSuite0 == SM_BYTE) { + + switch (cipherSuite) { +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 : + specs->bulk_cipher_algorithm = wolfssl_sm4_cbc; + specs->cipher_type = block; + specs->mac_algorithm = sm3_mac; + specs->kea = ecc_diffie_hellman_kea; + specs->sig_algo = sm2_sa_algo; + specs->hash_size = WC_SM3_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = SM4_KEY_SIZE; + specs->iv_size = SM4_IV_SIZE; + specs->block_size = SM4_BLOCK_SIZE; + + break; +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 : + specs->bulk_cipher_algorithm = wolfssl_sm4_gcm; + specs->cipher_type = aead; + specs->mac_algorithm = sm3_mac; + specs->kea = ecc_diffie_hellman_kea; + specs->sig_algo = sm2_sa_algo; + specs->hash_size = WC_SM3_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = SM4_KEY_SIZE; + specs->block_size = SM4_BLOCK_SIZE; + specs->iv_size = GCM_IMP_IV_SZ; + specs->aead_mac_size = SM4_GCM_AUTH_SZ; + + break; +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + case TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 : + specs->bulk_cipher_algorithm = wolfssl_sm4_ccm; + specs->cipher_type = aead; + specs->mac_algorithm = sm3_mac; + specs->kea = ecc_diffie_hellman_kea; + specs->sig_algo = sm2_sa_algo; + specs->hash_size = WC_SM3_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = SM4_KEY_SIZE; + specs->block_size = SM4_BLOCK_SIZE; + specs->iv_size = GCM_IMP_IV_SZ; + specs->aead_mac_size = SM4_CCM_AUTH_SZ; + + break; +#endif + + default: + break; + } + } if (cipherSuite0 != ECC_BYTE && cipherSuite0 != ECDHE_PSK_BYTE && cipherSuite0 != CHACHA_BYTE && +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \ + (defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_GCM) || \ + defined(WOLFSSL_SM4_CCM)) + cipherSuite0 != SM_BYTE && +#endif cipherSuite0 != TLS13_BYTE) { /* normal suites */ switch (cipherSuite) { +#ifdef BUILD_TLS_SM4_GCM_SM3 + case TLS_SM4_GCM_SM3 : + specs->bulk_cipher_algorithm = wolfssl_sm4_gcm; + specs->cipher_type = aead; + specs->mac_algorithm = sm3_mac; + specs->kea = 0; + specs->sig_algo = 0; + specs->hash_size = WC_SM3_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = SM4_KEY_SIZE; + specs->block_size = SM4_BLOCK_SIZE; + specs->iv_size = SM4_GCM_NONCE_SZ; + specs->aead_mac_size = SM4_GCM_AUTH_SZ; + + break; +#endif + +#ifdef BUILD_TLS_SM4_CCM_SM3 + case TLS_SM4_CCM_SM3 : + specs->bulk_cipher_algorithm = wolfssl_sm4_ccm; + specs->cipher_type = aead; + specs->mac_algorithm = sm3_mac; + specs->kea = 0; + specs->sig_algo = 0; + specs->hash_size = WC_SM3_DIGEST_SIZE; + specs->pad_size = PAD_SHA; + specs->static_ecdh = 0; + specs->key_size = SM4_KEY_SIZE; + specs->block_size = SM4_BLOCK_SIZE; + specs->iv_size = SM4_CCM_NONCE_SZ; + specs->aead_mac_size = SM4_CCM_AUTH_SZ; + + break; +#endif + #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA case SSL_RSA_WITH_RC4_128_SHA : specs->bulk_cipher_algorithm = wolfssl_rc4; @@ -2780,6 +2881,284 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } #endif /* HAVE_CAMELLIA */ +#ifdef WOLFSSL_SM4_CBC + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 16) /* AES_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for SM4_CBC + #endif + + if (specs->bulk_cipher_algorithm == wolfssl_sm4_cbc) { + int sm4Ret = 0; + + if (enc) { + if (enc->sm4 == NULL) { + enc->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (enc->sm4 == NULL) + return MEMORY_E; + } + else { + wc_Sm4Free(enc->sm4); + } + + XMEMSET(enc->sm4, 0, sizeof(wc_Sm4)); + } + if (dec) { + if (dec->sm4 == NULL) { + dec->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (dec->sm4 == NULL) + return MEMORY_E; + } + else { + wc_Sm4Free(dec->sm4); + } + + XMEMSET(dec->sm4, 0, sizeof(wc_Sm4)); + } + if (enc) { + if (wc_Sm4Init(enc->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + if (dec) { + if (wc_Sm4Init(dec->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + + if (side == WOLFSSL_CLIENT_END) { + if (enc) { + sm4Ret = wc_Sm4SetKey(enc->sm4, keys->client_write_key, + specs->key_size); + if (sm4Ret != 0) return sm4Ret; + sm4Ret = wc_Sm4SetIV(enc->sm4, keys->client_write_IV); + if (sm4Ret != 0) return sm4Ret; + } + if (dec) { + sm4Ret = wc_Sm4SetKey(dec->sm4, keys->server_write_key, + specs->key_size); + if (sm4Ret != 0) return sm4Ret; + sm4Ret = wc_Sm4SetIV(dec->sm4, keys->server_write_IV); + if (sm4Ret != 0) return sm4Ret; + } + } + else { + if (enc) { + sm4Ret = wc_Sm4SetKey(enc->sm4, keys->server_write_key, + specs->key_size); + if (sm4Ret != 0) return sm4Ret; + sm4Ret = wc_Sm4SetIV(enc->sm4, keys->server_write_IV); + if (sm4Ret != 0) return sm4Ret; + } + if (dec) { + sm4Ret = wc_Sm4SetKey(dec->sm4, keys->client_write_key, + specs->key_size); + if (sm4Ret != 0) return sm4Ret; + sm4Ret = wc_Sm4SetIV(dec->sm4, keys->client_write_IV); + if (sm4Ret != 0) return sm4Ret; + } + } + if (enc) + enc->setup = 1; + if (dec) + dec->setup = 1; + } +#endif /* WOLFSSL_SM4_CBC */ + +#ifdef WOLFSSL_SM4_GCM + /* check that buffer sizes are sufficient */ + #if (AEAD_MAX_IMP_SZ < 4) /* SM4-GCM_IMP_IV_SZ */ + #error AEAD_MAX_IMP_SZ too small for SM4-GCM + #endif + #if (AEAD_MAX_EXP_SZ < 8) /* SM4-GCM_EXP_IV_SZ */ + #error AEAD_MAX_EXP_SZ too small for SM4-GCM + #endif + #if (MAX_WRITE_IV_SZ < 4) /* SM4-GCM_IMP_IV_SZ */ + #error MAX_WRITE_IV_SZ too small for SM4-GCM + #endif + + if (specs->bulk_cipher_algorithm == wolfssl_sm4_gcm) { + int gcmRet; + + if (enc) { + if (enc->sm4 == NULL) { + enc->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (enc->sm4 == NULL) + return MEMORY_E; + } else { + wc_Sm4Free(enc->sm4); + } + + XMEMSET(enc->sm4, 0, sizeof(wc_Sm4)); + } + if (dec) { + if (dec->sm4 == NULL) { + dec->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (dec->sm4 == NULL) + return MEMORY_E; + } else { + wc_Sm4Free(dec->sm4); + } + + XMEMSET(dec->sm4, 0, sizeof(wc_Sm4)); + } + + if (enc) { + if (wc_Sm4Init(enc->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + if (dec) { + if (wc_Sm4Init(dec->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + + if (side == WOLFSSL_CLIENT_END) { + if (enc) { + gcmRet = wc_Sm4GcmSetKey(enc->sm4, keys->client_write_key, + specs->key_size); + if (gcmRet != 0) return gcmRet; + XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + } + if (dec) { + gcmRet = wc_Sm4GcmSetKey(dec->sm4, keys->server_write_key, + specs->key_size); + if (gcmRet != 0) return gcmRet; + XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + } + } + else { + if (enc) { + gcmRet = wc_Sm4GcmSetKey(enc->sm4, keys->server_write_key, + specs->key_size); + if (gcmRet != 0) return gcmRet; + XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + } + if (dec) { + gcmRet = wc_Sm4GcmSetKey(dec->sm4, keys->client_write_key, + specs->key_size); + if (gcmRet != 0) return gcmRet; + XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + } + } + if (enc) + enc->setup = 1; + if (dec) + dec->setup = 1; + } +#endif /* WOLFSSL_SM4_GCM */ + +#ifdef WOLFSSL_SM4_CCM + /* check that buffer sizes are sufficient (CCM is same size as GCM) */ + #if (AEAD_MAX_IMP_SZ < 4) /* SM4-CCM_IMP_IV_SZ */ + #error AEAD_MAX_IMP_SZ too small for SM4-CCM + #endif + #if (AEAD_MAX_EXP_SZ < 8) /* SM4-CCM_EXP_IV_SZ */ + #error AEAD_MAX_EXP_SZ too small for SM4-CCM + #endif + #if (MAX_WRITE_IV_SZ < 4) /* SM4-CCM_IMP_IV_SZ */ + #error MAX_WRITE_IV_SZ too small for SM4-CCM + #endif + + if (specs->bulk_cipher_algorithm == wolfssl_sm4_ccm) { + int CcmRet; + + if (enc) { + if (enc->sm4 == NULL) { + enc->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (enc->sm4 == NULL) + return MEMORY_E; + } else { + wc_Sm4Free(enc->sm4); + } + + XMEMSET(enc->sm4, 0, sizeof(wc_Sm4)); + } + if (dec) { + if (dec->sm4 == NULL) { + dec->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap, + DYNAMIC_TYPE_CIPHER); + if (dec->sm4 == NULL) + return MEMORY_E; + } else { + wc_Sm4Free(dec->sm4); + } + XMEMSET(dec->sm4, 0, sizeof(wc_Sm4)); + } + + if (enc) { + if (wc_Sm4Init(enc->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + if (dec) { + if (wc_Sm4Init(dec->sm4, heap, devId) != 0) { + WOLFSSL_MSG("Sm4Init failed in SetKeys"); + return ASYNC_INIT_E; + } + } + + if (side == WOLFSSL_CLIENT_END) { + if (enc) { + CcmRet = wc_Sm4SetKey(enc->sm4, keys->client_write_key, + specs->key_size); + if (CcmRet != 0) { + return CcmRet; + } + XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + } + if (dec) { + CcmRet = wc_Sm4SetKey(dec->sm4, keys->server_write_key, + specs->key_size); + if (CcmRet != 0) { + return CcmRet; + } + XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + } + } + else { + if (enc) { + CcmRet = wc_Sm4SetKey(enc->sm4, keys->server_write_key, + specs->key_size); + if (CcmRet != 0) { + return CcmRet; + } + XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + } + if (dec) { + CcmRet = wc_Sm4SetKey(dec->sm4, keys->client_write_key, + specs->key_size); + if (CcmRet != 0) { + return CcmRet; + } + XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + } + } + if (enc) + enc->setup = 1; + if (dec) + dec->setup = 1; + } +#endif /* WOLFSSL_SM4_CCM */ + #ifdef HAVE_NULL_CIPHER if (specs->bulk_cipher_algorithm == wolfssl_cipher_null) { #ifdef WOLFSSL_TLS13 diff --git a/src/pk.c b/src/pk.c index 07a8c97c4..7bcb6c29f 100644 --- a/src/pk.c +++ b/src/pk.c @@ -8815,6 +8815,10 @@ int EccEnumToNID(int n) return NID_brainpoolP384r1; case ECC_BRAINPOOLP512R1: return NID_brainpoolP512r1; + #ifdef WOLFSSL_SM2 + case ECC_SM2P256V1: + return NID_sm2; + #endif default: WOLFSSL_MSG("NID not found"); return -1; diff --git a/src/sniffer.c b/src/sniffer.c index 3a85d5254..54cca10e0 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -3267,6 +3267,11 @@ static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len, info->curve_id = ECC_SECP256R1; break; #endif /* !NO_ECC_SECP */ + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: + info->curve_id = ECC_SM2P256V1; + break; + #endif /* WOLFSSL_SM2 */ #endif #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP diff --git a/src/ssl.c b/src/ssl.c index bf2bd820f..084cb0259 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -448,6 +448,9 @@ const WOLF_EC_NIST_NAME kNistCurves[] = { {XSTR_SIZEOF("P384_KYBER_LEVEL3"), "P384_KYBER_LEVEL3", WOLFSSL_P384_KYBER_LEVEL3}, {XSTR_SIZEOF("P521_KYBER_LEVEL5"), "P521_KYBER_LEVEL5", WOLFSSL_P521_KYBER_LEVEL5}, #endif +#endif +#ifdef WOLFSSL_SM2 + {XSTR_SIZEOF("SM2"), "SM2", NID_sm2}, #endif {0, NULL, 0}, }; @@ -2647,6 +2650,9 @@ int wolfSSL_GetObjectSize(void) #endif #ifdef HAVE_CHACHA printf("\tsizeof chacha = %lu\n", (unsigned long)sizeof(ChaCha)); +#endif +#ifdef WOLFSSL_SM4 + printf("\tsizeof sm4 = %lu\n", (unsigned long)sizeof(Sm4)); #endif printf("sizeof cipher specs = %lu\n", (unsigned long)sizeof(CipherSpecs)); printf("sizeof keys = %lu\n", (unsigned long)sizeof(Keys)); @@ -2668,6 +2674,9 @@ int wolfSSL_GetObjectSize(void) #endif #ifdef WOLFSSL_SHA384 printf("\tsizeof SHA512 = %lu\n", (unsigned long)sizeof(wc_Sha512)); +#endif +#ifdef WOLFSSL_SM3 + printf("\tsizeof sm3 = %lu\n", (unsigned long)sizeof(Sm3)); #endif printf("sizeof Buffers = %lu\n", (unsigned long)sizeof(Buffers)); printf("sizeof Options = %lu\n", (unsigned long)sizeof(Options)); @@ -3692,6 +3701,7 @@ static int isValidCurveGroup(word16 name) case WOLFSSL_ECC_BRAINPOOLP256R1: case WOLFSSL_ECC_BRAINPOOLP384R1: case WOLFSSL_ECC_BRAINPOOLP512R1: + case WOLFSSL_ECC_SM2P256V1: case WOLFSSL_ECC_X25519: case WOLFSSL_ECC_X448: @@ -6127,8 +6137,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) XMEMCPY(signer->subjectNameHash, cert->subjectHash, SIGNER_DIGEST_SIZE); #ifdef HAVE_OCSP - XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, - KEYID_SIZE); + XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, KEYID_SIZE); #endif signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage : 0xFFFF; @@ -6874,11 +6883,23 @@ static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl, if (ssl) { ssl->options.haveStaticECC = 1; ssl->buffers.keyType = ecc_dsa_sa_algo; + #ifdef WOLFSSL_SM2 + if (key->dp->id == ECC_SM2P256V1) + ssl->buffers.keyType = sm2_sa_algo; + else + #endif + ssl->buffers.keyType = ecc_dsa_sa_algo; ssl->buffers.keySz = *keySz; } else { ctx->haveStaticECC = 1; ctx->privateKeyType = ecc_dsa_sa_algo; + #ifdef WOLFSSL_SM2 + if (key->dp->id == ECC_SM2P256V1) + ctx->privateKeyType = sm2_sa_algo; + else + #endif + ctx->privateKeyType = ecc_dsa_sa_algo; ctx->privateKeySz = *keySz; } @@ -7233,7 +7254,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, } #endif #ifdef HAVE_ECC - if ((*keyFormat == 0 || *keyFormat == ECDSAk)) { + if ((*keyFormat == 0) || (*keyFormat == ECDSAk) + #ifdef WOLFSSL_SM2 + || (*keyFormat == SM2k) + #endif + ) { ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keySz, idx, resetSuites, keyFormat, heap, devId); if (ret != 0) @@ -7628,6 +7653,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, case CTC_SHA512wECDSA: case CTC_ED25519: case CTC_ED448: + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case CTC_SM3wSM2: + #endif WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature"); if (ssl) ssl->options.haveECDSAsig = 1; @@ -7677,6 +7705,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } #endif #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + else if (cert->keyOID == SM2k) { + ssl->options.haveECC = 1; + } + #endif #ifdef HAVE_ED25519 else if (cert->keyOID == ED25519k) { ssl->options.haveECC = 1; @@ -7724,6 +7757,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } #endif #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + else if (cert->keyOID == SM2k) { + ctx->haveECC = 1; + } + #endif #ifdef HAVE_ED25519 else if (cert->keyOID == ED25519k) { ctx->haveECC = 1; @@ -7815,6 +7853,30 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } break; #endif /* HAVE_ECC */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + #ifdef WOLF_PRIVATE_KEY_ID + keyType = sm2_sa_algo; + #endif + /* Determine ECC key size based on curve */ + keySz = wc_ecc_get_curve_size_from_id( + wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL)); + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Ed key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + #endif /* HAVE_ED25519 */ #ifdef HAVE_ED25519 case ED25519k: #ifdef WOLF_PRIVATE_KEY_ID @@ -10005,6 +10067,11 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx) case ecc_dsa_sa_algo: type = EVP_PKEY_EC; break; +#endif +#ifdef WOLFSSL_SM2 + case sm2_sa_algo: + type = EVP_PKEY_EC; + break; #endif default: /* Other key types not supported either as ssl private keys @@ -22528,6 +22595,11 @@ static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo) authStr = "ECDSA"; break; #endif +#ifdef WOLFSSL_SM2 + case sm2_sa_algo: + authStr = "SM2"; + break; +#endif #ifdef HAVE_ED25519 case ed25519_sa_algo: authStr = "Ed25519"; @@ -26218,6 +26290,9 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { { NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"}, #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + { NID_sm3, SM3h, oidHashType, "SM3", "sm3"}, + #endif /* oidSigType */ #ifndef NO_DSA #ifndef NO_SHA @@ -26390,6 +26465,10 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { { NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID, oidCurveType, "brainpoolP320r1", "brainpoolP320r1"}, { NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID, oidCurveType, "brainpoolP384r1", "brainpoolP384r1"}, { NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID, oidCurveType, "brainpoolP512r1", "brainpoolP512r1"}, + + #ifdef WOLFSSL_SM2 + { NID_sm2, ECC_SM2P256V1_OID, oidCurveType, "sm2", "sm2"}, + #endif #endif /* HAVE_ECC */ /* oidBlkType */ @@ -27662,6 +27741,9 @@ struct WOLFSSL_HashSigInfo { { sha_mac, ecc_dsa_sa_algo, CTC_SHAwECDSA }, #endif #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + { sm3_mac, sm2_sa_algo, CTC_SM3wSM2 }, +#endif #ifdef HAVE_ED25519 { no_mac, ed25519_sa_algo, CTC_ED25519 }, #endif @@ -33594,6 +33676,13 @@ static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names) { curve = WOLFSSL_ECC_SECP521R1; } + #ifdef WOLFSSL_SM2 + else if ((XSTRNCMP(name, "sm2p256v1", len) == 0) || + (XSTRNCMP(name, "SM2", len) == 0)) + { + curve = WOLFSSL_ECC_SECP521R1; + } + #endif #ifdef HAVE_CURVE25519 else if (XSTRNCMP(name, "X25519", len) == 0) { @@ -36530,6 +36619,35 @@ int wolfSSL_RAND_poll(void) break; #endif +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + break; +#endif +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + WOLFSSL_MSG("SM4 CBC"); + XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE); + break; +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + WOLFSSL_MSG("SM4 CTR"); + XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE); + break; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + WOLFSSL_MSG("SM4 GCM"); + XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE); + break; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + WOLFSSL_MSG("SM4 CCM"); + XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE); + break; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); break; @@ -36624,6 +36742,35 @@ int wolfSSL_RAND_poll(void) break; #endif +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + break; +#endif +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + WOLFSSL_MSG("SM4 CBC"); + XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz); + break; +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + WOLFSSL_MSG("SM4 CTR"); + XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz); + break; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + WOLFSSL_MSG("SM4 GCM"); + XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz); + break; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + WOLFSSL_MSG("SM4 CCM"); + XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz); + break; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); break; diff --git a/src/tls.c b/src/tls.c index d16dba684..442a66535 100644 --- a/src/tls.c +++ b/src/tls.c @@ -156,6 +156,12 @@ int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen) ret |= wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); hashSz = WC_SHA384_DIGEST_SIZE; } +#endif +#ifdef WOLFSSL_SM3 + if (ssl->specs.mac_algorithm == sm3_mac) { + ret |= wc_Sm3GetHash(&ssl->hsHashes->hashSm3, hash); + hashSz = WC_SM3_DIGEST_SIZE; + } #endif } @@ -686,7 +692,12 @@ int wolfSSL_GetHmacType_ex(CipherSpecs* specs) { return WC_SHA384; } - + #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + { + return WC_SM3; + } #endif #ifndef NO_SHA case sha_mac: @@ -775,6 +786,12 @@ static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz) break; #endif /* WOLFSSL_SHA512 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Update(&hmac->hash.sm3, data, sz); + break; + #endif /* WOLFSSL_SM3 */ + default: break; } @@ -817,6 +834,12 @@ static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash) break; #endif /* WOLFSSL_SHA512 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3FinalRaw(&hmac->hash.sm3, hash); + break; + #endif /* WOLFSSL_SM3 */ + default: break; } @@ -913,6 +936,14 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, break; #endif /* WOLFSSL_SHA512 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + blockSz = WC_SM3_BLOCK_SIZE; + blockBits = 6; + padSz = WC_SM3_BLOCK_SIZE - WC_SM3_PAD_SIZE + 1; + break; + #endif /* WOLFSSL_SM3 */ + default: return BAD_FUNC_ARG; } @@ -3860,7 +3891,7 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, && !defined(HAVE_FFDHE) && !defined(HAVE_PQC) #error Elliptic Curves Extension requires Elliptic Curve Cryptography or liboqs groups. \ Use --enable-ecc and/or --enable-liboqs in the configure script or \ - define HAVE_ECC. Alternatively use FFDHE for DH ciphersuites. + define HAVE_ECC. Alternatively use FFDHE for DH cipher suites. #endif static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name, @@ -3987,6 +4018,21 @@ static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) for (i = 0; i < suites->suiteSz; i += 2) { if (suites->suites[i] == TLS13_BYTE) return; + #ifdef BUILD_TLS_SM4_GCM_SM3 + if ((suites->suites[i] == CIPHER_BYTE) && + (suites->suites[i+1] == TLS_SM4_GCM_SM3)) + return; + #endif + #ifdef BUILD_TLS_SM4_CCM_SM3 + if ((suites->suites[i] == CIPHER_BYTE) && + (suites->suites[i+1] == TLS_SM4_CCM_SM3)) + return; + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + if ((suites->suites[i] == SM_BYTE) && + (suites->suites[i+1] == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3)) + return; + #endif if ((suites->suites[i] == ECC_BYTE) || (suites->suites[i] == ECDHE_PSK_BYTE) || (suites->suites[i] == CHACHA_BYTE)) { @@ -4024,6 +4070,21 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) for (i = 0; i < suites->suiteSz; i += 2) { if (suites->suites[i] == TLS13_BYTE) return; + #ifdef BUILD_TLS_SM4_GCM_SM3 + if ((suites->suites[i] == CIPHER_BYTE) && + (suites->suites[i+1] == TLS_SM4_GCM_SM3)) + return; + #endif + #ifdef BUILD_TLS_SM4_CCM_SM3 + if ((suites->suites[i] == CIPHER_BYTE) && + (suites->suites[i+1] == TLS_SM4_CCM_SM3)) + return; + #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + if ((suites->suites[i] == SM_BYTE) && + (suites->suites[i+1] == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3)) + return; + #endif if ((suites->suites[i] == ECC_BYTE) || (suites->suites[i] == ECDHE_PSK_BYTE) || (suites->suites[i] == CHACHA_BYTE)) { @@ -4051,6 +4112,21 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) if (ssl->options.cipherSuite0 == TLS13_BYTE) return; +#ifdef BUILD_TLS_SM4_GCM_SM3 + if ((ssl->options.cipherSuite0 == CIPHER_BYTE) && + (ssl->options.cipherSuite == TLS_SM4_GCM_SM3)) + return; +#endif +#ifdef BUILD_TLS_SM4_CCM_SM3 + if ((ssl->options.cipherSuite0 == CIPHER_BYTE) && + (ssl->options.cipherSuite == TLS_SM4_CCM_SM3)) + return; +#endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + if ((ssl->options.cipherSuite0 == SM_BYTE) && + (ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3)) + return; +#endif #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) if (ssl->options.cipherSuite0 == ECC_BYTE || ssl->options.cipherSuite0 == ECDHE_PSK_BYTE || @@ -4671,6 +4747,12 @@ int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second, octets = 32; break; #endif /* HAVE_ECC_BRAINPOOL */ + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: + oid = ECC_SM2P256V1_OID; + octets = 32; + break; + #endif /* WOLFSSL_SM2 */ #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -7098,6 +7180,12 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) keySize = 32; break; #endif /* !NO_ECC_SECP */ + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: + curveId = ECC_SM2P256V1; + keySize = 32; + break; + #endif /* !NO_ECC_SECP */ #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -7888,6 +7976,11 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) curveId = ECC_SECP256R1; break; #endif /* !NO_ECC_SECP */ + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: + curveId = ECC_SM2P256V1; + break; + #endif #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -8834,6 +8927,10 @@ static int TLSX_KeyShare_IsSupported(int namedGroup) case WOLFSSL_ECC_BRAINPOOLP256R1: break; #endif + #ifdef WOLFSSL_SM2 + case WOLFSSL_ECC_SM2P256V1: + break; + #endif /* WOLFSSL_SM2 */ #endif #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 case WOLFSSL_ECC_X25519: @@ -8949,6 +9046,9 @@ static const word16 preferredGroup[] = { #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_ECC_SECP256R1, +#if !defined(HAVE_FIPS) && defined(WOLFSSL_SM2) + WOLFSSL_ECC_SM2P256V1, +#endif #endif #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_ECC_X25519, @@ -9124,7 +9224,7 @@ int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, TLSX** extensions) /* Server side KSE processing */ int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, - KeyShareEntry** kse, byte* searched) + byte cipherSuite0, byte cipherSuite, KeyShareEntry** kse, byte* searched) { TLSX* extension; KeyShareEntry* clientKSE = NULL; @@ -9133,6 +9233,9 @@ int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, int preferredRank = WOLFSSL_MAX_GROUP_COUNT; int rank; + (void)cipherSuite0; + (void)cipherSuite; + if (ssl == NULL || ssl->options.side != WOLFSSL_SERVER_END) return BAD_FUNC_ARG; @@ -9163,6 +9266,19 @@ int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, if (clientKSE->ke == NULL) continue; +#ifdef WOLFSSL_SM2 + if ((cipherSuite0 == CIPHER_BYTE) && + ((cipherSuite == TLS_SM4_GCM_SM3) || + (cipherSuite == TLS_SM4_CCM_SM3))) { + if (clientKSE->group != WOLFSSL_ECC_SM2P256V1) { + continue; + } + } + else if (clientKSE->group == WOLFSSL_ECC_SM2P256V1) { + continue; + } +#endif + /* Check consistency now - extensions in any order. */ if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group, extensions)) continue; @@ -9298,7 +9414,8 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry) *doHelloRetry = 0; - ret = TLSX_KeyShare_Choose(ssl, ssl->extensions, &clientKSE, &searched); + ret = TLSX_KeyShare_Choose(ssl, ssl->extensions, ssl->cipher.cipherSuite0, + ssl->cipher.cipherSuite, &clientKSE, &searched); if (ret != 0 || !searched) return ret; @@ -9780,6 +9897,10 @@ static WC_INLINE byte GetHmacLength(int hmac) case sha512_mac: return WC_SHA512_DIGEST_SIZE; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + return WC_SM3_DIGEST_SIZE; + #endif } return 0; } @@ -9791,8 +9912,8 @@ static WC_INLINE byte GetHmacLength(int hmac) * len The length of the identity data. * age The age of the identity. * hmac The HMAC algorithm. - * ciphersuite0 The first byte of the ciphersuite to use. - * ciphersuite The second byte of the ciphersuite to use. + * cipherSuite0 The first byte of the cipher suite to use. + * cipherSuite The second byte of the cipher suite to use. * resumption The PSK is for resumption of a session. * preSharedKey The new pre-shared key object. * returns 0 on success and other values indicate failure. @@ -11738,6 +11859,11 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; #endif + #ifdef WOLFSSL_SM2 + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SM2P256V1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif #endif #endif /* HAVE_ECC */ @@ -12135,6 +12261,16 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) } } else + #endif + #if (defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \ + defined(WOLFSSL_SM3) + if (cipherSuite0 == CIPHER_BYTE) { + if ((cipherSuite != TLS_SM4_GCM_SM3) && + (cipherSuite != TLS_SM4_CCM_SM3)) { + continue; + } + } + else #endif if (cipherSuite0 != TLS13_BYTE) continue; @@ -12175,7 +12311,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #endif if (ssl->options.client_psk_cb != NULL || ssl->options.client_psk_tls13_cb != NULL) { - /* Default ciphersuite. */ + /* Default cipher suite. */ byte cipherSuite0 = TLS13_BYTE; byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER; int cipherSuiteFlags = WOLFSSL_CIPHER_SUITE_FLAG_NONE; diff --git a/src/tls13.c b/src/tls13.c index 3ff4b532c..23d9123c0 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -338,6 +338,19 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen, hashSz = WC_SHA512_DIGEST_SIZE; digestAlg = WC_SHA512; break; +#endif +#ifdef WOLFSSL_SM3 + case sm3_mac: + ret = wc_InitSm3(&digest.sm3, ssl->heap, INVALID_DEVID); + if (ret == 0) { + ret = wc_Sm3Update(&digest.sm3, msg, msgLen); + if (ret == 0) + ret = wc_Sm3Final(&digest.sm3, hash); + wc_Sm3Free(&digest.sm3); + } + hashSz = WC_SM3_DIGEST_SIZE; + digestAlg = WC_SM3; + break; #endif default: digestAlg = -1; @@ -429,6 +442,15 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + hashSz = WC_SM3_DIGEST_SIZE; + digestAlg = WC_SM3; + if (includeMsgs) + ret = wc_Sm3GetHash(&ssl->hsHashes->hashSm3, hash); + break; + #endif + default: ret = HASH_TYPE_E; break; @@ -502,6 +524,13 @@ static WC_INLINE int mac2hash(int mac) hash = WC_SHA512; break; #endif + + #ifdef WOLFSSL_SM3 + case sm3_mac: + hash = WC_SM3; + break; + #endif + default: hash = WC_HASH_TYPE_NONE; } @@ -1202,6 +1231,12 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret) break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + digestAlg = WC_SM3; + break; + #endif + default: return BAD_FUNC_ARG; } @@ -1271,6 +1306,13 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash, ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash); break; #endif /* WOLFSSL_TLS13_SHA512 */ + #ifdef WOLFSSL_SM3 + case sm3_mac: + hashType = WC_SM3; + hashSz = WC_SM3_DIGEST_SIZE; + ret = wc_Sm3GetHash(&ssl->hsHashes->hashSm3, hash); + break; + #endif /* WOLFSSL_SM3 */ default: break; } @@ -2596,6 +2638,24 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, break; #endif + #ifdef WOLFSSL_SM4_GCM + case wolfssl_sm4_gcm: + nonceSz = SM4_GCM_NONCE_SZ; + ret = wc_Sm4GcmEncrypt(ssl->encrypt.sm4, output, input, + dataSz, ssl->encrypt.nonce, nonceSz, output + dataSz, + macSz, aad, aadSz); + break; + #endif + + #ifdef WOLFSSL_SM4_CCM + case wolfssl_sm4_ccm: + nonceSz = SM4_CCM_NONCE_SZ; + ret = wc_Sm4CcmEncrypt(ssl->encrypt.sm4, output, input, + dataSz, ssl->encrypt.nonce, nonceSz, output + dataSz, + macSz, aad, aadSz); + break; + #endif + #ifdef HAVE_NULL_CIPHER case wolfssl_cipher_null: ret = Tls13IntegrityOnly_Encrypt(ssl, output, input, dataSz, @@ -2972,6 +3032,24 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, break; #endif + #ifdef WOLFSSL_SM4_GCM + case wolfssl_sm4_gcm: + nonceSz = SM4_GCM_NONCE_SZ; + ret = wc_Sm4GcmDecrypt(ssl->decrypt.sm4, output, input, + dataSz, ssl->decrypt.nonce, nonceSz, output + dataSz, + macSz, aad, aadSz); + break; + #endif + + #ifdef WOLFSSL_SM4_CCM + case wolfssl_sm4_ccm: + nonceSz = SM4_CCM_NONCE_SZ; + ret = wc_Sm4CcmDecrypt(ssl->decrypt.sm4, output, input, + dataSz, ssl->decrypt.nonce, nonceSz, output + dataSz, + macSz, aad, aadSz); + break; + #endif + #ifdef HAVE_NULL_CIPHER case wolfssl_cipher_null: ret = Tls13IntegrityOnly_Decrypt(ssl, output, input, dataSz, @@ -3339,6 +3417,25 @@ byte SuiteMac(const byte* suite) break; } } +#if (defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \ + defined(WOLFSSL_SM3) + else if (suite[0] == CIPHER_BYTE) { + switch (suite[1]) { + #ifdef BUILD_TLS_SM4_GCM_SM3 + case TLS_SM4_GCM_SM3: + mac = sm3_mac; + break; + #endif + #ifdef BUILD_TLS_SM4_CCM_SM3 + case TLS_SM4_CCM_SM3: + mac = sm3_mac; + break; + #endif + default: + break; + } + } +#endif #ifdef HAVE_NULL_CIPHER else if (suite[0] == ECC_BYTE) { switch (suite[1]) { @@ -3472,6 +3569,11 @@ static int CreateCookie(const WOLFSSL* ssl, byte** hash, byte* hashSz, *hash = hashes->sha512; break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + *hash = hashes->sm3; + break; + #endif } *hashSz = ssl->specs.hash_size; @@ -4587,6 +4689,12 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, digestSize = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_TLS13_SHA512 */ +#ifdef WOLFSSL_SM3 + case sm3_mac: + digestType = WC_SM3; + digestSize = WC_SM3_DIGEST_SIZE; + break; +#endif /* WOLFSSL_SM3 */ default: ret = -1; break; @@ -4717,6 +4825,12 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, digestSize = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_TLS13_SHA512 */ +#ifdef WOLFSSL_SM3 + case sm3_mac: + digestType = WC_SM3; + digestSize = WC_SM3_DIGEST_SIZE; + break; +#endif /* WOLFSSL_SM3 */ default: ret = -1; break; @@ -5228,6 +5342,20 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ; } else +#endif +#if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_SM3) + if (ssl->options.cipherSuite0 == CIPHER_BYTE && + ssl->options.cipherSuite == TLS_SM4_GCM_SM3) { + ; /* Do nothing. */ + } + else +#endif +#if defined(WOLFSSL_SM4_CCM) && defined(WOLFSSL_SM3) + if (ssl->options.cipherSuite0 == CIPHER_BYTE && + ssl->options.cipherSuite == TLS_SM4_CCM_SM3) { + ; /* Do nothing. */ + } + else #endif /* Check that the negotiated ciphersuite matches protocol version. */ if (ssl->options.cipherSuite0 != TLS13_BYTE) { @@ -6812,6 +6940,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!args->usingPSK) { #ifndef NO_CERTS + /* Check that the negotiated ciphersuite matches protocol version. */ #ifdef HAVE_NULL_CIPHER if (ssl->options.cipherSuite0 == ECC_BYTE && (ssl->options.cipherSuite == TLS_SHA256_SHA256 || @@ -6820,7 +6949,20 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else #endif - /* Check that the negotiated ciphersuite matches protocol version. */ + #if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_SM3) + if (ssl->options.cipherSuite0 == CIPHER_BYTE && + ssl->options.cipherSuite == TLS_SM4_GCM_SM3) { + ; /* Do nothing. */ + } + else + #endif + #if defined(WOLFSSL_SM4_CCM) && defined(WOLFSSL_SM3) + if (ssl->options.cipherSuite0 == CIPHER_BYTE && + ssl->options.cipherSuite == TLS_SM4_CCM_SM3) { + ; /* Do nothing. */ + } + else + #endif if (ssl->options.cipherSuite0 != TLS13_BYTE) { WOLFSSL_MSG("Negotiated ciphersuite from lesser version than " "TLS v1.3"); @@ -7287,6 +7429,10 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, word16 reqSz; word16 hashSigAlgoSz = 0; SignatureAlgorithms* sa; + int haveSig = SIG_RSA | SIG_ECDSA | SIG_FALCON | SIG_DILITHIUM; +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + haveSig |= SIG_SM2; +#endif WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND); WOLFSSL_ENTER("SendTls13CertificateRequest"); @@ -7297,13 +7443,13 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, return SIDE_ERROR; /* Get the length of the hashSigAlgo buffer */ - InitSuitesHashSigAlgo_ex(NULL, 1, 1, 1, 1, 0, 1, ssl->buffers.keySz, - &hashSigAlgoSz); + InitSuitesHashSigAlgo_ex2(NULL, haveSig, 1, ssl->buffers.keySz, + &hashSigAlgoSz); sa = TLSX_SignatureAlgorithms_New(ssl, hashSigAlgoSz, ssl->heap); if (sa == NULL) return MEMORY_ERROR; - InitSuitesHashSigAlgo_ex(sa->hashSigAlgo, 1, 1, 1, 1, 0, 1, - ssl->buffers.keySz, &sa->hashSigAlgoSz); + InitSuitesHashSigAlgo_ex2(sa->hashSigAlgo, haveSig, 1, ssl->buffers.keySz, + &hashSigAlgoSz); ret = TLSX_Push(&ssl->extensions, TLSX_SIGNATURE_ALGORITHMS, sa, ssl->heap); if (ret != 0) { TLSX_SignatureAlgorithms_FreeAll(sa, ssl->heap); @@ -7412,6 +7558,12 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) output[1] = ecc_dsa_sa_algo; break; #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case sm2_sa_algo: + output[0] = SM2_SA_MAJOR; + output[1] = SM2_SA_MINOR; + break; +#endif #ifdef HAVE_ED25519 /* ED25519: 0x0807 */ case ed25519_sa_algo: @@ -7479,6 +7631,16 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, int ret = 0; switch (input[0]) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2_SA_MAJOR: + if (input[1] == SM2_SA_MINOR) { + *hsType = sm2_sa_algo; + *hashAlgo = sm3_mac; + } + else + ret = INVALID_PARAMETER; + break; + #endif case NEW_SA_MAJOR: /* PSS signatures: 0x080[4-6] */ if (input[1] >= sha256_mac && input[1] <= sha512_mac) { @@ -7579,6 +7741,13 @@ static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash) ret = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_TLS13_SHA512 */ + #ifdef WOLFSSL_SM3 + case sm3_mac: + ret = wc_Sm3GetHash(&ssl->hsHashes->hashSm3, hash); + if (ret == 0) + ret = WC_SM3_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SM3 */ default: break; } @@ -8358,8 +8527,17 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) if (ssl->hsType == DYNAMIC_TYPE_RSA) args->sigAlgo = rsa_pss_sa_algo; #ifdef HAVE_ECC - else if (ssl->hsType == DYNAMIC_TYPE_ECC) - args->sigAlgo = ecc_dsa_sa_algo; + else if (ssl->hsType == DYNAMIC_TYPE_ECC) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType == sm2_sa_algo) { + args->sigAlgo = sm2_sa_algo; + } + else + #endif + { + args->sigAlgo = ecc_dsa_sa_algo; + } + } #endif #ifdef HAVE_ED25519 else if (ssl->hsType == DYNAMIC_TYPE_ED25519) @@ -8460,12 +8638,17 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) if (ssl->hsType == DYNAMIC_TYPE_ECC) { sig->length = args->sendSz - args->idx - HASH_SIG_SIZE - VERIFY_HEADER; - ret = CreateECCEncodedSig(args->sigData, - args->sigDataSz, ssl->options.hashAlgo); - if (ret < 0) - goto exit_scv; - args->sigDataSz = (word16)ret; - ret = 0; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType != sm2_sa_algo) + #endif + { + ret = CreateECCEncodedSig(args->sigData, + args->sigDataSz, ssl->options.hashAlgo); + if (ret < 0) + goto exit_scv; + args->sigDataSz = (word16)ret; + ret = 0; + } } #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 @@ -8507,16 +8690,27 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) case TLS_ASYNC_DO: { #ifdef HAVE_ECC - if (ssl->hsType == DYNAMIC_TYPE_ECC) { - ret = EccSign(ssl, args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - (word32*)&sig->length, (ecc_key*)ssl->hsKey, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key - #else - NULL + if (ssl->hsType == DYNAMIC_TYPE_ECC) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType == sm2_sa_algo) { + ret = Sm2wSm3Sign(ssl, TLS13_SM2_SIG_ID, + TLS13_SM2_SIG_ID_SZ, args->sigData, args->sigDataSz, + args->verify + HASH_SIG_SIZE + VERIFY_HEADER, + (word32*)&sig->length, (ecc_key*)ssl->hsKey, NULL); + } + else #endif - ); + { + ret = EccSign(ssl, args->sigData, args->sigDataSz, + args->verify + HASH_SIG_SIZE + VERIFY_HEADER, + (word32*)&sig->length, (ecc_key*)ssl->hsKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } args->length = (word16)sig->length; } #endif /* HAVE_ECC */ @@ -8612,17 +8806,29 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) } #endif /* !NO_RSA */ #if defined(HAVE_ECC) && defined(WOLFSSL_CHECK_SIG_FAULTS) - if (ssl->hsType == DYNAMIC_TYPE_ECC) { - ret = EccVerify(ssl, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - sig->length, args->sigData, args->sigDataSz, - (ecc_key*)ssl->hsKey, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key - #else - NULL + if (ssl->hsType == DYNAMIC_TYPE_ECC) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->buffers.keyType == sm2_sa_algo) { + ret = Sm2wSm3Verify(ssl, TLS13_SM2_SIG_ID, + TLS13_SM2_SIG_ID_SZ, + args->verify + HASH_SIG_SIZE + VERIFY_HEADER, + sig->length, args->sigData, args->sigDataSz, + (ecc_key*)ssl->hsKey, NULL); + } + else #endif - ); + { + ret = EccVerify(ssl, + args->verify + HASH_SIG_SIZE + VERIFY_HEADER, + sig->length, args->sigData, args->sigDataSz, + (ecc_key*)ssl->hsKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } } #endif @@ -8948,6 +9154,13 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ssl->peerEccDsaKeyPresent; } #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo == sm2_sa_algo) { + WOLFSSL_MSG("Peer sent SM2 sig"); + validSigAlgo = (ssl->peerEccDsaKey != NULL) && + ssl->peerEccDsaKeyPresent; + } + #endif #ifdef HAVE_PQC if (args->sigAlgo == falcon_level1_sa_algo) { WOLFSSL_MSG("Peer sent Falcon Level 1 sig"); @@ -9012,12 +9225,17 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); if (ret != 0) goto exit_dcv; - ret = CreateECCEncodedSig(args->sigData, - args->sigDataSz, args->hashAlgo); - if (ret < 0) - goto exit_dcv; - args->sigDataSz = (word16)ret; - ret = 0; + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo != sm2_sa_algo) + #endif + { + ret = CreateECCEncodedSig(args->sigData, + args->sigDataSz, args->hashAlgo); + if (ret < 0) + goto exit_dcv; + args->sigDataSz = (word16)ret; + ret = 0; + } } #endif #ifdef HAVE_ED25519 @@ -9101,15 +9319,26 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, #endif /* !NO_RSA */ #ifdef HAVE_ECC if (ssl->peerEccDsaKeyPresent) { - ret = EccVerify(ssl, input + args->idx, args->sz, - args->sigData, args->sigDataSz, - ssl->peerEccDsaKey, - #ifdef HAVE_PK_CALLBACKS - &ssl->buffers.peerEccDsaKey - #else - NULL - #endif - ); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (args->sigAlgo == sm2_sa_algo) { + ret = Sm2wSm3Verify(ssl, TLS13_SM2_SIG_ID, + TLS13_SM2_SIG_ID_SZ, input + args->idx, args->sz, + args->sigData, args->sigDataSz, + ssl->peerEccDsaKey, NULL); + } + else + #endif + { + ret = EccVerify(ssl, input + args->idx, args->sz, + args->sigData, args->sigDataSz, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + } if (ret >= 0) { /* CLIENT/SERVER: data verified with public key from @@ -10254,6 +10483,13 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl) return ret; break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + ret = wc_Sm3Copy(&ssl->hsHashes->hashSm3, &digest.sm3); + if (ret != 0) + return ret; + break; + #endif } /* Generate the Client's Finished message and hash it. */ @@ -10307,6 +10543,15 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl) return ret; break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + wc_Sm3Free(&ssl->hsHashes->hashSm3); + ret = wc_Sm3Copy(&digest.sm3, &ssl->hsHashes->hashSm3); + wc_Sm3Free(&digest.sm3); + if (ret != 0) + return ret; + break; + #endif } return ret; diff --git a/tests/api.c b/tests/api.c index 266af639c..386d16977 100644 --- a/tests/api.c +++ b/tests/api.c @@ -137,6 +137,9 @@ #if !defined(DER_SZ) #define DER_SZ(ks) ((ks) * 2 + 1) #endif + #ifdef WOLFSSL_SM2 + #include + #endif #endif #ifndef NO_ASN #include @@ -173,12 +176,19 @@ #endif #endif +#ifdef WOLFSSL_SM3 + #include +#endif + #ifndef NO_AES #include #ifdef HAVE_AES_DECRYPT #include #endif #endif +#ifdef WOLFSSL_SM4 + #include +#endif #ifdef WOLFSSL_RIPEMD #include #endif @@ -14153,6 +14163,269 @@ static int test_wc_Shake256Hash(void) return EXPECT_RESULT(); } /* END test_wc_Shake256Hash */ + +/* + * Testing wc_InitSm3(), wc_Sm3Free() + */ +static int test_wc_InitSm3Free(void) +{ + EXPECT_DECLS; +#ifdef WOLFSSL_SM3 + wc_Sm3 sm3; + + /* Invalid Parameters */ + ExpectIntEQ(wc_InitSm3(NULL, NULL, INVALID_DEVID), BAD_FUNC_ARG); + + /* Valid Parameters */ + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + + wc_Sm3Free(NULL); + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_InitSm3 */ + +/* + * Testing wc_Sm3Update(), wc_Sm3Final() + */ +static int test_wc_Sm3UpdateFinal(void) +{ + EXPECT_DECLS; +#ifdef WOLFSSL_SM3 + wc_Sm3 sm3; + byte data[WC_SM3_BLOCK_SIZE * 4]; + byte hash[WC_SM3_DIGEST_SIZE]; + byte calcHash[WC_SM3_DIGEST_SIZE]; + byte expHash[WC_SM3_DIGEST_SIZE] = { + 0x38, 0x48, 0x15, 0xa7, 0x0e, 0xae, 0x0b, 0x27, + 0x5c, 0xde, 0x9d, 0xa5, 0xd1, 0xa4, 0x30, 0xa1, + 0xca, 0xd4, 0x54, 0x58, 0x44, 0xa2, 0x96, 0x1b, + 0xd7, 0x14, 0x80, 0x3f, 0x80, 0x1a, 0x07, 0xb6 + }; + word32 chunk; + word32 i; + + XMEMSET(data, 0, sizeof(data)); + + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + + /* Invalid Parameters */ + ExpectIntEQ(wc_Sm3Update(NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Update(&sm3, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Update(NULL, data, 1), BAD_FUNC_ARG); + + /* Valid Parameters */ + ExpectIntEQ(wc_Sm3Update(&sm3, NULL, 0), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE - 2), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_BLOCK_SIZE * 2), 0); + /* Ensure too many bytes for lengths. */ + ExpectIntEQ(wc_Sm3Update(&sm3, data, WC_SM3_PAD_SIZE), 0); + + /* Invalid Parameters */ + ExpectIntEQ(wc_Sm3Final(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Final(&sm3, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Final(NULL, hash), BAD_FUNC_ARG); + + /* Valid Parameters */ + ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0); + ExpectBufEQ(hash, expHash, WC_SM3_DIGEST_SIZE); + + /* Chunk tests. */ + ExpectIntEQ(wc_Sm3Update(&sm3, data, sizeof(data)), 0); + ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0); + for (chunk = 1; chunk <= WC_SM3_BLOCK_SIZE + 1; chunk++) { + for (i = 0; i + chunk <= (word32)sizeof(data); i += chunk) { + ExpectIntEQ(wc_Sm3Update(&sm3, data + i, chunk), 0); + } + if (i < (word32)sizeof(data)) { + ExpectIntEQ(wc_Sm3Update(&sm3, data + i, (word32)sizeof(data) - i), + 0); + } + ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0); + ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE); + } + + /* Not testing when the low 32-bit length overflows. */ + + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3Update */ + +/* + * Testing wc_Sm3GetHash() + */ +static int test_wc_Sm3GetHash(void) +{ + EXPECT_DECLS; +#ifdef WOLFSSL_SM3 + wc_Sm3 sm3; + byte hash[WC_SM3_DIGEST_SIZE]; + byte calcHash[WC_SM3_DIGEST_SIZE]; + byte data[WC_SM3_BLOCK_SIZE]; + + XMEMSET(data, 0, sizeof(data)); + + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0); + + /* Invalid Parameters */ + ExpectIntEQ(wc_Sm3GetHash(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3GetHash(&sm3, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3GetHash(NULL, hash), BAD_FUNC_ARG); + + /* Valid Parameters */ + ExpectIntEQ(wc_Sm3GetHash(&sm3, hash), 0); + ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE); + + /* With update. */ + ExpectIntEQ(wc_Sm3Update(&sm3, data, sizeof(data)), 0); + ExpectIntEQ(wc_Sm3GetHash(&sm3, hash), 0); + ExpectIntEQ(wc_Sm3Final(&sm3, calcHash), 0); + ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE); + + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3Update */ + +/* + * Testing wc_Sm3Copy() + */ +static int test_wc_Sm3Copy(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS) + wc_Sm3 sm3; + wc_Sm3 sm3Copy; + byte hash[WC_SM3_DIGEST_SIZE]; + byte hashCopy[WC_SM3_DIGEST_SIZE]; + byte data[WC_SM3_BLOCK_SIZE + 1]; + int i; + + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitSm3(&sm3Copy, NULL, INVALID_DEVID), 0); + + /* Invalid Parameters */ + ExpectIntEQ(wc_Sm3Copy(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Copy(&sm3, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Copy(NULL, &sm3Copy), BAD_FUNC_ARG); + + /* Valid Parameters */ + ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0); + + /* Ensure all parts of data updated during hashing are copied. */ + for (i = 0; i < WC_SM3_BLOCK_SIZE + 1; i++) { + ExpectIntEQ(wc_Sm3Update(&sm3, data, i), 0); + ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0); + ExpectIntEQ(wc_Sm3Update(&sm3, data, 1), 0); + ExpectIntEQ(wc_Sm3Update(&sm3Copy, data, 1), 0); + ExpectIntEQ(wc_Sm3Final(&sm3, hash), 0); + ExpectIntEQ(wc_Sm3Final(&sm3Copy, hashCopy), 0); + ExpectBufEQ(hash, hashCopy, WC_SM3_DIGEST_SIZE); + } + + wc_Sm3Free(&sm3Copy); + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3Copy */ + +/* + * Testing wc_Sm3FinalRaw() + */ +static int test_wc_Sm3FinalRaw(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SM3) && !defined(HAVE_SELFTEST) && \ + !defined(WOLFSSL_DEVCRYPTO) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 3))) && \ + !defined(WOLFSSL_NO_HASH_RAW) + wc_Sm3 sm3; + byte hash1[WC_SM3_DIGEST_SIZE]; + byte hash2[WC_SM3_DIGEST_SIZE]; + byte hash3[WC_SM3_DIGEST_SIZE]; + byte* hash_test[3] = { hash1, hash2, hash3 }; + int times; + int i; + + XMEMSET(&sm3, 0, sizeof(sm3)); + + /* Initialize */ + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + + /* Invalid Parameters */ + ExpectIntEQ(wc_Sm3FinalRaw(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3FinalRaw(&sm3, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3FinalRaw(NULL, hash1), BAD_FUNC_ARG); + + times = sizeof(hash_test) / sizeof(byte*); + for (i = 0; i < times; i++) { + ExpectIntEQ(wc_Sm3FinalRaw(&sm3, hash_test[i]), 0); + } + + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3FinalRaw */ +/* + * Testing wc_Sm3GetFlags, wc_Sm3SetFlags() + */ +static int test_wc_Sm3GetSetFlags(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS) + wc_Sm3 sm3; + wc_Sm3 sm3Copy; + word32 flags = 0; + + ExpectIntEQ(wc_InitSm3(&sm3, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitSm3(&sm3Copy, NULL, INVALID_DEVID), 0); + + ExpectIntEQ(wc_Sm3GetFlags(NULL, &flags), 0); + ExpectIntEQ(flags, 0); + ExpectIntEQ(wc_Sm3SetFlags(NULL, WC_HASH_FLAG_WILLCOPY), 0); + ExpectIntEQ(wc_Sm3GetFlags(NULL, &flags), 0); + ExpectIntEQ(flags, 0); + ExpectIntEQ(wc_Sm3GetFlags(&sm3, &flags), 0); + ExpectIntEQ(flags, 0); + ExpectIntEQ(wc_Sm3SetFlags(&sm3, WC_HASH_FLAG_WILLCOPY), 0); + ExpectIntEQ(wc_Sm3GetFlags(&sm3, &flags), 0); + ExpectIntEQ(flags, WC_HASH_FLAG_WILLCOPY); + + ExpectIntEQ(wc_Sm3Copy(&sm3, &sm3Copy), 0); + ExpectIntEQ(wc_Sm3GetFlags(&sm3Copy, &flags), 0); + ExpectIntEQ(flags, WC_HASH_FLAG_ISCOPY | WC_HASH_FLAG_WILLCOPY); + + wc_Sm3Free(&sm3Copy); + wc_Sm3Free(&sm3); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3Update */ + +/* + * Testing wc_Sm3Hash() + */ +static int test_wc_Sm3Hash(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SM3) && defined(WOLFSSL_HASH_FLAGS) + byte data[WC_SM3_BLOCK_SIZE]; + byte hash[WC_SM3_DIGEST_SIZE]; + + /* Invalid parameters. */ + ExpectIntEQ(wc_Sm3Hash(NULL, sizeof(data), hash), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm3Hash(data, sizeof(data), NULL), BAD_FUNC_ARG); + + /* Valid parameters. */ + ExpectIntEQ(wc_Sm3Hash(data, sizeof(data), hash), 0); +#endif + return EXPECT_RESULT(); +} /* END test_wc_Sm3Hash */ + /* * Test function for wc_HmacSetKey */ @@ -14191,7 +14464,7 @@ static int test_wc_Md5HmacSetKey(void) (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ExpectIntEQ(wc_HmacSetKey(&hmac, WC_MD5, NULL, (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); - ExpectIntEQ(wc_HmacSetKey(&hmac, 20, (byte*)keys[0], + ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0], (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ret = wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys[0], 0); #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5) @@ -14243,7 +14516,7 @@ static int test_wc_ShaHmacSetKey(void) (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA, NULL, (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); - ExpectIntEQ(wc_HmacSetKey(&hmac, 20, (byte*)keys[0], + ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0], (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ret = wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys[0], 0); @@ -14292,7 +14565,7 @@ static int test_wc_Sha224HmacSetKey(void) (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA224, NULL, (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); - ExpectIntEQ(wc_HmacSetKey(&hmac, 20, (byte*)keys[0], + ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0], (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ret = wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys[0], 0); #ifdef HAVE_FIPS @@ -14340,7 +14613,7 @@ static int test_wc_Sha256HmacSetKey(void) (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, NULL, (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); - ExpectIntEQ(wc_HmacSetKey(&hmac, 20, (byte*)keys[0], + ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0], (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ret = wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys[0], 0); #ifdef HAVE_FIPS @@ -14389,7 +14662,7 @@ static int test_wc_Sha384HmacSetKey(void) (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA384, NULL, (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); - ExpectIntEQ(wc_HmacSetKey(&hmac, 20, (byte*)keys[0], + ExpectIntEQ(wc_HmacSetKey(&hmac, 21, (byte*)keys[0], (word32)XSTRLEN(keys[0])), BAD_FUNC_ARG); ret = wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys[0], 0); #ifdef HAVE_FIPS @@ -15210,6 +15483,691 @@ static int test_wc_AesGcmStream(void) } /* END test_wc_AesGcmStream */ +/* + * Testing streaming SM4 API. + */ +static int test_wc_Sm4(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4 + EXPECT_DECLS; + wc_Sm4 sm4; +#if defined(WOLFSSL_SM4_ECB) || defined(WOLFSSL_SM4_CBC) || \ + defined(WOLFSSL_SM4_CTR) || defined(WOLFSSL_SM4_CCM) + unsigned char key[SM4_KEY_SIZE]; +#endif +#if defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_CTR) + unsigned char iv[SM4_IV_SIZE]; +#endif + + /* Invalid parameters - wc_Sm4Init */ + ExpectIntEQ(wc_Sm4Init(NULL, NULL, INVALID_DEVID), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4Init */ + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + +#if defined(WOLFSSL_SM4_ECB) || defined(WOLFSSL_SM4_CBC) || \ + defined(WOLFSSL_SM4_CTR) || defined(WOLFSSL_SM4_CCM) + XMEMSET(key, 0, sizeof(key)); + + /* Invalid parameters - wc_Sm4SetKey. */ + ExpectIntEQ(wc_Sm4SetKey(NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(&sm4, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(NULL, key, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(NULL, NULL, SM4_KEY_SIZE), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(&sm4, NULL, SM4_KEY_SIZE), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(NULL, key, SM4_KEY_SIZE), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE-1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE+1), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4SetKey. */ + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); +#endif + +#if defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_CTR) + XMEMSET(iv, 0, sizeof(iv)); + + /* Invalid parameters - wc_Sm4SetIV. */ + ExpectIntEQ(wc_Sm4SetIV(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetIV(&sm4, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4SetIV(NULL, iv), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4SetIV. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); +#endif + + /* Valid cases - wc_Sm4Free */ + wc_Sm4Free(NULL); + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4 */ + +/* + * Testing block based SM4-ECB API. + */ +static int test_wc_Sm4Ecb(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_ECB + EXPECT_DECLS; + wc_Sm4 sm4; + unsigned char key[SM4_KEY_SIZE]; + unsigned char in[SM4_BLOCK_SIZE * 2]; + unsigned char out[SM4_BLOCK_SIZE * 2]; + unsigned char out2[SM4_BLOCK_SIZE]; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(in, 0, sizeof(in)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 0), MISSING_KEY); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 0), MISSING_KEY); + + /* Tested in test_wc_Sm4. */ + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + + /* Invalid parameters - wc_Sm4EcbEncrypt. */ + ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, out, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, in, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(NULL, out, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 1), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4EcbEncrypt. */ + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, 0), 0); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0); + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0); + /* In and out are same pointer. */ + ExpectIntEQ(wc_Sm4EcbEncrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0); + + /* Invalid parameters - wc_Sm4EcbDecrypt. */ + ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, out, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, in, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(NULL, out, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 1), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4EcbDecrypt. */ + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, 0), 0); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0); + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0); + /* In and out are same pointer. */ + ExpectIntEQ(wc_Sm4EcbDecrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0); + + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4Ecb */ + +/* + * Testing block based SM4-CBC API. + */ +static int test_wc_Sm4Cbc(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CBC + EXPECT_DECLS; + wc_Sm4 sm4; + unsigned char key[SM4_KEY_SIZE]; + unsigned char iv[SM4_IV_SIZE]; + unsigned char in[SM4_BLOCK_SIZE * 2]; + unsigned char out[SM4_BLOCK_SIZE * 2]; + unsigned char out2[SM4_BLOCK_SIZE]; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + XMEMSET(in, 0, sizeof(in)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), MISSING_KEY); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), MISSING_KEY); + /* Tested in test_wc_Sm4. */ + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), MISSING_IV); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), MISSING_IV); + /* Tested in test_wc_Sm4. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + + /* Invalid parameters - wc_Sm4CbcEncrypt. */ + ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, out, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, in, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(NULL, out, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 1), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4CbcEncrypt. */ + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, 0), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0); + /* In and out are same pointer. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0); + + /* Invalid parameters - wc_Sm4CbcDecrypt. */ + ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, out, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, in, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(NULL, out, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 1), BAD_FUNC_ARG); + + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + /* Valid cases - wc_Sm4CbcDecrypt. */ + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, 0), 0); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0); + /* In and out are same pointer. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, in, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0); + + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4Cbc */ + +/* + * Testing streaming SM4-CTR API. + */ +static int test_wc_Sm4Ctr(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CTR + EXPECT_DECLS; + wc_Sm4 sm4; + unsigned char key[SM4_KEY_SIZE]; + unsigned char iv[SM4_IV_SIZE]; + unsigned char in[SM4_BLOCK_SIZE * 4]; + unsigned char out[SM4_BLOCK_SIZE * 4]; + unsigned char out2[SM4_BLOCK_SIZE * 4]; + word32 chunk; + word32 i; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + XMEMSET(in, 0, sizeof(in)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), MISSING_KEY); + /* Tested in test_wc_Sm4. */ + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), MISSING_IV); + /* Tested in test_wc_Sm4. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + + /* Invalid parameters - wc_Sm4CtrEncrypt. */ + ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, NULL, in, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CtrEncrypt(NULL, out, in, 0), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4CtrEncrypt. */ + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 0), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, 1), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, 1), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, SM4_BLOCK_SIZE), 0); + ExpectIntEQ(XMEMCMP(out2, out, 2), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out, out2, SM4_BLOCK_SIZE), 0); + /* In and out are same pointer. Also check encrypt of cipher text produces + * plaintext. + */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, out, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(in, out, SM4_BLOCK_SIZE * 2), 0); + + /* Chunking tests. */ + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, in, (word32)sizeof(in)), 0); + for (chunk = 1; chunk <= SM4_BLOCK_SIZE + 1; chunk++) { + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + for (i = 0; i + chunk <= (word32)sizeof(in); i += chunk) { + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out + i, in + i, chunk), 0); + } + if (i < (word32)sizeof(in)) { + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out + i, in + i, + (word32)sizeof(in) - i), 0); + } + ExpectIntEQ(XMEMCMP(out, out2, (word32)sizeof(out)), 0); + } + + for (i = 0; i < (word32)sizeof(iv); i++) { + iv[i] = 0xff; + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, out2, out, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(XMEMCMP(out2, in, SM4_BLOCK_SIZE * 2), 0); + } + + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4Ctr */ + +/* + * Testing stream SM4-GCM API. + */ +static int test_wc_Sm4Gcm(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_GCM + EXPECT_DECLS; + wc_Sm4 sm4; + unsigned char key[SM4_KEY_SIZE]; + unsigned char nonce[GCM_NONCE_MAX_SZ]; + unsigned char in[SM4_BLOCK_SIZE * 2]; + unsigned char in2[SM4_BLOCK_SIZE * 2]; + unsigned char out[SM4_BLOCK_SIZE * 2]; + unsigned char out2[SM4_BLOCK_SIZE * 2]; + unsigned char dec[SM4_BLOCK_SIZE * 2]; + unsigned char tag[SM4_BLOCK_SIZE]; + unsigned char aad[SM4_BLOCK_SIZE * 2]; + word32 i; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(nonce, 0, sizeof(nonce)); + XMEMSET(in, 0, sizeof(in)); + XMEMSET(in2, 0, sizeof(in2)); + XMEMSET(aad, 0, sizeof(aad)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 0, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), MISSING_KEY); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 0, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), MISSING_KEY); + + /* Invalid parameters - wc_Sm4GcmSetKey. */ + ExpectIntEQ(wc_Sm4GcmSetKey(NULL, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(NULL, key, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(NULL, NULL, SM4_KEY_SIZE), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, key, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, NULL, SM4_KEY_SIZE), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmSetKey(NULL, key, SM4_KEY_SIZE), BAD_FUNC_ARG); + + /* Valid parameters - wc_Sm4GcmSetKey. */ + ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, key, SM4_KEY_SIZE), 0); + + /* Invalid parameters - wc_Sm4GcmEncrypt. */ + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, nonce, GCM_NONCE_MID_SZ, + NULL, 0, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, tag, + SM4_BLOCK_SIZE, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(NULL, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, in, 1, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, NULL, 1, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, NULL, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, 0, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, + NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE+1, aad, sizeof(aad)), BAD_FUNC_ARG); + + /* Invalid parameters - wc_Sm4GcmDecrypt. */ + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, nonce, GCM_NONCE_MID_SZ, + NULL, 0, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, tag, + SM4_BLOCK_SIZE, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(NULL, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, in, 1, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, NULL, 1, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, NULL, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, 0, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, + NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 1, nonce, GCM_NONCE_MID_SZ, tag, + SM4_BLOCK_SIZE+1, aad, sizeof(aad)), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */ + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, NULL, NULL, 0, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in2, out, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in2, in, SM4_BLOCK_SIZE * 2), 0); + + /* Check vald values of nonce - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */ + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce, + GCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), + SM4_GCM_AUTH_E); + + /* Check valid values of tag size - wc_Sm4GcmEncrypt/wc_Sm4GcmDecrypt. */ + for (i = WOLFSSL_MIN_AUTH_TAG_SZ; i < SM4_BLOCK_SIZE; i++) { + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, i, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + GCM_NONCE_MID_SZ, tag, i, aad, sizeof(aad)), 0); + } + + /* Check different in/out sizes. */ + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 0, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, out, in, 0, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, 1, nonce, + GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + for (i = 2; i <= SM4_BLOCK_SIZE * 2; i++) { + XMEMCPY(out2, out, i - 1); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, out, in, i, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(out, out2, i - 1), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, dec, out, i, nonce, GCM_NONCE_MID_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in, dec, i), 0); + } + + /* Force the counter to roll over in first byte. */ + { + static unsigned char largeIn[256 * SM4_BLOCK_SIZE]; + static unsigned char largeOut[256 * SM4_BLOCK_SIZE]; + + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, largeOut, largeIn, sizeof(largeIn), + nonce, GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, largeOut, largeOut, sizeof(largeIn), + nonce, GCM_NONCE_MID_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(largeOut, largeIn, sizeof(largeIn)), 0); + } + + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4Gcm */ + +/* + * Testing stream SM4-CCM API. + */ +static int test_wc_Sm4Ccm(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CCM + EXPECT_DECLS; + wc_Sm4 sm4; + unsigned char key[SM4_KEY_SIZE]; + unsigned char nonce[CCM_NONCE_MAX_SZ]; + unsigned char in[SM4_BLOCK_SIZE * 2]; + unsigned char in2[SM4_BLOCK_SIZE * 2]; + unsigned char out[SM4_BLOCK_SIZE * 2]; + unsigned char out2[SM4_BLOCK_SIZE * 2]; + unsigned char dec[SM4_BLOCK_SIZE * 2]; + unsigned char tag[SM4_BLOCK_SIZE]; + unsigned char aad[SM4_BLOCK_SIZE * 2]; + word32 i; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(nonce, 0, sizeof(nonce)); + XMEMSET(in, 0, sizeof(in)); + XMEMSET(in2, 0, sizeof(in2)); + XMEMSET(aad, 0, sizeof(aad)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 0, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), MISSING_KEY); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 0, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), MISSING_KEY); + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + + /* Invalid parameters - wc_Sm4CcmEncrypt. */ + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, nonce, CCM_NONCE_MAX_SZ, + NULL, 0, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, NULL, NULL, 1, NULL, 0, tag, + SM4_BLOCK_SIZE, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(NULL, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, in, 1, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, NULL, 1, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, NULL, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, 0, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, + NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + WOLFSSL_MIN_AUTH_TAG_SZ-1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE+1, aad, sizeof(aad)), BAD_FUNC_ARG); + + /* Invalid parameters - wc_Sm4CcmDecrypt. */ + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, out, NULL, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, in, 1, NULL, 0, NULL, 0, NULL, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, nonce, CCM_NONCE_MAX_SZ, + NULL, 0, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, NULL, NULL, 1, NULL, 0, tag, + SM4_BLOCK_SIZE, NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(NULL, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, in, 1, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, NULL, 1, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, NULL, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, 0, tag, + SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, + NULL, SM4_BLOCK_SIZE, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + WOLFSSL_MIN_AUTH_TAG_SZ - 1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 1, nonce, CCM_NONCE_MAX_SZ, tag, + SM4_BLOCK_SIZE + 1, aad, sizeof(aad)), BAD_FUNC_ARG); + + /* Valid cases - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */ + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, NULL, NULL, 0, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 1), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE * 2, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE * 2, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in2, out, SM4_BLOCK_SIZE * 2), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in2, in2, SM4_BLOCK_SIZE * 2, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in2, in, SM4_BLOCK_SIZE * 2), 0); + + /* Check vald values of nonce - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */ + for (i = CCM_NONCE_MIN_SZ; i <= CCM_NONCE_MAX_SZ; i++) { + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + i, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + i, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + } + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MIN_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), + SM4_CCM_AUTH_E); + + /* Check invalid values of tag size - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. */ + for (i = 0; i < 4; i++) { + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), BAD_FUNC_ARG); + } + /* Odd values in range 4..SM4_BLOCK_SIZE. */ + for (i = 2; i < SM4_BLOCK_SIZE / 2; i++) { + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2 + 1, aad, sizeof(aad)), BAD_FUNC_ARG); + } + /* Check valid values of tag size - wc_Sm4CcmEncrypt/wc_Sm4CcmDecrypt. + * Even values in range 4..SM4_BLOCK_SIZE. + */ + for (i = 2; i < SM4_BLOCK_SIZE / 2; i++) { + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, in, out, SM4_BLOCK_SIZE, nonce, + CCM_NONCE_MAX_SZ, tag, i * 2, aad, sizeof(aad)), 0); + } + + /* Check different in/out sizes. */ + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 0, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, out, in, 0, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, 1, nonce, + CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, NULL, 0), 0); + for (i = 2; i <= SM4_BLOCK_SIZE * 2; i++) { + XMEMCPY(out2, out, i - 1); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, out, in, i, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(out, out2, i - 1), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, dec, out, i, nonce, CCM_NONCE_MAX_SZ, + tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(in, dec, i), 0); + } + + /* Force the counter to roll over in first byte. */ + { + static unsigned char largeIn[256 * SM4_BLOCK_SIZE]; + static unsigned char largeOut[256 * SM4_BLOCK_SIZE]; + + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, largeOut, largeIn, sizeof(largeIn), + nonce, CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, largeOut, largeOut, sizeof(largeIn), + nonce, CCM_NONCE_MAX_SZ, tag, SM4_BLOCK_SIZE, aad, sizeof(aad)), 0); + ExpectIntEQ(XMEMCMP(largeOut, largeIn, sizeof(largeIn)), 0); + } + + wc_Sm4Free(&sm4); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_wc_Sm4Ccm */ + + /* * unit test for wc_Des3_SetIV() */ @@ -21793,6 +22751,615 @@ static int test_wc_ecc_sig_size_calc(void) #endif return EXPECT_RESULT(); } /* END test_wc_ecc_sig_size_calc */ + +/* + * Testing wc_ecc_sm2_make_key() + */ +static int test_wc_ecc_sm2_make_key(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) + EXPECT_DECLS; + WC_RNG rng[1]; + ecc_key key[1]; + + XMEMSET(rng, 0, sizeof(*rng)); + XMEMSET(key, 0, sizeof(*key)); + + ExpectIntEQ(wc_InitRng(rng), 0); + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_make_key(NULL, NULL, WC_ECC_FLAG_NONE), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_make_key(rng, NULL, WC_ECC_FLAG_NONE), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_make_key(NULL, key, WC_ECC_FLAG_NONE), + BAD_FUNC_ARG); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0); + ExpectIntEQ(key->dp->id, ECC_SM2P256V1); + + wc_ecc_free(key); + wc_FreeRng(rng); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* + * Testing wc_ecc_sm2_shared_secret() + */ +static int test_wc_ecc_sm2_shared_secret(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) + EXPECT_DECLS; + WC_RNG rng[1]; + ecc_key keyA[1]; + ecc_key keyB[1]; + byte outA[32]; + byte outB[32]; + word32 outALen = 32; + word32 outBLen = 32; + + XMEMSET(rng, 0, sizeof(*rng)); + XMEMSET(keyA, 0, sizeof(*keyA)); + XMEMSET(keyB, 0, sizeof(*keyB)); + + ExpectIntEQ(wc_InitRng(rng), 0); + ExpectIntEQ(wc_ecc_init(keyA), 0); + ExpectIntEQ(wc_ecc_init(keyB), 0); + ExpectIntEQ(wc_ecc_sm2_make_key(rng, keyA, WC_ECC_FLAG_NONE), 0); + ExpectIntEQ(wc_ecc_sm2_make_key(rng, keyB, WC_ECC_FLAG_NONE), 0); + +#ifdef ECC_TIMING_RESISTANT + ExpectIntEQ(wc_ecc_set_rng(keyA, rng), 0); + ExpectIntEQ(wc_ecc_set_rng(keyB, rng), 0); +#endif + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, NULL, NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, keyB, NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, outA, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, NULL, NULL, &outALen), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(NULL, keyB, outA, &outALen), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, NULL, outA, &outALen), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, NULL, &outALen), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, outA, NULL), BAD_FUNC_ARG); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyA, keyB, outA, &outALen), 0); + ExpectIntLE(outALen, 32); + ExpectIntEQ(wc_ecc_sm2_shared_secret(keyB, keyA, outB, &outBLen), 0); + ExpectIntLE(outBLen, 32); + ExpectIntEQ(outALen, outBLen); + ExpectBufEQ(outA, outB, outALen); + + wc_ecc_free(keyB); + wc_ecc_free(keyA); + wc_FreeRng(rng); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* + * Testing wc_ecc_sm2_create_digest() + */ +static int test_wc_ecc_sm2_create_digest(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && !defined(NO_HASH_WRAPPER) && \ + (defined(WOLFSSL_SM3) || !defined(NO_SHA256)) + EXPECT_DECLS; + ecc_key key[1]; + enum wc_HashType hashType; + unsigned char pub[] = { + 0x04, + 0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33, + 0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F, + 0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B, + 0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F, + 0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C, + 0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA, + 0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3, + 0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33 + }; + unsigned char id[] = { + 0x01, 0x02, 0x03, + }; + unsigned char msg[] = { + 0x01, 0x02, 0x03, + }; + unsigned char hash[32]; +#ifdef WOLFSSL_SM3 + unsigned char expHash[32] = { + 0xc1, 0xdd, 0x92, 0xc5, 0x60, 0xd3, 0x94, 0x28, + 0xeb, 0x0f, 0x57, 0x79, 0x3f, 0xc9, 0x96, 0xc5, + 0xfa, 0xf5, 0x90, 0xb2, 0x64, 0x2f, 0xaf, 0x9c, + 0xc8, 0x57, 0x21, 0x6a, 0x52, 0x7e, 0xf1, 0x95 + }; +#else + unsigned char expHash[32] = { + 0xea, 0x41, 0x55, 0x21, 0x61, 0x00, 0x5c, 0x9a, + 0x57, 0x35, 0x6b, 0x49, 0xca, 0x8f, 0x65, 0xc2, + 0x0e, 0x29, 0x0c, 0xa0, 0x1d, 0xa7, 0xc4, 0xed, + 0xdd, 0x51, 0x12, 0xf6, 0xe7, 0x55, 0xc5, 0xf4 + }; +#endif + +#ifdef WOLFSSL_SM3 + hashType = WC_HASH_TYPE_SM3; +#else + hashType = WC_HASH_TYPE_SHA256; +#endif + + XMEMSET(key, 0, sizeof(*key)); + + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test with no curve set. */ + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + hashType, hash, sizeof(hash), key), BAD_FUNC_ARG); + + ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg), + hashType, NULL, sizeof(hash), NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), NULL, sizeof(msg), + hashType, NULL, sizeof(hash), NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), msg, sizeof(msg), + hashType, NULL, sizeof(hash), NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg), + hashType, hash, sizeof(hash), NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), NULL, sizeof(msg), + hashType, NULL, sizeof(hash), key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(NULL, sizeof(id), msg, sizeof(msg), + hashType, hash, sizeof(hash), key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), NULL, sizeof(msg), + hashType, hash, sizeof(hash), key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + hashType, NULL, sizeof(hash), key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + hashType, hash, sizeof(hash), NULL), BAD_FUNC_ARG); + + /* Bad hash type. */ + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + -1, hash, 0, key), BAD_FUNC_ARG); + /* Bad hash size. */ + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + hashType, hash, 0, key), BUFFER_E); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_create_digest(id, sizeof(id), msg, sizeof(msg), + hashType, hash, sizeof(hash), key), 0); + ExpectBufEQ(hash, expHash, sizeof(expHash)); + + wc_ecc_free(key); + + res = EXPECT_RESULT(); +#endif + return res; +} +/* + * Testing wc_ecc_sm2_verify_hash_ex() + */ +static int test_wc_ecc_sm2_verify_hash_ex(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_VERIFY) && \ + defined(WOLFSSL_PUBLIC_MP) + EXPECT_DECLS; + ecc_key key[1]; + mp_int r[1]; + mp_int s[1]; + int verified; + unsigned char pub[] = { + 0x04, + 0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33, + 0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F, + 0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B, + 0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F, + 0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C, + 0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA, + 0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3, + 0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33 + }; + unsigned char hash[] = { + 0x3B, 0xFA, 0x5F, 0xFB, 0xC4, 0x27, 0x8C, 0x9D, + 0x02, 0x3A, 0x19, 0xCB, 0x1E, 0xAA, 0xD2, 0xF1, + 0x50, 0x69, 0x5B, 0x20 + }; + unsigned char rData[] = { + 0xD2, 0xFC, 0xA3, 0x88, 0xE3, 0xDF, 0xA3, 0x00, + 0x73, 0x9B, 0x3C, 0x2A, 0x0D, 0xAD, 0x44, 0xA2, + 0xFC, 0x62, 0xD5, 0x6B, 0x84, 0x54, 0xD8, 0x40, + 0x22, 0x62, 0x3D, 0x5C, 0xA6, 0x61, 0x9B, 0xE7, + }; + unsigned char sData[] = { + 0x1D, + 0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97, + 0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B, + 0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A, + 0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDC + }; + unsigned char rBadData[] = { + 0xD2, 0xFC, 0xA3, 0x88, 0xE3, 0xDF, 0xA3, 0x00, + 0x73, 0x9B, 0x3C, 0x2A, 0x0D, 0xAD, 0x44, 0xA2, + 0xFC, 0x62, 0xD5, 0x6B, 0x84, 0x54, 0xD8, 0x40, + 0x22, 0x62, 0x3D, 0x5C, 0xA6, 0x61, 0x9B, 0xE8, + }; + + XMEMSET(key, 0, sizeof(*key)); + XMEMSET(r, 0, sizeof(*r)); + XMEMSET(s, 0, sizeof(*s)); + + ExpectIntEQ(mp_init(r), 0); + ExpectIntEQ(mp_init(s), 0); + ExpectIntEQ(mp_read_unsigned_bin(r, rData, sizeof(rData)), 0); + ExpectIntEQ(mp_read_unsigned_bin(s, sData, sizeof(sData)), 0); + + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test with no curve set. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + + ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, NULL, NULL, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, s, NULL, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, hash, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash), + &verified, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, NULL, NULL, sizeof(hash), + NULL, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(NULL, s, hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, NULL, hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, NULL, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + NULL, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + &verified, NULL), BAD_FUNC_ARG); + + /* Make key not on the SM2 curve. */ + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + &verified, key), 0); + ExpectIntEQ(verified, 1); + + ExpectIntEQ(mp_read_unsigned_bin(r, rBadData, sizeof(rBadData)), 0); + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), + &verified, key), 0); + ExpectIntEQ(verified, 0); + + mp_free(s); + mp_free(r); + wc_ecc_free(key); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* + * Testing wc_ecc_sm2_verify_hash() + */ +static int test_wc_ecc_sm2_verify_hash(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_VERIFY) + EXPECT_DECLS; + ecc_key key[1]; + int verified; + unsigned char pub[] = { + 0x04, + 0x63, 0x7F, 0x1B, 0x13, 0x50, 0x36, 0xC9, 0x33, + 0xDC, 0x3F, 0x7A, 0x8E, 0xBB, 0x1B, 0x7B, 0x2F, + 0xD1, 0xDF, 0xBD, 0x26, 0x8D, 0x4F, 0x89, 0x4B, + 0x5A, 0xD4, 0x7D, 0xBD, 0xBE, 0xCD, 0x55, 0x8F, + 0xE8, 0x81, 0x01, 0xD0, 0x80, 0x48, 0xE3, 0x6C, + 0xCB, 0xF6, 0x1C, 0xA3, 0x8D, 0xDF, 0x7A, 0xBA, + 0x54, 0x2B, 0x44, 0x86, 0xE9, 0x9E, 0x49, 0xF3, + 0xA7, 0x47, 0x0A, 0x85, 0x7A, 0x09, 0x64, 0x33 + }; + unsigned char hash[] = { + 0x3B, 0xFA, 0x5F, 0xFB, 0xC4, 0x27, 0x8C, 0x9D, + 0x02, 0x3A, 0x19, 0xCB, 0x1E, 0xAA, 0xD2, 0xF1, + 0x50, 0x69, 0x5B, 0x20 + }; + unsigned char sig[] = { + 0x30, 0x45, 0x02, 0x21, 0x00, 0xD2, 0xFC, 0xA3, + 0x88, 0xE3, 0xDF, 0xA3, 0x00, 0x73, 0x9B, 0x3C, + 0x2A, 0x0D, 0xAD, 0x44, 0xA2, 0xFC, 0x62, 0xD5, + 0x6B, 0x84, 0x54, 0xD8, 0x40, 0x22, 0x62, 0x3D, + 0x5C, 0xA6, 0x61, 0x9B, 0xE7, 0x02, 0x20, 0x1D, + 0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97, + 0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B, + 0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A, + 0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDC + }; + unsigned char sigBad[] = { + 0x30, 0x45, 0x02, 0x21, 0x00, 0xD2, 0xFC, 0xA3, + 0x88, 0xE3, 0xDF, 0xA3, 0x00, 0x73, 0x9B, 0x3C, + 0x2A, 0x0D, 0xAD, 0x44, 0xA2, 0xFC, 0x62, 0xD5, + 0x6B, 0x84, 0x54, 0xD8, 0x40, 0x22, 0x62, 0x3D, + 0x5C, 0xA6, 0x61, 0x9B, 0xE7, 0x02, 0x20, 0x1D, + 0xB5, 0xB5, 0xD9, 0xD8, 0xF1, 0x20, 0xDD, 0x97, + 0x92, 0xBF, 0x7E, 0x9B, 0x3F, 0xE6, 0x3C, 0x4B, + 0x03, 0xD8, 0x80, 0xBD, 0xB7, 0x27, 0x7E, 0x6A, + 0x84, 0x23, 0xDE, 0x61, 0x7C, 0x8D, 0xDD + }; + + + XMEMSET(key, 0, sizeof(*key)); + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test with no curve set. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + + ExpectIntEQ(wc_ecc_import_x963_ex(pub, sizeof(pub), key, ECC_SM2P256V1), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), NULL, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), hash, sizeof(hash), + NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash), + &verified, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), NULL, sizeof(hash), + NULL, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(NULL, sizeof(sig), hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), NULL, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), + NULL, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), + &verified, NULL), BAD_FUNC_ARG); + + /* Make key not on the SM2 curve. */ + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0); + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), + &verified, key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), + &verified, key), 0); + ExpectIntEQ(verified, 1); + + ExpectIntEQ(wc_ecc_sm2_verify_hash(sigBad, sizeof(sigBad), hash, + sizeof(hash), &verified, key), 0); + ExpectIntEQ(verified, 0); + + wc_ecc_free(key); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* + * Testing wc_ecc_sm2_verify_hash_ex() + */ +static int test_wc_ecc_sm2_sign_hash_ex(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_SIGN) && \ + defined(WOLFSSL_PUBLIC_MP) + EXPECT_DECLS; + WC_RNG rng[1]; + ecc_key key[1]; + mp_int r[1]; + mp_int s[1]; + unsigned char hash[32]; +#ifdef HAVE_ECC_VERIFY + int verified; +#endif + + XMEMSET(rng, 0, sizeof(*rng)); + XMEMSET(key, 0, sizeof(*key)); + XMEMSET(r, 0, sizeof(*r)); + XMEMSET(s, 0, sizeof(*s)); + + ExpectIntEQ(wc_InitRng(rng), 0); + ExpectIntEQ(mp_init(r), 0); + ExpectIntEQ(mp_init(s), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(rng, hash, sizeof(hash)), 0); + + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test with no curve set. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s), + BAD_FUNC_ARG); + + ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), NULL, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), rng, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, key, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, r, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), NULL, NULL, NULL, + s), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(NULL, sizeof(hash), rng, key, r, s), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), NULL, key, r, s), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, NULL, r, s), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, NULL, s), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, NULL), + BAD_FUNC_ARG); + + /* Make key not on the SM2 curve. */ + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0); + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0); + +#ifdef WOLFSSL_SP_MATH_ALL + { + mp_int smallR[1]; + sp_init_size(smallR, 1); + /* Force failure in _ecc_sm2_calc_r_s by r being too small. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, + smallR, s), MP_VAL); + } +#endif + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash_ex(hash, sizeof(hash), rng, key, r, s), + 0); +#ifdef HAVE_ECC_VERIFY + ExpectIntEQ(wc_ecc_sm2_verify_hash_ex(r, s, hash, sizeof(hash), &verified, + key), 0); + ExpectIntEQ(verified, 1); +#endif + + mp_free(s); + mp_free(r); + wc_ecc_free(key); + wc_FreeRng(rng); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + + +/* + * Testing wc_ecc_sm2_verify_hash() + */ +static int test_wc_ecc_sm2_sign_hash(void) +{ + int res = TEST_SKIPPED; +#if defined(HAVE_ECC) && defined(WOLFSSL_SM2) && defined(HAVE_ECC_SIGN) + EXPECT_DECLS; + WC_RNG rng[1]; + ecc_key key[1]; + unsigned char hash[32]; + unsigned char sig[72]; + word32 sigSz = sizeof(sig); +#ifdef HAVE_ECC_VERIFY + int verified; +#endif + + XMEMSET(rng, 0, sizeof(*rng)); + XMEMSET(key, 0, sizeof(*key)); + + ExpectIntEQ(wc_InitRng(rng), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(rng, hash, sizeof(hash)), 0); + + ExpectIntEQ(wc_ecc_init(key), 0); + + /* Test with no curve set. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key), + BAD_FUNC_ARG); + + ExpectIntEQ(wc_ecc_sm2_make_key(rng, key, WC_ECC_FLAG_NONE), 0); + + /* Test invalid parameters. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), NULL, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), sig, NULL, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, &sigSz, NULL, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, rng, + NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), NULL, NULL, NULL, + key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(NULL, sizeof(hash), sig, &sigSz, rng, + key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), NULL, &sigSz, rng, + key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, NULL, rng, + key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, NULL, + key), BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, + NULL), BAD_FUNC_ARG); + + /* Make key not on the SM2 curve. */ + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SECP256R1), 0); + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key), + BAD_FUNC_ARG); + ExpectIntEQ(wc_ecc_set_curve(key, 32, ECC_SM2P256V1), 0); + + /* Test valid parameters. */ + ExpectIntEQ(wc_ecc_sm2_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, key), + 0); +#ifdef HAVE_ECC_VERIFY + ExpectIntEQ(wc_ecc_sm2_verify_hash(sig, sigSz, hash, sizeof(hash), + &verified, key), 0); + ExpectIntEQ(verified, 1); +#endif + + wc_ecc_free(key); + wc_FreeRng(rng); +#ifdef FP_ECC + wc_ecc_fp_free(); +#endif + + res = EXPECT_RESULT(); +#endif + return res; +} + + /* * Testing ToTraditional */ @@ -36896,8 +38463,8 @@ static int test_wolfSSL_ERR_print_errors(void) ExpectNotNull(bio = BIO_new(BIO_s_mem())); ERR_clear_error(); /* clear out any error nodes */ ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0); - /* Choosing -299 as an unused errno between MIN_CODE_E < x < WC_LAST_E. */ - ERR_put_error(0,SYS_F_BIND, -299, "asn.c", 100); + /* Choosing -600 as an unused errno. */ + ERR_put_error(0,SYS_F_BIND, -600, "asn.c", 100); ERR_print_errors(bio); ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56); @@ -36906,7 +38473,7 @@ static int test_wolfSSL_ERR_print_errors(void) buf, 55), 0); ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57); ExpectIntEQ(XSTRNCMP( - "error:299:wolfSSL library:unknown error number:asn.c:100", + "error:600:wolfSSL library:unknown error number:asn.c:100", buf, 56), 0); ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1); ExpectIntEQ(buf[0], '\0'); @@ -40478,6 +42045,7 @@ static int test_wolfSSL_SHA(void) return EXPECT_RESULT(); } + /* test_EVP_Cipher_extra, Extra-test on EVP_CipherUpdate/Final. see also test.c */ #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) &&\ (!defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)) @@ -43367,6 +44935,23 @@ static int test_wolfSSL_EVP_CIPHER_block_size(void) ExpectIntEQ(EVP_CIPHER_block_size(wolfSSL_EVP_chacha20_poly1305()), 1); #endif #endif + +#ifdef WOLFSSL_SM4_ECB + ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ecb()), SM4_BLOCK_SIZE); +#endif +#ifdef WOLFSSL_SM4_CBC + ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_cbc()), SM4_BLOCK_SIZE); +#endif +#ifdef WOLFSSL_SM4_CTR + ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ctr()), 1); +#endif +#ifdef WOLFSSL_SM4_GCM + ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_gcm()), 1); +#endif +#ifdef WOLFSSL_SM4_CCM + ExpectIntEQ(EVP_CIPHER_block_size(EVP_sm4_ccm()), 1); +#endif + return EXPECT_RESULT(); } @@ -50093,6 +51678,511 @@ static int test_wolfssl_EVP_chacha20(void) return EXPECT_RESULT(); } +static int test_wolfssl_EVP_sm4_ecb(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_ECB) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte plainText[SM4_BLOCK_SIZE] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF + }; + byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE]; + byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WOLFSSL_FAILURE); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, SM4_BLOCK_SIZE); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_cbc(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CBC) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_BLOCK_SIZE]; + byte plainText[SM4_BLOCK_SIZE] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF + }; + byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE]; + byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WOLFSSL_FAILURE); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, SM4_BLOCK_SIZE); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_cbc(), key, NULL, 0), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 0), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText + outSz, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_ctr(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CTR) + EXPECT_DECLS; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_BLOCK_SIZE]; + byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF}; + byte cipherText[sizeof(plainText)]; + byte decryptedText[sizeof(plainText)]; + EVP_CIPHER_CTX* ctx; + int outSz; + + XMEMSET(key, 0, sizeof(key)); + XMEMSET(iv, 0, sizeof(iv)); + + /* Encrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + /* Any tag length must fail - not an AEAD cipher. */ + ExpectIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, NULL), + WOLFSSL_FAILURE); + ExpectIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(plainText)); + ExpectIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufNE(cipherText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, EVP_sm4_ctr(), NULL, NULL, NULL), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + /* Test partial Inits. CipherInit() allow setting of key and iv + * in separate calls. */ + ExpectNotNull((ctx = EVP_CIPHER_CTX_new())); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_sm4_ctr(), key, NULL, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, sizeof(cipherText)); + ExpectIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + ExpectIntEQ(outSz, 0); + ExpectBufEQ(decryptedText, plainText, sizeof(plainText)); + EVP_CIPHER_CTX_free(ctx); + + res = EXPECT_RESULT(); +#endif + return res; +} + +static int test_wolfssl_EVP_sm4_gcm_zeroLen(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM) + /* Zero length plain text */ + EXPECT_DECLS; + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + unsigned char tag_kat[16] = { + 0x23,0x2f,0x0c,0xfe,0x30,0x8b,0x49,0xea, + 0x6f,0xc8,0x82,0x29,0xb5,0xdc,0x85,0x8d + }; + + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + ExpectIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag))); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_gcm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_gcm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_GCM) + EXPECT_DECLS; + byte *key = (byte*)"0123456789012345"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = SM4_BLOCK_SIZE; + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[SM4_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_gcm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_GCM_GET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_gcm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[SM4_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_GCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_ccm_zeroLen(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM) + /* Zero length plain text */ + EXPECT_DECLS; + byte key[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte iv[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* align */ + byte plaintxt[1]; + int ivSz = 12; + int plaintxtSz = 0; + unsigned char tag[16]; + + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + + EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new(); + + ExpectIntEQ(1, EVP_EncryptInit_ex(en, EVP_sm4_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, + plaintxtSz)); + ExpectIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_CIPHER_CTX_cleanup(en)); + + ExpectIntEQ(0, ciphertxtSz); + + EVP_CIPHER_CTX_init(de); + ExpectIntEQ(1, EVP_DecryptInit_ex(de, EVP_sm4_ccm(), NULL, key, iv)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(0, decryptedtxtSz); + + EVP_CIPHER_CTX_free(en); + EVP_CIPHER_CTX_free(de); + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */ + return res; +} + +static int test_wolfssl_EVP_sm4_ccm(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM4_CCM) + EXPECT_DECLS; + byte *key = (byte*)"0123456789012345"; + byte *iv = (byte*)"0123456789012"; + int ivSz = (int)XSTRLEN((char*)iv); + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[SM4_BLOCK_SIZE] = {0}; + int plaintxtSz = (int)XSTRLEN((char*)plaintxt); + int aadSz = (int)XSTRLEN((char*)aad); + byte ciphertxt[SM4_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[SM4_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + int i = 0; + EVP_CIPHER_CTX en[2]; + EVP_CIPHER_CTX de[2]; + + for (i = 0; i < 2; i++) { + EVP_CIPHER_CTX_init(&en[i]); + + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], EVP_sm4_ccm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_EncryptInit_ex(&en[i], NULL, NULL, key, iv)); + } + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_EncryptUpdate(&en[i], ciphertxt, &len, plaintxt, + plaintxtSz)); + ciphertxtSz = len; + ExpectIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len)); + ciphertxtSz += len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i], EVP_CTRL_CCM_GET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1); + + EVP_CIPHER_CTX_init(&de[i]); + if (i == 0) { + /* Default uses 96-bits IV length */ + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, key, + iv)); + } + else { + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_sm4_ccm(), NULL, NULL, + NULL)); + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + decryptedtxtSz = len; + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + ExpectIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + decryptedtxtSz += len; + ExpectIntEQ(ciphertxtSz, decryptedtxtSz); + ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[SM4_BLOCK_SIZE-1]+=0xBB; + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_CCM_SET_TAG, + SM4_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, + ciphertxtSz)); + ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); + ExpectIntEQ(0, len); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); + } + + res = EXPECT_RESULT(); +#endif /* OPENSSL_EXTRA && WOLFSSL_SM4_CCM */ + return res; +} + static int test_wolfSSL_EVP_PKEY_hkdf(void) { EXPECT_DECLS; @@ -56985,6 +59075,100 @@ static int test_wolfSSL_EVP_shake256(void) return EXPECT_RESULT(); } +/* + * Testing EVP digest API with SM3 + */ +static int test_wolfSSL_EVP_sm3(void) +{ + int res = TEST_SKIPPED; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SM3) + EXPECT_DECLS; + const EVP_MD* md = NULL; + EVP_MD_CTX* mdCtx = NULL; + byte data[WC_SM3_BLOCK_SIZE * 4]; + byte hash[WC_SM3_DIGEST_SIZE]; + byte calcHash[WC_SM3_DIGEST_SIZE]; + byte expHash[WC_SM3_DIGEST_SIZE] = { + 0x38, 0x48, 0x15, 0xa7, 0x0e, 0xae, 0x0b, 0x27, + 0x5c, 0xde, 0x9d, 0xa5, 0xd1, 0xa4, 0x30, 0xa1, + 0xca, 0xd4, 0x54, 0x58, 0x44, 0xa2, 0x96, 0x1b, + 0xd7, 0x14, 0x80, 0x3f, 0x80, 0x1a, 0x07, 0xb6 + }; + word32 chunk; + word32 i; + unsigned int sz; + int ret; + + XMEMSET(data, 0, sizeof(data)); + + md = EVP_sm3(); + ExpectTrue(md != NULL); + ExpectIntEQ(XSTRNCMP(md, "SM3", XSTRLEN("SM3")), 0); + mdCtx = EVP_MD_CTX_new(); + ExpectTrue(mdCtx != NULL); + + /* Invalid Parameters */ + ExpectIntEQ(EVP_DigestInit(NULL, md), BAD_FUNC_ARG); + /* Valid Parameters */ + ExpectIntEQ(EVP_DigestInit(mdCtx, md), WOLFSSL_SUCCESS); + + ExpectIntEQ(EVP_DigestUpdate(NULL, NULL, 1), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, NULL, 1), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestUpdate(NULL, data, 1), WOLFSSL_FAILURE); + + /* Valid Parameters */ + ExpectIntEQ(EVP_DigestUpdate(mdCtx, NULL, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, 1), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, 1), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE - 2), + WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_BLOCK_SIZE * 2), + WOLFSSL_SUCCESS); + /* Ensure too many bytes for lengths. */ + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, WC_SM3_PAD_SIZE), + WOLFSSL_SUCCESS); + + /* Invalid Parameters */ + ExpectIntEQ(EVP_DigestFinal(NULL, NULL, NULL), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestFinal(mdCtx, NULL, NULL), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestFinal(NULL, hash, NULL), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestFinal(NULL, hash, NULL), WOLFSSL_FAILURE); + ExpectIntEQ(EVP_DigestFinal(mdCtx, NULL, NULL), WOLFSSL_FAILURE); + + /* Valid Parameters */ + ExpectIntEQ(EVP_DigestFinal(mdCtx, hash, NULL), WOLFSSL_SUCCESS); + ExpectBufEQ(hash, expHash, WC_SM3_DIGEST_SIZE); + + /* Chunk tests. */ + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data, sizeof(data)), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_DigestFinal(mdCtx, calcHash, &sz), WOLFSSL_SUCCESS); + ExpectIntEQ(sz, WC_SM3_DIGEST_SIZE); + for (chunk = 1; chunk <= WC_SM3_BLOCK_SIZE + 1; chunk++) { + for (i = 0; i + chunk <= (word32)sizeof(data); i += chunk) { + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data + i, chunk), + WOLFSSL_SUCCESS); + } + if (i < (word32)sizeof(data)) { + ExpectIntEQ(EVP_DigestUpdate(mdCtx, data + i, + (word32)sizeof(data) - i), WOLFSSL_SUCCESS); + } + ExpectIntEQ(EVP_DigestFinal(mdCtx, hash, NULL), WOLFSSL_SUCCESS); + ExpectBufEQ(hash, calcHash, WC_SM3_DIGEST_SIZE); + } + + /* Not testing when the low 32-bit length overflows. */ + + ret = EVP_MD_CTX_cleanup(mdCtx); + ExpectIntEQ(ret, WOLFSSL_SUCCESS); + wolfSSL_EVP_MD_CTX_free(mdCtx); + + res = EXPECT_RESULT(); +#endif + return res; +} /* END test_EVP_sm3 */ + static int test_EVP_blake2(void) { EXPECT_DECLS; @@ -59971,6 +62155,15 @@ TEST_CASE testCases[] = { TEST_DECL(test_wc_Shake256_Copy), TEST_DECL(test_wc_Shake256Hash), + /* SM3 Digest */ + TEST_DECL(test_wc_InitSm3Free), + TEST_DECL(test_wc_Sm3UpdateFinal), + TEST_DECL(test_wc_Sm3GetHash), + TEST_DECL(test_wc_Sm3Copy), + TEST_DECL(test_wc_Sm3FinalRaw), + TEST_DECL(test_wc_Sm3GetSetFlags), + TEST_DECL(test_wc_Sm3Hash), + TEST_DECL(test_wc_HashInit), TEST_DECL(test_wc_HashSetFlags), TEST_DECL(test_wc_HashGetFlags), @@ -60038,6 +62231,14 @@ TEST_CASE testCases[] = { TEST_DECL(test_wc_AesCcmSetKey), TEST_DECL(test_wc_AesCcmEncryptDecrypt), + /* SM4 cipher */ + TEST_DECL(test_wc_Sm4), + TEST_DECL(test_wc_Sm4Ecb), + TEST_DECL(test_wc_Sm4Cbc), + TEST_DECL(test_wc_Sm4Ctr), + TEST_DECL(test_wc_Sm4Gcm), + TEST_DECL(test_wc_Sm4Ccm), + /* RNG tests */ #ifdef HAVE_HASHDRBG #ifdef TEST_RESEED_INTERVAL @@ -60131,6 +62332,15 @@ TEST_CASE testCases[] = { TEST_DECL(test_wc_ecc_sig_size_calc), TEST_DECL(test_wc_EccPrivateKeyToDer), + /* SM2 elliptic curve */ + TEST_DECL(test_wc_ecc_sm2_make_key), + TEST_DECL(test_wc_ecc_sm2_shared_secret), + TEST_DECL(test_wc_ecc_sm2_create_digest), + TEST_DECL(test_wc_ecc_sm2_verify_hash_ex), + TEST_DECL(test_wc_ecc_sm2_verify_hash), + TEST_DECL(test_wc_ecc_sm2_sign_hash_ex), + TEST_DECL(test_wc_ecc_sm2_sign_hash), + /* Curve25519 */ TEST_DECL(test_wc_curve25519_init), TEST_DECL(test_wc_curve25519_size), @@ -60321,6 +62531,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_EVP_shake128), TEST_DECL(test_wolfSSL_EVP_shake256), + TEST_DECL(test_wolfSSL_EVP_sm3), TEST_DECL(test_EVP_blake2), #ifdef OPENSSL_ALL TEST_DECL(test_wolfSSL_EVP_md4), @@ -60347,6 +62558,13 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfssl_EVP_aes_ccm_zeroLen), TEST_DECL(test_wolfssl_EVP_chacha20), TEST_DECL(test_wolfssl_EVP_chacha20_poly1305), + TEST_DECL(test_wolfssl_EVP_sm4_ecb), + TEST_DECL(test_wolfssl_EVP_sm4_cbc), + TEST_DECL(test_wolfssl_EVP_sm4_ctr), + TEST_DECL(test_wolfssl_EVP_sm4_gcm_zeroLen), + TEST_DECL(test_wolfssl_EVP_sm4_gcm), + TEST_DECL(test_wolfssl_EVP_sm4_ccm_zeroLen), + TEST_DECL(test_wolfssl_EVP_sm4_ccm), #ifdef OPENSSL_ALL TEST_DECL(test_wolfSSL_EVP_aes_256_gcm), TEST_DECL(test_wolfSSL_EVP_aes_192_gcm), diff --git a/tests/include.am b/tests/include.am index 54c40f635..132c2fc59 100644 --- a/tests/include.am +++ b/tests/include.am @@ -66,6 +66,7 @@ EXTRA_DIST += tests/unit.h \ tests/test-dhprime.conf \ tests/test-p521.conf \ tests/test-ecc-cust-curves.conf \ + tests/test-sm2.conf \ tests/NCONF_test.cnf \ tests/test-tls-downgrade.conf \ tests/TXT_DB.txt diff --git a/tests/suites.c b/tests/suites.c index b8049a54c..1e20d3b5a 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -1275,6 +1275,18 @@ int SuiteTest(int argc, char** argv) } #endif /* HAVE_RSA and HAVE_ECC */ #endif /* !WC_STRICT_SIG */ +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \ + (defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) + /* add SM2/SM3/SM4 test suites */ + XSTRLCPY(argv0[1], "tests/test-sm2.conf", sizeof(argv0[1])); + printf("starting SM2/SM3/SM4 cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } +#endif #ifndef NO_PSK #ifndef WOLFSSL_NO_TLS12 #if !defined(NO_RSA) || defined(HAVE_ECC) diff --git a/tests/test-sm2.conf b/tests/test-sm2.conf new file mode 100644 index 000000000..d492e2526 --- /dev/null +++ b/tests/test-sm2.conf @@ -0,0 +1,189 @@ +# server TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-A ./certs/sm2/client-sm2.pem +-V +# Remove -V when CRL for SM2 certificates available. + +# client TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/client-sm2.pem +-k ./certs/sm2/client-sm2-priv.pem +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-SM4-GCM-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-GCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-SM4-GCM-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-GCM-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-SM4-CCM-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-SM4-CCM-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CCM-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# server TLSv1.3 TLS13-SM4-CCM-SM3 +-v 4 +-l TLS13-SM4-CCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-d + +# client TLSv1.3 TLS13-SM4-CCM-SM3 +-v 4 +-l TLS13-SM4-CCM-SM3 +-A ./certs/sm2/root-sm2.pem +-C + +# Enable when CRL for SM2 certificates available. +# server TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-A ./certs/sm2/client-sm2.pem +-V +# Remove -V when CRL for SM2 certificates available. + +# client TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-c ./certs/sm2/client-sm2.pem +-k ./certs/sm2/client-sm2-priv.pem +-A ./certs/sm2/root-sm2.pem +-C + +# Enable when CRL for SM2 certificates available. +# server TLSv1.3 TLS13-SM4-CCM-SM3 +-v 4 +-l TLS13-SM4-CCM-SM3 +-c ./certs/sm2/server-sm2.pem +-k ./certs/sm2/server-sm2-priv.pem +-A ./certs/sm2/client-sm2.pem +-V +# Remove -V when CRL for SM2 certificates available. + +# client TLSv1.3 TLS13-SM4-CCM-SM3 +-v 4 +-l TLS13-SM4-CCM-SM3 +-c ./certs/sm2/client-sm2.pem +-k ./certs/sm2/client-sm2-priv.pem +-A ./certs/sm2/root-sm2.pem +-C + +# GmSSL certificates and keys +# server TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-A ./certs/sm2/self-sm2-cert.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-A ./certs/sm2/self-sm2-cert.pem +-V + +# client TLSv1.2 ECDHE-ECDSA-SM4-CBC-SM3 +-v 3 +-l ECDHE-ECDSA-SM4-CBC-SM3 +-A ./certs/sm2/self-sm2-cert.pem +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-C + +# server TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-d + +# client TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-A ./certs/sm2/self-sm2-cert.pem +-C + +# server TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-A ./certs/sm2/self-sm2-cert.pem +-V + +# client TLSv1.3 TLS13-SM4-GCM-SM3 +-v 4 +-l TLS13-SM4-GCM-SM3 +-A ./certs/sm2/self-sm2-cert.pem +-c ./certs/sm2/self-sm2-cert.pem +-k ./certs/sm2/self-sm2-priv.pem +-C diff --git a/tests/unit.h b/tests/unit.h index bbd3e0cd0..c1d8c7fa0 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -189,17 +189,17 @@ #define ExpectPtr(x, y, op, er) do { \ if (_ret != TEST_FAIL) { \ - PRAGMA_DIAG_PUSH; \ + PRAGMA_GCC_DIAG_PUSH; \ /* remarkably, without this inhibition, */ \ /* the _Pragma()s make the declarations warn. */ \ - PRAGMA("GCC diagnostic ignored \"-Wdeclaration-after-statement\""); \ + PRAGMA_GCC("GCC diagnostic ignored \"-Wdeclaration-after-statement\"");\ /* inhibit "ISO C forbids conversion of function pointer */ \ /* to object pointer type [-Werror=pedantic]" */ \ - PRAGMA("GCC diagnostic ignored \"-Wpedantic\""); \ + PRAGMA_GCC("GCC diagnostic ignored \"-Wpedantic\""); \ void* _x = (void*)(x); \ void* _y = (void*)(y); \ Expect(_x op _y, ("%s " #op " %s", #x, #y), ("%p " #er " %p", _x, _y));\ - PRAGMA_DIAG_POP; \ + PRAGMA_GCC_DIAG_POP; \ } \ } while(0) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 9eec61525..22b505844 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -79,6 +79,9 @@ #ifdef HAVE_CAMELLIA #include #endif +#ifdef WOLFSSL_SM4 + #include +#endif #ifndef NO_MD5 #include #endif @@ -94,6 +97,9 @@ #ifdef WOLFSSL_SHA3 #include #endif +#ifdef WOLFSSL_SM3 + #include +#endif #ifndef NO_RSA #include #endif @@ -124,6 +130,9 @@ #ifdef HAVE_ECC #include #endif +#ifdef WOLFSSL_SM2 + #include +#endif #ifdef HAVE_CURVE25519 #include #endif @@ -472,6 +481,10 @@ #define BENCH_AES_CFB 0x00010000 #define BENCH_AES_OFB 0x00020000 #define BENCH_AES_SIV 0x00040000 +#define BENCH_SM4_CBC 0x00080000 +#define BENCH_SM4_GCM 0x00100000 +#define BENCH_SM4_CCM 0x00200000 +#define BENCH_SM4 (BENCH_SM4_CBC | BENCH_SM4_GCM | BENCH_SM4_CCM) /* Digest algorithms. */ #define BENCH_MD5 0x00000001 #define BENCH_POLY1305 0x00000002 @@ -494,6 +507,7 @@ #define BENCH_RIPEMD 0x00004000 #define BENCH_BLAKE2B 0x00008000 #define BENCH_BLAKE2S 0x00010000 +#define BENCH_SM3 0x00020000 /* MAC algorithms. */ #define BENCH_CMAC 0x00000001 @@ -530,6 +544,7 @@ #define BENCH_ECC_P256 0x01000000 #define BENCH_ECC_P384 0x02000000 #define BENCH_ECC_P521 0x04000000 +#define BENCH_SM2 0x08000000 #define BENCH_ECCSI_KEYGEN 0x00000020 #define BENCH_ECCSI_PAIRGEN 0x00000040 #define BENCH_ECCSI_VALIDATE 0x00000080 @@ -646,6 +661,18 @@ static const bench_alg bench_cipher_opt[] = { #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) { "-chacha20-poly1305", BENCH_CHACHA20_POLY1305 }, #endif +#ifdef WOLFSSL_SM4_CBC + { "-sm4-cbc", BENCH_SM4_CBC }, +#endif +#ifdef WOLFSSL_SM4_GCM + { "-sm4-gcm", BENCH_SM4_GCM }, +#endif +#ifdef WOLFSSL_SM4_CCM + { "-sm4-ccm", BENCH_SM4_CCM }, +#endif +#ifdef WOLFSSL_SM4 + { "-sm4", BENCH_SM4 }, +#endif #ifndef NO_DES3 { "-des", BENCH_DES }, #endif @@ -704,6 +731,9 @@ static const bench_alg bench_digest_opt[] = { { "-shake256", BENCH_SHAKE256 }, #endif #endif +#ifdef WOLFSSL_SM3 + { "-sm3", BENCH_SM3 }, +#endif #ifdef WOLFSSL_RIPEMD { "-ripemd", BENCH_RIPEMD }, #endif @@ -776,6 +806,9 @@ static const bench_alg bench_asym_opt[] = { #endif { "-ecc-all", BENCH_ECC_ALL }, #endif +#ifdef WOLFSSL_SM2 + { "-sm2", BENCH_SM2 }, +#endif #ifdef HAVE_CURVE25519 { "-curve25519-kg", BENCH_CURVE25519_KEYGEN }, #ifdef HAVE_CURVE25519_SHARED_SECRET @@ -2401,6 +2434,18 @@ static void* benchmarks_do(void* args) if (bench_all || (bench_cipher_algs & BENCH_CAMELLIA)) bench_camellia(); #endif +#ifdef WOLFSSL_SM4_CBC + if (bench_all || (bench_cipher_algs & BENCH_SM4_CBC)) + bench_sm4_cbc(); +#endif +#ifdef WOLFSSL_SM4_GCM + if (bench_all || (bench_cipher_algs & BENCH_SM4_GCM)) + bench_sm4_gcm(); +#endif +#ifdef WOLFSSL_SM4_CCM + if (bench_all || (bench_cipher_algs & BENCH_SM4_CCM)) + bench_sm4_ccm(); +#endif #ifndef NO_RC4 if (bench_all || (bench_cipher_algs & BENCH_ARC4)) { #ifndef NO_SW_BENCH @@ -2580,6 +2625,16 @@ static void* benchmarks_do(void* args) } #endif /* WOLFSSL_SHAKE256 */ #endif +#ifdef WOLFSSL_SM3 + if (bench_all || (bench_digest_algs & BENCH_SM3)) { + #ifndef NO_SW_BENCH + bench_sm3(0); + #endif + #ifdef BENCH_DEVID + bench_sm3(1); + #endif + } +#endif #ifdef WOLFSSL_RIPEMD if (bench_all || (bench_digest_algs & BENCH_RIPEMD)) bench_ripemd(); @@ -2810,6 +2865,11 @@ static void* benchmarks_do(void* args) } } #endif +#ifdef WOLFSSL_SM2 + if (bench_all || (bench_asym_algs & BENCH_SM2)) { + bench_sm2(0); + } +#endif #ifdef HAVE_CURVE25519 if (bench_all || (bench_asym_algs & BENCH_CURVE25519_KEYGEN)) { @@ -4284,7 +4344,171 @@ void bench_camellia(void) } #endif +#ifdef WOLFSSL_SM4_CBC +void bench_sm4_cbc(void) +{ + wc_Sm4 sm4; + double start; + int ret; + int i; + int count; + ret = wc_Sm4SetKey(&sm4, bench_key, SM4_KEY_SIZE); + if (ret != 0) { + printf("Sm4SetKey failed, ret = %d\n", ret); + return; + } + ret = wc_Sm4SetIV(&sm4, bench_iv); + if (ret != 0) { + printf("Sm4SetIV failed, ret = %d\n", ret); + return; + } + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret = wc_Sm4CbcEncrypt(&sm4, bench_cipher, bench_plain, bench_size); + if (ret < 0) { + printf("Sm4CbcEncrypt failed: %d\n", ret); + return; + } + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-CBC-enc", 0, count, bench_size, start, ret); + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret = wc_Sm4CbcDecrypt(&sm4, bench_plain, bench_cipher, bench_size); + if (ret < 0) { + printf("Sm4CbcDecrypt failed: %d\n", ret); + return; + } + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-CBC-dec", 0, count, bench_size, start, ret); +} +#endif + +#ifdef WOLFSSL_SM4_GCM +void bench_sm4_gcm(void) +{ + wc_Sm4 sm4; + double start; + int ret; + int i; + int count; + + WC_DECLARE_VAR(bench_additional, byte, AES_AUTH_ADD_SZ, HEAP_HINT); + WC_DECLARE_VAR(bench_tag, byte, AES_AUTH_TAG_SZ, HEAP_HINT); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + if (bench_additional == NULL || bench_tag == NULL) { + printf("bench_aesgcm_internal malloc failed\n"); + return; + } +#endif + + ret = wc_Sm4GcmSetKey(&sm4, bench_key, SM4_KEY_SIZE); + if (ret != 0) { + printf("Sm4GcmSetKey failed, ret = %d\n", ret); + return; + } + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret = wc_Sm4GcmEncrypt(&sm4, bench_cipher, bench_plain, bench_size, + bench_iv, GCM_NONCE_MID_SZ, bench_tag, SM4_BLOCK_SIZE, + bench_additional, aesAuthAddSz); + if (ret < 0) { + printf("Sm4GcmEncrypt failed: %d\n", ret); + return; + } + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-GCM-enc", 0, count, bench_size, start, ret); + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret = wc_Sm4GcmDecrypt(&sm4, bench_plain, bench_cipher, bench_size, + bench_iv, GCM_NONCE_MID_SZ, bench_tag, SM4_BLOCK_SIZE, + bench_additional, aesAuthAddSz); + if (ret < 0) { + printf("Sm4GcmDecrypt failed: %d\n", ret); + return; + } + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-GCM-dec", 0, count, bench_size, start, ret); +} +#endif + +#ifdef WOLFSSL_SM4_CCM +void bench_sm4_ccm() +{ + wc_Sm4 enc; + double start; + int ret, i, count; + + WC_DECLARE_VAR(bench_additional, byte, AES_AUTH_ADD_SZ, HEAP_HINT); + WC_DECLARE_VAR(bench_tag, byte, AES_AUTH_TAG_SZ, HEAP_HINT); + +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + if (bench_additional == NULL || bench_tag == NULL) { + printf("bench_aesccm malloc failed\n"); + goto exit; + } +#endif + + XMEMSET(bench_tag, 0, AES_AUTH_TAG_SZ); + XMEMSET(bench_additional, 0, AES_AUTH_ADD_SZ); + + if ((ret = wc_Sm4SetKey(&enc, bench_key, 16)) != 0) { + printf("wc_Sm4SetKey failed, ret = %d\n", ret); + goto exit; + } + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret |= wc_Sm4CcmEncrypt(&enc, bench_cipher, bench_plain, bench_size, + bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ, + bench_additional, 0); + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-CCM-enc", 0, count, bench_size, start, ret); + if (ret != 0) { + printf("wc_Sm4Encrypt failed, ret = %d\n", ret); + goto exit; + } + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + ret |= wc_Sm4CcmDecrypt(&enc, bench_plain, bench_cipher, bench_size, + bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ, + bench_additional, 0); + } + count += i; + } while (bench_stats_check(start)); + bench_stats_sym_finish("SM4-CCM-dec", 0, count, bench_size, start, ret); + if (ret != 0) { + printf("wc_Sm4Decrypt failed, ret = %d\n", ret); + goto exit; + } + + exit: + + WC_FREE_VAR(bench_additional, HEAP_HINT); + WC_FREE_VAR(bench_tag, HEAP_HINT); +} +#endif /* HAVE_AESCCM */ #ifndef NO_DES3 void bench_des(int useDeviceID) { @@ -5771,6 +5995,96 @@ exit: #endif /* WOLFSSL_SHAKE256 */ #endif +#ifdef WOLFSSL_SM3 +void bench_sm3(int useDeviceID) +{ + wc_Sm3 hash[BENCH_MAX_PENDING]; + double start; + int ret = 0, i, count = 0, times, pending = 0; + WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SM3_DIGEST_SIZE, + HEAP_HINT); + WC_INIT_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SM3_DIGEST_SIZE, + HEAP_HINT); + + /* clear for done cleanup */ + XMEMSET(hash, 0, sizeof(hash)); + + if (digest_stream) { + /* init keys */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + ret = wc_InitSm3(&hash[i], HEAP_HINT, + useDeviceID ? devId: INVALID_DEVID); + if (ret != 0) { + printf("InitSm3 failed, ret = %d\n", ret); + goto exit; + } + } + + bench_stats_start(&count, &start); + do { + for (times = 0; times < numBlocks || pending > 0; ) { + bench_async_poll(&pending); + + /* while free pending slots in queue, submit ops */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), + 0, ×, numBlocks, &pending)) { + ret = wc_Sm3Update(&hash[i], bench_plain, + bench_size); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, &pending)) { + goto exit_sm3; + } + } + } /* for i */ + } /* for times */ + count += times; + + times = 0; + do { + bench_async_poll(&pending); + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), + 0, ×, numBlocks, &pending)) { + ret = wc_Sm3Final(&hash[i], digest[i]); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, &pending)) { + goto exit_sm3; + } + } + } /* for i */ + } while (pending > 0); + } while (bench_stats_check(start)); + } + else { + bench_stats_start(&count, &start); + do { + for (times = 0; times < numBlocks; times++) { + ret = wc_InitSm3(hash, HEAP_HINT, + useDeviceID ? devId: INVALID_DEVID); + if (ret == 0) + ret = wc_Sm3Update(hash, bench_plain, bench_size); + if (ret == 0) + ret = wc_Sm3Final(hash, digest[0]); + if (ret != 0) + goto exit_sm3; + } /* for times */ + count += times; + } while (bench_stats_check(start)); + } +exit_sm3: + bench_stats_sym_finish("SM3", useDeviceID, count, bench_size, start, ret); + +exit: + + for (i = 0; i < BENCH_MAX_PENDING; i++) { + wc_Sm3Free(&hash[i]); + } + + WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT); +} +#endif + #ifdef WOLFSSL_RIPEMD void bench_ripemd(void) @@ -7836,6 +8150,286 @@ exit: #endif } #endif + +#ifdef WOLFSSL_SM2 +static void bench_sm2_MakeKey(int useDeviceID) +{ + int ret = 0, i, times, count, pending = 0; + int deviceID; + int keySize; + ecc_key genKey[BENCH_MAX_PENDING]; + char name[BENCH_ECC_NAME_SZ]; + double start; + const char**desc = bench_desc_words[lng_index]; + + deviceID = useDeviceID ? devId : INVALID_DEVID; + keySize = wc_ecc_get_curve_size_from_id(ECC_SM2P256V1); + + /* clear for done cleanup */ + XMEMSET(&genKey, 0, sizeof(genKey)); + + /* ECC Make Key */ + bench_stats_start(&count, &start); + do { + /* while free pending slots in queue, submit ops */ + for (times = 0; times < agreeTimes || pending > 0; ) { + bench_async_poll(&pending); + + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 0, + ×, agreeTimes, &pending)) { + + wc_ecc_free(&genKey[i]); + ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID); + if (ret < 0) { + goto exit; + } + + ret = wc_ecc_sm2_make_key(&gRng, &genKey[i], + WC_ECC_FLAG_NONE); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&genKey[i]), 0, ×, + &pending)) { + goto exit; + } + } + } /* for i */ + } /* for times */ + count += times; + } while (bench_stats_check(start)); +exit: + (void)XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECC [%15s]", + wc_ecc_get_name(ECC_SM2P256V1)); + bench_stats_asym_finish(name, keySize * 8, desc[2], useDeviceID, count, start, + ret); + + /* cleanup */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + wc_ecc_free(&genKey[i]); + } +} + + +void bench_sm2(int useDeviceID) +{ + int ret = 0, i, times, count, pending = 0; + int deviceID; + int keySize; + char name[BENCH_ECC_NAME_SZ]; + ecc_key genKey[BENCH_MAX_PENDING]; +#ifdef HAVE_ECC_DHE + ecc_key genKey2[BENCH_MAX_PENDING]; +#endif +#if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) +#ifdef HAVE_ECC_VERIFY + int verify[BENCH_MAX_PENDING]; +#endif +#endif + word32 x[BENCH_MAX_PENDING]; + double start = 0; + const char**desc = bench_desc_words[lng_index]; + +#ifdef HAVE_ECC_DHE + WC_DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT); +#endif +#if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) + WC_DECLARE_ARRAY(sig, byte, BENCH_MAX_PENDING, ECC_MAX_SIG_SIZE, HEAP_HINT); + WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT); +#endif + +#ifdef HAVE_ECC_DHE + WC_INIT_ARRAY(shared, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT); +#endif +#if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) + WC_INIT_ARRAY(sig, byte, BENCH_MAX_PENDING, ECC_MAX_SIG_SIZE, HEAP_HINT); + WC_INIT_ARRAY(digest, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT); +#endif + deviceID = useDeviceID ? devId : INVALID_DEVID; + + bench_sm2_MakeKey(useDeviceID); + + /* clear for done cleanup */ + XMEMSET(&genKey, 0, sizeof(genKey)); +#ifdef HAVE_ECC_DHE + XMEMSET(&genKey2, 0, sizeof(genKey2)); +#endif + keySize = wc_ecc_get_curve_size_from_id(ECC_SM2P256V1); + + /* init keys */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + /* setup an context for each key */ + if ((ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID)) < 0) { + goto exit; + } + ret = wc_ecc_sm2_make_key(&gRng, &genKey[i], WC_ECC_FLAG_NONE); + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wc_AsyncWait(ret, &genKey[i].asyncDev, WC_ASYNC_FLAG_NONE); + #endif + if (ret < 0) { + goto exit; + } + + #ifdef HAVE_ECC_DHE + if ((ret = wc_ecc_init_ex(&genKey2[i], HEAP_HINT, deviceID)) < 0) { + goto exit; + } + if ((ret = wc_ecc_sm2_make_key(&gRng, &genKey2[i], + WC_ECC_FLAG_NONE)) > 0) { + goto exit; + } + #endif + } + +#ifdef HAVE_ECC_DHE +#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ + !defined(HAVE_SELFTEST) + for (i = 0; i < BENCH_MAX_PENDING; i++) { + (void)wc_ecc_set_rng(&genKey[i], &gRng); + } +#endif + + /* ECC Shared Secret */ + bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); + do { + for (times = 0; times < agreeTimes || pending > 0; ) { + bench_async_poll(&pending); + + /* while free pending slots in queue, submit ops */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1, + ×, agreeTimes, &pending)) { + x[i] = (word32)keySize; + ret = wc_ecc_sm2_shared_secret(&genKey[i], &genKey2[i], + shared[i], &x[i]); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&genKey[i]), 1, ×, + &pending)) { + goto exit_ecdhe; + } + } + } /* for i */ + } /* for times */ + count += times; + } while (bench_stats_check(start)); + PRIVATE_KEY_UNLOCK(); +exit_ecdhe: + (void)XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDHE [%15s]", wc_ecc_get_name(ECC_SM2P256V1)); + + bench_stats_asym_finish(name, keySize * 8, desc[3], useDeviceID, count, start, + ret); + + if (ret < 0) { + goto exit; + } +#endif /* HAVE_ECC_DHE */ + +#if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) + + /* Init digest to sign */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + for (count = 0; count < keySize; count++) { + digest[i][count] = (byte)count; + } + } + + /* ECC Sign */ + bench_stats_start(&count, &start); + do { + for (times = 0; times < agreeTimes || pending > 0; ) { + bench_async_poll(&pending); + + /* while free pending slots in queue, submit ops */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1, + ×, agreeTimes, &pending)) { + if (genKey[i].state == 0) + x[i] = ECC_MAX_SIG_SIZE; + ret = wc_ecc_sm2_sign_hash(digest[i], (word32)keySize, + sig[i], &x[i], &gRng, &genKey[i]); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&genKey[i]), 1, ×, + &pending)) { + goto exit_ecdsa_sign; + } + } + } /* for i */ + } /* for times */ + count += times; + } while (bench_stats_check(start)); +exit_ecdsa_sign: + (void)XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(ECC_SM2P256V1)); + + bench_stats_asym_finish(name, keySize * 8, desc[4], useDeviceID, count, start, + ret); + + if (ret < 0) { + goto exit; + } + +#ifdef HAVE_ECC_VERIFY + + /* ECC Verify */ + bench_stats_start(&count, &start); + do { + for (times = 0; times < agreeTimes || pending > 0; ) { + bench_async_poll(&pending); + + /* while free pending slots in queue, submit ops */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1, + ×, agreeTimes, &pending)) { + if (genKey[i].state == 0) + verify[i] = 0; + ret = wc_ecc_sm2_verify_hash(sig[i], x[i], digest[i], + (word32)keySize, &verify[i], &genKey[i]); + if (!bench_async_handle(&ret, + BENCH_ASYNC_GET_DEV(&genKey[i]), 1, ×, + &pending)) { + goto exit_ecdsa_verify; + } + } + } /* for i */ + } /* for times */ + count += times; + } while (bench_stats_check(start)); +exit_ecdsa_verify: + (void)XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(ECC_SM2P256V1)); + + bench_stats_asym_finish(name, keySize * 8, desc[5], useDeviceID, count, start, + ret); +#endif /* HAVE_ECC_VERIFY */ +#endif /* !NO_ASN && HAVE_ECC_SIGN */ + +exit: + + /* cleanup */ + for (i = 0; i < BENCH_MAX_PENDING; i++) { + wc_ecc_free(&genKey[i]); + #ifdef HAVE_ECC_DHE + wc_ecc_free(&genKey2[i]); + #endif + } + +#ifdef HAVE_ECC_DHE + WC_FREE_ARRAY(shared, BENCH_MAX_PENDING, HEAP_HINT); +#endif +#if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) + WC_FREE_ARRAY(sig, BENCH_MAX_PENDING, HEAP_HINT); + WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT); +#endif + + (void)useDeviceID; + (void)pending; + (void)x; + (void)count; + (void)times; + (void)desc; + (void)start; + (void)name; +} +#endif /* WOLFSSL_SM2 */ #endif /* HAVE_ECC */ #ifdef HAVE_CURVE25519 diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index f119fc969..29256874d 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -61,6 +61,9 @@ void bench_aesofb(void); void bench_aessiv(void); void bench_poly1305(void); void bench_camellia(void); +void bench_sm4_cbc(void); +void bench_sm4_gcm(void); +void bench_sm4_ccm(void); void bench_md5(int useDeviceID); void bench_sha(int useDeviceID); void bench_sha224(int useDeviceID); @@ -81,6 +84,7 @@ void bench_sha3_384(int useDeviceID); void bench_sha3_512(int useDeviceID); void bench_shake128(int useDeviceID); void bench_shake256(int useDeviceID); +void bench_sm3(int useDeviceID); void bench_ripemd(void); void bench_cmac(int useDeviceID); void bench_scrypt(void); @@ -101,6 +105,7 @@ void bench_ecc_curve(int curveId); void bench_eccMakeKey(int useDeviceID, int curveId); void bench_ecc(int useDeviceID, int curveId); void bench_eccEncrypt(int curveId); +void bench_sm2(int useDeviceID); void bench_curve25519KeyGen(int useDeviceID); void bench_curve25519KeyAgree(int useDeviceID); void bench_ed25519KeyGen(void); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index d4b2b80d8..6f1b607ab 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -4890,12 +4890,12 @@ static WC_INLINE void RIGHTSHIFTX(byte* x) #ifdef GCM_TABLE -static void GenerateM0(Aes* aes) +void GenerateM0(Gcm* gcm) { int i, j; - byte (*m)[AES_BLOCK_SIZE] = aes->M0; + byte (*m)[AES_BLOCK_SIZE] = gcm->M0; - XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE); + XMEMCPY(m[128], gcm->H, AES_BLOCK_SIZE); for (i = 64; i > 0; i /= 2) { XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE); @@ -4924,17 +4924,17 @@ static WC_INLINE void Shift4_M0(byte *r8, byte *z8) } #endif -static void GenerateM0(Aes* aes) +void GenerateM0(Gcm* gcm) { #if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU) int i; #endif - byte (*m)[AES_BLOCK_SIZE] = aes->M0; + byte (*m)[AES_BLOCK_SIZE] = gcm->M0; /* 0 times -> 0x0 */ XMEMSET(m[0x0], 0, AES_BLOCK_SIZE); /* 1 times -> 0x8 */ - XMEMCPY(m[0x8], aes->H, AES_BLOCK_SIZE); + XMEMCPY(m[0x8], gcm->H, AES_BLOCK_SIZE); /* 2 times -> 0x4 */ XMEMCPY(m[0x4], m[0x8], AES_BLOCK_SIZE); RIGHTSHIFTX(m[0x4]); @@ -5015,8 +5015,8 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) } #ifdef OPENSSL_EXTRA - XMEMSET(aes->aadH, 0, sizeof(aes->aadH)); - aes->aadLen = 0; + XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH)); + aes->gcm.aadLen = 0; #endif XMEMSET(iv, 0, AES_BLOCK_SIZE); ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); @@ -5037,10 +5037,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #if !defined(FREESCALE_LTC_AES_GCM) if (ret == 0) - ret = wc_AesEncrypt(aes, iv, aes->H); + ret = wc_AesEncrypt(aes, iv, aes->gcm.H); if (ret == 0) { #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) - GenerateM0(aes); + GenerateM0(&aes->gcm); #endif /* GCM_TABLE */ } #endif /* FREESCALE_LTC_AES_GCM */ @@ -5147,7 +5147,7 @@ static void GMULT(byte* X, byte* Y) } -void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; @@ -5155,11 +5155,11 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 blocks, partial; byte* h; - if (aes == NULL) { + if (gcm == NULL) { return; } - h = aes->H; + h = gcm->H; XMEMSET(x, 0, AES_BLOCK_SIZE); /* Hash in A, the Additional Authentication Data */ @@ -5223,7 +5223,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE); \ - GMULT(AES_TAG(aes), aes->H); \ + GMULT(AES_TAG(aes), aes->gcm.H); \ } \ while (0) #endif /* WOLFSSL_AESGCM_STREAM */ @@ -5350,14 +5350,14 @@ static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE]) #endif } -void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; byte scratch[AES_BLOCK_SIZE]; word32 blocks, partial; - if (aes == NULL) { + if (gcm == NULL) { return; } @@ -5369,14 +5369,14 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, partial = aSz % AES_BLOCK_SIZE; while (blocks--) { xorbuf(x, a, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); a += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, a, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); } } @@ -5386,14 +5386,14 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, partial = cSz % AES_BLOCK_SIZE; while (blocks--) { xorbuf(x, c, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); c += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, c, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); } } @@ -5401,7 +5401,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, FlattenSzInBits(&scratch[0], aSz); FlattenSzInBits(&scratch[8], cSz); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); /* Copy the result into s. */ XMEMCPY(s, x, sSz); @@ -5424,7 +5424,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE); \ - GMULT(AES_TAG(aes), aes->M0); \ + GMULT(AES_TAG(aes), aes->gcm.M0); \ } \ while (0) #endif /* WOLFSSL_AESGCM_STREAM */ @@ -5650,14 +5650,14 @@ static WC_INLINE void GMULT(byte *x, byte m[32][AES_BLOCK_SIZE]) } #endif -void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; byte scratch[AES_BLOCK_SIZE]; word32 blocks, partial; - if (aes == NULL) { + if (gcm == NULL) { return; } @@ -5669,14 +5669,14 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, partial = aSz % AES_BLOCK_SIZE; while (blocks--) { xorbuf(x, a, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); a += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, a, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); } } @@ -5686,14 +5686,14 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, partial = cSz % AES_BLOCK_SIZE; while (blocks--) { xorbuf(x, c, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); c += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, c, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); } } @@ -5701,7 +5701,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, FlattenSzInBits(&scratch[0], aSz); FlattenSzInBits(&scratch[8], cSz); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->M0); + GMULT(x, gcm->M0); /* Copy the result into s. */ XMEMCPY(s, x, sSz); @@ -5724,7 +5724,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE); \ - GMULT(AES_TAG(aes), (aes)->M0); \ + GMULT(AES_TAG(aes), (aes)->gcm.M0); \ } \ while (0) #endif /* WOLFSSL_AESGCM_STREAM */ @@ -5768,18 +5768,18 @@ static void GMULT(word64* X, word64* Y) } -void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { word64 x[2] = {0,0}; word32 blocks, partial; word64 bigH[2]; - if (aes == NULL) { + if (gcm == NULL) { return; } - XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE); + XMEMCPY(bigH, gcm->H, AES_BLOCK_SIZE); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE); #endif @@ -5811,10 +5811,10 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, } #ifdef OPENSSL_EXTRA /* store AAD partial tag for next call */ - aes->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32); - aes->aadH[1] = (word32)(x[0] & 0xFFFFFFFF); - aes->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32); - aes->aadH[3] = (word32)(x[1] & 0xFFFFFFFF); + gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32); + gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF); + gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32); + gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF); #endif } @@ -5825,9 +5825,9 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, partial = cSz % AES_BLOCK_SIZE; #ifdef OPENSSL_EXTRA /* Start from last AAD partial tag */ - if(aes->aadLen) { - x[0] = ((word64)aes->aadH[0]) << 32 | aes->aadH[1]; - x[1] = ((word64)aes->aadH[2]) << 32 | aes->aadH[3]; + if(gcm->aadLen) { + x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1]; + x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3]; } #endif while (blocks--) { @@ -5857,8 +5857,8 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word64 len[2]; len[0] = aSz; len[1] = cSz; #ifdef OPENSSL_EXTRA - if (aes->aadLen) - len[0] = (word64)aes->aadLen; + if (gcm->aadLen) + len[0] = (word64)gcm->aadLen; #endif /* Lengths are in bytes. Convert to bits. */ len[0] *= 8; @@ -5884,7 +5884,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, * @param [in] aes AES GCM object. */ #define GHASH_INIT_EXTRA(aes) \ - ByteReverseWords64((word64*)aes->H, (word64*)aes->H, AES_BLOCK_SIZE) + ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, AES_BLOCK_SIZE) /* GHASH one block of data.. * @@ -5896,7 +5896,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 block64[2]; \ XMEMCPY(block64, block, AES_BLOCK_SIZE); \ ByteReverseWords64(block64, block64, AES_BLOCK_SIZE); \ @@ -5916,11 +5916,11 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_LEN_BLOCK(aes) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 len[2]; \ len[0] = aes->aSz; len[1] = aes->cSz; \ - if (aes->aadLen) \ - len[0] = (word64)aes->aadLen; \ + if (aes->gcm.aadLen) \ + len[0] = (word64)aes->gcm.aadLen; \ /* Lengths are in bytes. Convert to bits. */ \ len[0] *= 8; \ len[1] *= 8; \ @@ -5941,7 +5941,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_LEN_BLOCK(aes) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 len[2]; \ len[0] = aes->aSz; len[1] = aes->cSz; \ /* Lengths are in bytes. Convert to bits. */ \ @@ -5974,7 +5974,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 block64[2]; \ XMEMCPY(block64, block, AES_BLOCK_SIZE); \ x[0] ^= block64[0]; \ @@ -5993,11 +5993,11 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_LEN_BLOCK(aes) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 len[2]; \ len[0] = aes->aSz; len[1] = aes->cSz; \ - if (aes->aadLen) \ - len[0] = (word64)aes->aadLen; \ + if (aes->gcm.aadLen) \ + len[0] = (word64)aes->gcm.aadLen; \ /* Lengths are in bytes. Convert to bits. */ \ len[0] *= 8; \ len[1] *= 8; \ @@ -6017,7 +6017,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_LEN_BLOCK(aes) \ do { \ word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->H; \ + word64* h = (word64*)aes->gcm.H; \ word64 len[2]; \ len[0] = aes->aSz; len[1] = aes->cSz; \ /* Lengths are in bytes. Convert to bits. */ \ @@ -6085,18 +6085,18 @@ static void GMULT(word32* X, word32* Y) } -void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { word32 x[4] = {0,0,0,0}; word32 blocks, partial; word32 bigH[4]; - if (aes == NULL) { + if (gcm == NULL) { return; } - XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE); + XMEMCPY(bigH, gcm->H, AES_BLOCK_SIZE); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE); #endif @@ -6194,7 +6194,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. */ #define GHASH_INIT_EXTRA(aes) \ - ByteReverseWords((word32*)aes->H, (word32*)aes->H, AES_BLOCK_SIZE) + ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, AES_BLOCK_SIZE) /* GHASH one block of data.. * @@ -6206,7 +6206,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ word32* x = (word32*)AES_TAG(aes); \ - word32* h = (word32*)aes->H; \ + word32* h = (word32*)aes->gcm.H; \ word32 bigEnd[4]; \ XMEMCPY(bigEnd, block, AES_BLOCK_SIZE); \ ByteReverseWords(bigEnd, bigEnd, AES_BLOCK_SIZE); \ @@ -6228,7 +6228,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, do { \ word32 len[4]; \ word32* x = (word32*)AES_TAG(aes); \ - word32* h = (word32*)aes->H; \ + word32* h = (word32*)aes->gcm.H; \ len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3)); \ len[1] = aes->aSz << 3; \ len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3)); \ @@ -6258,7 +6258,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #define GHASH_ONE_BLOCK(aes, block) \ do { \ word32* x = (word32*)AES_TAG(aes); \ - word32* h = (word32*)aes->H; \ + word32* h = (word32*)aes->gcm.H; \ word32 block32[4]; \ XMEMCPY(block32, block, AES_BLOCK_SIZE); \ x[0] ^= block32[0]; \ @@ -6277,7 +6277,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, do { \ word32 len[4]; \ word32* x = (word32*)AES_TAG(aes); \ - word32* h = (word32*)aes->H; \ + word32* h = (word32*)aes->gcm.H; \ len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3)); \ len[1] = aes->aSz << 3; \ len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3)); \ @@ -6547,7 +6547,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( pCtr[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE); } XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */ @@ -6721,7 +6721,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( /* return authTag */ if (authTag) { if (useSwGhash) { - GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); + GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz); ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag); if (ret == 0) { xorbuf(authTag, tag, authTagSz); @@ -6779,12 +6779,12 @@ WARN_UNUSED_RESULT int AES_GCM_encrypt_C( else { /* Counter is GHASH of IV. */ #ifdef OPENSSL_EXTRA - word32 aadTemp = aes->aadLen; - aes->aadLen = 0; + word32 aadTemp = aes->gcm.aadLen; + aes->gcm.aadLen = 0; #endif - GHASH(aes, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); #ifdef OPENSSL_EXTRA - aes->aadLen = aadTemp; + aes->gcm.aadLen = aadTemp; #endif } XMEMCPY(initialCounter, counter, AES_BLOCK_SIZE); @@ -6844,7 +6844,7 @@ WARN_UNUSED_RESULT int AES_GCM_encrypt_C( xorbufout(c, scratch, p, partial); } if (authTag) { - GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); + GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz); ret = wc_AesEncrypt(aes, initialCounter, scratch); if (ret != 0) return ret; @@ -6852,7 +6852,7 @@ WARN_UNUSED_RESULT int AES_GCM_encrypt_C( #ifdef OPENSSL_EXTRA if (!in && !sz) /* store AAD size for next call */ - aes->aadLen = authInSz; + aes->gcm.aadLen = authInSz; #endif } @@ -7060,7 +7060,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( pCtr[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE); } /* Make copy of expected authTag, which could get corrupted in some @@ -7089,7 +7089,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( || authPadSz != authInSz #endif ) { - GHASH(aes, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag)); + GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag)); ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock); if (ret != 0) return ret; @@ -7304,17 +7304,17 @@ int WARN_UNUSED_RESULT AES_GCM_decrypt_C( else { /* Counter is GHASH of IV. */ #ifdef OPENSSL_EXTRA - word32 aadTemp = aes->aadLen; - aes->aadLen = 0; + word32 aadTemp = aes->gcm.aadLen; + aes->gcm.aadLen = 0; #endif - GHASH(aes, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); #ifdef OPENSSL_EXTRA - aes->aadLen = aadTemp; + aes->gcm.aadLen = aadTemp; #endif } /* Calc the authTag again using received auth data and the cipher text */ - GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); + GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); ret = wc_AesEncrypt(aes, counter, EKY0); if (ret != 0) return ret; @@ -7337,7 +7337,7 @@ int WARN_UNUSED_RESULT AES_GCM_decrypt_C( if (!out) { /* authenticated, non-confidential data */ /* store AAD size for next call */ - aes->aadLen = authInSz; + aes->gcm.aadLen = authInSz; } #endif @@ -7563,12 +7563,12 @@ static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz else { /* Counter is GHASH of IV. */ #ifdef OPENSSL_EXTRA - word32 aadTemp = aes->aadLen; - aes->aadLen = 0; + word32 aadTemp = aes->gcm.aadLen; + aes->gcm.aadLen = 0; #endif - GHASH(aes, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); #ifdef OPENSSL_EXTRA - aes->aadLen = aadTemp; + aes->gcm.aadLen = aadTemp; #endif } @@ -7695,7 +7695,7 @@ static WARN_UNUSED_RESULT int AesGcmFinal_C( xorbuf(authTag, AES_INITCTR(aes), authTagSz); #ifdef OPENSSL_EXTRA /* store AAD size for next call */ - aes->aadLen = aes->aSz; + aes->gcm.aadLen = aes->aSz; #endif /* Zeroize last block to protect sensitive data. */ ForceZero(AES_LASTBLOCK(aes), AES_BLOCK_SIZE); @@ -7788,8 +7788,8 @@ static WARN_UNUSED_RESULT int AesGcmInit_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { SAVE_VECTOR_REGISTERS(return _svr_ret;); - AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz, aes->H, - AES_COUNTER(aes), AES_INITCTR(aes)); + AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz, + aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes)); RESTORE_VECTOR_REGISTERS(); } else @@ -7797,16 +7797,16 @@ static WARN_UNUSED_RESULT int AesGcmInit_aesni( #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { SAVE_VECTOR_REGISTERS(return _svr_ret;); - AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz, aes->H, - AES_COUNTER(aes), AES_INITCTR(aes)); + AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz, + aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes)); RESTORE_VECTOR_REGISTERS(); } else #endif { SAVE_VECTOR_REGISTERS(return _svr_ret;); - AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz, aes->H, - AES_COUNTER(aes), AES_INITCTR(aes)); + AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz, + aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes)); RESTORE_VECTOR_REGISTERS(); } return 0; @@ -7847,20 +7847,20 @@ static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif { AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } /* Reset count. */ aes->aOver = 0; @@ -7878,20 +7878,20 @@ static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_aad_update_avx2(a, blocks * AES_BLOCK_SIZE, - AES_TAG(aes), aes->H); + AES_TAG(aes), aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_aad_update_avx1(a, blocks * AES_BLOCK_SIZE, - AES_TAG(aes), aes->H); + AES_TAG(aes), aes->gcm.H); } else #endif { AES_GCM_aad_update_aesni(a, blocks * AES_BLOCK_SIZE, - AES_TAG(aes), aes->H); + AES_TAG(aes), aes->gcm.H); } /* Skip over to end of AAD blocks. */ a += blocks * AES_BLOCK_SIZE; @@ -7910,19 +7910,21 @@ static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni( /* GHASH last AAD block. */ #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { - AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), + aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { - AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), + aes->gcm.H); } else #endif { AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } /* Clear partial count for next time through. */ aes->aOver = 0; @@ -7975,20 +7977,20 @@ static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif { AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } /* Reset count. */ aes->cOver = 0; @@ -8007,7 +8009,7 @@ static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds, - c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } else @@ -8015,14 +8017,14 @@ static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni( #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds, - c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } else #endif { AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds, - c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } /* Skip over to end of blocks. */ @@ -8089,39 +8091,41 @@ static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni( /* GHASH last cipher block. */ #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { - AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes), + aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { - AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes), + aes->gcm.H); } else #endif { AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } } /* Calculate the authentication tag. */ #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes)); + aes->aSz, aes->gcm.H, AES_INITCTR(aes)); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes)); + aes->aSz, aes->gcm.H, AES_INITCTR(aes)); } else #endif { AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes)); + aes->aSz, aes->gcm.H, AES_INITCTR(aes)); } RESTORE_VECTOR_REGISTERS(); return 0; @@ -8205,20 +8209,20 @@ static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } else #endif { AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes), - aes->H); + aes->gcm.H); } /* Reset count. */ aes->cOver = 0; @@ -8237,7 +8241,7 @@ static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni( #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds, - p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } else @@ -8245,14 +8249,14 @@ static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni( #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds, - p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } else #endif { AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds, - p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->H, + p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes)); } /* Skip over to end of blocks. */ @@ -8325,38 +8329,38 @@ static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni( /* Hash the last block of cipher text. */ #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { - AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { - AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->H); + AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H); } else #endif { - AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->H); + AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H); } } /* Calculate and compare the authentication tag. */ #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes), &res); + aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res); } else #endif #ifdef HAVE_INTEL_AVX1 if (IS_INTEL_AVX1(intel_flags)) { AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes), &res); + aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res); } else #endif { AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz, - aes->aSz, aes->H, AES_INITCTR(aes), &res); + aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res); } RESTORE_VECTOR_REGISTERS(); /* Return error code when calculated doesn't match input. */ @@ -9818,8 +9822,8 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #ifdef HAVE_AESGCM #ifdef OPENSSL_EXTRA - XMEMSET(aes->aadH, 0, sizeof(aes->aadH)); - aes->aadLen = 0; + XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH)); + aes->gcm.aadLen = 0; #endif #endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 02c76a571..e1569825e 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -142,6 +142,10 @@ ASN Options: #include #endif +#ifdef WOLFSSL_SM2 + #include +#endif + #ifdef HAVE_ED25519 #include #endif @@ -4028,6 +4032,10 @@ static word32 SetBitString16Bit(word16 val, byte* output) static const byte sigSha3_512wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 12}; #endif #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + /* 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 */ + static const byte sigSm3wSm2Oid[] = {42, 129, 28, 207, 85, 1, 131, 117}; + #endif #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 static const byte sigEd25519Oid[] = {43, 101, 112}; @@ -4646,6 +4654,12 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) break; #endif #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case CTC_SM3wSM2: + oid = sigSm3wSm2Oid; + *oidSz = sizeof(sigSm3wSm2Oid); + break; + #endif #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 case CTC_ED25519: @@ -11322,8 +11336,8 @@ static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx, ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL); if (ret == 0) { #ifdef HAVE_OCSP - ret = CalcHashId(source + *srcIdx, (word32)length, - cert->subjectKeyHash); + ret = CalcHashId_ex(source + *srcIdx, (word32)length, + cert->subjectKeyHash, HashIdAlg(cert->signatureOID)); } if (ret == 0) { #endif @@ -11926,7 +11940,8 @@ static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx, *srcIdx += (word32)length; #ifdef HAVE_OCSP - return CalcHashId(cert->publicKey, cert->pubKeySize, cert->subjectKeyHash); + return CalcHashId_ex(cert->publicKey, cert->pubKeySize, + cert->subjectKeyHash, HashIdAlg(cert->signatureOID)); #else return 0; #endif @@ -11956,8 +11971,8 @@ static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx, #endif #ifdef HAVE_OCSP /* Calculate the hash of the public key for OCSP. */ - ret = CalcHashId(cert->publicKey, cert->pubKeySize, - cert->subjectKeyHash); + ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize, + cert->subjectKeyHash, HashIdAlg(cert->signatureOID)); #endif } @@ -12058,8 +12073,8 @@ static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx, #endif #ifdef HAVE_OCSP - ret = CalcHashId(source + *srcIdx, (word32)length, - cert->subjectKeyHash); + ret = CalcHashId_ex(source + *srcIdx, (word32)length, + cert->subjectKeyHash, HashIdAlg(cert->signatureOID)); if (ret != 0) return ret; #endif @@ -12108,9 +12123,9 @@ static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx, #ifdef HAVE_OCSP /* Calculate the hash of the subject public key for OCSP. */ - ret = CalcHashId(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data, + ret = CalcHashId_ex(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data, dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length, - cert->subjectKeyHash); + cert->subjectKeyHash, HashIdAlg(cert->signatureOID)); } if (ret == 0) { #endif @@ -12336,6 +12351,9 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx, break; #endif /* NO_RSA */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + #endif case ECDSAk: ret = StoreEccKey(cert, source, &srcIdx, maxIdx, source + pubIdx, (word32)pubLen); @@ -12426,6 +12444,30 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx, } #endif +/* Return the hash algorithm to use with the signature algorithm. + * + * @param [in] oidSum Signature id. + * @return Hash algorithm id. + */ +int HashIdAlg(int oidSum) +{ + (void)oidSum; + +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (oidSum == CTC_SM3wSM2) { + return WC_SM3; + } + if (oidSum == SM2k) { + return WC_SM3; + } +#endif +#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256)) + return WC_SHA256; +#else + return WC_SHA; +#endif +} + /* Calculate hash of the id using the SHA-1 or SHA-256. * * @param [in] data Data to hash. @@ -12435,19 +12477,56 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx, * @return MEMORY_E when dynamic memory allocation fails. */ int CalcHashId(const byte* data, word32 len, byte* hash) +{ + /* Use default hash algorithm. */ + return CalcHashId_ex(data, len, hash, +#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256)) + WC_SHA256 +#else + WC_SHA +#endif + ); +} + +/* Calculate hash of the id using the SHA-1 or SHA-256. + * + * @param [in] data Data to hash. + * @param [in] len Length of data to hash. + * @param [out] hash Buffer to hold hash. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int CalcHashId_ex(const byte* data, word32 len, byte* hash, int hashAlg) { int ret; +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (hashAlg == WC_SM3) { + ret = wc_Sm3Hash(data, len, hash); + } + else +#endif #if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256)) - ret = wc_Sha256Hash(data, len, hash); + if (hashAlg == WC_SHA256) { + ret = wc_Sha256Hash(data, len, hash); + } + else #elif !defined(NO_SHA) - ret = wc_ShaHash(data, len, hash); + if (hashAlg == WC_SHA) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + XMEMSET(hash + WC_SHA_DIGEST_SIZE, 0, KEYID_SIZE - WC_SHA_DIGEST_SIZE); + #endif + ret = wc_ShaHash(data, len, hash); + } + else #else - ret = NOT_COMPILED_IN; (void)data; (void)len; (void)hash; #endif + { + ret = NOT_COMPILED_IN; + } return ret; } @@ -12463,16 +12542,24 @@ int CalcHashId(const byte* data, word32 len, byte* hash) * @return 0 on success. * @return MEMORY_E when dynamic memory allocation fails. */ -static int GetHashId(const byte* id, int length, byte* hash) +static int GetHashId(const byte* id, int length, byte* hash, int hashAlg) { int ret; - if (length == KEYID_SIZE) { +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (length == wc_HashGetDigestSize(wc_HashTypeConvert(hashAlg))) +#else + if (length == KEYID_SIZE) +#endif + { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + XMEMSET(hash + length, 0, KEYID_SIZE - length); + #endif XMEMCPY(hash, id, (size_t)length); ret = 0; } else { - ret = CalcHashId(id, (word32)length, hash); + ret = CalcHashId_ex(id, (word32)length, hash, hashAlg); } return ret; @@ -13205,8 +13292,10 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be * calculated over the entire DER encoding of the Name field, including * the tag and length. */ - if (CalcHashId(input + *inOutIdx, maxIdx - *inOutIdx, hash) != 0) + if (CalcHashId_ex(input + *inOutIdx, maxIdx - *inOutIdx, hash, + HashIdAlg(cert->signatureOID)) != 0) { return ASN_PARSE_E; + } #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(WOLFCRYPT_ONLY) @@ -13858,7 +13947,8 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType, /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be * calculated over the entire DER encoding of the Name field, including * the tag and length. */ - if (CalcHashId(input + srcIdx, maxIdx - srcIdx, hash) != 0) { + if (CalcHashId_ex(input + srcIdx, maxIdx - srcIdx, hash, + HashIdAlg(cert->signatureOID)) != 0) { ret = ASN_PARSE_E; } @@ -14939,9 +15029,8 @@ int DecodeToKey(DecodedCert* cert, int verify) else #endif { - cert->selfSigned = XMEMCMP(cert->issuerHash, - cert->subjectHash, - KEYID_SIZE) == 0 ? 1 : 0; + cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash, + KEYID_SIZE) == 0 ? 1 : 0; } ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx); @@ -15214,6 +15303,9 @@ static WC_INLINE int IsSigAlgoECC(word32 algoOID) #ifdef HAVE_ECC || IsSigAlgoECDSA(algoOID) #endif + #ifdef WOLFSSL_SM2 + || (algoOID == SM2k) + #endif #ifdef HAVE_ED25519 || (algoOID == ED25519k) #endif @@ -15532,6 +15624,9 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) #endif #ifdef HAVE_ECC case ECDSAk: + #ifdef WOLFSSL_SM2 + case SM2k: + #endif #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ defined(WC_ASYNC_ENABLE_ECC) if (sigCtx->key.ecc->nb_ctx != NULL) { @@ -15716,6 +15811,14 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, break; #endif #endif + #if defined(WOLFSSL_SM2) & defined(WOLFSSL_SM3) + case CTC_SM3wSM2: + if ((ret = wc_Sm3Hash(buf, bufSz, digest)) == 0) { + *typeH = SM3h; + *digestSz = WC_SM3_DIGEST_SIZE; + } + break; + #endif #ifdef HAVE_ED25519 case CTC_ED25519: /* Hashes done in signing operation. @@ -15858,6 +15961,12 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } } else + #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigOID == CTC_SM3wSM2) { + ; /* SM2 hash requires public key. Done later. */ + } + else #endif { ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest, @@ -16027,6 +16136,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } #endif /* !NO_DSA && !HAVE_SELFTEST */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + #endif case ECDSAk: { word32 idx = 0; @@ -16478,9 +16590,50 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* !NO_DSA && !HAVE_SELFTEST */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + { + /* OpenSSL creates signature without CERT_SIG_ID. */ + ret = wc_ecc_sm2_create_digest(CERT_SIG_ID, 0, buf, bufSz, + WC_HASH_TYPE_SM3, sigCtx->digest, WC_SM3_DIGEST_SIZE, + sigCtx->key.ecc); + if (ret == 0) { + sigCtx->typeH = SM3h; + sigCtx->digestSz = WC_SM3_DIGEST_SIZE; + } + else { + WOLFSSL_MSG("SM2wSM3 create digest failed"); + WOLFSSL_ERROR_VERBOSE(ret); + goto exit_cs; + } + ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest, + sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc); + break; + } + #endif #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY) case ECDSAk: { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (sigOID == CTC_SM3wSM2) { + ret = wc_ecc_sm2_create_digest(CERT_SIG_ID, + CERT_SIG_ID_SZ, buf, bufSz, WC_HASH_TYPE_SM3, + sigCtx->digest, WC_SM3_DIGEST_SIZE, + sigCtx->key.ecc); + if (ret == 0) { + sigCtx->typeH = SM3h; + sigCtx->digestSz = WC_SM3_DIGEST_SIZE; + } + else { + WOLFSSL_MSG("SM2wSM3 create digest failed"); + WOLFSSL_ERROR_VERBOSE(ret); + goto exit_cs; + } + ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest, + sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc); + } + else + #endif #if defined(HAVE_PK_CALLBACKS) if (sigCtx->pkCbEcc) { ret = sigCtx->pkCbEcc( @@ -16666,6 +16819,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } #endif /* !NO_DSA && !HAVE_SELFTEST */ #ifdef HAVE_ECC + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + #endif case ECDSAk: { if (sigCtx->verify == 1) { @@ -18682,7 +18838,8 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert) cert->extAuthKeyIdSz = length; #endif /* OPENSSL_EXTRA */ - return GetHashId(input + idx, length, cert->extAuthKeyId); + return GetHashId(input + idx, length, cert->extAuthKeyId, + HashIdAlg(cert->signatureOID)); #else DECL_ASNGETDATA(dataASN, authKeyIdASN_Length); int ret = 0; @@ -18716,7 +18873,7 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert) /* Get the hash or hash of the hash if wrong size. */ ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data, (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length, - cert->extAuthKeyId); + cert->extAuthKeyId, HashIdAlg(cert->signatureOID)); } } @@ -18753,7 +18910,8 @@ static int DecodeSubjKeyId(const byte* input, word32 sz, DecodedCert* cert) #endif /* OPENSSL_EXTRA */ /* Get the hash or hash of the hash if wrong size. */ - ret = GetHashId(input + idx, length, cert->extSubjKeyId); + ret = GetHashId(input + idx, length, cert->extSubjKeyId, + HashIdAlg(cert->signatureOID)); } return ret; @@ -21322,6 +21480,7 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) * * @param [in] input Input data. * @param [in] maxIdx Maximum index for data. + * @param [in] sigOID Signature OID for determining hash algorithm. * @param [out] hash Hash of AKI. * @param [out] set Whether the hash buffer was set. * @param [in] heap Dynamic memory allocation hint. @@ -21330,8 +21489,8 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) * is invalid. * @return MEMORY_E on dynamic memory allocation failure. */ -static int GetAKIHash(const byte* input, word32 maxIdx, byte* hash, int* set, - void* heap) +static int GetAKIHash(const byte* input, word32 maxIdx, int sigOID, + byte* hash, int* set, void* heap) { /* AKI and Certificate Extenion ASN.1 templates are the same length. */ DECL_ASNGETDATA(dataASN, certExtASN_Length); @@ -21381,7 +21540,7 @@ static int GetAKIHash(const byte* input, word32 maxIdx, byte* hash, int* set, ret = GetHashId( dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data, dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length, - hash); + hash, sigOID); } break; } @@ -21646,7 +21805,7 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, /* Get the hash or hash of the hash if wrong * size. */ ret = GetHashId(cert + extIdx, extLen, - hash); + hash, HashIdAlg(signatureOID)); } } break; @@ -21668,14 +21827,16 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, if (extAuthKeyIdSet) ca = GetCA(cm, hash); if (ca == NULL) { - ret = CalcHashId(cert + issuerIdx, issuerSz, hash); + ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash, + HashIdAlg(signatureOID)); if (ret == 0) ca = GetCAByName(cm, hash); } } #else if (ret == 0 && pubKey == NULL) { - ret = CalcHashId(cert + issuerIdx, issuerSz, hash); + ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash, + HashIdAlg(signatureOID)); if (ret == 0) ca = GetCA(cm, hash); } @@ -21904,7 +22065,8 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, /* Find the AKI extension in list of extensions and get hash. */ if ((!req) && (akiData != NULL)) { /* TODO: test case */ - ret = GetAKIHash(akiData, akiLen, hash, &extAuthKeyIdSet, heap); + ret = GetAKIHash(akiData, akiLen, sigOID, hash, &extAuthKeyIdSet, + heap); } /* Get the CA by hash one was found. */ @@ -21915,7 +22077,7 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, #endif { /* Try hash of issuer name. */ - ret = CalcHashId(caName, caNameLen, hash); + ret = CalcHashId_ex(caName, caNameLen, hash, HashIdAlg(sigOID)); if (ret == 0) { ca = GetCAByName(cm, hash); } @@ -22391,8 +22553,16 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) #ifndef NO_SKID if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL && cert->pubKeySize > 0) { - ret = CalcHashId(cert->publicKey, cert->pubKeySize, - cert->extSubjKeyId); + if (cert->signatureOID == CTC_SM3wSM2) { + /* TODO: GmSSL creates IDs this way but whole public key info + * block should be hashed. */ + ret = CalcHashId_ex(cert->publicKey + cert->pubKeySize - 65, 65, + cert->extSubjKeyId, HashIdAlg(cert->signatureOID)); + } + else { + ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize, + cert->extSubjKeyId, HashIdAlg(cert->signatureOID)); + } if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); return ret; @@ -22412,7 +22582,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) cert->ca = GetCA(cm, cert->extSubjKeyId); } if (cert->ca != NULL && XMEMCMP(cert->issuerHash, - cert->ca->subjectNameHash, KEYID_SIZE) != 0) { + cert->ca->subjectNameHash, KEYID_SIZE) != 0) { cert->ca = NULL; } if (cert->ca == NULL) { @@ -22541,7 +22711,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) if (cert->ca) { /* Need the CA's public key hash for OCSP */ XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash, - KEYID_SIZE); + KEYID_SIZE); } } #endif /* HAVE_OCSP */ @@ -22560,7 +22730,8 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) return ret; } cert->sigCtx.CertAtt.certBegin = cert->certBegin; - } else if (cert->keyOID == ECDSAk) { + } + else if (cert->keyOID == ECDSAk) { cert->sigCtx.CertAtt.certBegin = cert->certBegin; } /* check if we can use TSIP for cert verification */ @@ -29992,12 +30163,22 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, /* Compute SKID by hashing public key */ if (kid_type == SKID_TYPE) { - ret = CalcHashId(buf, (word32)bufferSz, cert->skid); + int hashId = HashIdAlg(cert->sigType); + ret = CalcHashId_ex(buf, (word32)bufferSz, cert->skid, hashId); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + cert->skidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId)); + #else cert->skidSz = KEYID_SIZE; + #endif } else if (kid_type == AKID_TYPE) { - ret = CalcHashId(buf, (word32)bufferSz, cert->akid); + int hashId = HashIdAlg(cert->sigType); + ret = CalcHashId_ex(buf, (word32)bufferSz, cert->akid, hashId); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId)); + #else cert->akidSz = KEYID_SIZE; + #endif } else ret = BAD_FUNC_ARG; @@ -30231,9 +30412,14 @@ static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded) } else { - /* Put the SKID of CA to AKID of certificate */ - XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE); + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + cert->sigType))); + #else cert->akidSz = KEYID_SIZE; + #endif + /* Put the SKID of CA to AKID of certificate */ + XMEMCPY(cert->akid, decoded->extSubjKeyId, cert->akidSz); } return ret; @@ -31835,6 +32021,9 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) { /* ignore error, did not have pkcs8 header */ } + else { + curve_id = wc_ecc_get_oid(algId, NULL, NULL); + } if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; @@ -31944,7 +32133,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, byte version; int ret = 0; int curve_id = ECC_CURVE_DEF; -#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) +#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2) word32 algId = 0; #endif @@ -31953,11 +32142,14 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, ret = BAD_FUNC_ARG; } -#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) +#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2) /* if has pkcs8 header skip it */ if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) { /* ignore error, did not have pkcs8 header */ } + else { + curve_id = wc_ecc_get_oid(algId, NULL, NULL); + } #endif CALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap); @@ -32372,10 +32564,14 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, if (ret == 0) { /* Clear dynamic data for ECC public key. */ XMEMSET(dataASN, 0, sizeof(*dataASN) * eccPublicKeyASN_Length); +#if !defined(WOLFSSL_SM2) || !defined(WOLFSSL_SM3) /* Set required ECDSA OID and ignore the curve OID type. */ GetASN_ExpBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], keyEcdsaOid, sizeof(keyEcdsaOid)); - GetASN_OID(&dataASN[oidIdx], oidIgnoreType); +#else + GetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType); +#endif + GetASN_OID(&dataASN[oidIdx], oidCurveType); /* Decode the public ECC key. */ ret = GetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length, 1, input, inOutIdx, inSz); @@ -32389,7 +32585,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, /* Clear dynamic data for ECC private key. */ XMEMSET(dataASN, 0, sizeof(*dataASN) * eccKeyASN_Length); /* Check named curve OID type. */ - GetASN_OID(&dataASN[oidIdx], oidIgnoreType); + GetASN_OID(&dataASN[oidIdx], oidCurveType); /* Try private key format .*/ ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input, inOutIdx, inSz); @@ -32399,6 +32595,14 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, } } +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if ((ret == 0) && (oidIdx == ECCPUBLICKEYASN_IDX_ALGOID_CURVEID)) { + int oidSum = dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum; + if ((oidSum != ECDSAk) && (oidSum != SM2k)) { + ret = ASN_PARSE_E; + } + } +#endif if (ret == 0) { if (dataASN[oidIdx].tag != 0) { /* Named curve - check and get id. */ @@ -33872,6 +34076,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #else DECL_ASNGETDATA(dataASN, singleResponseASN_Length); int ret = 0; + word32 ocspDigestSize = OCSP_DIGEST_SIZE; CertStatus* cs = NULL; word32 serialSz; word32 issuerHashLen; @@ -33918,12 +34123,18 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, ret = GetASN_Items(singleResponseASN, dataASN, singleResponseASN_Length, 1, source, ioIndex, size); } + if (ret == 0) { + single->hashAlgoOID = + dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum; + ocspDigestSize = wc_HashGetDigestSize( + wc_OidGetHash(single->hashAlgoOID)); + } /* Validate the issuer hash length is the size required. */ - if ((ret == 0) && (issuerHashLen != OCSP_DIGEST_SIZE)) { + if ((ret == 0) && (issuerHashLen != ocspDigestSize)) { ret = ASN_PARSE_E; } /* Validate the issuer key hash length is the size required. */ - if ((ret == 0) && (issuerKeyHashLen != OCSP_DIGEST_SIZE)) { + if ((ret == 0) && (issuerKeyHashLen != ocspDigestSize)) { ret = ASN_PARSE_E; } if (ret == 0) { @@ -35147,17 +35358,20 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) byte extArray[MAX_OCSP_EXT_SZ]; word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz; int i, snSz; + int keyIdSz; WOLFSSL_ENTER("EncodeOcspRequest"); #ifdef NO_SHA algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0); + keyIdSz = WC_SHA256_DIGEST_SIZE; #else algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0); + keyIdSz = WC_SHA_DIGEST_SIZE; #endif - issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray); - issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray); + issuerSz = SetDigest(req->issuerHash, keyIdSz, issuerArray); + issuerKeySz = SetDigest(req->issuerKeyHash, keyIdSz, issuerKeyArray); snSz = SetSerialNumber(req->serial, req->serialSz, snArray, MAX_SN_SZ, MAX_SN_SZ); extSz = 0; @@ -35215,6 +35429,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) word32 extSz = 0; int sz = 0; int ret = 0; + int keyIdSz; WOLFSSL_ENTER("EncodeOcspRequest"); @@ -35225,16 +35440,18 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) #ifdef NO_SHA SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHA256h, oidHashType); + keyIdSz = WC_SHA256_DIGEST_SIZE; #else SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHAh, oidHashType); + keyIdSz = WC_SHA_DIGEST_SIZE; #endif /* Set issuer, issuer key hash and serial number of certificate being * checked. */ SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUER], - req->issuerHash, KEYID_SIZE); + req->issuerHash, keyIdSz); SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY], - req->issuerKeyHash, KEYID_SIZE); + req->issuerKeyHash, keyIdSz); SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_SERIAL], req->serial, req->serialSz); /* Only extension to write is nonce - check if one to encode. */ @@ -35377,6 +35594,7 @@ void FreeOcspRequest(OcspRequest* req) int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) { int cmp = -1; /* default as not matching, cmp gets set on each check */ + int ocspDigestSize; OcspEntry *single, *next, *prev = NULL, *top; WOLFSSL_ENTER("CompareOcspReqResp"); @@ -35412,11 +35630,17 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) /* match based on found status and return */ for (single = resp->single; single; single = next) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + ocspDigestSize = wc_HashGetDigestSize( + wc_OidGetHash(single->hashAlgoOID)); + #else + ocspDigestSize = OCSP_DIGEST_SIZE; + #endif cmp = req->serialSz - single->status->serialSz; if (cmp == 0) { cmp = XMEMCMP(req->serial, single->status->serial, req->serialSz) - || XMEMCMP(req->issuerHash, single->issuerHash, OCSP_DIGEST_SIZE) - || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash, OCSP_DIGEST_SIZE); + || XMEMCMP(req->issuerHash, single->issuerHash, ocspDigestSize) + || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash, ocspDigestSize); if (cmp == 0) { /* match found */ if (resp->single != single && prev) { @@ -35461,6 +35685,14 @@ enum { /* store WC_SHA hash of NAME */ int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) +{ + /* Use summy signature OID. */ + return GetNameHash_ex(source, idx, hash, maxIdx, 0); +} + +/* store WC_SHA hash of NAME */ +int GetNameHash_ex(const byte* source, word32* idx, byte* hash, int maxIdx, + int sigOID) { #ifndef WOLFSSL_ASN_TEMPLATE int length; /* length of all distinguished names */ @@ -35489,7 +35721,8 @@ int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) if (GetSequence(source, idx, &length, (word32)maxIdx) < 0) return ASN_PARSE_E; - ret = CalcHashId(source + dummy, (word32)length + *idx - dummy, hash); + ret = CalcHashId_ex(source + dummy, (word32)length + *idx - dummy, hash, + HashIdAlg(sigOID)); *idx += (word32)length; @@ -35509,10 +35742,10 @@ int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) * calculated over the entire DER encoding of the Name field, including * the tag and length. */ /* Calculate hash of complete name including SEQUENCE. */ - ret = CalcHashId( + ret = CalcHashId_ex( GetASNItem_Addr(dataASN[NAMEHASHASN_IDX_NAME], source), GetASNItem_Length(dataASN[NAMEHASHASN_IDX_NAME], source), - hash); + hash, HashIdAlg(sigOID)); } return ret; @@ -35827,7 +36060,7 @@ static int PaseCRL_CheckSignature(DecodedCRL* dcrl, const byte* buff, void* cm) } /* Check issuerHash matched CA's subjectNameHash. */ if ((ca != NULL) && (XMEMCMP(dcrl->issuerHash, ca->subjectNameHash, - KEYID_SIZE) != 0)) { + KEYID_SIZE) != 0)) { ca = NULL; } if (ca == NULL) { @@ -35899,7 +36132,7 @@ static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl, dcrl->issuer = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz); #endif - if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0) + if (GetNameHash_ex(buf, &idx, dcrl->issuerHash, sz, oid) < 0) return ASN_PARSE_E; if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) @@ -35989,7 +36222,8 @@ static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl) dcrl->extAuthKeyIdSet = 1; /* Get the hash or hash of the hash if wrong size. */ - ret = GetHashId(input + idx, length, dcrl->extAuthKeyId); + ret = GetHashId(input + idx, length, dcrl->extAuthKeyId, + HashIdAlg(dcrl->signatureOID)); return ret; #else @@ -36015,7 +36249,7 @@ static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl) /* Get the hash or hash of the hash if wrong size. */ ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data, dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length, - dcrl->extAuthKeyId); + dcrl->extAuthKeyId, HashIdAlg(dcrl->signatureOID)); } } @@ -36348,7 +36582,7 @@ int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz, ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */ } if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash, - KEYID_SIZE) != 0) { + KEYID_SIZE) != 0) { ca = NULL; } if (ca == NULL) { @@ -36474,9 +36708,10 @@ end: (int)dcrl->issuerSz); #endif /* Calculate the Hash id from the issuer name. */ - ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), + ret = CalcHashId_ex( + GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff), - dcrl->issuerHash); + dcrl->issuerHash, HashIdAlg(dcrl->signatureOID)); if (ret < 0) { ret = ASN_PARSE_E; } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index a837986ad..359bcee76 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -101,6 +101,7 @@ ECC Curve Types: * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off + * WOLFSSL_SM2 Enables SM2 curves default: off */ /* @@ -648,6 +649,21 @@ enum { #endif #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ #endif /* HAVE_ECC_BRAINPOOL */ + #ifdef WOLFSSL_SM2 + #ifdef HAVE_OID_ENCODING + #define CODED_SM2P256V1 {1,2,156,10197,1,301} + #define CODED_SM2P256V1_SZ 6 + #else + #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d} + #define CODED_SM2P256V1_SZ 8 + #endif + #ifndef WOLFSSL_ECC_CURVE_STATIC + static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1; + #else + #define ecc_oid_sm2p256v1 CODED_SM2P256V1 + #endif + #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ + #endif /* WOLFSSL_SM2 */ #endif /* ECC256 */ #ifdef ECC320 #ifdef HAVE_ECC_BRAINPOOL @@ -1128,6 +1144,25 @@ const ecc_set_type ecc_sets[] = { 1, /* cofactor */ }, #endif /* HAVE_ECC_BRAINPOOL */ + #ifdef WOLFSSL_SM2 + { + 32, /* size/bytes */ + ECC_SM2P256V1, /* ID */ + "SM2P256V1", /* curve name */ + + /* bottom of draft-shen-sm2-ecdsa-02, recommended values */ + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */ + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */ + "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */ + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */ + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */ + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */ + ecc_oid_sm2p256v1, /* oid/oidSz */ + ecc_oid_sm2p256v1_sz, + ECC_SM2P256V1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* WOLFSSL_SM2 */ #endif /* ECC256 */ #ifdef ECC320 #ifdef HAVE_ECC_BRAINPOOL @@ -2109,6 +2144,12 @@ done: #ifndef WOLFSSL_SP_NO_256 if (modBits == 256) { + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, + Q->z, R->x, R->y, R->z); + } + #endif return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z, R->x, R->y, R->z); } @@ -2473,6 +2514,12 @@ static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, #ifndef WOLFSSL_SP_NO_256 if (modBits == 256) { + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, + R->z); + } + #endif return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z); } #endif @@ -2725,6 +2772,11 @@ done: #ifndef WOLFSSL_SP_NO_256 if (mp_count_bits(modulus) == 256) { + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + return sp_ecc_map_sm2_256(P->x, P->y, P->z); + } + #endif return sp_ecc_map_256(P->x, P->y, P->z); } #endif @@ -2906,21 +2958,11 @@ static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R, #else static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus, - mp_digit mp, mp_int* tx, mp_int* ty) + mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu) { int err = MP_OKAY; - DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE); - NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC); -#ifdef MP_INT_SIZE_CHECK_NULL - if (mu == NULL) - err = MEMORY_E; -#endif - - if (err == MP_OKAY) - err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus)); - if (err == MP_OKAY) - err = mp_montgomery_calc_normalization(mu, modulus); + err = mp_montgomery_calc_normalization(mu, modulus); /* Generate random value to multiply into p->z. */ if (err == MP_OKAY) err = wc_ecc_gen_k(rng, size, ty, modulus); @@ -2953,9 +2995,6 @@ static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus, if (err == MP_OKAY) err = mp_montgomery_reduce(p->y, modulus, mp); - mp_clear(mu); - FREE_MP_INT_SIZE(mu, NULL, DYNAMIC_TYPE_ECC); - return err; } @@ -2993,9 +3032,23 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, #ifndef WC_NO_CACHE_RESISTANT /* First bit always 1 (fix at end) and swap equals first bit */ int swap = 1; +#ifdef WOLFSSL_SMALL_STACK + mp_int* tmp = NULL; +#else + mp_int tmp[1]; +#endif #endif int infinity; +#ifdef WOLFSSL_SMALL_STACK + tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } +#endif + if (err == MP_OKAY) + err = mp_init(tmp); + /* Step 1: R[0] = P; R[1] = P */ /* R[0] = P */ if (err == MP_OKAY) @@ -3015,9 +3068,9 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, /* Randomize z ordinates to obfuscate timing. */ if ((err == MP_OKAY) && (rng != NULL)) - err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y); + err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt); if ((err == MP_OKAY) && (rng != NULL)) - err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y); + err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt); if (err == MP_OKAY) { /* Order could be one greater than the size of the modulus. */ @@ -3050,12 +3103,18 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, #else /* Swap R[0] and R[1] if other index is needed. */ swap ^= (int)b; - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->x, R[1]->x, (int)modulus->used, swap); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->y, R[1]->y, (int)modulus->used, swap); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->z, R[1]->z, (int)modulus->used, swap); + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap, + tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap, + tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap, + tmp); + } swap = (int)b; if (err == MP_OKAY) @@ -3070,12 +3129,18 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, #ifndef WC_NO_CACHE_RESISTANT /* Swap back if last bit is 0. */ swap ^= 1; - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->x, R[1]->x, (int)modulus->used, swap); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->y, R[1]->y, (int)modulus->used, swap); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->z, R[1]->z, (int)modulus->used, swap); + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap, + tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap, + tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap, + tmp); + } #endif /* Step 5: b = k[0]; R[b] = R[b] - P */ @@ -3094,21 +3159,32 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, &infinity); #else /* Swap R[0] and R[1], if necessary, to operate on the one we want. */ - err = mp_cond_swap_ct(R[0]->x, R[1]->x, (int)modulus->used, (int)b); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->y, R[1]->y, (int)modulus->used, (int)b); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->z, R[1]->z, (int)modulus->used, (int)b); + err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b, + tmp); + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, + (int)b, tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, + (int)b, tmp); + } if (err == MP_OKAY) err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus, mp, &infinity); /* Swap back if necessary. */ - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->x, R[1]->x, (int)modulus->used, (int)b); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->y, R[1]->y, (int)modulus->used, (int)b); - if (err == MP_OKAY) - err = mp_cond_swap_ct(R[0]->z, R[1]->z, (int)modulus->used, (int)b); + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, + (int)b, tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, + (int)b, tmp); + } + if (err == MP_OKAY) { + err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, + (int)b, tmp); + } #endif } @@ -3120,6 +3196,10 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, if (err == MP_OKAY) err = mp_copy(R[0]->z, Q->z); +#ifdef WOLFSSL_SMALL_STACK + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); +#endif + return err; } @@ -3211,10 +3291,10 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, /* Randomize z ordinates to obfuscate timing. */ if ((err == MP_OKAY) && (rng != NULL)) err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x, - R[TMP_IDX]->y); + R[TMP_IDX]->y, kt); if ((err == MP_OKAY) && (rng != NULL)) err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x, - R[TMP_IDX]->y); + R[TMP_IDX]->y, kt); if (err == MP_OKAY) { /* Order could be one greater than the size of the modulus. */ @@ -3597,6 +3677,11 @@ exit: #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 if (mp_count_bits(modulus) == 256) { + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + return sp_ecc_mulmod_sm2_256(k, G, R, map, heap); + } + #endif return sp_ecc_mulmod_256(k, G, R, map, heap); } #endif @@ -4585,6 +4670,14 @@ int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, #endif /* !WC_ECC_NONBLOCK */ } else +#ifdef WOLFSSL_SM2 + if (private_key->idx != ECC_CUSTOM_IDX && + ecc_sets[private_key->idx].id == ECC_SM2P256V1) { + err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen, + private_key->heap); + } + else +#endif #endif /* ! WOLFSSL_SP_NO_256 */ #ifdef WOLFSSL_SP_384 if (private_key->idx != ECC_CUSTOM_IDX && @@ -5169,7 +5262,13 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve, err = sp_ecc_mulmod_base_256(key->k, pub, 1, key->heap); } else +#ifdef WOLFSSL_SM2 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) { + err = sp_ecc_mulmod_base_sm2_256(&key->k, pub, 1, key->heap); + } + else #endif +#endif /* WOLFSSL_SP_NO_256 */ #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { err = sp_ecc_mulmod_base_384(key->k, pub, 1, key->heap); @@ -5545,6 +5644,15 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, } } else +#ifdef WOLFSSL_SM2 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) { + err = sp_ecc_make_key_sm2_256(rng, &key->k, &key->pubkey, key->heap); + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + } + } + else +#endif #endif /* !WOLFSSL_SP_NO_256 */ #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { @@ -6753,6 +6861,12 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng, } #endif } + #ifdef WOLFSSL_SM2 + if (ecc_sets[key->idx].id == ECC_SM2P256V1) { + return sp_ecc_sign_sm2_256(in, inlen, rng, &key->k, r, s, sign_k, + key->heap); + } + #endif #endif #ifdef WOLFSSL_SP_384 if (ecc_sets[key->idx].id == ECC_SECP384R1) { @@ -8319,6 +8433,21 @@ static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash, } #endif } + #ifdef WOLFSSL_SM2 + if (ecc_sets[key->idx].id == ECC_SM2P256V1) { + #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD) + return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x, + key->pubkey.y, key->pubkey.z, r, s, res, + sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1, + key->fpIdx, key->fpBuild, key->heap), + key->heap); + #endif + #if !defined(FP_ECC_CONTROL) + return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x, + key->pubkey.y, key->pubkey.z, r, s, res, key->heap); + #endif + } + #endif #endif #ifdef WOLFSSL_SP_384 if (ecc_sets[key->idx].id == ECC_SECP384R1) { @@ -8942,6 +9071,13 @@ int wc_ecc_import_point_der_ex(const byte* in, word32 inLen, err = sp_ecc_uncompress_256(point->x, pointType, point->y); } else + #ifdef WOLFSSL_SM2 + if (curve_idx != ECC_CUSTOM_IDX && + ecc_sets[curve_idx->idx].id == ECC_SM2P256V1) { + sp_ecc_uncompress_sm2_256(point->x, pointType, point->y); + } + else + #endif #endif #ifdef WOLFSSL_SP_384 if (curve_idx != ECC_CUSTOM_IDX && @@ -9490,6 +9626,11 @@ static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 if (mp_count_bits(prime) == 256) { + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(prime, 224)) { + return sp_ecc_is_point_sm2_256(ecp->x, ecp->y); + } + #endif return sp_ecc_is_point_256(ecp->x, ecp->y); } #endif @@ -9582,6 +9723,14 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) } } else + #ifdef WOLFSSL_SM2 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) { + if (err == MP_OKAY) { + err = sp_ecc_mulmod_base_sm2_256(&key->k, res, 1, key->heap); + } + } + else + #endif #endif #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { @@ -9815,6 +9964,13 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap); } else + #ifdef WOLFSSL_SM2 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SM2P256V1) { + err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap); + } + else + #endif #endif #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && @@ -9920,6 +10076,12 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap); } +#ifdef WOLFSSL_SM2 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) { + return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y + key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap); + } +#endif #endif #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { @@ -10300,6 +10462,12 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, key->pubkey.y); } else + #ifdef WOLFSSL_SM2 + if (key->dp->id == ECC_SM2P256V1) { + sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y); + } + else + #endif #endif #ifdef WOLFSSL_SP_384 if (key->dp->id == ECC_SECP384R1) { @@ -12861,7 +13029,15 @@ int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, if (mp_count_bits(modulus) == 256) { int ret; SAVE_VECTOR_REGISTERS(return _svr_ret); - ret = sp_ecc_mulmod_256(k, G, R, map, heap); + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap); + } + else + #endif + { + ret = sp_ecc_mulmod_256(k, G, R, map, heap); + } RESTORE_VECTOR_REGISTERS(); return ret; } @@ -13030,7 +13206,15 @@ int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, if (mp_count_bits(modulus) == 256) { int ret; SAVE_VECTOR_REGISTERS(return _svr_ret); - ret = sp_ecc_mulmod_256(k, G, R, map, heap); + #ifdef WOLFSSL_SM2 + if (!mp_is_bit_set(modulus, 224)) { + ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap); + } + else + #endif + { + ret = sp_ecc_mulmod_256(k, G, R, map, heap); + } RESTORE_VECTOR_REGISTERS(); return ret; } diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 27bf65389..80b3469ad 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -589,6 +589,12 @@ const char* wc_GetErrorString(int error) case ASN_LEN_E: return "ASN.1 length invalid"; + case SM4_GCM_AUTH_E: + return "SM4-GCM Authentication check fail"; + + case SM4_CCM_AUTH_E: + return "SM4-CCM Authentication check fail"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 0925c9244..390bc0191 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -101,6 +101,9 @@ static const struct s_ent { #ifndef WOLFSSL_NOSHA3_512 {WC_HASH_TYPE_SHA3_512, NID_sha3_512, "SHA3_512"}, #endif +#ifdef WOLFSSL_SM3 + {WC_HASH_TYPE_SM3, NID_sm3, "SM3"}, +#endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 {WC_HASH_TYPE_BLAKE2B, NID_blake2b512, "BLAKE2B512"}, #endif @@ -254,6 +257,22 @@ static const struct s_ent { static const char EVP_CHACHA20[] = "CHACHA20"; #endif +#ifdef WOLFSSL_SM4_ECB + static const char EVP_SM4_ECB[] = "SM4-ECB"; +#endif /* WOLFSSL_SM4_ECB */ +#ifdef WOLFSSL_SM4_CBC + static const char EVP_SM4_CBC[] = "SM4-CBC"; +#endif /* WOLFSSL_SM4_CBC */ +#ifdef WOLFSSL_SM4_CTR + static const char EVP_SM4_CTR[] = "SM4-CTR"; +#endif /* WOLFSSL_SM4_CTR */ +#ifdef WOLFSSL_SM4_GCM + static const char EVP_SM4_GCM[] = "SM4-GCM"; +#endif /* WOLFSSL_SM4_GCM */ +#ifdef WOLFSSL_SM4_CCM + static const char EVP_SM4_CCM[] = "SM4-CCM"; +#endif /* WOLFSSL_SM4_CCM */ + static const char EVP_NULL[] = "NULL"; #define EVP_CIPHER_TYPE_MATCHES(x, y) (XSTRCMP(x,y) == 0) @@ -342,6 +361,21 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c) #endif #ifdef HAVE_CHACHA case CHACHA20_TYPE: return CHACHA_MAX_KEY_SZ; + #endif + #ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: return 16; + #endif + #ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: return 16; + #endif + #ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: return 16; + #endif + #ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: return 16; + #endif + #ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: return 16; #endif default: return 0; @@ -628,8 +662,30 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, #ifndef NO_RC4 case ARC4_TYPE: wc_Arc4Process(&ctx->cipher.arc4, out, in, inl); - break; + break; #endif +#if defined(WOLFSSL_SM4_ECB) + case SM4_ECB_TYPE: + if (ctx->enc) + wc_Sm4EcbEncrypt(&ctx->cipher.sm4, out, in, inl); + else + wc_Sm4EcbDecrypt(&ctx->cipher.sm4, out, in, inl); + break; +#endif +#if defined(WOLFSSL_SM4_CBC) + case SM4_CBC_TYPE: + if (ctx->enc) + wc_Sm4CbcEncrypt(&ctx->cipher.sm4, out, in, inl); + else + wc_Sm4CbcDecrypt(&ctx->cipher.sm4, out, in, inl); + break; +#endif +#if defined(WOLFSSL_SM4_CTR) + case SM4_CTR_TYPE: + wc_Sm4CtrEncrypt(&ctx->cipher.sm4, out, in, inl); + break; +#endif + default: ret = WOLFSSL_FAILURE; } @@ -641,8 +697,8 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } -#if defined(HAVE_AESGCM) -#ifndef WOLFSSL_AESGCM_STREAM +#if defined(HAVE_AESGCM) || defined(WOLFSSL_SM4_GCM) +#if defined(WOLFSSL_SM4_GCM) || !defined(WOLFSSL_AESGCM_STREAM) static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int inl) { if (in && inl > 0) { @@ -666,76 +722,87 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { -#ifndef WOLFSSL_AESGCM_STREAM - int ret = 0; +#if defined(WOLFSSL_SM4_GCM) || !defined(WOLFSSL_AESGCM_STREAM) +#if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_AESGCM_STREAM) + if (ctx->cipherType == SM4_GCM_TYPE) +#endif + { + int ret = 0; - *outl = inl; - if (out) { - /* Buffer input for one-shot API */ - if (inl > 0) { - byte* tmp; - tmp = (byte*)XREALLOC(ctx->authBuffer, - ctx->authBufferLen + inl, NULL, - DYNAMIC_TYPE_OPENSSL); - if (tmp) { - XMEMCPY(tmp + ctx->authBufferLen, in, inl); - ctx->authBufferLen += inl; - ctx->authBuffer = tmp; - *outl = 0; + *outl = inl; + if (out) { + /* Buffer input for one-shot API */ + if (inl > 0) { + byte* tmp; + tmp = (byte*)XREALLOC(ctx->authBuffer, + ctx->authBufferLen + inl, NULL, + DYNAMIC_TYPE_OPENSSL); + if (tmp) { + XMEMCPY(tmp + ctx->authBufferLen, in, inl); + ctx->authBufferLen += inl; + ctx->authBuffer = tmp; + *outl = 0; + } + else { + ret = MEMORY_E; + } + } + } + else { + ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, in, inl); + } + + if (ret != 0) { + *outl = 0; + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; + } +#endif +#if defined(WOLFSSL_SM4_GCM) && defined(WOLFSSL_AESGCM_STREAM) + else +#endif +#if defined(WOLFSSL_AESGCM_STREAM) + { + int ret; + + /* When out is NULL then this is AAD. */ + if (out == NULL) { + if (ctx->enc) { + ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, + in, inl); } else { - ret = MEMORY_E; + ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, + in, inl); } } - } - else { - ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, in, inl); - } - - if (ret != 0) { - *outl = 0; - return WOLFSSL_FAILURE; - } - - return WOLFSSL_SUCCESS; -#else - int ret; - - /* When out is NULL then this is AAD. */ - if (out == NULL) { - if (ctx->enc) { - ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in, - inl); + /* When out is not NULL then this is plaintext/cipher text. */ + else { + if (ctx->enc) { + ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, out, in, inl, + NULL, 0); + } + else { + ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, out, in, inl, + NULL, 0); + } + } + *outl = inl; + if (ret == 0) { + ret = WOLFSSL_SUCCESS; } else { - ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in, - inl); + ret = WOLFSSL_FAILURE; } + return ret; } - /* When out is not NULL then this is plaintext/cipher text. */ - else { - if (ctx->enc) { - ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, out, in, inl, NULL, - 0); - } - else { - ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, out, in, inl, NULL, - 0); - } - } - *outl = inl; - if (ret == 0) { - ret = WOLFSSL_SUCCESS; - } - else { - ret = WOLFSSL_FAILURE; - } - return ret; #endif /* WOLFSSL_AESGCM_STREAM */ } -#endif /* HAVE_AESGCM */ +#endif /* HAVE_AESGCM || WOLFSSL_SM4_GCM */ -#if defined(HAVE_AESCCM) +#if defined(HAVE_AESCCM) || defined(WOLFSSL_SM4_CCM) static int wolfSSL_EVP_CipherUpdate_CCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int inl) { if (in && inl > 0) { @@ -790,7 +857,7 @@ static int wolfSSL_EVP_CipherUpdate_CCM(WOLFSSL_EVP_CIPHER_CTX *ctx, return WOLFSSL_SUCCESS; } -#endif /* HAVE_AESCCM */ +#endif /* HAVE_AESCCM || WOLFSSL_SM4_CCM */ /* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, @@ -866,6 +933,17 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, } *outl = inl; return WOLFSSL_SUCCESS; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + /* if out == NULL, in/inl contains the additional auth data */ + return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl); +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + /* if out == NULL, in/inl contains the + * additional auth data */ + return wolfSSL_EVP_CipherUpdate_CCM(ctx, out, outl, in, inl); #endif default: /* fall-through */ @@ -990,9 +1068,9 @@ static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff) return ctx->block_size - n; } -#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \ - ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ - || FIPS_VERSION_GE(2,0)) +#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \ + ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || FIPS_VERSION_GE(2,0)) static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) { int i; @@ -1001,8 +1079,7 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) break; } } -#endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) || - * HAVE_FIPS_VERSION >= 2 */ +#endif int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) @@ -1047,8 +1124,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, ctx->authBufferLen = 0; if (ctx->authIncIv) { - IncCtr((byte*)ctx->cipher.aes.reg, - ctx->cipher.aes.nonceSz); + IncCtr((byte*)ctx->cipher.aes.reg, ctx->cipher.aes.nonceSz); ctx->authIncIv = 0; } } @@ -1132,8 +1208,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, ctx->authBufferLen = 0; if (ctx->authIncIv) { - IncCtr((byte*)ctx->cipher.aes.reg, - ctx->cipher.aes.nonceSz); + IncCtr((byte*)ctx->cipher.aes.reg, ctx->cipher.aes.nonceSz); ctx->authIncIv = 0; } } @@ -1167,6 +1242,109 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, *outl = 0; return WOLFSSL_SUCCESS; } + break; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + if ((ctx->authBuffer && ctx->authBufferLen > 0) || + (ctx->authBufferLen == 0)) { + if (ctx->enc) + ret = wc_Sm4GcmEncrypt(&ctx->cipher.sm4, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + ctx->authIn, ctx->authInSz); + else + ret = wc_Sm4GcmDecrypt(&ctx->cipher.sm4, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + ctx->authIn, ctx->authInSz); + + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + *outl = ctx->authBufferLen; + } + else { + ret = WOLFSSL_FAILURE; + *outl = 0; + } + + XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authBuffer = NULL; + ctx->authBufferLen = 0; + + if (ctx->authIncIv) { + IncCtr((byte*)ctx->cipher.sm4.iv, ctx->cipher.sm4.nonceSz); + ctx->authIncIv = 0; + } + } + else { + *outl = 0; + } + if (ret == WOLFSSL_SUCCESS) { + if (ctx->authIncIv) { + ctx->authIncIv = 0; + } + else { + /* Clear IV, since IV reuse is not recommended for SM4 GCM. + */ + XMEMSET(ctx->iv, 0, SM4_BLOCK_SIZE); + } + if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { + ret = WOLFSSL_FAILURE; + } + } + break; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + if ((ctx->authBuffer && ctx->authBufferLen > 0) || + (ctx->authBufferLen == 0)) { + if (ctx->enc) + ret = wc_Sm4CcmEncrypt(&ctx->cipher.sm4, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + ctx->authIn, ctx->authInSz); + else + ret = wc_Sm4CcmDecrypt(&ctx->cipher.sm4, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + ctx->authIn, ctx->authInSz); + + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + *outl = ctx->authBufferLen; + } + else { + ret = WOLFSSL_FAILURE; + *outl = 0; + } + + XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authBuffer = NULL; + ctx->authBufferLen = 0; + + if (ctx->authIncIv) { + IncCtr((byte*)ctx->cipher.sm4.iv, ctx->cipher.sm4.nonceSz); + ctx->authIncIv = 0; + } + } + else { + *outl = 0; + } + if (ret == WOLFSSL_SUCCESS) { + if (ctx->authIncIv) { + ctx->authIncIv = 0; + } + else { + /* Clear IV, since IV reuse is not recommended + * for SM4 CCM. */ + XMEMSET(ctx->iv, 0, SM4_BLOCK_SIZE); + } + if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { + ret = WOLFSSL_FAILURE; + } + } + break; #endif default: if (!out) @@ -1230,7 +1408,8 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, } if (ret == WOLFSSL_SUCCESS) { -#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \ +#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \ ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ || FIPS_VERSION_GE(2,0)) byte tmp = 0; @@ -1250,6 +1429,12 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, || ctx->cipherType == AES_128_CCM_TYPE || ctx->cipherType == AES_192_CCM_TYPE || ctx->cipherType == AES_256_CCM_TYPE + #endif + #ifdef WOLFSSL_SM4_GCM + || ctx->cipherType == SM4_GCM_TYPE + #endif + #ifdef WOLFSSL_SM4_CCM + || ctx->cipherType == SM4_CCM_TYPE #endif ) { tmp = ctx->authIvGenEnable; @@ -1259,9 +1444,9 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, /* reset cipher state after final */ ret = wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1); -#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \ - ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \ - || FIPS_VERSION_GE(2,0)) +#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \ + ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || FIPS_VERSION_GE(2,0)) if (FALSE #ifdef HAVE_AESGCM || ctx->cipherType == AES_128_GCM_TYPE || @@ -1272,6 +1457,12 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, || ctx->cipherType == AES_128_CCM_TYPE || ctx->cipherType == AES_192_CCM_TYPE || ctx->cipherType == AES_256_CCM_TYPE + #endif + #ifdef WOLFSSL_SM4_GCM + || ctx->cipherType == SM4_GCM_TYPE + #endif + #ifdef WOLFSSL_SM4_CCM + || ctx->cipherType == SM4_CCM_TYPE #endif ) { ctx->authIvGenEnable = tmp; @@ -1336,7 +1527,7 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) { if (ctx == NULL) return BAD_FUNC_ARG; switch (ctx->cipherType) { -#if !defined(NO_AES) || !defined(NO_DES3) +#if !defined(NO_AES) || !defined(NO_DES3) || defined(WOLFSSL_SM4) #if !defined(NO_AES) #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) case AES_128_CBC_TYPE: @@ -1388,9 +1579,24 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) case DES_ECB_TYPE: case DES_EDE3_CBC_TYPE: case DES_EDE3_ECB_TYPE: +#endif +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: +#endif +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: #endif return ctx->block_size; -#endif /* !NO_AES || !NO_DES3 */ +#endif /* !NO_AES || !NO_DES3 || WOLFSSL_SM4 */ default: return 0; } @@ -1561,94 +1767,138 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) return CHACHA20_TYPE; #endif +#ifdef WOLFSSL_SM4_ECB + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_SM4_ECB)) + return SM4_ECB_TYPE; +#endif +#ifdef WOLFSSL_SM4_CBC + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_SM4_CBC)) + return SM4_CBC_TYPE; +#endif +#ifdef WOLFSSL_SM4_CTR + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_SM4_CTR)) + return SM4_CTR_TYPE; +#endif +#ifdef WOLFSSL_SM4_GCM + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_SM4_GCM)) + return SM4_GCM_TYPE; +#endif +#ifdef WOLFSSL_SM4_CCM + else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_SM4_CCM)) + return SM4_CCM_TYPE; +#endif + else return 0; } int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) { - if (cipher == NULL) return BAD_FUNC_ARG; - switch (cipherType(cipher)) { -#if !defined(NO_AES) - #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) - case AES_128_CBC_TYPE: - case AES_192_CBC_TYPE: - case AES_256_CBC_TYPE: - return AES_BLOCK_SIZE; - #endif - #if defined(HAVE_AESGCM) - case AES_128_GCM_TYPE: - case AES_192_GCM_TYPE: - case AES_256_GCM_TYPE: - return 1; - #endif - #if defined(HAVE_AESCCM) - case AES_128_CCM_TYPE: - case AES_192_CCM_TYPE: - case AES_256_CCM_TYPE: - return 1; - #endif - #if defined(WOLFSSL_AES_COUNTER) - case AES_128_CTR_TYPE: - case AES_192_CTR_TYPE: - case AES_256_CTR_TYPE: - return 1; - #endif - #if defined(HAVE_AES_ECB) - case AES_128_ECB_TYPE: - case AES_192_ECB_TYPE: - case AES_256_ECB_TYPE: - return AES_BLOCK_SIZE; - #endif - #if defined(WOLFSSL_AES_CFB) - case AES_128_CFB1_TYPE: - case AES_192_CFB1_TYPE: - case AES_256_CFB1_TYPE: - case AES_128_CFB8_TYPE: - case AES_192_CFB8_TYPE: - case AES_256_CFB8_TYPE: - case AES_128_CFB128_TYPE: - case AES_192_CFB128_TYPE: - case AES_256_CFB128_TYPE: - return 1; - #endif - #if defined(WOLFSSL_AES_OFB) - case AES_128_OFB_TYPE: - case AES_192_OFB_TYPE: - case AES_256_OFB_TYPE: - return 1; - #endif - #if defined(WOLFSSL_AES_XTS) - case AES_128_XTS_TYPE: - case AES_256_XTS_TYPE: - return 1; - #endif -#endif /* NO_AES */ + if (cipher == NULL) + return BAD_FUNC_ARG; -#ifndef NO_RC4 - case ARC4_TYPE: - return 1; -#endif + switch (cipherType(cipher)) { +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + case AES_128_CBC_TYPE: + case AES_192_CBC_TYPE: + case AES_256_CBC_TYPE: + return AES_BLOCK_SIZE; + #endif + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: + return 1; + #endif + #if defined(HAVE_AESCCM) + case AES_128_CCM_TYPE: + case AES_192_CCM_TYPE: + case AES_256_CCM_TYPE: + return 1; + #endif + #if defined(WOLFSSL_AES_COUNTER) + case AES_128_CTR_TYPE: + case AES_192_CTR_TYPE: + case AES_256_CTR_TYPE: + return 1; + #endif + #if defined(HAVE_AES_ECB) + case AES_128_ECB_TYPE: + case AES_192_ECB_TYPE: + case AES_256_ECB_TYPE: + return AES_BLOCK_SIZE; + #endif + #if defined(WOLFSSL_AES_CFB) + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: + return 1; + #endif + #if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: + return 1; + #endif + #if defined(WOLFSSL_AES_XTS) + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: + return 1; + #endif + #endif /* NO_AES */ + + #ifndef NO_RC4 + case ARC4_TYPE: + return 1; + #endif #ifndef NO_DES3 - case DES_CBC_TYPE: return 8; - case DES_EDE3_CBC_TYPE: return 8; - case DES_ECB_TYPE: return 8; - case DES_EDE3_ECB_TYPE: return 8; + case DES_CBC_TYPE: return 8; + case DES_EDE3_CBC_TYPE: return 8; + case DES_ECB_TYPE: return 8; + case DES_EDE3_ECB_TYPE: return 8; #endif #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) - case CHACHA20_POLY1305_TYPE: - return 1; + case CHACHA20_POLY1305_TYPE: + return 1; #endif #ifdef HAVE_CHACHA - case CHACHA20_TYPE: - return 1; + case CHACHA20_TYPE: + return 1; #endif - default: - return 0; - } +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + return 1; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + return 1; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + return 1; +#endif + + default: + return 0; + } } unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) @@ -1729,16 +1979,39 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) #ifdef HAVE_CHACHA case CHACHA20_TYPE: return WOLFSSL_EVP_CIPH_STREAM_CIPHER; + #endif + #ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + return WOLFSSL_EVP_CIPH_ECB_MODE; + #endif + #ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + return WOLFSSL_EVP_CIPH_CBC_MODE; + #endif + #ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + return WOLFSSL_EVP_CIPH_CTR_MODE; + #endif + #ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + return WOLFSSL_EVP_CIPH_GCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + #endif + #ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + return WOLFSSL_EVP_CIPH_CCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; #endif default: return 0; - } + } } unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) { - if (cipher == NULL) return 0; - return WOLFSSL_CIPHER_mode(cipher) & WOLFSSL_EVP_CIPH_MODE; + if (cipher == NULL) + return 0; + return WOLFSSL_CIPHER_mode(cipher) & WOLFSSL_EVP_CIPH_MODE; } void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags) @@ -1757,20 +2030,23 @@ void wolfSSL_EVP_CIPHER_CTX_clear_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags) unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher) { - if (cipher == NULL) return 0; - return WOLFSSL_CIPHER_mode(cipher); + if (cipher == NULL) + return 0; + return WOLFSSL_CIPHER_mode(cipher); } -int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, int padding) +int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, + int padding) { - if (ctx == NULL) return BAD_FUNC_ARG; - if (padding) { - ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING; - } - else { - ctx->flags |= WOLFSSL_EVP_CIPH_NO_PADDING; - } - return 1; + if (ctx == NULL) + return BAD_FUNC_ARG; + if (padding) { + ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING; + } + else { + ctx->flags |= WOLFSSL_EVP_CIPH_NO_PADDING; + } + return 1; } int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest) @@ -1793,9 +2069,9 @@ int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx) { if (ctx == NULL) #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L - return; + return; #else - return 0; + return 0; #endif WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_free"); if (ctx->pkey != NULL) @@ -3738,6 +4014,11 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, } else #endif #endif + #ifdef WOLFSSL_SM3 + if (XSTRCMP(type, "SM3") == 0) { + hashType = WC_SM3; + } else + #endif #ifndef NO_MD5 if (XSTRCMP(type, "MD5") == 0) { hashType = WC_MD5; @@ -3890,6 +4171,12 @@ static int wolfssl_mac_len(unsigned char macType) #endif #endif + #ifdef WOLFSSL_SM3 + case WC_SM3: + hashLen = WC_SM3_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SM3 */ + default: hashLen = 0; } @@ -4451,6 +4738,22 @@ static const struct cipher{ {CHACHA20_TYPE, EVP_CHACHA20, NID_chacha20}, #endif +#ifdef WOLFSSL_SM4_ECB + {SM4_ECB_TYPE, EVP_SM4_ECB, NID_sm4_ecb}, +#endif +#ifdef WOLFSSL_SM4_CBC + {SM4_CBC_TYPE, EVP_SM4_CBC, NID_sm4_cbc}, +#endif +#ifdef WOLFSSL_SM4_CTR + {SM4_CTR_TYPE, EVP_SM4_CTR, NID_sm4_ctr}, +#endif +#ifdef WOLFSSL_SM4_GCM + {SM4_GCM_TYPE, EVP_SM4_GCM, NID_sm4_gcm}, +#endif +#ifdef WOLFSSL_SM4_CCM + {SM4_CCM_TYPE, EVP_SM4_CCM, NID_sm4_ccm}, +#endif + { 0, NULL, 0} }; @@ -4559,6 +4862,22 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name) #endif #endif #endif +#ifdef WOLFSSL_SM4_EBC + {EVP_SM4_ECB, "sm4-ecb"}, +#endif +#ifdef WOLFSSL_SM4_CBC + {EVP_SM4_CBC, "sm4"}, + {EVP_SM4_CBC, "sm4-cbc"}, +#endif +#ifdef WOLFSSL_SM4_CTR + {EVP_SM4_CTR, "sm4-ctr"}, +#endif +#ifdef WOLFSSL_SM4_GCM + {EVP_SM4_GCM, "sm4-gcm"}, +#endif +#ifdef WOLFSSL_SM4_CCM + {EVP_SM4_CCM, "sm4-ccm"}, +#endif #ifndef NO_RC4 {EVP_ARC4, "RC4"}, #endif @@ -4705,6 +5024,27 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) return wolfSSL_EVP_chacha20(); #endif +#ifdef WOLFSSL_SM4_ECB + case NID_sm4_ecb: + return wolfSSL_EVP_sm4_ecb(); +#endif +#ifdef WOLFSSL_SM4_CBC + case NID_sm4_cbc: + return wolfSSL_EVP_sm4_cbc(); +#endif +#ifdef WOLFSSL_SM4_CTR + case NID_sm4_ctr: + return wolfSSL_EVP_sm4_ctr(); +#endif +#ifdef WOLFSSL_SM4_GCM + case NID_sm4_gcm: + return wolfSSL_EVP_sm4_gcm(); +#endif +#ifdef WOLFSSL_SM4_CCM + case NID_sm4_ccm: + return wolfSSL_EVP_sm4_ccm(); +#endif + default: WOLFSSL_MSG("Bad cipher id value"); } @@ -4836,6 +5176,12 @@ void wolfSSL_EVP_init(void) ret = NOT_COMPILED_IN; #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Copy(&src->hash.digest.sm3, + &des->hash.digest.sm3); + break; + #endif case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD4: @@ -5083,7 +5429,6 @@ void wolfSSL_EVP_init(void) } #endif /* WOLFSSL_AES_2128 */ - #ifdef WOLFSSL_AES_192 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void) { @@ -5182,6 +5527,42 @@ void wolfSSL_EVP_init(void) } #endif +#ifdef WOLFSSL_SM4_ECB + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_sm4_ecb"); + return EVP_SM4_ECB; + } +#endif +#ifdef WOLFSSL_SM4_CBC + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_cbc(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_sm4_cbc"); + return EVP_SM4_CBC; + } +#endif +#ifdef WOLFSSL_SM4_CTR + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ctr(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_sm4_ctr"); + return EVP_SM4_CTR; + } +#endif +#ifdef WOLFSSL_SM4_GCM + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_sm4_gcm"); + return EVP_SM4_GCM; + } +#endif +#ifdef WOLFSSL_SM4_CCM + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ccm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_sm4_ccm"); + return EVP_SM4_CCM; + } +#endif + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void) { WOLFSSL_ENTER("wolfSSL_EVP_enc_null"); @@ -5227,6 +5608,7 @@ void wolfSSL_EVP_init(void) ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg); break; #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) case EVP_CTRL_AEAD_SET_IVLEN: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) @@ -5239,6 +5621,22 @@ void wolfSSL_EVP_init(void) } else #endif /* HAVE_CHACHA && HAVE_POLY1305 */ + #if defined(WOLFSSL_SM4_GCM) + if (ctx->cipherType == SM4_GCM_TYPE) { + if (arg <= 0 || arg > SM4_BLOCK_SIZE) { + break; + } + } + else + #endif + #if defined(WOLFSSL_SM4_CCM) + if (ctx->cipherType == SM4_CCM_TYPE) { + if (arg <= 0 || arg > SM4_BLOCK_SIZE) { + break; + } + } + else + #endif { if (arg <= 0 || arg > AES_BLOCK_SIZE) break; @@ -5246,7 +5644,8 @@ void wolfSSL_EVP_init(void) ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); break; -#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) +#if defined(HAVE_AESGCM) || defined(WOLFSSL_SM4_GCM) || \ + (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) case EVP_CTRL_AEAD_SET_IV_FIXED: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; @@ -5285,7 +5684,7 @@ void wolfSSL_EVP_init(void) break; } } - #ifdef HAVE_AESGCM + #if defined(HAVE_AESGCM) || defined(WOLFSSL_SM4_GCM) if (ret == WOLFSSL_SUCCESS) { /* * OpenSSL requires that a EVP_CTRL_AEAD_SET_IV_FIXED @@ -5297,9 +5696,9 @@ void wolfSSL_EVP_init(void) #endif #endif /* !WC_NO_RNG */ break; -#endif /* HAVE_AESGCM || (HAVE_CHACHA && HAVE_POLY1305) */ -#if defined(HAVE_AESGCM) && !defined(_WIN32) && !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || FIPS_VERSION_GE(2,0)) +#endif /* HAVE_AESGCM || WOLFSSL_SM4_GCM || (HAVE_CHACHA && HAVE_POLY1305) */ +#if (defined(HAVE_AESGCM) || defined(WOLFSSL_SM4_GCM)) && !defined(_WIN32) && \ + !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(2,0)) /* * Using EVP_CTRL_GCM_IV_GEN is a way to do AES-GCM encrypt/decrypt * multiple times with EVP_Cipher without having to call @@ -5340,8 +5739,8 @@ void wolfSSL_EVP_init(void) ctx->authIncIv = 1; ret = WOLFSSL_SUCCESS; break; -#endif /* HAVE_AESGCM && !_WIN32 && !HAVE_SELFTEST && (!HAVE_FIPS || - * FIPS_VERSION >= 2)*/ +#endif /* (HAVE_AESGCM || WOLFSSL_SM4_GCM) && !_WIN32 && !HAVE_SELFTEST && + * !HAVE_FIPS || FIPS_VERSION >= 2)*/ case EVP_CTRL_AEAD_SET_TAG: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; @@ -5359,6 +5758,32 @@ void wolfSSL_EVP_init(void) } else #endif /* HAVE_CHACHA && HAVE_POLY1305 */ +#if defined(WOFLSSL_SM4_GCM) + if (ctx->cipherType == WOLFSSL_SM4_GCM) { + if ((arg <= 0) || (arg > SM4_BLOCK_SIZE) || (ptr == NULL)) { + break; + } + + XMEMCPY(ctx->authTag, ptr, arg); + ctx->authTagSz = arg; + ret = WOLFSSL_SUCCESS; + break; + } + else +#endif +#if defined(WOFLSSL_SM4_CCM) + if (ctx->cipherType == WOLFSSL_SM4_CCM) { + if ((arg <= 0) || (arg > SM4_BLOCK_SIZE) || (ptr == NULL)) { + break; + } + + XMEMCPY(ctx->authTag, ptr, arg); + ctx->authTagSz = arg; + ret = WOLFSSL_SUCCESS; + break; + } + else +#endif { if(arg <= 0 || arg > 16 || (ptr == NULL)) break; @@ -5380,6 +5805,22 @@ void wolfSSL_EVP_init(void) } else #endif /* HAVE_CHACHA && HAVE_POLY1305 */ +#if defined(WOLFSSL_SM4_GCM) + if (ctx->cipherType == WOLFSSL_SM4_GCM) { + if (arg <= 0 || arg > SM4_BLOCK_SIZE) { + break; + } + } + else +#endif +#if defined(WOLFSSL_SM4_CCM) + if (ctx->cipherType == WOLFSSL_SM4_CCM) { + if (arg <= 0 || arg > SM4_BLOCK_SIZE) { + break; + } + } + else +#endif { if (arg <= 0 || arg > AES_BLOCK_SIZE) break; @@ -5390,7 +5831,8 @@ void wolfSSL_EVP_init(void) ret = WOLFSSL_SUCCESS; } break; -#endif /* HAVE_AESGCM || HAVE_AESCCM || (HAVE_CHACHA && HAVE_POLY1305) */ +#endif /* HAVE_AESGCM || HAVE_AESCCM || WOLFSSL_SM4_GCM || WOLFSSL_SM4_CCM || + * (HAVE_CHACHA && HAVE_POLY1305) */ default: WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); break; @@ -5466,6 +5908,27 @@ void wolfSSL_EVP_init(void) #endif /* AES */ #endif /* not FIPS or FIPS v2+ */ +#ifdef WOLFSSL_SM4 + switch (ctx->cipherType) { + #ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + #endif + #ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + #endif + #ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + #endif + #ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + #endif + #ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + #endif + wc_Sm4Free(&ctx->cipher.sm4); + } +#endif + ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */ #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) if (ctx->key) { @@ -5475,7 +5938,8 @@ void wolfSSL_EVP_init(void) } #endif ctx->keyLen = 0; -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) if (ctx->authBuffer) { XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL); ctx->authBuffer = NULL; @@ -6669,6 +7133,141 @@ void wolfSSL_EVP_init(void) } } #endif +#ifdef WOLFSSL_SM4_ECB + if (ctx->cipherType == SM4_ECB_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_SM4_ECB))) { + WOLFSSL_MSG("EVP_SM4_ECB"); + ctx->cipherType = SM4_ECB_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = SM4_KEY_SIZE; + ctx->block_size = SM4_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_Sm4SetKey(&ctx->cipher.sm4, key, ctx->keyLen); + } + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } +#endif +#ifdef WOLFSSL_SM4_CBC + if (ctx->cipherType == SM4_CBC_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_SM4_CBC))) { + WOLFSSL_MSG("EVP_SM4_CBC"); + ctx->cipherType = SM4_CBC_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; + ctx->keyLen = SM4_KEY_SIZE; + ctx->block_size = SM4_BLOCK_SIZE; + ctx->ivSz = SM4_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key != NULL) { + ret = wc_Sm4SetKey(&ctx->cipher.sm4, key, ctx->keyLen); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + if (iv != NULL) { + ret = wc_Sm4SetIV(&ctx->cipher.sm4, iv); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + } +#endif +#ifdef WOLFSSL_SM4_CTR + if (ctx->cipherType == SM4_CTR_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_SM4_CTR))) { + WOLFSSL_MSG("EVP_SM4_CTR"); + ctx->cipherType = SM4_CTR_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; + ctx->keyLen = SM4_KEY_SIZE; + ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->ivSz = SM4_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key != NULL) { + ret = wc_Sm4SetKey(&ctx->cipher.sm4, key, ctx->keyLen); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + if (iv != NULL) { + ret = wc_Sm4SetIV(&ctx->cipher.sm4, iv); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + } +#endif +#ifdef WOLFSSL_SM4_GCM + if (ctx->cipherType == SM4_GCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_SM4_GCM))) { + WOLFSSL_MSG("EVP_SM4_GCM"); + ctx->cipherType = SM4_GCM_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->keyLen = SM4_KEY_SIZE; + if (ctx->ivSz == 0) { + ctx->ivSz = GCM_NONCE_MID_SZ; + } + ctx->authTagSz = SM4_BLOCK_SIZE; + if (ctx->authIn) { + XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authIn = NULL; + } + ctx->authInSz = 0; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key != NULL) { + ret = wc_Sm4GcmSetKey(&ctx->cipher.sm4, key, ctx->keyLen); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + if (iv != NULL) { + XMEMCPY(ctx->iv, iv, ctx->ivSz); + } + } +#endif +#ifdef WOLFSSL_SM4_CCM + if (ctx->cipherType == SM4_CCM_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_SM4_CCM))) { + WOLFSSL_MSG("EVP_SM4_CCM"); + ctx->cipherType = SM4_CCM_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CCM_MODE | + WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->keyLen = SM4_KEY_SIZE; + if (ctx->ivSz == 0) { + ctx->ivSz = GCM_NONCE_MID_SZ; + } + ctx->authTagSz = SM4_BLOCK_SIZE; + if (ctx->authIn) { + XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL); + ctx->authIn = NULL; + } + ctx->authInSz = 0; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key != NULL) { + ret = wc_Sm4SetKey(&ctx->cipher.sm4, key, ctx->keyLen); + if (ret != 0) { + return WOLFSSL_FAILURE; + } + } + if (iv != NULL) { + XMEMCPY(ctx->iv, iv, ctx->ivSz); + } + } +#endif #ifndef NO_DES3 if (ctx->cipherType == DES_CBC_TYPE || (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_CBC))) { @@ -6868,6 +7467,31 @@ void wolfSSL_EVP_init(void) return NID_chacha20; #endif +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE: + return NID_sm4_ecb; +#endif + +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE: + return NID_sm4_cbc; +#endif + +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE: + return NID_sm4_ctr; +#endif + +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE: + return NID_sm4_gcm; +#endif + +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE: + return NID_sm4_ccm; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_ERROR_MSG("Null cipher has no NID"); FALL_THROUGH; @@ -6983,6 +7607,12 @@ void wolfSSL_EVP_init(void) && ctx->cipherType != AES_128_CCM_TYPE && ctx->cipherType != AES_192_CCM_TYPE && ctx->cipherType != AES_256_CCM_TYPE + #endif + #ifdef WOLFSSL_SM4_GCM + && ctx->cipherType != SM4_GCM_TYPE + #endif + #ifdef WOLFSSL_SM4_CCM + && ctx->cipherType != SM4_CCM_TYPE #endif ))) { WOLFSSL_MSG("Bad argument."); @@ -7166,6 +7796,108 @@ void wolfSSL_EVP_init(void) break; #endif + /* TODO: Chacha??? */ + +#ifdef WOLFSSL_SM4_ECB + case SM4_ECB_TYPE : + WOLFSSL_MSG("Sm4 ECB"); + if (ctx->enc) + ret = wc_Sm4EcbEncrypt(&ctx->cipher.sm4, dst, src, len); + else + ret = wc_Sm4EcbDecrypt(&ctx->cipher.sm4, dst, src, len); + if (ret == 0) + ret = (len / SM4_BLOCK_SIZE) * SM4_BLOCK_SIZE; + break; +#endif +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE : + WOLFSSL_MSG("Sm4 CBC"); + if (ctx->enc) + ret = wc_Sm4CbcEncrypt(&ctx->cipher.sm4, dst, src, len); + else + ret = wc_Sm4CbcDecrypt(&ctx->cipher.sm4, dst, src, len); + if (ret == 0) + ret = (len / SM4_BLOCK_SIZE) * SM4_BLOCK_SIZE; + break; +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE : + WOLFSSL_MSG("AES CTR"); + ret = wc_Sm4CtrEncrypt(&ctx->cipher.sm4, dst, src, len); + if (ret == 0) + ret = len; + break; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE : + WOLFSSL_MSG("SM4 GCM"); + /* No destination means only AAD. */ + if (src != NULL && dst == NULL) { + ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, src, len); + } + else if (src != NULL && dst != NULL) { + if (ctx->enc) { + ret = wc_Sm4GcmEncrypt(&ctx->cipher.sm4, dst, src, + len, ctx->iv, ctx->ivSz, ctx->authTag, + ctx->authTagSz, ctx->authIn, + ctx->authInSz); + } + else { + ret = wc_Sm4GcmDecrypt(&ctx->cipher.sm4, dst, src, + len, ctx->iv, ctx->ivSz, ctx->authTag, + ctx->authTagSz, ctx->authIn, + ctx->authInSz); + } + if (ctx->authIncIv) { + IncCtr((byte*)ctx->cipher.sm4.iv, + ctx->cipher.sm4.nonceSz); + ctx->authIncIv = 0; + } + } + break; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE : + WOLFSSL_MSG("SM4 CCM"); + /* No destination means only AAD. */ + if (src != NULL && dst == NULL) { + ret = wolfSSL_EVP_CipherUpdate_CCM_AAD(ctx, src, len); + } + else if (src != NULL && dst != NULL) { + if (ctx->enc) { + ret = wc_Sm4CcmEncrypt(&ctx->cipher.sm4, dst, src, + len, ctx->iv, ctx->ivSz, ctx->authTag, + ctx->authTagSz, ctx->authIn, + ctx->authInSz); + } + else { + ret = wc_Sm4CcmDecrypt(&ctx->cipher.sm4, dst, src, + len, ctx->iv, ctx->ivSz, ctx->authTag, + ctx->authTagSz, ctx->authIn, + ctx->authInSz); + } + if (ctx->authIncIv) { + IncCtr((byte*)ctx->cipher.sm4.iv, + ctx->cipher.sm4.nonceSz); + ctx->authIncIv = 0; + } + } + if (src == NULL) { + /* + * Clear any leftover AAD on final (final is when src is + * NULL). + */ + if (ctx->authIn != NULL) { + XMEMSET(ctx->authIn, 0, ctx->authInSz); + } + ctx->authInSz = 0; + } + if (ret == 0) { + ret = len; + } + break; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL CIPHER"); XMEMCPY(dst, src, len); @@ -8048,6 +8780,32 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) WOLFSSL_MSG("CHACHA20"); return WOLFSSL_EVP_CHACHA_IV_BYTES; #endif /* HAVE_CHACHA */ +#ifdef WOLFSSL_SM4_CBC + case SM4_CBC_TYPE : + WOLFSSL_MSG("SM4 CBC"); + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_CTR + case SM4_CTR_TYPE : + WOLFSSL_MSG("SM4 CTR"); + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_GCM + case SM4_GCM_TYPE : + WOLFSSL_MSG("SM4 GCM"); + if (ctx->ivSz != 0) { + return ctx->ivSz; + } + return GCM_NONCE_MID_SZ; +#endif +#ifdef WOLFSSL_SM4_CCM + case SM4_CCM_TYPE : + WOLFSSL_MSG("SM4 CCM"); + if (ctx->ivSz != 0) { + return ctx->ivSz; + } + return CCM_NONCE_MIN_SZ; +#endif case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); @@ -8156,6 +8914,23 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher) return WOLFSSL_EVP_CHACHA_IV_BYTES; #endif +#ifdef WOLFSSL_SM4_CBC + if (XSTRCMP(name, EVP_SM4_CBC) == 0) + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_CTR + if (XSTRCMP(name, EVP_SM4_CTR) == 0) + return SM4_BLOCK_SIZE; +#endif +#ifdef WOLFSSL_SM4_GCM + if (XSTRCMP(name, EVP_SM4_GCM) == 0) + return GCM_NONCE_MID_SZ; +#endif +#ifdef WOLFSSL_SM4_CCM + if (XSTRCMP(name, EVP_SM4_CCM) == 0) + return CCM_NONCE_MIN_SZ; +#endif + (void)name; return 0; @@ -8657,6 +9432,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 + const WOLFSSL_EVP_MD* wolfSSL_EVP_sm3(void) + { + WOLFSSL_ENTER("EVP_sm3"); + return EVP_get_digestbyname("SM3"); + } +#endif /* WOLFSSL_SM3 */ WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void) @@ -8920,6 +9702,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) wc_Sha3_512_Free((wc_Sha3*)&ctx->hash.digest); #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + wc_Sm3Free(&ctx->hash.digest.sm3); + break; + #endif case WC_HASH_TYPE_NONE: /* Not an error since an unused struct could be free'd or * reset. */ @@ -9039,6 +9826,17 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } else #endif #endif + #ifdef WOLFSSL_SM3 + if (XSTRCMP(md, "SM3") == 0) { + ret = wc_InitSm3(&ctx->hash.digest.sm3, NULL, INVALID_DEVID); + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + } else + #endif { ctx->macType = WC_HASH_TYPE_NONE; return BAD_FUNC_ARG; @@ -9146,6 +9944,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) (unsigned long)sz); #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Update(&ctx->hash.digest.sm3, data, + (unsigned long)sz); + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + break; + #endif case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD5_SHA: @@ -9259,6 +10069,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) if (s) *s = WC_SHA3_512_DIGEST_SIZE; #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Final(&ctx->hash.digest.sm3, md); + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + if (s) *s = WC_SM3_DIGEST_SIZE; + break; + #endif case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD5_SHA: @@ -9318,6 +10140,10 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) #ifdef WOLFSSL_SHA512 case NID_sha512: return wolfSSL_EVP_sha512(); +#endif +#ifdef WOLFSSL_SM3 + case NID_sm3: + return wolfSSL_EVP_sm3(); #endif default: WOLFSSL_MSG("Bad digest id value"); @@ -9391,6 +10217,11 @@ int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD* type) } #endif #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 + if (XSTRCMP(type, "SM3") == 0) { + return WC_SM3_BLOCK_SIZE; + } else +#endif return BAD_FUNC_ARG; } @@ -9468,9 +10299,14 @@ int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type) #ifndef WOLFSSL_NOSHA3_512 if (XSTRCMP(type, "SHA3_512") == 0) { return WC_SHA3_512_DIGEST_SIZE; - } + } else #endif #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 + if (XSTRCMP(type, "SM3") == 0) { + return WC_SM3_DIGEST_SIZE; + } +#endif return BAD_FUNC_ARG; } @@ -10721,6 +11557,11 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, } else #endif #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 + if (XSTRCMP("SM3", evp) == 0) { + hash = WC_HASH_TYPE_SM3; + } else +#endif #ifdef WOLFSSL_MD2 if (XSTRCMP("MD2", evp) == 0) { hash = WC_HASH_TYPE_MD2; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 7a146359a..3e5bde0fa 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -59,7 +59,8 @@ enum Hash_Sum { SHA3_384h = 422, SHA3_512h = 423, SHAKE128h = 424, - SHAKE256h = 425 + SHAKE256h = 425, + SM3h = 640 /* 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11 */ }; #endif /* !NO_ASN */ @@ -121,6 +122,11 @@ enum wc_HashType wc_HashTypeConvert(int hashType) eHashType = WC_HASH_TYPE_SHA3_512; break; #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + eHashType = WC_HASH_TYPE_SM3; + break; + #endif default: eHashType = WC_HASH_TYPE_NONE; break; @@ -222,6 +228,11 @@ int wc_HashGetOID(enum wc_HashType hash_type) oid = SHAKE256h; break; #endif + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + oid = SM3h; + break; + #endif /* Not Supported */ case WC_HASH_TYPE_MD4: @@ -289,6 +300,11 @@ enum wc_HashType wc_OidGetHash(int oid) hash_type = WC_HASH_TYPE_SHA3_512; break; #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case SM3h: + hash_type = WC_HASH_TYPE_SM3; + #endif + break; default: break; } @@ -395,6 +411,12 @@ int wc_HashGetDigestSize(enum wc_HashType hash_type) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + dig_size = WC_SM3_DIGEST_SIZE; + break; + #endif + /* Not Supported */ #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: @@ -508,6 +530,12 @@ int wc_HashGetBlockSize(enum wc_HashType hash_type) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + block_size = WC_SM3_BLOCK_SIZE; + break; + #endif + /* Not Supported */ #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: @@ -626,6 +654,12 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data, #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Hash(data, data_len, hash); + break; + #endif + /* Not Supported */ case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD4: @@ -723,6 +757,12 @@ int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type, void* heap, #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_InitSm3(&hash->sm3, heap, devId); + break; + #endif + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -829,6 +869,12 @@ int wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type, const byte* data, #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Update(&hash->sm3, data, dataSz); + break; + #endif + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -926,6 +972,12 @@ int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, byte* out) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3Final(&hash->sm3, out); + break; + #endif + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -1035,6 +1087,13 @@ int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + wc_Sm3Free(&hash->sm3); + ret = 0; + break; + #endif + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -1110,6 +1169,12 @@ int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, word32 flags) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3SetFlags(&hash->sm3, flags); + #endif + break; + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -1183,6 +1248,12 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #endif break; + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + ret = wc_Sm3GetFlags(&hash->sm3, flags); + break; + #endif + /* not supported */ case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD2: @@ -1763,6 +1834,43 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #endif /* WOLFSSL_SHAKE_256 */ #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 + int wc_Sm3Hash(const byte* data, word32 len, byte* hash) + { + int ret = 0; + #ifdef WOLFSSL_SMALL_STACK + wc_Sm3* sm3; + #else + wc_Sm3 sm3[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + sm3 = (wc_Sm3*)XMALLOC(sizeof(wc_Sm3), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sm3 == NULL) + return MEMORY_E; + #endif + + if ((ret = wc_InitSm3(sm3, NULL, INVALID_DEVID)) != 0) { + WOLFSSL_MSG("InitSm3 failed"); + } + else { + if ((ret = wc_Sm3Update(sm3, data, len)) != 0) { + WOLFSSL_MSG("Sm3Update failed"); + } + else if ((ret = wc_Sm3Final(sm3, hash)) != 0) { + WOLFSSL_MSG("Sm3Final failed"); + } + wc_Sm3Free(sm3); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(sm3, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + return ret; + } +#endif /* !WOLFSSL_NOSHA3_224 */ + #endif /* !NO_HASH_WRAPPER */ #ifdef WOLFSSL_HASH_KEEP diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 058868758..29dfc3e21 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -141,6 +141,9 @@ int wc_HmacSizeByType(int type) int ret; if (!(type == WC_MD5 || type == WC_SHA || + #ifdef WOLFSSL_SM3 + type == WC_SM3 || + #endif type == WC_SHA224 || type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 || type == WC_SHA3_224 || type == WC_SHA3_256 || @@ -200,7 +203,12 @@ int wc_HmacSizeByType(int type) case WC_SHA3_512: ret = WC_SHA3_512_DIGEST_SIZE; break; + #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = WC_SM3_DIGEST_SIZE; + break; #endif default: @@ -278,6 +286,12 @@ int _InitHmac(Hmac* hmac, int type, void* heap) #endif #endif + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_InitSm3(&hmac->hash.sm3, heap, devId); + break; + #endif + default: ret = BAD_FUNC_ARG; break; @@ -306,6 +320,9 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) if (hmac == NULL || (key == NULL && length != 0) || !(type == WC_MD5 || type == WC_SHA || + #ifdef WOLFSSL_SM3 + type == WC_SM3 || + #endif type == WC_SHA224 || type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 || type == WC_SHA3_224 || type == WC_SHA3_256 || @@ -558,6 +575,27 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + hmac_block_size = WC_SM3_BLOCK_SIZE; + if (length <= WC_SM3_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } + } + else { + ret = wc_Sm3Update(&hmac->hash.sm3, key, length); + if (ret != 0) + break; + ret = wc_Sm3Final(&hmac->hash.sm3, ip); + if (ret != 0) + break; + + length = WC_SM3_DIGEST_SIZE; + } + break; + #endif + default: return BAD_FUNC_ARG; } @@ -670,6 +708,13 @@ static int HmacKeyInnerHash(Hmac* hmac) #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->ipad, + WC_SM3_BLOCK_SIZE); + break; + #endif + default: break; } @@ -776,6 +821,12 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Update(&hmac->hash.sm3, msg, length); + break; + #endif + default: break; } @@ -993,6 +1044,23 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Final(&hmac->hash.sm3, (byte*)hmac->innerHash); + if (ret != 0) + break; + ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->opad, + WC_SM3_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->innerHash, + WC_SM3_DIGEST_SIZE); + if (ret != 0) + break; + ret = wc_Sm3Final(&hmac->hash.sm3, hash); + break; + #endif + default: ret = BAD_FUNC_ARG; break; @@ -1167,6 +1235,12 @@ void wc_HmacFree(Hmac* hmac) #endif #endif /* WOLFSSL_SHA3 */ + #ifdef WOLFSSL_SM3 + case WC_SM3: + wc_Sm3Free(&hmac->hash.sm3); + break; + #endif + default: break; } diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 5ea1cb5a6..4050f8d43 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -553,6 +553,15 @@ int mp_exch (mp_int * a, mp_int * b) return MP_OKAY; } +int mp_cond_swap_ct_ex (mp_int * a, mp_int * b, int c, int m, mp_int * t) +{ + (void)c; + (void)t; + if (m == 1) + mp_exch(a, b); + return MP_OKAY; +} + int mp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m) { (void)c; diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 948caf696..2280be7bf 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -113,6 +113,13 @@ int wc_PRF(byte* result, word32 resLen, const byte* secret, break; #endif + #ifdef WOLFSSL_SM3 + case sm3_mac: + hash = WC_SM3; + len = WC_SM3_DIGEST_SIZE; + break; + #endif + #ifndef NO_SHA case sha_mac: hash = WC_SHA; @@ -376,6 +383,13 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, len = WC_SHA512_DIGEST_SIZE; break; #endif + + #ifdef WOLFSSL_SM3 + case WC_SM3: + len = WC_SM3_DIGEST_SIZE; + break; + #endif + default: return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index f80c9c649..8ccf766ba 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -104,13 +104,13 @@ masking and clearing memory logic. WC_MISC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y) { - return (x << y) | (x >> (sizeof(y) * 8 - y)); + return (x << y) | (x >> (sizeof(x) * 8 - y)); } /* This routine performs a right circular arithmetic shift of by value. */ WC_MISC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y) { - return (x >> y) | (x << (sizeof(y) * 8 - y)); + return (x >> y) | (x << (sizeof(x) * 8 - y)); } #endif @@ -120,14 +120,14 @@ masking and clearing memory logic. /* This routine performs a left circular arithmetic shift of by value */ WC_MISC_STATIC WC_INLINE word16 rotlFixed16(word16 x, word16 y) { - return (x << y) | (x >> (sizeof(y) * 8 - y)); + return (x << y) | (x >> (sizeof(x) * 8 - y)); } /* This routine performs a right circular arithmetic shift of by value */ WC_MISC_STATIC WC_INLINE word16 rotrFixed16(word16 x, word16 y) { - return (x >> y) | (x << (sizeof(y) * 8 - y)); + return (x >> y) | (x << (sizeof(x) * 8 - y)); } #endif /* WC_RC2 */ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index ce7d77c98..f469966c1 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2374,6 +2374,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, word32 totalSz, total2Sz; int idx = 0, ret = 0; int digEncAlgoId, digEncAlgoType; + int keyIdSize; byte* flatSignedAttribs = NULL; word32 flatSignedAttribsSz = 0; @@ -2392,6 +2393,13 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + pkcs7->publicKeyOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + #ifdef WOLFSSL_SMALL_STACK signedDataOid = (byte *)XMALLOC(MAX_OID_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (signedDataOid == NULL) { @@ -2485,11 +2493,10 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } else if (pkcs7->sidType == CMS_SKID) { /* SubjectKeyIdentifier */ - esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID); - esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE, + esd->issuerSKIDSz = SetOctetString(keyIdSize, esd->issuerSKID); + esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + keyIdSize, esd->issuerSKIDSeq); - signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz + - KEYID_SIZE); + signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz + keyIdSize); /* version MUST be 3 */ esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0); @@ -2723,8 +2730,8 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, idx += esd->issuerSKIDSeqSz; XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz); idx += esd->issuerSKIDSz; - XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE); - idx += KEYID_SIZE; + XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, keyIdSize); + idx += keyIdSize; } else if (pkcs7->sidType == DEGENERATE_SID) { /* no signer infos in degenerate case */ } else { @@ -6118,6 +6125,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, int ret = 0; int keySz, direction = 0; int blockKeySz = 0; + int keyIdSize; /* ASN.1 layout */ int totalSz = 0; @@ -6169,6 +6177,13 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + pkcs7->publicKeyOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + /* allocate and init memory for recipient */ recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -6294,12 +6309,12 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, totalSz += (encryptedKeyOctetSz + encryptedKeySz); /* SubjectKeyIdentifier */ - subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet); - totalSz += (subjKeyIdOctetSz + KEYID_SIZE); + subjKeyIdOctetSz = SetOctetString(keyIdSize, subjKeyIdOctet); + totalSz += (subjKeyIdOctetSz + keyIdSize); /* RecipientKeyIdentifier IMPLICIT [0] */ recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz + - KEYID_SIZE, recipKeyIdSeq); + keyIdSize, recipKeyIdSeq); totalSz += recipKeyIdSeqSz; /* RecipientEncryptedKey */ @@ -6423,8 +6438,8 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz); idx += subjKeyIdOctetSz; /* subject key id */ - XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, KEYID_SIZE); - idx += KEYID_SIZE; + XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, keyIdSize); + idx += keyIdSize; XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz); idx += encryptedKeyOctetSz; /* encrypted CEK */ @@ -6473,6 +6488,7 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, WC_RNG rng; word32 idx = 0; word32 encryptedKeySz = 0; + int keyIdSize; int ret = 0, blockKeySz; int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0; @@ -6599,6 +6615,13 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, return ret; } +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + decoded->signatureOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { /* version, must be 0 for IssuerAndSerialNumber */ @@ -6655,7 +6678,7 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, verSz = SetMyVersion(2, ver, 0); recip->recipVersion = 2; - issuerSKIDSz = SetLength(KEYID_SIZE, issuerSKID); + issuerSKIDSz = SetLength(keyIdSize, issuerSKID); } else { FreeDecodedCert(decoded); #ifdef WOLFSSL_SMALL_STACK @@ -6815,10 +6838,10 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, } else { recipSeqSz = SetSequence(verSz + ASN_TAG_SZ + issuerSKIDSz + - KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz + + keyIdSize + keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz, recipSeq); - if (recipSeqSz + verSz + ASN_TAG_SZ + issuerSKIDSz + KEYID_SIZE + + if (recipSeqSz + verSz + ASN_TAG_SZ + issuerSKIDSz + keyIdSize + keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) { WOLFSSL_MSG("RecipientInfo output buffer too small"); FreeDecodedCert(decoded); @@ -6852,8 +6875,8 @@ int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz, idx += ASN_TAG_SZ; XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz); idx += issuerSKIDSz; - XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE); - idx += KEYID_SIZE; + XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, keyIdSize); + idx += keyIdSize; } XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz); idx += keyEncAlgSz; @@ -8567,6 +8590,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, { int length, encryptedKeySz = 0, ret = 0; int keySz, version, sidType = 0; + int keyIdSize; word32 encOID = 0; word32 keyIdx; byte issuerHash[KEYID_SIZE]; @@ -8593,6 +8617,13 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, RsaKey privKey[1]; #endif +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + pkcs7->publicKeyOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + switch (pkcs7->state) { case WC_PKCS7_DECRYPT_KTRI: #ifndef NO_PKCS7_STREAM @@ -8680,11 +8711,12 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0) + if (GetNameHash_ex(pkiMsg, idx, issuerHash, pkiMsgSz, + pkcs7->publicKeyOID) < 0) return ASN_PARSE_E; /* if we found correct recipient, issuer hashes will match */ - if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) { + if (XMEMCMP(issuerHash, pkcs7->issuerHash, keyIdSize) == 0) { *recipFound = 1; } @@ -8732,15 +8764,15 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if (KEYID_SIZE > pkiMsgSz - (*idx)) + if ((word32)keyIdSize > pkiMsgSz - (*idx)) return BUFFER_E; /* if we found correct recipient, SKID will match */ if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId, - KEYID_SIZE) == 0) { + keyIdSize) == 0) { *recipFound = 1; } - (*idx) += KEYID_SIZE; + (*idx) += keyIdSize; } if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0) @@ -9149,11 +9181,19 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, { int length; byte tag; + int keyIdSize; if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL || rid == NULL) return BAD_FUNC_ARG; +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + kari->decoded->signatureOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + /* remove RecipientKeyIdentifier IMPLICIT [0] */ if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) { return ASN_PARSE_E; @@ -9178,14 +9218,14 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if (length != KEYID_SIZE) + if (length != keyIdSize) return ASN_PARSE_E; - XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE); + XMEMCPY(rid, pkiMsg + (*idx), keyIdSize); (*idx) += length; /* subject key id should match if recipient found */ - if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) { + if (XMEMCMP(rid, kari->decoded->extSubjKeyId, keyIdSize) == 0) { *recipFound = 1; } @@ -9200,6 +9240,7 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari, int* recipFound, byte* rid) { int length, ret; + int keyIdSize; #ifdef WOLFSSL_SMALL_STACK mp_int* serial; mp_int* recipSerial; @@ -9212,15 +9253,24 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari, return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + kari->decoded->signatureOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + /* remove IssuerAndSerialNumber */ if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0) + if (GetNameHash_ex(pkiMsg, idx, rid, pkiMsgSz, + kari->decoded->signatureOID) < 0) { return ASN_PARSE_E; + } /* if we found correct recipient, issuer hashes will match */ - if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) { + if (XMEMCMP(rid, kari->decoded->issuerHash, keyIdSize) == 0) { *recipFound = 1; } @@ -9876,6 +9926,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz, int ret, keySz; int encryptedKeySz; int direction = 0; + int keyIdSize; word32 keyAgreeOID, keyWrapOID; byte rid[KEYID_SIZE]; @@ -9899,6 +9950,13 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz, return BAD_FUNC_ARG; } +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + keyIdSize = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( + pkcs7->publicKeyOID))); +#else + keyIdSize = KEYID_SIZE; +#endif + switch (pkcs7->state) { case WC_PKCS7_DECRYPT_KARI: { WC_PKCS7_KARI* kari; @@ -10054,7 +10112,7 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz, tmpKeySz = (word32)ret; keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz, - rid, KEYID_SIZE, tmpKeyDer, tmpKeySz, + rid, keyIdSize, tmpKeyDer, tmpKeySz, decryptedKey, *decryptedKeySz, keyWrapOID, (int)PKCS7_KARI, direction); XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 20691a76a..2bc2ca52a 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -1462,7 +1462,7 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) /* PMULL and RBIT only with AArch64 */ /* Use ARM hardware for polynomial multiply */ -static void GMULT(byte* X, byte* Y) +void GMULT(byte* X, byte* Y) { __asm__ volatile ( "LD1 {v0.16b}, [%[inX]] \n" @@ -1511,14 +1511,19 @@ static void GMULT(byte* X, byte* Y) } -void GHASH(Aes* aes, const byte* a, word32 aSz, - const byte* c, word32 cSz, byte* s, word32 sSz) +void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, + word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; byte scratch[AES_BLOCK_SIZE]; word32 blocks, partial; - byte* h = aes->H; + byte* h; + if (gcm == NULL) { + return; + } + + h = gcm->H; XMEMSET(x, 0, AES_BLOCK_SIZE); /* Hash in A, the Additional Authentication Data */ @@ -1597,8 +1602,8 @@ static int Aes128GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); - GMULT(initialCounter, aes->H); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GMULT(initialCounter, aes->gcm.H); } XMEMCPY(counter, initialCounter, AES_BLOCK_SIZE); @@ -1611,14 +1616,14 @@ static int Aes128GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* do as many blocks as possible */ while (blocks--) { xorbuf(x, authIn, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); authIn += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, authIn, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } } @@ -1777,10 +1782,10 @@ static int Aes128GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, "STR q17, [%[xOut]] \n" /* GHASH x value for partial blocks */ :[out] "=r" (out), "=r" (keyPt), [ctrOut] "=r" (ctr), "=r" (in) - ,[xOut] "=r" (xPt),"=m" (aes->H) + ,[xOut] "=r" (xPt),"=m" (aes->gcm.H) :"0" (out), [Key] "1" (keyPt), [ctr] "2" (ctr), [blocks] "r" (blocks), [input] "3" (in) - ,[inX] "4" (xPt), [inY] "m" (aes->H) + ,[inX] "4" (xPt), [inY] "m" (aes->gcm.H) : "cc", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14" ,"v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24" @@ -1797,7 +1802,7 @@ static int Aes128GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, out, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } /* Hash in the lengths of A and C in bits */ @@ -1866,7 +1871,7 @@ static int Aes128GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, :[out] "=r" (sPt), "=r" (keyPt), "=r" (iCtr) :[tag] "0" (sPt), [Key] "1" (keyPt), - [ctr] "2" (iCtr) , [h] "m" (aes->H) + [ctr] "2" (iCtr) , [h] "m" (aes->gcm.H) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10","v11","v12","v13","v14", "v15", "v16", "v17","v18", "v19", "v20","v21","v22","v23","v24" @@ -1915,8 +1920,8 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); - GMULT(initialCounter, aes->H); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GMULT(initialCounter, aes->gcm.H); } XMEMCPY(counter, initialCounter, AES_BLOCK_SIZE); @@ -1929,14 +1934,14 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* do as many blocks as possible */ while (blocks--) { xorbuf(x, authIn, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); authIn += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, authIn, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } } @@ -2103,10 +2108,10 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, "STR q17, [%[xOut]] \n" /* GHASH x value for partial blocks */ :[out] "=r" (out), "=r" (keyPt), [ctrOut] "=r" (ctr), "=r" (in) - ,[xOut] "=r" (xPt),"=m" (aes->H) + ,[xOut] "=r" (xPt),"=m" (aes->gcm.H) :"0" (out), [Key] "1" (keyPt), [ctr] "2" (ctr), [blocks] "r" (blocks), [input] "3" (in) - ,[inX] "4" (xPt), [inY] "m" (aes->H) + ,[inX] "4" (xPt), [inY] "m" (aes->gcm.H) : "cc", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14" ,"v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", @@ -2124,7 +2129,7 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, out, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } /* Hash in the lengths of A and C in bits */ @@ -2198,7 +2203,7 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, :[out] "=r" (sPt), "=r" (keyPt), "=r" (iCtr) :[tag] "0" (sPt), [Key] "1" (keyPt), - [ctr] "2" (iCtr) , [h] "m" (aes->H) + [ctr] "2" (iCtr) , [h] "m" (aes->gcm.H) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10","v11","v12","v13","v14", "v15", "v16", "v17","v18", "v19", "v20","v21","v22","v23","v24" @@ -2248,8 +2253,8 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); - GMULT(initialCounter, aes->H); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GMULT(initialCounter, aes->gcm.H); } XMEMCPY(counter, initialCounter, AES_BLOCK_SIZE); @@ -2262,14 +2267,14 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* do as many blocks as possible */ while (blocks--) { xorbuf(x, authIn, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); authIn += AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, authIn, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } } @@ -2444,10 +2449,10 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, "STR q17, [%[xOut]] \n" /* GHASH x value for partial blocks */ :[out] "=r" (out), "=r" (keyPt), [ctrOut] "=r" (ctr), "=r" (in) - ,[xOut] "=r" (xPt),"=m" (aes->H) + ,[xOut] "=r" (xPt),"=m" (aes->gcm.H) :"0" (out), [Key] "1" (keyPt), [ctr] "2" (ctr), [blocks] "r" (blocks), [input] "3" (in) - ,[inX] "4" (xPt), [inY] "m" (aes->H) + ,[inX] "4" (xPt), [inY] "m" (aes->gcm.H) : "cc", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14" ,"v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24" @@ -2464,7 +2469,7 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, out, partial); xorbuf(x, scratch, AES_BLOCK_SIZE); - GMULT(x, aes->H); + GMULT(x, aes->gcm.H); } /* Hash in the lengths of A and C in bits */ @@ -2542,7 +2547,7 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, :[out] "=r" (sPt), "=r" (keyPt), "=r" (iCtr) :[tag] "0" (sPt), [Key] "1" (keyPt), - [ctr] "2" (iCtr) , [h] "m" (aes->H) + [ctr] "2" (iCtr) , [h] "m" (aes->gcm.H) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10","v11","v12","v13","v14", "v15", "v16", "v17","v18", "v19", "v20","v21","v22","v23", @@ -2670,8 +2675,8 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); - GMULT(initialCounter, aes->H); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GMULT(initialCounter, aes->gcm.H); } XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE); @@ -2681,8 +2686,8 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte Tprime[AES_BLOCK_SIZE]; byte EKY0[AES_BLOCK_SIZE]; - GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); - GMULT(Tprime, aes->H); + GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); + GMULT(Tprime, aes->gcm.H); wc_AesEncrypt(aes, ctr, EKY0); xorbuf(Tprime, EKY0, sizeof(Tprime)); @@ -4280,7 +4285,7 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, byte x[AES_BLOCK_SIZE]; byte scratch[AES_BLOCK_SIZE]; word32 blocks, partial; - byte* h = aes->H; + byte* h = aes->gcm.H; XMEMSET(x, 0, AES_BLOCK_SIZE); @@ -4377,7 +4382,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); } XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE); @@ -4398,7 +4403,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, } - GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); + GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz); wc_AesEncrypt(aes, initialCounter, scratch); if (authTagSz > AES_BLOCK_SIZE) { xorbuf(authTag, scratch, AES_BLOCK_SIZE); @@ -4454,7 +4459,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { - GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); } XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE); @@ -4464,7 +4469,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte Tprime[AES_BLOCK_SIZE]; byte EKY0[AES_BLOCK_SIZE]; - GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); + GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); wc_AesEncrypt(aes, ctr, EKY0); xorbuf(Tprime, EKY0, sizeof(Tprime)); @@ -4523,7 +4528,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, #define GHASH_ONE_BLOCK(aes, block) \ do { \ xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE); \ - GMULT(AES_TAG(aes), aes->H); \ + GMULT(AES_TAG(aes), aes->gcm.H); \ } \ while (0) @@ -4719,8 +4724,8 @@ static void AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz) word32 aadTemp = aes->aadLen; aes->aadLen = 0; #endif - GHASH(aes, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); - GMULT(counter, aes->H); + GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); + GMULT(counter, aes->gcm.H); #ifdef OPENSSL_EXTRA aes->aadLen = aadTemp; #endif @@ -5401,10 +5406,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) aes->gcmKeySet = 1; #endif - wc_AesEncrypt(aes, iv, aes->H); + wc_AesEncrypt(aes, iv, aes->gcm.H); #if defined(__aarch64__) { - word32* pt = (word32*)aes->H; + word32* pt = (word32*)aes->gcm.H; __asm__ volatile ( "LD1 {v0.16b}, [%[h]] \n" "RBIT v0.16b, v0.16b \n" @@ -5416,7 +5421,7 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) } #else { - word32* pt = (word32*)aes->H; + word32* pt = (word32*)aes->gcm.H; __asm__ volatile ( "VLD1.32 {q0}, [%[h]] \n" "VREV64.8 q0, q0 \n" @@ -5970,7 +5975,7 @@ static void GenerateM0(Aes* aes) /* 0 times -> 0x0 */ XMEMSET(m[0x0], 0, AES_BLOCK_SIZE); /* 1 times -> 0x8 */ - XMEMCPY(m[0x8], aes->H, AES_BLOCK_SIZE); + XMEMCPY(m[0x8], aes->gcm.H, AES_BLOCK_SIZE); /* 2 times -> 0x4 */ XMEMCPY(m[0x4], m[0x8], AES_BLOCK_SIZE); RIGHTSHIFTX(m[0x4]); @@ -6035,7 +6040,7 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); if (ret == 0) { - AES_ECB_encrypt(iv, aes->H, AES_BLOCK_SIZE, + AES_ECB_encrypt(iv, aes->gcm.H, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds); GenerateM0(aes); } diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 39c68cbb3..af4387c14 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2085,6 +2085,9 @@ int wc_hash2mgf(enum wc_HashType hType) case WC_HASH_TYPE_SHA3_512: case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2S: +#ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: +#endif #ifdef WOLFSSL_SHAKE128 case WC_HASH_TYPE_SHAKE128: #endif diff --git a/wolfcrypt/src/sm2.c b/wolfcrypt/src/sm2.c new file mode 100644 index 000000000..e16c5c5b1 --- /dev/null +++ b/wolfcrypt/src/sm2.c @@ -0,0 +1,13 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFSSL_SM2 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfcrypt/src/sm3.c b/wolfcrypt/src/sm3.c new file mode 100644 index 000000000..60adc9dd2 --- /dev/null +++ b/wolfcrypt/src/sm3.c @@ -0,0 +1,13 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFSSL_SM3 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfcrypt/src/sm3_asm.S b/wolfcrypt/src/sm3_asm.S new file mode 100644 index 000000000..62c3ed811 --- /dev/null +++ b/wolfcrypt/src/sm3_asm.S @@ -0,0 +1,3 @@ + +#error "Contact wolfSSL to get the implementation of this file" + diff --git a/wolfcrypt/src/sm4.c b/wolfcrypt/src/sm4.c new file mode 100644 index 000000000..51ade6283 --- /dev/null +++ b/wolfcrypt/src/sm4.c @@ -0,0 +1,13 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFSSL_SM4 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index d2853311d..ce4d6960d 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -5227,6 +5227,53 @@ int sp_exch(sp_int* a, sp_int* b) #if defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT) && \ !defined(WC_NO_CACHE_RESISTANT) +/* Conditional swap of SP int values in constant time. + * + * @param [in] a First SP int to conditionally swap. + * @param [in] b Second SP int to conditionally swap. + * @param [in] cnt Count of words to copy. + * @param [in] swap When value is 1 then swap. + * @param [in] t Temporary SP int to use in swap. + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_cond_swap_ct_ex(sp_int* a, sp_int* b, int cnt, int swap, sp_int* t) +{ + unsigned int i; + sp_int_digit mask = (sp_int_digit)0 - (sp_int_digit)swap; + + /* XOR other fields in sp_int into temp - mask set when swapping. */ + t->used = (a->used ^ b->used) & (unsigned int)mask; +#ifdef WOLFSSL_SP_INT_NEGATIVE + t->sign = (a->sign ^ b->sign) & (unsigned int)mask; +#endif + + /* XOR requested words into temp - mask set when swapping. */ + for (i = 0; i < (unsigned int)cnt; i++) { + t->dp[i] = (a->dp[i] ^ b->dp[i]) & mask; + } + + /* XOR temporary - when mask set then result will be b. */ + a->used ^= t->used; +#ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign ^= t->sign; +#endif + for (i = 0; i < (unsigned int)cnt; i++) { + a->dp[i] ^= t->dp[i]; + } + + /* XOR temporary - when mask set then result will be a. */ + b->used ^= t->used; +#ifdef WOLFSSL_SP_INT_NEGATIVE + b->sign ^= b->sign; +#endif + for (i = 0; i < (unsigned int)cnt; i++) { + b->dp[i] ^= t->dp[i]; + } + + return MP_OKAY; +} + /* Conditional swap of SP int values in constant time. * * @param [in] a First SP int to conditionally swap. @@ -5238,43 +5285,13 @@ int sp_exch(sp_int* a, sp_int* b) */ int sp_cond_swap_ct(sp_int* a, sp_int* b, int cnt, int swap) { - unsigned int i; int err = MP_OKAY; - sp_int_digit mask = (sp_int_digit)0 - (sp_int_digit)swap; DECL_SP_INT(t, (size_t)cnt); /* Allocate temporary to hold masked xor of a and b. */ ALLOC_SP_INT(t, cnt, err, NULL); - if (err == MP_OKAY) { - /* XOR other fields in sp_int into temp - mask set when swapping. */ - t->used = (a->used ^ b->used) & (unsigned int)mask; - #ifdef WOLFSSL_SP_INT_NEGATIVE - t->sign = (a->sign ^ b->sign) & (unsigned int)mask; - #endif - /* XOR requested words into temp - mask set when swapping. */ - for (i = 0; i < (unsigned int)cnt; i++) { - t->dp[i] = (a->dp[i] ^ b->dp[i]) & mask; - } - - /* XOR temporary - when mask set then result will be b. */ - a->used ^= t->used; - #ifdef WOLFSSL_SP_INT_NEGATIVE - a->sign ^= t->sign; - #endif - for (i = 0; i < (unsigned int)cnt; i++) { - a->dp[i] ^= t->dp[i]; - } - - /* XOR temporary - when mask set then result will be a. */ - b->used ^= t->used; - #ifdef WOLFSSL_SP_INT_NEGATIVE - b->sign ^= b->sign; - #endif - for (i = 0; i < (unsigned int)cnt; i++) { - b->dp[i] ^= t->dp[i]; - } - } + err = sp_cond_swap_ct_ex(a, b, cnt, swap, t); FREE_SP_INT(t, NULL); return err; diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index eb463f74f..4c1fa9aac 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -4807,21 +4807,10 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) #endif /* WOLFSSL_KEY_GEN || HAVE_ECC */ -static int fp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m) +static int fp_cond_swap_ct_ex(mp_int* a, mp_int* b, int c, int m, mp_int* t) { int i; mp_digit mask = (mp_digit)0 - m; -#ifndef WOLFSSL_SMALL_STACK - fp_int t[1]; -#else - fp_int* t; -#endif - -#ifdef WOLFSSL_SMALL_STACK - t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); - if (t == NULL) - return FP_MEM; -#endif t->used = (a->used ^ b->used) & mask; for (i = 0; i < c; i++) { @@ -4836,6 +4825,26 @@ static int fp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m) b->dp[i] ^= t->dp[i]; } + return FP_OKAY; +} + + +static int fp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m) +{ +#ifndef WOLFSSL_SMALL_STACK + fp_int t[1]; +#else + fp_int* t; +#endif + +#ifdef WOLFSSL_SMALL_STACK + t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) + return FP_MEM; +#endif + + fp_cond_swap_ct_ex(a, b, c, m, t); + #ifdef WOLFSSL_SMALL_STACK XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); #endif @@ -5426,7 +5435,12 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) #endif /* !NO_RSA || !NO_DSA || !NO_DH || WOLFSSL_KEY_GEN */ -int mp_cond_swap_ct(mp_int * a, mp_int * b, int c, int m) +int mp_cond_swap_ct_ex(mp_int* a, mp_int* b, int c, int m, mp_int* t) +{ + return fp_cond_swap_ct_ex(a, b, c, m, t); +} + +int mp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m) { return fp_cond_swap_ct(a, b, c, m); } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index cab2e8d5e..9d532358e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -257,6 +257,9 @@ const byte const_byte_array[] = "A+Gd\0\0\0"; #ifdef HAVE_ECC #include #endif +#ifdef WOLFSSL_SM2 + #include +#endif #ifdef HAVE_HPKE #include #endif @@ -293,6 +296,12 @@ const byte const_byte_array[] = "A+Gd\0\0\0"; #ifdef WOLFSSL_SHA3 #include #endif +#ifdef WOLFSSL_SM3 + #include +#endif +#ifdef WOLFSSL_SM4 + #include +#endif #ifdef HAVE_LIBZ #include #endif @@ -439,6 +448,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha384_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha3_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake128_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake256_test(void); +WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm3_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_md5_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha_test(void); @@ -488,6 +498,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t gmac_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesccm_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aeskeywrap_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t camellia_test(void); +#ifdef WOLFSSL_SM4 +WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm4_test(void); +#endif #ifdef WC_RSA_NO_PADDING WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_no_pad_test(void); #endif @@ -1110,6 +1123,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ TEST_PASS("SHAKE256 test passed!\n"); #endif +#ifdef WOLFSSL_SM3 + if ( (ret = sm3_test()) != 0) + return err_sys("SM-3 test failed!\n", ret); + else + TEST_PASS("SM-3 test passed!\n"); +#endif + #ifndef NO_HASH_WRAPPER if ( (ret = hash_test()) != 0) TEST_FAIL("Hash test failed!\n", ret); @@ -1374,6 +1394,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ TEST_PASS("CAMELLIA test passed!\n"); #endif +#ifdef WOLFSSL_SM4 + if ( (ret = sm4_test()) != 0) + return err_sys("SM-4 test failed!\n", ret); + else + TEST_PASS("SM-4 test passed!\n"); +#endif + #if !defined(NO_RSA) #ifdef WC_RSA_NO_PADDING if ( (ret = rsa_no_pad_test()) != 0) @@ -4749,6 +4776,168 @@ exit: } #endif +#ifdef WOLFSSL_SM3 +WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm3_test(void) +{ + wc_Sm3 sm3, sm3Copy; + byte hash[WC_SM3_DIGEST_SIZE]; + byte hashGet[WC_SM3_DIGEST_SIZE]; + byte hashCopy[WC_SM3_DIGEST_SIZE]; + wc_test_ret_t ret = 0; + + testVector a, b, c; + testVector test_sm3[3]; + int times = sizeof(test_sm3) / sizeof(struct testVector), i; + + a.input = ""; + a.output = "\x1a\xb2\x1d\x83\x55\xcf\xa1\x7f\x8e\x61\x19\x48\x31\xe8\x1a" + "\x8f\x22\xbe\xc8\xc7\x28\xfe\xfb\x74\x7e\xd0\x35\xeb\x50\x82" + "\xaa\x2b"; + a.inLen = XSTRLEN(a.input); + a.outLen = WC_SM3_DIGEST_SIZE; + + b.input = "abc"; + b.output = "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1\xf2\xd4\x6b\xdc\x10\xe4" + "\xe2\x41\x67\xc4\x87\x5c\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b" + "\xa8\xe0"; + b.inLen = XSTRLEN(b.input); + b.outLen = WC_SM3_DIGEST_SIZE; + + c.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + c.output = "\x63\x9b\x6c\xc5\xe6\x4d\x9e\x37\xa3\x90\xb1\x92\xdf\x4f\xa1" + "\xea\x07\x20\xab\x74\x7f\xf6\x92\xb9\xf3\x8c\x4e\x66\xad\x7b" + "\x8c\x05"; + c.inLen = XSTRLEN(c.input); + c.outLen = WC_SM3_DIGEST_SIZE; + + test_sm3[0] = a; + test_sm3[1] = b; + test_sm3[2] = c; + + ret = wc_InitSm3(&sm3, HEAP_HINT, devId); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_InitSm3(&sm3Copy, HEAP_HINT, devId); + if (ret != 0) { + wc_Sm3Free(&sm3); + return WC_TEST_RET_ENC_EC(ret); + } + + /* Test all the KATs. */ + for (i = 0; i < times; ++i) { + ret = wc_Sm3Update(&sm3, (byte*)test_sm3[i].input, + (word32)test_sm3[i].inLen); + if (ret != 0) { + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + } + /* Get the final hash but leave ready for more updates. */ + ret = wc_Sm3GetHash(&sm3, hashGet); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + + /* Make a copy of the hash. */ + ret = wc_Sm3Copy(&sm3, &sm3Copy); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + /* Get the final hash with original. */ + ret = wc_Sm3Final(&sm3, hash); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + + /* Get the final hash with copy. */ + ret = wc_Sm3Final(&sm3Copy, hashCopy); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + /* Dispose of copy. */ + wc_Sm3Free(&sm3Copy); + + /* Check hashes match expected. */ + if (XMEMCMP(hash, test_sm3[i].output, WC_SM3_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + if (XMEMCMP(hash, hashGet, WC_SM3_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + if (XMEMCMP(hash, hashCopy, WC_SM3_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + } + +#ifndef NO_LARGE_HASH_TEST + { + word32 sz; + byte large_input[1024]; + #ifdef HASH_SIZE_LIMIT + const char* large_digest = + "\x6c\x42\x57\x64\x8e\x45\xf3\xb6\xc0\x83\xd3\x41\x83\x66\x51\xb4" + "\x50\xfe\x06\xb5\xb7\x1e\xd5\x0d\x41\xfc\x1e\xe5\xc6\x57\x95\x0f"; + + times = 20; + #else + const char* large_digest = + "\x34\x51\x3c\xde\x7c\x30\xb7\xc5\xaa\x97\x3b\xed\xb3\x16\xb9\x76" + "\x35\x46\x14\x80\x2a\x57\xca\xd9\x48\xf9\x93\xcc\x1f\xdd\xab\x79"; + + times = 100; + #endif + + /* Set large input to something. */ + for (i = 0; i < (int)sizeof(large_input); i++) { + large_input[i] = (byte)(i & 0xFF); + } + + /* Hash a large number of times. */ + for (i = 0; i < times; ++i) { + ret = wc_Sm3Update(&sm3, (byte*)large_input, + (word32)sizeof(large_input)); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + } + /* Calculate hash and compare to expected. */ + ret = wc_Sm3Final(&sm3, hash); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit); + if (XMEMCMP(hash, large_digest, WC_SM3_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit); + + + /* Check updating with various sizes works. */ + for (sz = 1; sz <= 64; sz++) { + /* Hash a large number of times. */ + for (i = 0; i < times; ++i) { + word32 o; + + /* Update sz bytes at a time from large input buffer. */ + for (o = 0; o + sz <= (word32)sizeof(large_input); o += sz) { + ret = wc_Sm3Update(&sm3, (byte*)(large_input + o), sz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(o), exit); + } + /* Check for left-overs. */ + if (o < (word32)sizeof(large_input)) { + ret = wc_Sm3Update(&sm3, (byte*)(large_input + o), + (word32)sizeof(large_input) - o); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(i), exit); + } + } + + /* Calculate hash and compare to expected. */ + ret = wc_Sm3Final(&sm3, hash); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(sz), exit); + if (XMEMCMP(hash, large_digest, WC_SM3_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_I(sz), exit); + } + } +#endif /* NO_LARGE_HASH_TEST */ + +exit: + + wc_Sm3Free(&sm3); + wc_Sm3Free(&sm3Copy); + + return ret; +} +#endif + #ifndef NO_HASH_WRAPPER WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void) { @@ -5413,7 +5602,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha256_test(void) #ifndef HAVE_FIPS if ((ret = wc_HmacSizeByType(WC_SHA256)) != WC_SHA256_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); - if ((ret = wc_HmacSizeByType(20)) != BAD_FUNC_ARG) + if ((ret = wc_HmacSizeByType(21)) != BAD_FUNC_ARG) return WC_TEST_RET_ENC_EC(ret); #endif if ((ret = wolfSSL_GetHmacMaxSize()) != WC_MAX_DIGEST_SIZE) @@ -13028,6 +13217,528 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t camellia_test(void) } #endif /* HAVE_CAMELLIA */ +#ifdef WOLFSSL_SM4 +#ifdef WOLFSSL_SM4_ECB +static int sm4_ecb_test(void) +{ + /* draft-ribose-cfrg-sm4-10 A.2.1.1 */ + WOLFSSL_SMALL_STACK_STATIC const byte k1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p1[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB + }; + WOLFSSL_SMALL_STACK_STATIC const byte c1_ecb[] = { + 0x5E, 0xC8, 0x14, 0x3D, 0xE5, 0x09, 0xCF, 0xF7, + 0xB5, 0x17, 0x9F, 0x8F, 0x47, 0x4B, 0x86, 0x19, + 0x2F, 0x1D, 0x30, 0x5A, 0x7F, 0xB1, 0x7D, 0xF9, + 0x85, 0xF8, 0x1C, 0x84, 0x82, 0x19, 0x23, 0x04 + }; + + wc_Sm4 sm4; + byte enc[SM4_BLOCK_SIZE * 4]; + byte dec[SM4_BLOCK_SIZE * 4]; + int ret; + + ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + /* Encrypt and decrypt with ECB. */ + ret = wc_Sm4SetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4EcbEncrypt(&sm4, enc, p1, sizeof(p1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c1_ecb, sizeof(c1_ecb)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4EcbDecrypt(&sm4, dec, enc, sizeof(c1_ecb)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p1, sizeof(p1)) != 0) + return WC_TEST_RET_ENC_NC; + + wc_Sm4Free(&sm4); + + return 0; +} +#endif + +#ifdef WOLFSSL_SM4_CBC +static int sm4_cbc_test(void) +{ + /* draft-ribose-cfrg-sm4-10 A.2.2.1 */ + WOLFSSL_SMALL_STACK_STATIC const byte k1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p1[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB + }; + WOLFSSL_SMALL_STACK_STATIC const byte i1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }; + WOLFSSL_SMALL_STACK_STATIC const byte c1_cbc[] = { + 0x78, 0xEB, 0xB1, 0x1C, 0xC4, 0x0B, 0x0A, 0x48, + 0x31, 0x2A, 0xAE, 0xB2, 0x04, 0x02, 0x44, 0xCB, + 0x4C, 0xB7, 0x01, 0x69, 0x51, 0x90, 0x92, 0x26, + 0x97, 0x9B, 0x0D, 0x15, 0xDC, 0x6A, 0x8F, 0x6D + }; + + wc_Sm4 sm4; + byte enc[SM4_BLOCK_SIZE * 4]; + byte dec[SM4_BLOCK_SIZE * 4]; + int ret; + + ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + /* Encrypt and decrypt with CBC. */ + ret = wc_Sm4SetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4CbcEncrypt(&sm4, enc, p1, sizeof(p1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c1_cbc, sizeof(c1_cbc)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4CbcDecrypt(&sm4, dec, enc, sizeof(c1_cbc)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p1, sizeof(p1)) != 0) + return WC_TEST_RET_ENC_NC; + + /* Encrypt and decrypt in-place with CBC. */ + ret = wc_Sm4SetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + XMEMCPY(enc, p1, sizeof(p1)); + ret = wc_Sm4CbcEncrypt(&sm4, enc, enc, sizeof(p1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c1_cbc, sizeof(c1_cbc)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4CbcDecrypt(&sm4, enc, enc, sizeof(c1_cbc)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, p1, sizeof(p1)) != 0) + return WC_TEST_RET_ENC_NC; + + wc_Sm4Free(&sm4); + + return 0; +} +#endif + +#ifdef WOLFSSL_SM4_CTR +static int sm4_ctr_test(void) +{ + /* draft-ribose-cfrg-sm4-10 A.2.5.1 */ + WOLFSSL_SMALL_STACK_STATIC const byte k1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte i1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }; + WOLFSSL_SMALL_STACK_STATIC const byte p2[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB + }; + WOLFSSL_SMALL_STACK_STATIC const byte c2_ctr[] = { + 0xAC, 0x32, 0x36, 0xCB, 0x97, 0x0C, 0xC2, 0x07, + 0x91, 0x36, 0x4C, 0x39, 0x5A, 0x13, 0x42, 0xD1, + 0xA3, 0xCB, 0xC1, 0x87, 0x8C, 0x6F, 0x30, 0xCD, + 0x07, 0x4C, 0xCE, 0x38, 0x5C, 0xDD, 0x70, 0xC7, + 0xF2, 0x34, 0xBC, 0x0E, 0x24, 0xC1, 0x19, 0x80, + 0xFD, 0x12, 0x86, 0x31, 0x0C, 0xE3, 0x7B, 0x92, + 0x6E, 0x02, 0xFC, 0xD0, 0xFA, 0xA0, 0xBA, 0xF3, + 0x8B, 0x29, 0x33, 0x85, 0x1D, 0x82, 0x45, 0x14 + }; + + wc_Sm4 sm4; + byte enc[SM4_BLOCK_SIZE * 4]; + byte dec[SM4_BLOCK_SIZE * 4]; + int chunk; + int i; + int ret; + + ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + /* Encrypt and decrypt using encrypt with CTR. */ + ret = wc_Sm4SetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4CtrEncrypt(&sm4, enc, p2, sizeof(p2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c2_ctr, sizeof(c2_ctr)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sm4CtrEncrypt(&sm4, dec, enc, sizeof(c2_ctr)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p2, sizeof(p2)) != 0) + return WC_TEST_RET_ENC_NC; + + for (chunk = 1; chunk <= SM4_BLOCK_SIZE + 1; chunk++) { + ret = wc_Sm4SetIV(&sm4, i1); + if (ret != 0) + return WC_TEST_RET_ENC_I(chunk); + + XMEMSET(enc, 0, sizeof(enc)); + for (i = 0; i + chunk <= (int)sizeof(p2); i += chunk) { + ret = wc_Sm4CtrEncrypt(&sm4, enc + i, p2 + i, chunk); + if (ret != 0) + return WC_TEST_RET_ENC_I(i); + } + if (i < (int)sizeof(p2)) { + ret = wc_Sm4CtrEncrypt(&sm4, enc + i, p2 + i, sizeof(p2) - i); + if (ret != 0) + return WC_TEST_RET_ENC_I(chunk); + } + if (XMEMCMP(enc, c2_ctr, sizeof(c2_ctr)) != 0) + return WC_TEST_RET_ENC_I(chunk); + } + + wc_Sm4Free(&sm4); + + return 0; +} +#endif + +#ifdef WOLFSSL_SM4_GCM +static int sm4_gcm_test(void) +{ + WOLFSSL_SMALL_STACK_STATIC const byte k1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p1[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB + }; + WOLFSSL_SMALL_STACK_STATIC const byte i1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }; + WOLFSSL_SMALL_STACK_STATIC const byte a1[] = { + 0xFF, 0xEE, 0xDD + }; + WOLFSSL_SMALL_STACK_STATIC const byte tag1[] = { + 0x83, 0xb2, 0x91, 0xcf, 0x22, 0xc9, 0x5f, 0x89, + 0xde, 0x3d, 0x52, 0x8d, 0xd7, 0x13, 0x50, 0x89 + }; + WOLFSSL_SMALL_STACK_STATIC const byte c1[] = { + 0xff, 0x8b, 0xb2, 0x3b, 0x0a, 0x0a, 0x12, 0xa4, + 0xa8, 0x4c, 0x4f, 0x67, 0x06, 0x81, 0xbb, 0x88, + 0x66, 0x17, 0xc7, 0x43, 0xbf, 0xae, 0x41, 0x40, + 0xec, 0x1e, 0x03, 0x85, 0x2b, 0x56, 0xa8, 0xc0 + }; + /* RFC8998 A.1. */ + WOLFSSL_SMALL_STACK_STATIC const byte i2[] = { + 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, + 0x00, 0x00, 0xAB, 0xCD + }; + WOLFSSL_SMALL_STACK_STATIC const byte k2[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p2[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA + }; + WOLFSSL_SMALL_STACK_STATIC const byte a2[] = { + 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, + 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, + 0xAB, 0xAD, 0xDA, 0xD2 + }; + WOLFSSL_SMALL_STACK_STATIC const byte c2[] = { + 0x17, 0xF3, 0x99, 0xF0, 0x8C, 0x67, 0xD5, 0xEE, + 0x19, 0xD0, 0xDC, 0x99, 0x69, 0xC4, 0xBB, 0x7D, + 0x5F, 0xD4, 0x6F, 0xD3, 0x75, 0x64, 0x89, 0x06, + 0x91, 0x57, 0xB2, 0x82, 0xBB, 0x20, 0x07, 0x35, + 0xD8, 0x27, 0x10, 0xCA, 0x5C, 0x22, 0xF0, 0xCC, + 0xFA, 0x7C, 0xBF, 0x93, 0xD4, 0x96, 0xAC, 0x15, + 0xA5, 0x68, 0x34, 0xCB, 0xCF, 0x98, 0xC3, 0x97, + 0xB4, 0x02, 0x4A, 0x26, 0x91, 0x23, 0x3B, 0x8D + }; + WOLFSSL_SMALL_STACK_STATIC const byte tag2[] = { + 0x83, 0xDE, 0x35, 0x41, 0xE4, 0xC2, 0xB5, 0x81, + 0x77, 0xE0, 0x65, 0xA9, 0xBF, 0x7B, 0x62, 0xEC + }; + + wc_Sm4 sm4; + byte enc[SM4_BLOCK_SIZE * 4]; + byte dec[SM4_BLOCK_SIZE * 4]; + byte tag[SM4_BLOCK_SIZE]; + int ret; + + ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + /* Encrypt and decrypt using encrypt with GCM. */ + ret = wc_Sm4GcmSetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4GcmEncrypt(&sm4, enc, p1, sizeof(p1), i1, sizeof(i1), tag, + sizeof(tag), a1, sizeof(a1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c1, sizeof(c1)) != 0) + return WC_TEST_RET_ENC_NC; + if (XMEMCMP(tag, tag1, sizeof(tag1)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4GcmDecrypt(&sm4, dec, enc, sizeof(c1), i1, sizeof(i1), tag, + sizeof(tag), a1, sizeof(a1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p1, sizeof(p1)) != 0) + return WC_TEST_RET_ENC_NC; + + /* RFC8998 test vector. */ + ret = wc_Sm4GcmSetKey(&sm4, k2, sizeof(k2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4GcmEncrypt(&sm4, enc, p2, sizeof(p2), i2, sizeof(i2), tag, + sizeof(tag), a2, sizeof(a2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c2, sizeof(c2)) != 0) + return WC_TEST_RET_ENC_NC; + if (XMEMCMP(tag, tag2, sizeof(tag2)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4GcmDecrypt(&sm4, dec, enc, sizeof(c2), i2, sizeof(i2), tag, + sizeof(tag), a2, sizeof(a2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p2, sizeof(p2)) != 0) + return WC_TEST_RET_ENC_NC; + + wc_Sm4Free(&sm4); + + return 0; +} +#endif + +#ifdef WOLFSSL_SM4_CCM +static int sm4_ccm_test(void) +{ + WOLFSSL_SMALL_STACK_STATIC const byte k1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p1[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB + }; + WOLFSSL_SMALL_STACK_STATIC const byte i1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }; + WOLFSSL_SMALL_STACK_STATIC const byte a1[] = { + 0xFF, 0xEE, 0xDD + }; + WOLFSSL_SMALL_STACK_STATIC const byte tag1[] = { + 0x9a, 0x98, 0x04, 0xb6, 0x0f, 0x19, 0x4a, 0x46, + 0xba, 0xed, 0xe6, 0x89, 0x69, 0x34, 0xad, 0x61 + }; + WOLFSSL_SMALL_STACK_STATIC const byte c1[] = { + 0xbd, 0xc0, 0x72, 0x60, 0xda, 0x2d, 0x11, 0xdc, + 0x66, 0x33, 0xcc, 0xec, 0xb2, 0xf4, 0x53, 0x59, + 0x9e, 0xb1, 0xb3, 0x6b, 0x1f, 0x1c, 0xfb, 0x29, + 0xf5, 0x37, 0xfc, 0x00, 0xf2, 0x4e, 0x70, 0x6f + }; + /* RFC8998 A.1. */ + WOLFSSL_SMALL_STACK_STATIC const byte i2[] = { + 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, + 0x00, 0x00, 0xAB, 0xCD + }; + WOLFSSL_SMALL_STACK_STATIC const byte k2[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 + }; + WOLFSSL_SMALL_STACK_STATIC const byte p2[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA + }; + WOLFSSL_SMALL_STACK_STATIC const byte a2[] = { + 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, + 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, + 0xAB, 0xAD, 0xDA, 0xD2 + }; + WOLFSSL_SMALL_STACK_STATIC const byte c2[] = { + 0x48, 0xAF, 0x93, 0x50, 0x1F, 0xA6, 0x2A, 0xDB, + 0xCD, 0x41, 0x4C, 0xCE, 0x60, 0x34, 0xD8, 0x95, + 0xDD, 0xA1, 0xBF, 0x8F, 0x13, 0x2F, 0x04, 0x20, + 0x98, 0x66, 0x15, 0x72, 0xE7, 0x48, 0x30, 0x94, + 0xFD, 0x12, 0xE5, 0x18, 0xCE, 0x06, 0x2C, 0x98, + 0xAC, 0xEE, 0x28, 0xD9, 0x5D, 0xF4, 0x41, 0x6B, + 0xED, 0x31, 0xA2, 0xF0, 0x44, 0x76, 0xC1, 0x8B, + 0xB4, 0x0C, 0x84, 0xA7, 0x4B, 0x97, 0xDC, 0x5B + }; + WOLFSSL_SMALL_STACK_STATIC const byte tag2[] = { + 0x16, 0x84, 0x2D, 0x4F, 0xA1, 0x86, 0xF5, 0x6A, + 0xB3, 0x32, 0x56, 0x97, 0x1F, 0xA1, 0x10, 0xF4 + }; + + wc_Sm4 sm4; + byte enc[SM4_BLOCK_SIZE * 4]; + byte dec[SM4_BLOCK_SIZE * 4]; + byte tag[SM4_BLOCK_SIZE]; + int ret; + + ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID); + if (ret != 0) + return -6720; + + /* Encrypt and decrypt using encrypt with CCM. */ + ret = wc_Sm4SetKey(&sm4, k1, sizeof(k1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4CcmEncrypt(&sm4, enc, p1, sizeof(p1), i1, sizeof(i1), tag, + sizeof(tag), a1, sizeof(a1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c1, sizeof(c1)) != 0) + return WC_TEST_RET_ENC_NC; + if (XMEMCMP(tag, tag1, sizeof(tag1)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4CcmDecrypt(&sm4, dec, enc, sizeof(c1), i1, sizeof(i1), tag, + sizeof(tag), a1, sizeof(a1)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p1, sizeof(p1)) != 0) + return WC_TEST_RET_ENC_NC; + + /* RFC8998 test vector. */ + ret = wc_Sm4SetKey(&sm4, k2, sizeof(k2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + + ret = wc_Sm4CcmEncrypt(&sm4, enc, p2, sizeof(p2), i2, sizeof(i2), tag, + sizeof(tag), a2, sizeof(a2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(enc, c2, sizeof(c2)) != 0) + return WC_TEST_RET_ENC_NC; + if (XMEMCMP(tag, tag2, sizeof(tag2)) != 0) + return WC_TEST_RET_ENC_NC; + + ret = wc_Sm4CcmDecrypt(&sm4, dec, enc, sizeof(c2), i2, sizeof(i2), tag, + sizeof(tag), a2, sizeof(a2)); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + if (XMEMCMP(dec, p2, sizeof(p2)) != 0) + return WC_TEST_RET_ENC_NC; + + wc_Sm4Free(&sm4); + + return 0; +} +#endif + +WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm4_test(void) +{ + wc_test_ret_t ret; + +#ifdef WOLFSSL_SM4_ECB + ret = sm4_ecb_test(); + if (ret != 0) + return ret; +#endif +#ifdef WOLFSSL_SM4_CBC + ret = sm4_cbc_test(); + if (ret != 0) + return ret; +#endif +#ifdef WOLFSSL_SM4_CTR + ret = sm4_ctr_test(); + if (ret != 0) + return ret; +#endif +#ifdef WOLFSSL_SM4_GCM + ret = sm4_gcm_test(); + if (ret != 0) + return ret; +#endif +#ifdef WOLFSSL_SM4_CCM + ret = sm4_ccm_test(); + if (ret != 0) + return ret; +#endif + + return 0; +} +#endif + #ifdef HAVE_XCHACHA WOLFSSL_TEST_SUBROUTINE wc_test_ret_t XChaCha_test(void) { wc_test_ret_t ret; @@ -13290,6 +14001,7 @@ exit: return ret; } + static wc_test_ret_t random_rng_test(void) { WC_RNG localRng; @@ -13322,9 +14034,6 @@ static wc_test_ret_t random_rng_test(void) if (rng == NULL) return WC_TEST_RET_ENC_ERRNO; - #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) - rng->devId = devId; - #endif ret = _rng_test(rng, WC_TEST_RET_ENC_NC); wc_rng_free(rng); @@ -13533,9 +14242,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_test(void) #endif #if defined(WOLFSSL_STATIC_MEMORY) || !defined(WOLFSSL_NO_MALLOC) -static wc_test_ret_t simple_mem_test(int sz) +static int simple_mem_test(int sz) { - wc_test_ret_t ret = 0; + int ret = 0; byte* b; int i; @@ -14004,15 +14713,12 @@ static void initDefaultName(void) WOLFSSL_SMALL_STACK_STATIC const char certKeyUsage[] = "digitalSignature,nonRepudiation"; #endif - #if !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) && \ - !defined(NO_ASN_TIME) && defined(WOLFSSL_CERT_REQ) && \ - !defined(WOLFSSL_NO_MALLOC) + #if defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) WOLFSSL_SMALL_STACK_STATIC const char certKeyUsage2[] = "digitalSignature,nonRepudiation,keyEncipherment,keyAgreement"; #endif #endif /* WOLFSSL_CERT_EXT */ -#endif /* WOLFSSL_CERT_GEN && (!NO_RSA || HAVE_ECC) || (WOLFSSL_TEST_CERT && - * (HAVE_ED25519 || HAVE_ED448)) */ +#endif /* WOLFSSL_CERT_GEN */ #ifndef NO_RSA @@ -15079,10 +15785,11 @@ static wc_test_ret_t rsa_decode_test(RsaKey* keyPub) } ret = wc_RsaPublicKeyDecodeRaw(n, (word32)-1, e, sizeof(e), keyPub); #if !defined(WOLFSSL_SP_MATH) & !defined(WOLFSSL_SP_MATH_ALL) - if (ret != 0) { + if (ret != 0) #else - if (ret != ASN_GETINT_E) { + if (ret != ASN_GETINT_E) #endif + { ret = WC_TEST_RET_ENC_EC(ret); goto done; } @@ -25321,12 +26028,12 @@ done: #undef ECC_TEST_VERIFY_COUNT #define ECC_TEST_VERIFY_COUNT 2 -static wc_test_ret_t ecc_test_curve(WC_RNG* rng, int keySize) +static wc_test_ret_t ecc_test_curve(WC_RNG* rng, int keySize, int curve_id) { wc_test_ret_t ret; - ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, - ECC_CURVE_DEF, NULL); + ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, curve_id, + NULL); if (ret < 0) { if (ret == ECC_CURVE_OID_E) { /* ignore error for curves not found */ @@ -25931,9 +26638,8 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) #else ecc_key key[1]; #endif -#if ((defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ - (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT))) \ - && !defined(NO_ECC_SECP) +#if (defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ + (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT)) word32 idx = 0; #endif @@ -25984,9 +26690,8 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) (void)rng; #endif /* !WC_NO_RNG */ -#if ((defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ - (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT))) \ - && !defined(NO_ECC_SECP) +#if (defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ + (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT)) /* Use test ECC key - ensure real private "d" exists */ #ifdef USE_CERT_BUFFERS_256 ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, @@ -26355,6 +27060,550 @@ static wc_test_ret_t ecc_test_custom_curves(WC_RNG* rng) } #endif /* WOLFSSL_CUSTOM_CURVES */ +#ifdef WOLFSSL_SM2 +#ifdef HAVE_ECC_VERIFY +#if defined(WOLFSSL_PUBLIC_MP) && defined(WOLFSSL_CUSTOM_CURVES) + #ifdef WOLFSSL_SM2 + #ifdef HAVE_OID_ENCODING + #define CODED_SM2P256V1 {1,2,156,10197,1,301} + #define CODED_SM2P256V1_SZ 6 + #else + #define CODED_SM2P256V1 {0x06,0x08,0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D} + #define CODED_SM2P256V1_SZ 10 + #endif + #ifndef WOLFSSL_ECC_CURVE_STATIC + static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1; + #else + #define ecc_oid_sm2p256v1 CODED_SM2P256V1 + #endif + #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ + #endif /* WOLFSSL_SM2 */ + #define ECC_SM2P256V1_TEST 102 +static int test_sm2_verify_caseA2() +{ + ecc_key key; + int ret, res; + mp_int r,s; + + /* test key values */ + const char qx[] = "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A"; + const char qy[] = "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857"; + const char d[] = "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263"; + + const ecc_set_type ecc_sm2_A2 = { + 32, /* size/bytes */ + ECC_SM2P256V1_TEST, /* ID */ + "SM2P256V1_TEST", /* curve name */ + + /* from test case A.2 in draft-shen-sm2-ecdsa-02 */ + "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", /* prime */ + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", /* A */ + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", /* B */ + "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", /* order n */ + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", /* Gx */ + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", /* Gy */ + ecc_oid_sm2p256v1, /* oid/oidSz */ + ecc_oid_sm2p256v1_sz, + ECC_SM2P256V1_OID, /* oid sum */ + 1, /* cofactor */ + }; + + /* use canned hash value hash = H(ZA||M) */ + const byte hash[] = { + 0xB5,0x24,0xF5,0x52,0xCD,0x82,0xB8,0xB0, + 0x28,0x47,0x6E,0x00,0x5C,0x37,0x7F,0xB1, + 0x9A,0x87,0xE6,0xFC,0x68,0x2D,0x48,0xBB, + 0x5D,0x42,0xE3,0xD9,0xB9,0xEF,0xFE,0x76 + }; + + /* canned r and s */ + const byte rCan[] = { + 0x40,0xF1,0xEC,0x59,0xF7,0x93,0xD9,0xF4, + 0x9E,0x09,0xDC,0xEF,0x49,0x13,0x0D,0x41, + 0x94,0xF7,0x9F,0xB1,0xEE,0xD2,0xCA,0xA5, + 0x5B,0xAC,0xDB,0x49,0xC4,0xE7,0x55,0xD1 + }; + + const byte sCan[] = { + 0x6F,0xC6,0xDA,0xC3,0x2C,0x5D,0x5C,0xF1, + 0x0C,0x77,0xDF,0xB2,0x0F,0x7C,0x2E,0xB6, + 0x67,0xA4,0x57,0x87,0x2F,0xB0,0x9E,0xC5, + 0x63,0x27,0xA6,0x7E,0xC7,0xDE,0xEB,0xE7 + }; + mp_init(&r); + mp_init(&s); + + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + ret = wc_ecc_set_custom_curve(&key, &ecc_sm2_A2); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + ret = wc_ecc_import_raw_ex(&key, qx, qy, d, ECC_SM2P256V1_TEST); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + mp_read_unsigned_bin(&r, rCan, sizeof(rCan)); + mp_read_unsigned_bin(&s, sCan, sizeof(sCan)); + + ret = wc_ecc_sm2_verify_hash_ex(&r, &s, hash, sizeof(hash), &res, &key); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (res != 1) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + +done: + mp_free(&r); + mp_free(&s); + wc_ecc_free(&key); + return ret; +} +#endif /* WOLFSSL_PUBLIC_MP && WOLFSSL_CUSTOM_CURVES */ + +static int test_sm2_verify_case() +{ + ecc_key key; + int ret, res; + + /* test key values */ + const char qx[] = "637F1B135036C933DC3F7A8EBB1B7B2FD1DFBD268D4F894B5AD47DBDBECD558F"; + const char qy[] = "E88101D08048E36CCBF61CA38DDF7ABA542B4486E99E49F3A7470A857A096433"; + + /* use canned hash value hash = H(ZA||M) */ + const byte hash[] = { + 0x3B,0xFA,0x5F,0xFB,0xC4,0x27,0x8C,0x9D, + 0x02,0x3A,0x19,0xCB,0x1E,0xAA,0xD2,0xF1, + 0x50,0x69,0x5B,0x20 + }; + + const byte sig[] = { + 0x30,0x45,0x02,0x21,0x00,0xD2,0xFC,0xA3, + 0x88,0xE3,0xDF,0xA3,0x00,0x73,0x9B,0x3C, + 0x2A,0x0D,0xAD,0x44,0xA2,0xFC,0x62,0xD5, + 0x6B,0x84,0x54,0xD8,0x40,0x22,0x62,0x3D, + 0x5C,0xA6,0x61,0x9B,0xE7,0x02,0x20,0x1D, + 0xB5,0xB5,0xD9,0xD8,0xF1,0x20,0xDD,0x97, + 0x92,0xBF,0x7E,0x9B,0x3F,0xE6,0x3C,0x4B, + 0x03,0xD8,0x80,0xBD,0xB7,0x27,0x7E,0x6A, + 0x84,0x23,0xDE,0x61,0x7C,0x8D,0xDC + }; + + const byte badSig[] = { + 0x30,0x45,0x02,0x21,0x00,0xD2,0xFC,0xA3, + 0x88,0xE3,0xDF,0xA3,0x00,0x73,0x9B,0x3C, + 0x2A,0x0D,0xAD,0x44,0xA2,0xFC,0x62,0xD5, + 0x6B,0x84,0x54,0xD8,0x40,0x22,0x62,0x3D, + 0x5C,0xA6,0x61,0x9B,0xE7,0x02,0x20,0x1D, + 0xB5,0xB5,0xE9,0xD8,0xF1,0x20,0xDD,0x97, + 0x92,0xBF,0x7E,0x9B,0x3F,0xE6,0x3C,0x4B, + 0x03,0xD8,0x80,0xBD,0xB7,0x27,0x7E,0x6A, + 0x84,0x23,0xDE,0x61,0x7C,0x8D,0xDC + }; + + + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + ret = wc_ecc_import_raw(&key, qx, qy, NULL, "SM2P256V1"); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + ret = wc_ecc_sm2_verify_hash(sig, sizeof(sig), hash, sizeof(hash), &res, + &key); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (res != 1) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + + /* now test a case that should fail */ + ret = wc_ecc_sm2_verify_hash(badSig, sizeof(badSig), hash, sizeof(hash), + &res, &key); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (res == 1) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +done: + wc_ecc_free(&key); + return ret; +} + +static int ecc_sm2_test_curve(WC_RNG* rng, int testVerifyCount) +{ + const ecc_set_type* dp = wc_ecc_get_curve_params( + wc_ecc_get_curve_idx(ECC_SM2P256V1)); + int keySize = 32; + int curve_id = ECC_SM2P256V1; +#if (defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH)) && !defined(WC_NO_RNG) + WC_DECLARE_VAR(sharedA, byte, ECC_SHARED_SIZE, HEAP_HINT); + WC_DECLARE_VAR(sharedB, byte, ECC_SHARED_SIZE, HEAP_HINT); +#endif +#ifdef HAVE_ECC_KEY_EXPORT + #define ECC_KEY_EXPORT_BUF_SIZE (MAX_ECC_BYTES * 2 + 32) + WC_DECLARE_VAR(exportBuf, byte, ECC_KEY_EXPORT_BUF_SIZE, HEAP_HINT); +#endif + word32 x = 0; +#if (defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH)) && !defined(WC_NO_RNG) + word32 y; +#endif +#ifdef HAVE_ECC_SIGN + WC_DECLARE_VAR(sig, byte, ECC_SIG_SIZE, HEAP_HINT); + WC_DECLARE_VAR(digest, byte, ECC_DIGEST_SIZE, HEAP_HINT); + int i; +#ifdef HAVE_ECC_VERIFY + int verify; +#endif /* HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN */ + int ret; +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + ecc_key *userA = (ecc_key *)XMALLOC(sizeof *userA, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + ecc_key *userB = (ecc_key *)XMALLOC(sizeof *userB, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + ecc_key *pubKey = (ecc_key *)XMALLOC(sizeof *pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#else + ecc_key userA[1]; + ecc_key userB[1]; + ecc_key pubKey[1]; +#endif +#ifndef WC_NO_RNG + int curveSize; +#endif + +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC +#if (defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH)) && !defined(WC_NO_RNG) + if (sharedA == NULL || sharedB == NULL) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif + +#ifdef HAVE_ECC_KEY_EXPORT + if (exportBuf == NULL) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif + +#ifdef HAVE_ECC_SIGN + if (sig == NULL || digest == NULL) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif +#endif /* WOLFSSL_SMALL_STACK && !WOLFSSL_NO_MALLOC */ + + (void)testVerifyCount; + (void)dp; + (void)x; + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if ((userA == NULL) || + (userB == NULL) || + (pubKey == NULL)) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif + + XMEMSET(userA, 0, sizeof *userA); + XMEMSET(userB, 0, sizeof *userB); + XMEMSET(pubKey, 0, sizeof *pubKey); + + ret = wc_ecc_init_ex(userA, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + ret = wc_ecc_init_ex(userB, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + ret = wc_ecc_init_ex(pubKey, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + +#ifndef WC_NO_RNG + ret = wc_ecc_sm2_make_key(rng, userA, WC_ECC_FLAG_NONE); + if (ret == ECC_CURVE_OID_E) + goto done; /* catch case, where curve is not supported */ + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + TEST_SLEEP(); + + if (wc_ecc_get_curve_idx(curve_id) != -1) { + curveSize = wc_ecc_get_curve_size_from_id(userA->dp->id); + if (curveSize != userA->dp->size) { + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + } + } + + ret = wc_ecc_check_key(userA); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + TEST_SLEEP(); + + ret = wc_ecc_sm2_make_key(rng, userB, WC_ECC_FLAG_NONE); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + /* only perform the below tests if the key size matches */ + if (dp == NULL && keySize > 0 && wc_ecc_size(userA) != keySize) + if (ret != 0) { + ret = ECC_CURVE_OID_E; + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + } + +#ifdef HAVE_ECC_DHE +#if defined(ECC_TIMING_RESISTANT) + ret = wc_ecc_set_rng(userA, rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + ret = wc_ecc_set_rng(userB, rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); +#endif + + x = ECC_SHARED_SIZE; + ret = wc_ecc_sm2_shared_secret(userA, userB, sharedA, &x); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + y = ECC_SHARED_SIZE; + ret = wc_ecc_sm2_shared_secret(userB, userA, sharedB, &y); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (y != x) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + + if (XMEMCMP(sharedA, sharedB, x)) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif /* HAVE_ECC_DHE */ + +#ifdef HAVE_ECC_KEY_EXPORT + x = ECC_KEY_EXPORT_BUF_SIZE; + ret = wc_ecc_export_x963_ex(userA, exportBuf, &x, 0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + +#ifdef HAVE_ECC_KEY_IMPORT + ret = wc_ecc_import_x963_ex(exportBuf, x, pubKey, curve_id); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + +#ifdef HAVE_ECC_DHE + y = ECC_SHARED_SIZE; + ret = wc_ecc_sm2_shared_secret(userB, pubKey, sharedB, &y); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (XMEMCMP(sharedA, sharedB, y)) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +#endif /* HAVE_ECC_DHE */ + + #ifdef HAVE_COMP_KEY + /* try compressed export / import too */ + x = ECC_KEY_EXPORT_BUF_SIZE; + ret = wc_ecc_export_x963_ex(userA, exportBuf, &x, 1); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + wc_ecc_free(pubKey); + + ret = wc_ecc_init_ex(pubKey, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + #endif + ret = wc_ecc_import_x963_ex(exportBuf, x, pubKey, curve_id); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + #ifdef HAVE_ECC_DHE + y = ECC_SHARED_SIZE; + ret = wc_ecc_sm2_shared_secret(userB, pubKey, sharedB, &y); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (XMEMCMP(sharedA, sharedB, y)) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + #endif /* HAVE_ECC_DHE */ + +#endif /* HAVE_ECC_KEY_IMPORT */ +#endif /* HAVE_ECC_KEY_EXPORT */ +#endif /* !WC_NO_RNG */ + +#if !defined(ECC_TIMING_RESISTANT) || (defined(ECC_TIMING_RESISTANT) && \ + !defined(WC_NO_RNG)) +#ifdef HAVE_ECC_SIGN + /* ECC w/out Shamir has issue with all 0 digest */ + /* WC_BIGINT doesn't have 0 len well on hardware */ + /* Cryptocell has issues with all 0 digest */ +#if defined(ECC_SHAMIR) + /* test DSA sign hash with zeros */ + for (i = 0; i < (int)ECC_DIGEST_SIZE; i++) { + digest[i] = 0; + } + + x = ECC_SIG_SIZE; + ret = wc_ecc_sm2_sign_hash(digest, ECC_DIGEST_SIZE, sig, &x, rng, userA); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + +#ifdef HAVE_ECC_VERIFY + for (i = 0; i < testVerifyCount; i++) { + verify = 0; + ret = wc_ecc_sm2_verify_hash(sig, x, digest, ECC_DIGEST_SIZE, &verify, + userA); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + if (verify != 1) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + } +#endif /* HAVE_ECC_VERIFY */ +#endif /* ECC_SHAMIR */ + + /* test DSA sign hash with sequence (0,1,2,3,4,...) */ + for (i = 0; i < (int)ECC_DIGEST_SIZE; i++) { + digest[i] = (byte)i; + } + + x = ECC_SIG_SIZE; + ret = wc_ecc_sm2_sign_hash(digest, ECC_DIGEST_SIZE, sig, &x, rng, userA); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + +#ifdef HAVE_ECC_VERIFY + for (i = 0; i < testVerifyCount; i++) { + verify = 0; + ret = wc_ecc_sm2_verify_hash(sig, x, digest, ECC_DIGEST_SIZE, &verify, + userA); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + if (verify != 1) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + } +#endif /* HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN */ +#endif /* !ECC_TIMING_RESISTANT || (ECC_TIMING_RESISTANT && !WC_NO_RNG) */ + +#if defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG) + x = ECC_KEY_EXPORT_BUF_SIZE; + ret = wc_ecc_export_private_only(userA, exportBuf, &x); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); +#elif defined(HAVE_ECC_KEY_EXPORT) + (void)exportBuf; +#endif /* HAVE_ECC_KEY_EXPORT */ + +done: + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if (userA != NULL) { + wc_ecc_free(userA); + XFREE(userA, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + } + if (userB != NULL) { + wc_ecc_free(userB); + XFREE(userB, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + } + if (pubKey != NULL) { + wc_ecc_free(pubKey); + XFREE(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + } +#else + wc_ecc_free(pubKey); + wc_ecc_free(userB); + wc_ecc_free(userA); +#endif + +#if defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH) + WC_FREE_VAR(sharedA, HEAP_HINT); + WC_FREE_VAR(sharedB, HEAP_HINT); +#endif +#ifdef HAVE_ECC_KEY_EXPORT + WC_FREE_VAR(exportBuf, HEAP_HINT); +#endif +#ifdef HAVE_ECC_SIGN + WC_FREE_VAR(sig, HEAP_HINT); + WC_FREE_VAR(digest, HEAP_HINT); +#endif + + (void)keySize; + (void)curve_id; + (void)rng; + + return ret; +} +#endif /* HAVE_ECC_VERIFY */ + +static int test_sm2_create_digest() +{ + const byte msg[] = "message to sign"; + const byte id[] = "0123456789"; + const byte badId[] = "0123556789"; + byte expected[] = { + 0xdd, 0x4d, 0x65, 0x49, 0xa3, 0x64, 0x76, 0xc0, + 0x73, 0x05, 0xdc, 0x05, 0x16, 0xb5, 0xee, 0x9f, + 0x82, 0xf9, 0xe9, 0x7d, 0x01, 0x1a, 0xdc, 0x88, + 0x5a, 0x59, 0x9c, 0x44, 0xcc, 0x47, 0xa4, 0x78 + }; + ecc_key key; + int ret; + + /* test key values */ + const char qx[] = + "af178b7b8740cc9d5b493fbd22049c12621bc27dcc5802e75ff4d045a4158baf"; + const char qy[] = + "89933faf7a4798f48c5b9b4cd3a7693d54c9e05449946eb489c0dd50a5294805"; + const char d[] = + "b3e66c2dbfb50c6ff6830c1fac4b51293a2562f9e667052b03df2d4b43c1f34a"; + byte digest[WC_SHA256_DIGEST_SIZE]; + + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + ret = wc_ecc_import_raw(&key, qx, qy, d, "SM2P256V1"); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + ret = wc_ecc_sm2_create_digest(id, (int)XSTRLEN((const char*)id), + msg, (int)XSTRLEN((const char*)msg), WC_HASH_TYPE_SHA256, digest, + WC_SHA256_DIGEST_SIZE, &key); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + + if (XMEMCMP(digest, expected, WC_SHA256_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + + ret = wc_ecc_sm2_create_digest(badId, (int)XSTRLEN((const char*)badId), + msg, (int)XSTRLEN((const char*)msg), WC_HASH_TYPE_SHA256, digest, + WC_SHA256_DIGEST_SIZE, &key); + if (ret != 0) + goto done; + + /* should be different than the previous ID used */ + if (XMEMCMP(digest, expected, WC_SHA256_DIGEST_SIZE) == 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, done); +done: + wc_ecc_free(&key); + return ret; +} + +static int test_sm2_verify() +{ + int ret = 0; + +#ifdef HAVE_ECC_VERIFY +#if defined(WOLFSSL_PUBLIC_MP) && defined(WOLFSSL_CUSTOM_CURVES) + ret = test_sm2_verify_caseA2(); + if (ret != 0) + return ret; +#endif + + ret = test_sm2_verify_case(); + if (ret != 0) + return ret; +#endif /* HAVE_ECC_VERIFY */ + + ret = test_sm2_create_digest(); + + return ret; +} +#endif /* WOLFSSL_SM2 */ + + #if defined(WOLFSSL_CERT_GEN) && !defined(NO_ECC_SECP) && !defined(NO_ASN_TIME) /* Make Cert / Sign example for ECC cert and ECC CA */ @@ -27133,44 +28382,51 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void) #endif #if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112 - ret = ecc_test_curve(&rng, 14); + ret = ecc_test_curve(&rng, 14, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=14, Default\n"); goto done; } #endif /* HAVE_ECC112 */ #if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128 - ret = ecc_test_curve(&rng, 16); + ret = ecc_test_curve(&rng, 16, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=16, Default\n"); goto done; } #endif /* HAVE_ECC128 */ #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160 - ret = ecc_test_curve(&rng, 20); + ret = ecc_test_curve(&rng, 20, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=20, Default\n"); goto done; } #endif /* HAVE_ECC160 */ #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192 - ret = ecc_test_curve(&rng, 24); + ret = ecc_test_curve(&rng, 24, ECC_CURVE_DEF); + printf("keySize=24, Default\n"); if (ret < 0) { goto done; } #endif /* HAVE_ECC192 */ #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224 - ret = ecc_test_curve(&rng, 28); + ret = ecc_test_curve(&rng, 28, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=28, Default\n"); goto done; } #endif /* HAVE_ECC224 */ #if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239 - ret = ecc_test_curve(&rng, 30); + ret = ecc_test_curve(&rng, 30, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=30, Default\n"); goto done; } #endif /* HAVE_ECC239 */ #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 - ret = ecc_test_curve(&rng, 32); + ret = ecc_test_curve(&rng, 32, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=32, Default\n"); goto done; } #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ @@ -27184,38 +28440,64 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void) #if !defined(NO_ECC_SECP) || defined(WOLFSSL_CUSTOM_CURVES) ret = ecc_def_curve_test(&rng); if (ret < 0) { + fprintf(stderr, "Default\n"); goto done; } #endif #endif /* !NO_ECC256 */ #if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320 - ret = ecc_test_curve(&rng, 40); + ret = ecc_test_curve(&rng, 40, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=40, Default\n"); goto done; } #endif /* HAVE_ECC320 */ #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 - ret = ecc_test_curve(&rng, 48); + ret = ecc_test_curve(&rng, 48, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=48, Default\n"); goto done; } #endif /* HAVE_ECC384 */ #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 - ret = ecc_test_curve(&rng, 64); + ret = ecc_test_curve(&rng, 64, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=64, Default\n"); goto done; } #endif /* HAVE_ECC512 */ #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521 - ret = ecc_test_curve(&rng, 66); + ret = ecc_test_curve(&rng, 66, ECC_CURVE_DEF); if (ret < 0) { + printf("keySize=68, Default\n"); goto done; } #endif /* HAVE_ECC521 */ +#ifdef WOLFSSL_SM2 + ret = ecc_test_curve(&rng, 32, ECC_SM2P256V1); + if (ret < 0) { + fprintf(stderr, "SM2\n"); + goto done; + } +#endif #if defined(WOLFSSL_CUSTOM_CURVES) ret = ecc_test_custom_curves(&rng); if (ret != 0) { + fprintf(stderr, "Custom\n"); + goto done; + } +#endif + +#if defined(WOLFSSL_SM2) + ret = test_sm2_verify(); + if (ret != 0) { + fprintf(stderr, "SM2 Verify\n"); + goto done; + } + ret = ecc_sm2_test_curve(&rng, ECC_TEST_VERIFY_COUNT); + if (ret != 0) { + fprintf(stderr, "SM2 test\n"); goto done; } #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fba891061..877c595b5 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -58,6 +58,9 @@ #ifdef HAVE_CAMELLIA #include #endif +#ifdef WOLFSSL_SM4 + #include +#endif #include #ifndef NO_HMAC #include @@ -83,6 +86,9 @@ #ifdef WOLFSSL_SHA512 #include #endif +#ifdef WOLFSSL_SM3 + #include +#endif #ifdef HAVE_AESGCM #include #endif @@ -95,6 +101,9 @@ #ifdef HAVE_ECC #include #endif +#ifdef WOLFSSL_SM2 + #include +#endif #ifndef NO_DH #include #endif @@ -840,6 +849,17 @@ #endif #endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + #ifdef WOLFSSL_SM4_CBC + #define BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 + #endif + #ifdef WOLFSSL_SM4_GCM + #define BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 + #endif + #ifdef WOLFSSL_SM4_CCM + #define BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 + #endif + #endif #endif #if defined(WOLFSSL_TLS13) @@ -872,6 +892,16 @@ #define BUILD_TLS_SHA384_SHA384 #endif #endif + + #ifdef WOLFSSL_SM3 + #ifdef WOLFSSL_SM4_GCM + #define BUILD_TLS_SM4_GCM_SM3 + #endif + + #ifdef WOLFSSL_SM4_CCM + #define BUILD_TLS_SM4_CCM_SM3 + #endif + #endif #endif #if !defined(WOLFCRYPT_ONLY) && defined(NO_PSK) && \ @@ -971,6 +1001,7 @@ defined(HAVE_AESCCM) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \ !defined(NO_CHAPOL_AEAD)) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ (defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)) #define HAVE_AEAD @@ -1140,6 +1171,15 @@ enum { TLS_SHA256_SHA256 = 0xB4, TLS_SHA384_SHA384 = 0xB5, + /* TLS v1.3 SM cipher suites - 0x00 (CIPHER_BYTE) is first byte */ + TLS_SM4_GCM_SM3 = 0xC6, + TLS_SM4_CCM_SM3 = 0xC7, + + /* TLS v1.2 SM cipher suites - 0xE0 (SM_BYTE) is first byte */ + TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 = 0x11, + TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 = 0x51, + TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 = 0x52, + /* Fallback SCSV (Signaling Cipher Suite Value) */ TLS_FALLBACK_SCSV = 0x56, /* Renegotiation Indication Extension Special Suite */ @@ -1395,6 +1435,15 @@ enum { #define DTLS_AEAD_AES_CCM_FAIL_LIMIT w64From32(0x00B5, 0x04F3) #define DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT w64From32(0x005A, 0x8279) +/* Limit is (2^22 - 1) full messages [2^36 - 31 octets] + * https://www.rfc-editor.org/rfc/rfc8998.html#name-aead_sm4_gcm + */ +#define AEAD_SM4_GCM_LIMIT w64From32(0, (1 << 22) - 1) +/* Limit is (2^10 - 1) full messages [2^24 - 1 octets] + * https://www.rfc-editor.org/rfc/rfc8998.html#name-aead_sm4_ccm + */ +#define AEAD_SM4_CCM_LIMIT w64From32(0, (1 << 10) - 1) + #if defined(WOLFSSL_TLS13) || !defined(NO_PSK) #define TLS13_TICKET_NONCE_MAX_SZ 255 @@ -1432,6 +1481,7 @@ enum Misc { CHACHA_BYTE = 0xCC, /* ChaCha first cipher suite */ TLS13_BYTE = 0x13, /* TLS v1.3 first byte of cipher suite */ ECDHE_PSK_BYTE = 0xD0, /* RFC 8442 */ + SM_BYTE = 0xE0, /* SM first byte - private range */ SEND_CERT = 1, SEND_BLANK_CERT = 2, @@ -1651,6 +1701,9 @@ enum Misc { AESGCM_IMP_IV_SZ = 4, /* Size of GCM/CCM AEAD implicit IV */ AESGCM_EXP_IV_SZ = 8, /* Size of GCM/CCM AEAD explicit IV */ AESGCM_NONCE_SZ = AESGCM_EXP_IV_SZ + AESGCM_IMP_IV_SZ, + GCM_IMP_IV_SZ = 4, /* Size of GCM/CCM AEAD implicit IV */ + GCM_EXP_IV_SZ = 8, /* Size of GCM/CCM AEAD explicit IV */ + GCM_NONCE_SZ = GCM_EXP_IV_SZ + GCM_IMP_IV_SZ, CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */ CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */ @@ -1663,6 +1716,11 @@ enum Misc { AES_CCM_8_AUTH_SZ = 8, /* AES-CCM-8 Auth Tag Length */ AESCCM_NONCE_SZ = 12, + SM4_GCM_AUTH_SZ = 16, /* SM4-GCM Auth Tag length */ + SM4_GCM_NONCE_SZ = 12, /* SM4 GCM Nonce length */ + SM4_CCM_AUTH_SZ = 16, /* SM4-CCM Auth Tag length */ + SM4_CCM_NONCE_SZ = 12, /* SM4 CCM Nonce length */ + CAMELLIA_128_KEY_SIZE = 16, /* for 128 bit */ CAMELLIA_192_KEY_SIZE = 24, /* for 192 bit */ CAMELLIA_256_KEY_SIZE = 32, /* for 256 bit */ @@ -1689,6 +1747,8 @@ enum Misc { ED25519_SA_MINOR = 7, /* Least significant byte for ED25519 */ ED448_SA_MAJOR = 8, /* Most significant byte for ED448 */ ED448_SA_MINOR = 8, /* Least significant byte for ED448 */ + SM2_SA_MAJOR = 7, /* Most significant byte for SM2 with SM3 */ + SM2_SA_MINOR = 8, /* Least significant byte for SM2 with SM3 */ PQC_SA_MAJOR = 0xFE,/* Most significant byte used with PQC sig algs */ @@ -2252,6 +2312,9 @@ WOLFSSL_LOCAL void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, int haveRSAsig, int haveFalconSig, int haveDilithiumSig, int haveAnon, int tls1_2, int keySz, word16* len); +WOLFSSL_LOCAL void InitSuitesHashSigAlgo_ex2(byte* hashSigAlgo, int have, + int tls1_2, int keySz, + word16* len); WOLFSSL_LOCAL int AllocateCtxSuites(WOLFSSL_CTX* ctx); WOLFSSL_LOCAL int AllocateSuites(WOLFSSL* ssl); WOLFSSL_LOCAL void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, @@ -2341,7 +2404,9 @@ struct WOLFSSL_OCSP { typedef struct CRL_Entry CRL_Entry; -#ifdef NO_SHA +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + #define CRL_DIGEST_SIZE WC_SM3_DIGEST_SIZE +#elif defined(NO_SHA) #define CRL_DIGEST_SIZE WC_SHA256_DIGEST_SIZE #else #define CRL_DIGEST_SIZE WC_SHA_DIGEST_SIZE @@ -3195,10 +3260,11 @@ WOLFSSL_LOCAL int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data, KeyShareEntry **kse, TLSX** extensions); WOLFSSL_LOCAL int TLSX_KeyShare_Empty(WOLFSSL* ssl); WOLFSSL_LOCAL int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, - TLSX** extensions); + TLSX** extensions); WOLFSSL_LOCAL int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse); WOLFSSL_LOCAL int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, - KeyShareEntry** kse, byte* searched); + byte cipherSuite0, byte cipherSuite, KeyShareEntry** kse, + byte* searched); WOLFSSL_LOCAL int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE); WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl, int* doHelloRetry); WOLFSSL_LOCAL int TLSX_KeyShare_DeriveSecret(WOLFSSL* sclientKSEclientKSEsl); @@ -3825,6 +3891,14 @@ enum KeyExchangeAlgorithm { ecc_static_diffie_hellman_kea /* for verify suite only */ }; +/* Used with InitSuitesHashSigAlgo_ex2 */ +#define SIG_ECDSA 0x01 +#define SIG_RSA 0x02 +#define SIG_SM2 0x04 +#define SIG_FALCON 0x08 +#define SIG_DILITHIUM 0x10 +#define SIG_ANON 0x20 + /* Supported Authentication Schemes */ enum SignatureAlgorithm { anonymous_sa_algo = 0, @@ -3840,6 +3914,7 @@ enum SignatureAlgorithm { dilithium_level2_sa_algo = 14, dilithium_level3_sa_algo = 15, dilithium_level5_sa_algo = 16, + sm2_sa_algo = 17, invalid_sa_algo = 255 }; @@ -3855,6 +3930,18 @@ enum SigAlgRsaPss { pss_sha512 = 0x0b, }; +#ifdef WOLFSSL_SM2 + /* Default SM2 signature ID. */ + #define TLS12_SM2_SIG_ID ((byte*)"1234567812345678") + /* Length of default SM2 signature ID. */ + #define TLS12_SM2_SIG_ID_SZ 16 + + /* https://www.rfc-editor.org/rfc/rfc8998.html#name-sm2-signature-scheme */ + /* ID to use when signing/verifying TLS v1.3 data. */ + #define TLS13_SM2_SIG_ID ((byte*)"TLSv1.3+GM+Cipher+Suite") + /* Length of ID to use when signing/verifying TLS v1.3 data. */ + #define TLS13_SM2_SIG_ID_SZ 23 +#endif /* Supported ECC Curve Types */ enum EccCurves { @@ -3930,6 +4017,9 @@ typedef struct Ciphers { #ifdef HAVE_CHACHA ChaCha* chacha; #endif +#ifdef WOLFSSL_SM4 + wc_Sm4* sm4; +#endif #if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) && !defined(NO_HMAC) Hmac* hmac; #endif @@ -3988,6 +4078,9 @@ typedef struct Hashes { #ifdef WOLFSSL_SHA512 byte sha512[WC_SHA512_DIGEST_SIZE]; #endif + #ifdef WOLFSSL_SM3 + byte sm3[WC_SM3_DIGEST_SIZE]; + #endif } Hashes; WOLFSSL_LOCAL int BuildCertHashes(const WOLFSSL* ssl, Hashes* hashes); @@ -4003,6 +4096,9 @@ typedef union Digest { #ifdef WOLFSSL_SHA512 wc_Sha512 sha512; #endif +#ifdef WOLFSSL_SM3 + wc_Sm3 sm3; +#endif } Digest; #endif @@ -4498,7 +4594,8 @@ struct Options { word16 sentChangeCipher:1; /* Change Cipher Spec sent */ #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ - ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + ((defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)) || \ + (defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) word16 cacheMessages:1; /* Cache messages for sign/verify */ #endif @@ -4977,8 +5074,12 @@ typedef struct HS_Hashes { #ifdef WOLFSSL_SHA512 wc_Sha512 hashSha512; /* sha512 hash of handshake msgs */ #endif -#if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) +#ifdef WOLFSSL_SM3 + wc_Sm3 hashSm3; /* sm3 hash of handshake msgs */ +#endif +#if (defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + (defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3))) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) byte* messages; /* handshake messages */ int length; /* length of handshake messages' data */ int prevLen; /* length of messages but last */ @@ -5921,6 +6022,14 @@ WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen, int side); #endif /* HAVE_ECC */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + WOLFSSL_LOCAL int Sm2wSm3Sign(WOLFSSL* ssl, const byte* id, word32 idSz, + const byte* in, word32 inSz, byte* out, word32* outSz, ecc_key* key, + DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int Sm2wSm3Verify(WOLFSSL* ssl, const byte* id, + word32 idSz, const byte* in, word32 inSz, const byte* out, + word32 outSz, ecc_key* key, buffer* keyBufInfo); + #endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */ #ifdef HAVE_ED25519 WOLFSSL_LOCAL int Ed25519CheckPubKey(WOLFSSL* ssl); WOLFSSL_LOCAL int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 4b8bcf337..567c4a409 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -57,6 +57,12 @@ #include #include #include +#ifdef WOLFSSL_SM3 + #include +#endif +#ifdef WOLFSSL_SM4 + #include +#endif #if defined(WOLFSSL_BASE64_ENCODE) || defined(WOLFSSL_BASE64_DECODE) #include @@ -91,6 +97,8 @@ WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sm3(void); + WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void); @@ -149,7 +157,21 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20_poly1305(void); #define WOLFSSL_EVP_CHACHA_IV_BYTES (CHACHA_IV_BYTES + sizeof(word32)) WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20(void); #endif - +#ifdef WOLFSSL_SM4_ECB +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ecb(void); +#endif +#ifdef WOLFSSL_SM4_CBC +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_cbc(void); +#endif +#ifdef WOLFSSL_SM4_CTR +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ctr(void); +#endif +#ifdef WOLFSSL_SM4_GCM +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_gcm(void); +#endif +#ifdef WOLFSSL_SM4_CCM +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_sm4_ccm(void); +#endif typedef union { #ifndef NO_MD4 @@ -186,6 +208,9 @@ typedef union { #ifndef WOLFSSL_NOSHA3_512 WOLFSSL_SHA3_512_CTX sha3_512; #endif + #ifdef WOLFSSL_SM3 + wc_Sm3 sm3; + #endif } WOLFSSL_Hasher; @@ -225,6 +250,9 @@ typedef union { #ifdef HAVE_CHACHA ChaCha chacha; #endif +#ifdef WOLFSSL_SM4 + wc_Sm4 sm4; +#endif } WOLFSSL_Cipher; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -266,6 +294,11 @@ typedef union { #define NID_camellia_256_cbc 753 #define NID_chacha20_poly1305 1018 #define NID_chacha20 1019 +#define NID_sm4_ecb 1133 +#define NID_sm4_cbc 1134 +#define NID_sm4_ctr 1139 +#define NID_sm4_gcm 1248 +#define NID_sm4_ccm 1249 #define NID_md5WithRSA 104 #define NID_md2WithRSAEncryption 9 #define NID_md5WithRSAEncryption 99 @@ -303,6 +336,7 @@ typedef union { #define NID_shake256 1101 #define NID_sha1 64 #define NID_sha224 675 +#define NID_sm3 1143 #define NID_md2 77 #define NID_md4 257 #define NID_md5 40 @@ -346,6 +380,8 @@ typedef union { #define NID_auth_srp 1052 #define NID_auth_null 1054 #define NID_auth_any 1055 +/* Curve */ +#define NID_sm2 1172 #define NID_X9_62_id_ecPublicKey EVP_PKEY_EC #define NID_rsaEncryption EVP_PKEY_RSA @@ -360,52 +396,57 @@ typedef union { #define EVP_PKEY_PRINT_INDENT_MAX 128 enum { - AES_128_CBC_TYPE = 1, - AES_192_CBC_TYPE = 2, - AES_256_CBC_TYPE = 3, - AES_128_CTR_TYPE = 4, - AES_192_CTR_TYPE = 5, - AES_256_CTR_TYPE = 6, - AES_128_ECB_TYPE = 7, - AES_192_ECB_TYPE = 8, - AES_256_ECB_TYPE = 9, - DES_CBC_TYPE = 10, - DES_ECB_TYPE = 11, - DES_EDE3_CBC_TYPE = 12, - DES_EDE3_ECB_TYPE = 13, - ARC4_TYPE = 14, - NULL_CIPHER_TYPE = 15, - EVP_PKEY_RSA = 16, - EVP_PKEY_DSA = 17, - EVP_PKEY_EC = 18, - AES_128_GCM_TYPE = 21, - AES_192_GCM_TYPE = 22, - AES_256_GCM_TYPE = 23, - EVP_PKEY_DH = NID_dhKeyAgreement, - EVP_PKEY_HMAC = NID_hmac, - EVP_PKEY_CMAC = NID_cmac, - EVP_PKEY_HKDF = NID_hkdf, - EVP_PKEY_FALCON = 300, /* Randomly picked value. */ - EVP_PKEY_DILITHIUM= 301, /* Randomly picked value. */ - AES_128_CFB1_TYPE = 24, - AES_192_CFB1_TYPE = 25, - AES_256_CFB1_TYPE = 26, - AES_128_CFB8_TYPE = 27, - AES_192_CFB8_TYPE = 28, - AES_256_CFB8_TYPE = 29, - AES_128_CFB128_TYPE = 30, - AES_192_CFB128_TYPE = 31, - AES_256_CFB128_TYPE = 32, - AES_128_OFB_TYPE = 33, - AES_192_OFB_TYPE = 34, - AES_256_OFB_TYPE = 35, - AES_128_XTS_TYPE = 36, - AES_256_XTS_TYPE = 37, + AES_128_CBC_TYPE = 1, + AES_192_CBC_TYPE = 2, + AES_256_CBC_TYPE = 3, + AES_128_CTR_TYPE = 4, + AES_192_CTR_TYPE = 5, + AES_256_CTR_TYPE = 6, + AES_128_ECB_TYPE = 7, + AES_192_ECB_TYPE = 8, + AES_256_ECB_TYPE = 9, + DES_CBC_TYPE = 10, + DES_ECB_TYPE = 11, + DES_EDE3_CBC_TYPE = 12, + DES_EDE3_ECB_TYPE = 13, + ARC4_TYPE = 14, + NULL_CIPHER_TYPE = 15, + EVP_PKEY_RSA = 16, + EVP_PKEY_DSA = 17, + EVP_PKEY_EC = 18, + AES_128_GCM_TYPE = 21, + AES_192_GCM_TYPE = 22, + AES_256_GCM_TYPE = 23, + EVP_PKEY_DH = NID_dhKeyAgreement, + EVP_PKEY_HMAC = NID_hmac, + EVP_PKEY_CMAC = NID_cmac, + EVP_PKEY_HKDF = NID_hkdf, + EVP_PKEY_FALCON = 300, /* Randomly picked value. */ + EVP_PKEY_DILITHIUM = 301, /* Randomly picked value. */ + AES_128_CFB1_TYPE = 24, + AES_192_CFB1_TYPE = 25, + AES_256_CFB1_TYPE = 26, + AES_128_CFB8_TYPE = 27, + AES_192_CFB8_TYPE = 28, + AES_256_CFB8_TYPE = 29, + AES_128_CFB128_TYPE = 30, + AES_192_CFB128_TYPE = 31, + AES_256_CFB128_TYPE = 32, + AES_128_OFB_TYPE = 33, + AES_192_OFB_TYPE = 34, + AES_256_OFB_TYPE = 35, + AES_128_XTS_TYPE = 36, + AES_256_XTS_TYPE = 37, CHACHA20_POLY1305_TYPE = 38, - CHACHA20_TYPE = 39, - AES_128_CCM_TYPE = 40, - AES_192_CCM_TYPE = 41, - AES_256_CCM_TYPE = 42 + CHACHA20_TYPE = 39, + AES_128_CCM_TYPE = 40, + AES_192_CCM_TYPE = 41, + AES_256_CCM_TYPE = 42, + SM4_ECB_TYPE = 43, + SM4_CBC_TYPE = 44, + SM4_CTR_TYPE = 45, + SM4_GCM_TYPE = 46, + SM4_CCM_TYPE = 47 }; #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -421,6 +462,8 @@ struct WOLFSSL_EVP_CIPHER_CTX { #if !defined(NO_AES) /* working iv pointer into cipher */ ALIGN16 unsigned char iv[AES_BLOCK_SIZE]; +#elif defined(WOLFSSL_SM4) + ALIGN16 unsigned char iv[SM4_BLOCK_SIZE]; #elif defined(HAVE_CHACHA) && defined(HAVE_POLY1305) ALIGN16 unsigned char iv[CHACHA20_POLY1305_AEAD_IV_SIZE]; #elif !defined(NO_DES3) @@ -433,10 +476,12 @@ struct WOLFSSL_EVP_CIPHER_CTX { int lastUsed; #if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_AESGCM) || \ defined (WOLFSSL_AES_XTS) || (defined(HAVE_CHACHA) || \ - defined(HAVE_POLY1305) || defined(HAVE_AESCCM)) + defined(HAVE_POLY1305) || defined(HAVE_AESCCM)) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) #define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV int ivSz; -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) byte* authBuffer; int authBufferLen; byte* authIn; @@ -446,15 +491,19 @@ struct WOLFSSL_EVP_CIPHER_CTX { byte* key; /* used in partial Init()s */ #endif #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ - (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) || \ + (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; +#elif defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) + ALIGN16 unsigned char authTag[SM4_BLOCK_SIZE]; #else ALIGN16 unsigned char authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; #endif int authTagSz; #endif -#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \ + defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM) byte authIvGenEnable:1; byte authIncIv:1; #endif @@ -877,6 +926,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_ripemd160 wolfSSL_EVP_ripemd160 #define EVP_shake128 wolfSSL_EVP_shake128 #define EVP_shake256 wolfSSL_EVP_shake256 +#define EVP_sm3 wolfSSL_EVP_sm3 #define EVP_set_pw_prompt wolfSSL_EVP_set_pw_prompt #define EVP_sha3_224 wolfSSL_EVP_sha3_224 @@ -923,6 +973,11 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_rc4 wolfSSL_EVP_rc4 #define EVP_chacha20 wolfSSL_EVP_chacha20 #define EVP_chacha20_poly1305 wolfSSL_EVP_chacha20_poly1305 +#define EVP_sm4_ecb wolfSSL_EVP_sm4_ecb +#define EVP_sm4_cbc wolfSSL_EVP_sm4_cbc +#define EVP_sm4_ctr wolfSSL_EVP_sm4_ctr +#define EVP_sm4_gcm wolfSSL_EVP_sm4_gcm +#define EVP_sm4_ccm wolfSSL_EVP_sm4_ccm #define EVP_enc_null wolfSSL_EVP_enc_null #define EVP_MD_size wolfSSL_EVP_MD_size diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3e70dde71..63bbfb107 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3227,7 +3227,10 @@ enum BulkCipherAlgorithm { wolfssl_aes_gcm = 7, wolfssl_aes_ccm = 8, wolfssl_chacha = 9, - wolfssl_camellia = 10 + wolfssl_camellia = 10, + wolfssl_sm4_cbc = 11, + wolfssl_sm4_gcm = 12, + wolfssl_sm4_ccm = 13 }; @@ -3235,7 +3238,8 @@ enum BulkCipherAlgorithm { enum KDF_MacAlgorithm { wolfssl_sha256 = 4, /* needs to match hash.h wc_MACAlgorithm */ wolfssl_sha384, - wolfssl_sha512 + wolfssl_sha512, + wolfssl_sm3 = 9 }; @@ -3895,7 +3899,8 @@ enum { WOLFSSL_ECC_BRAINPOOLP512R1 = 28, WOLFSSL_ECC_X25519 = 29, WOLFSSL_ECC_X448 = 30, - WOLFSSL_ECC_MAX = 30, + WOLFSSL_ECC_SM2P256V1 = 41, + WOLFSSL_ECC_MAX = 41, WOLFSSL_FFDHE_2048 = 256, WOLFSSL_FFDHE_3072 = 257, diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 90cb8a86c..e5d872379 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -36,6 +36,33 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include +#if !defined(NO_AES) || defined(WOLFSSL_SM4) +typedef struct Gcm { + ALIGN16 byte H[16]; +#ifdef OPENSSL_EXTRA + word32 aadH[4]; /* additional authenticated data GHASH */ + word32 aadLen; /* additional authenticated data len */ +#endif +#ifdef GCM_TABLE + /* key-based fast multiplication table. */ + ALIGN16 byte M0[256][16]; +#elif defined(GCM_TABLE_4BIT) + #if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU) + ALIGN16 byte M0[16][16]; + #else + ALIGN16 byte M0[32][16]; + #endif +#endif /* GCM_TABLE */ +} Gcm; + +WOLFSSL_LOCAL void GenerateM0(Gcm* gcm); +#ifdef WOLFSSL_ARMASM +WOLFSSL_LOCAL void GMULT(byte* X, byte* Y); +#endif +WOLFSSL_LOCAL void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, + word32 cSz, byte* s, word32 sSz); +#endif + #ifndef NO_AES #if defined(HAVE_FIPS) && \ @@ -184,7 +211,6 @@ enum { WOLF_ENUM_DUMMY_LAST_ELEMENT(AES) }; - struct Aes { /* AESNI needs key first, rounds 2nd, not sure why yet */ ALIGN16 word32 key[60]; @@ -199,11 +225,7 @@ struct Aes { word32 nonceSz; #endif #ifdef HAVE_AESGCM - ALIGN16 byte H[AES_BLOCK_SIZE]; -#ifdef OPENSSL_EXTRA - word32 aadH[4]; /* additional authenticated data GHASH */ - word32 aadLen; /* additional authenticated data len */ -#endif + Gcm gcm; #ifdef WOLFSSL_SE050 sss_symmetric_t aes_ctx; /* used as the function context */ @@ -212,16 +234,6 @@ struct Aes { byte keyIdSet; byte useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */ #endif -#ifdef GCM_TABLE - /* key-based fast multiplication table. */ - ALIGN16 byte M0[256][AES_BLOCK_SIZE]; -#elif defined(GCM_TABLE_4BIT) - #if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU) - ALIGN16 byte M0[16][AES_BLOCK_SIZE]; - #else - ALIGN16 byte M0[32][AES_BLOCK_SIZE]; - #endif -#endif /* GCM_TABLE */ #ifdef HAVE_CAVIUM_OCTEON_SYNC word32 y0; #endif @@ -505,8 +517,6 @@ WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, const byte* authIn, word32 authInSz, const byte* authTag, word32 authTagSz); #endif /* WC_NO_RNG */ - WOLFSSL_LOCAL void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, - word32 cSz, byte* s, word32 sSz); #endif /* HAVE_AESGCM */ #ifdef HAVE_AESCCM WOLFSSL_LOCAL int wc_AesCcmCheckTagSize(int sz); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 7f797c25b..6bc2785d7 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -64,6 +64,9 @@ that can be serialized and deserialized in a cross-platform way. #include #endif #include +#ifdef WOLFSSL_SM3 + #include +#endif #include /* public interface */ #if defined(NO_SHA) && defined(NO_SHA256) @@ -903,7 +906,9 @@ enum Misc_ASN { ASN_BOOL_SIZE = 2, /* including type */ ASN_ECC_HEADER_SZ = 2, /* String type + 1 byte len */ ASN_ECC_CONTEXT_SZ = 2, /* Content specific type + 1 byte len */ -#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256)) +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + KEYID_SIZE = WC_SM3_DIGEST_SIZE, +#elif defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256)) KEYID_SIZE = WC_SHA256_DIGEST_SIZE, #else KEYID_SIZE = WC_SHA_DIGEST_SIZE, @@ -1085,7 +1090,8 @@ enum Hash_Sum { SHA3_384h = 422, SHA3_512h = 423, SHAKE128h = 424, - SHAKE256h = 425 + SHAKE256h = 425, + SM3h = 640 }; #if !defined(NO_DES3) || !defined(NO_AES) @@ -1119,6 +1125,7 @@ enum Key_Sum { RSAPSSk = 654, RSAESOAEPk = 651, /* 1.2.840.113549.1.1.7 */ ECDSAk = 518, + SM2k = 667, ED25519k = 256, /* 1.3.101.112 */ X25519k = 254, /* 1.3.101.110 */ ED448k = 257, /* 1.3.101.113 */ @@ -1913,7 +1920,9 @@ struct DecodedCert { #endif }; -#ifdef NO_SHA +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + #define SIGNER_DIGEST_SIZE WC_SM3_DIGEST_SIZE +#elif defined(NO_SHA) #define SIGNER_DIGEST_SIZE WC_SHA256_DIGEST_SIZE #else #define SIGNER_DIGEST_SIZE WC_SHA_DIGEST_SIZE @@ -2021,7 +2030,10 @@ typedef enum MimeStatus #endif /* HAVE_SMIME */ +WOLFSSL_LOCAL int HashIdAlg(int oidSum); WOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash); +WOLFSSL_LOCAL int CalcHashId_ex(const byte* data, word32 len, byte* hash, + int hashAlg); WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, @@ -2207,6 +2219,8 @@ WOLFSSL_LOCAL int wc_GetSerialNumber(const byte* input, word32* inOutIdx, #endif WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx); +WOLFSSL_LOCAL int GetNameHash_ex(const byte* source, word32* idx, byte* hash, + int maxIdx, int sigOID); WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der); WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, const byte* pubKey, word32 pubKeySz, enum Key_Sum ks); @@ -2364,7 +2378,9 @@ struct CertStatus { typedef struct OcspEntry OcspEntry; -#ifdef NO_SHA +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) +#define OCSP_DIGEST_SIZE WC_SM3_DIGEST_SIZE +#elif defined(NO_SHA) #define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE #else #define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE @@ -2427,6 +2443,9 @@ struct OcspResponse { struct OcspRequest { byte issuerHash[KEYID_SIZE]; byte issuerKeyHash[KEYID_SIZE]; +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + int hashSz; +#endif byte* serial; /* copy of the serial number in source cert */ int serialSz; #ifdef OPENSSL_EXTRA diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 91d833db7..49b7ec03f 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -104,6 +104,7 @@ enum Ecc_Sum { ECC_SECP256R1_OID = 526, ECC_SECP256K1_OID = 186, ECC_BRAINPOOLP256R1_OID = 104, + ECC_SM2P256V1_OID = 667, ECC_X25519_OID = 365, ECC_ED25519_OID = 256, ECC_BRAINPOOLP320R1_OID = 106, @@ -207,6 +208,8 @@ enum Ctc_SigType { CTC_RSASSAPSS = 654, + CTC_SM3wSM2 = 740, /* 1.2.156.10197.1.501 */ + CTC_ED25519 = 256, CTC_ED448 = 257, diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 1709b597a..0f5d14e45 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -243,6 +243,9 @@ typedef enum ecc_curve_id { ECC_BRAINPOOLP384R1, ECC_BRAINPOOLP512R1, + /* SM2 */ + ECC_SM2P256V1, + /* Twisted Edwards Curves */ #ifdef HAVE_CURVE25519 ECC_X25519, diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 5c062efd4..dff5f14ff 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -260,7 +260,10 @@ enum { ASN_DEPTH_E = -296, /* Invalid ASN.1 - depth check */ ASN_LEN_E = -297, /* ASN.1 length invalid */ - WC_LAST_E = -297, /* Update this to indicate last error */ + SM4_GCM_AUTH_E = -298, /* SM4-GCM Authentication check failure */ + SM4_CCM_AUTH_E = -299, /* SM4-CCM Authentication check failure */ + + WC_LAST_E = -299, /* Update this to indicate last error */ MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 71a21c2e3..b8079ba28 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -55,6 +55,9 @@ #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) #include #endif +#ifdef WOLFSSL_SM3 + #include +#endif #ifdef __cplusplus @@ -76,7 +79,8 @@ enum wc_MACAlgorithm { sha384_mac, sha512_mac, rmd_mac, - blake2b_mac + blake2b_mac, + sm3_mac, }; enum wc_HashFlags { @@ -112,6 +116,9 @@ typedef union { #ifdef WOLFSSL_SHA3 wc_Sha3 sha3; #endif + #ifdef WOLFSSL_SM3 + wc_Sm3 sm3; + #endif } wc_HashAlg; #endif /* !NO_HASH_WRAPPER */ @@ -132,6 +139,9 @@ typedef union { #elif !defined(NO_SHA256) #define WC_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE #define WC_MAX_BLOCK_SIZE WC_SHA256_BLOCK_SIZE +#elif defined(WOLFSSL_SM3) + #define WC_MAX_DIGEST_SIZE WC_SM3_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SM3_BLOCK_SIZE #elif defined(WOLFSSL_SHA224) #define WC_MAX_DIGEST_SIZE WC_SHA224_DIGEST_SIZE #define WC_MAX_BLOCK_SIZE WC_SHA224_BLOCK_SIZE @@ -226,6 +236,10 @@ WOLFSSL_API int wc_Shake256Hash(const byte* data, word32 len, byte* hash, #endif #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SM3 +WOLFSSL_API int wc_Sm3Hash(const byte* data, word32 len, byte* hash); +#endif + #endif /* !NO_HASH_WRAPPER */ #if defined(WOLFSSL_HASH_KEEP) diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index b17e40f46..6199cb9a6 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -144,6 +144,9 @@ typedef union { #ifdef WOLFSSL_SHA3 wc_Sha3 sha3; #endif +#ifdef WOLFSSL_SM3 + wc_Sm3 sm3; +#endif } wc_HmacHash; /* Hmac digest */ diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index c8d831c5e..f8f4a81bb 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -75,7 +75,10 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/cryptocb.h \ wolfssl/wolfcrypt/kyber.h \ wolfssl/wolfcrypt/wc_kyber.h \ - wolfssl/wolfcrypt/ext_kyber.h + wolfssl/wolfcrypt/ext_kyber.h \ + wolfssl/wolfcrypt/sm2.h \ + wolfssl/wolfcrypt/sm3.h \ + wolfssl/wolfcrypt/sm4.h noinst_HEADERS+= \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 3ec64ae66..da9c9ed55 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -329,6 +329,8 @@ MP_API int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); MP_API void mp_zero (mp_int * a); MP_API void mp_clamp (mp_int * a); MP_API int mp_exch (mp_int * a, mp_int * b); +MP_API int mp_cond_swap_ct_ex (mp_int * a, mp_int * b, int c, int m, + mp_int * t); MP_API int mp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m); MP_API void mp_rshd (mp_int * a, int b); MP_API void mp_rshb (mp_int * a, int b); diff --git a/wolfssl/wolfcrypt/sm2.h b/wolfssl/wolfcrypt/sm2.h new file mode 100644 index 000000000..ed0fe231c --- /dev/null +++ b/wolfssl/wolfcrypt/sm2.h @@ -0,0 +1,7 @@ + +#ifdef WOLFSSL_SM2 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfssl/wolfcrypt/sm3.h b/wolfssl/wolfcrypt/sm3.h new file mode 100644 index 000000000..d4bbe8f2b --- /dev/null +++ b/wolfssl/wolfcrypt/sm3.h @@ -0,0 +1,7 @@ + +#ifdef WOLFSSL_SM3 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfssl/wolfcrypt/sm4.h b/wolfssl/wolfcrypt/sm4.h new file mode 100644 index 000000000..cb6e78168 --- /dev/null +++ b/wolfssl/wolfcrypt/sm4.h @@ -0,0 +1,7 @@ + +#ifdef WOLFSSL_SM4 + +#error "Contact wolfSSL to get the implementation of this file" + +#endif + diff --git a/wolfssl/wolfcrypt/sp.h b/wolfssl/wolfcrypt/sp.h index 3d44dccf1..2bf033af0 100644 --- a/wolfssl/wolfcrypt/sp.h +++ b/wolfssl/wolfcrypt/sp.h @@ -366,6 +366,39 @@ WOLFSSL_LOCAL int sp_ecc_verify_521_nb(sp_ecc_ctx_t* ctx, const byte* hash, const mp_int* r, const mp_int* sm, int* res, void* heap); #endif /* WOLFSSL_SP_NONBLOCK */ +#ifdef HAVE_ECC_SM2 + +WOLFSSL_LOCAL int sp_ecc_mulmod_sm2_256(mp_int* km, ecc_point* gm, + ecc_point* rm, int map, void* heap); +WOLFSSL_LOCAL int sp_ecc_mulmod_base_sm2_256(mp_int* km, ecc_point* rm, int map, + void* heap); + +WOLFSSL_LOCAL int sp_ecc_make_key_sm2_256(WC_RNG* rng, mp_int* priv, + ecc_point* pub, void* heap); +WOLFSSL_LOCAL int sp_ecc_secret_gen_sm2_256(mp_int* priv, ecc_point* pub, + byte* out, word32* outlen, void* heap); + +WOLFSSL_LOCAL int sp_ecc_sign_sm2_256(const byte* hash, word32 hashLen, + WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap); +WOLFSSL_LOCAL int sp_ecc_verify_sm2_256(const byte* hash, word32 hashLen, + mp_int* pX, mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, + void* heap); + +WOLFSSL_LOCAL int sp_ecc_is_point_sm2_256(mp_int* pX, mp_int* pY); +WOLFSSL_LOCAL int sp_ecc_check_key_sm2_256(mp_int* pX, mp_int* pY, + mp_int* privm, void* heap); + +WOLFSSL_LOCAL int sp_ecc_proj_add_point_sm2_256(mp_int* pX, mp_int* pY, + mp_int* pZ, mp_int* qX, mp_int* qY, mp_int* qZ, mp_int* rX, mp_int* rY, + mp_int* rZ); +WOLFSSL_LOCAL int sp_ecc_proj_dbl_point_sm2_256(mp_int* pX, mp_int* pY, + mp_int* pZ, mp_int* rX, mp_int* rY, mp_int* rZ); +WOLFSSL_LOCAL int sp_ecc_map_sm2_256(mp_int* pX, mp_int* pY, mp_int* pZ); +WOLFSSL_LOCAL int sp_ecc_uncompress_sm2_256(mp_int* xm, int odd, mp_int* ym); + +#endif + + #endif /* WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 1a9704f88..d72fd5c3e 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -924,6 +924,8 @@ MP_API int sp_init_copy (sp_int* r, const sp_int* a); MP_API int sp_copy(const sp_int* a, sp_int* r); MP_API int sp_exch(sp_int* a, sp_int* b); MP_API int sp_cond_swap_ct(sp_int* a, sp_int* b, int cnt, int swap); +MP_API int sp_cond_swap_ct_ex(sp_int* a, sp_int* b, int cnt, int swap, + sp_int* t); #ifdef WOLFSSL_SP_INT_NEGATIVE MP_API int sp_abs(const sp_int* a, sp_int* r); @@ -1100,6 +1102,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp); #define mp_init_copy sp_init_copy #define mp_exch sp_exch #define mp_cond_swap_ct sp_cond_swap_ct +#define mp_cond_swap_ct_ex sp_cond_swap_ct_ex #define mp_cmp_mag sp_cmp_mag #define mp_cmp sp_cmp #define mp_count_bits sp_count_bits diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 94912a3c9..5f1171b46 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -899,7 +899,8 @@ MP_API int mp_lcm(fp_int *a, fp_int *b, fp_int *c); MP_API int mp_rand_prime(mp_int* a, int len, WC_RNG* rng, void* heap); MP_API int mp_exch(mp_int *a, mp_int *b); #endif /* WOLFSSL_KEY_GEN */ -MP_API int mp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m); +MP_API int mp_cond_swap_ct_ex(mp_int* a, mp_int* b, int c, int m, mp_int* t); +MP_API int mp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m); MP_API int mp_cnt_lsb(fp_int *a); MP_API int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 17f774db8..23f22188f 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1009,6 +1009,7 @@ typedef struct w64wrapper { DYNAMIC_TYPE_SESSION = 96, DYNAMIC_TYPE_DILITHIUM = 97, DYNAMIC_TYPE_SPHINCS = 98, + DYNAMIC_TYPE_SM4_BUFFER = 99, DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_PB = 1002, @@ -1067,7 +1068,7 @@ typedef struct w64wrapper { WC_HASH_TYPE_SHA3_512 = 13, WC_HASH_TYPE_BLAKE2B = 14, WC_HASH_TYPE_BLAKE2S = 19, - WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S + WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S, #ifndef WOLFSSL_NOSHA512_224 #define WOLFSSL_NOSHA512_224 #endif @@ -1104,12 +1105,19 @@ typedef struct w64wrapper { #endif #ifdef WOLFSSL_SHAKE128 WC_HASH_TYPE_SHAKE128 = 18, + #undef _WC_HASH_TYPE_MAX + #define _WC_HASH_TYPE_MAX WC_HASH_TYPE_SHAKE128 #endif #ifdef WOLFSSL_SHAKE256 WC_HASH_TYPE_SHAKE256 = 19, #undef _WC_HASH_TYPE_MAX #define _WC_HASH_TYPE_MAX WC_HASH_TYPE_SHAKE256 #endif + #ifdef WOLFSSL_SM3 + WC_HASH_TYPE_SM3 = 20, + #undef _WC_HASH_TYPE_MAX + #define _WC_HASH_TYPE_MAX WC_HASH_TYPE_SM3 + #endif WC_HASH_TYPE_MAX = _WC_HASH_TYPE_MAX #undef _WC_HASH_TYPE_MAX