diff --git a/Backport-Add-documents-for-SM2-cert-verification.patch b/Backport-Add-documents-for-SM2-cert-verification.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c8acd108067a9d4c72ce7ffb908319602d0b9b2 --- /dev/null +++ b/Backport-Add-documents-for-SM2-cert-verification.patch @@ -0,0 +1,108 @@ +From 400e9ffc906d66318e4f9364494809d5a519c718 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Wed, 13 Mar 2019 17:22:31 +0800 +Subject: [PATCH 06/15] Add documents for SM2 cert verification + +This follows #8321 which added the SM2 certificate verification feature. +This commit adds the related docs - the newly added 2 APIs and options +in apps/verify. + +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/8465) +--- + doc/man1/verify.pod | 14 ++++++++++++ + doc/man3/X509_get0_sm2_id.pod | 43 +++++++++++++++++++++++++++++++++++ + 2 files changed, 57 insertions(+) + create mode 100644 doc/man3/X509_get0_sm2_id.pod + +diff --git a/doc/man1/verify.pod b/doc/man1/verify.pod +index da2b702..a6b6b2b 100644 +--- a/doc/man1/verify.pod ++++ b/doc/man1/verify.pod +@@ -50,6 +50,8 @@ B B + [B<-verify_name name>] + [B<-x509_strict>] + [B<-show_chain>] ++[B<-sm2-id string>] ++[B<-sm2-hex-id hex-string>] + [B<->] + [certificates] + +@@ -319,6 +321,16 @@ Display information about the certificate chain that has been built (if + successful). Certificates in the chain that came from the untrusted list will be + flagged as "untrusted". + ++=item B<-sm2-id> ++ ++Specify the ID string to use when verifying an SM2 certificate. The ID string is ++required by the SM2 signature algorithm for signing and verification. ++ ++=item B<-sm2-hex-id> ++ ++Specify a binary ID string to use when signing or verifying using an SM2 ++certificate. The argument for this option is string of hexadecimal digits. ++ + =item B<-> + + Indicates the last option. All arguments following this are assumed to be +@@ -774,6 +786,8 @@ The B<-show_chain> option was added in OpenSSL 1.1.0. + The B<-issuer_checks> option is deprecated as of OpenSSL 1.1.0 and + is silently ignored. + ++The B<-sm2-id> and B<-sm2-hex-id> options were added in OpenSSL 3.0.0. ++ + =head1 COPYRIGHT + + Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod +new file mode 100644 +index 0000000..84da71e +--- /dev/null ++++ b/doc/man3/X509_get0_sm2_id.pod +@@ -0,0 +1,43 @@ ++=pod ++ ++=head1 NAME ++ ++X509_get0_sm2_id, X509_set_sm2_id - get or set SM2 ID for certificate operations ++ ++=head1 SYNOPSIS ++ ++ #include ++ ++ ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); ++ void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); ++ ++=head1 DESCRIPTION ++ ++X509_get0_sm2_id() gets the ID value of an SM2 certificate B by returning an ++B object which should not be freed by the caller. ++X509_set_sm2_id() sets the B value to an SM2 certificate B. ++ ++=head1 NOTES ++ ++SM2 signature algorithm requires an ID value when generating and verifying a ++signature. The functions described in this manual provide the user with the ++ability to set and retrieve the SM2 ID value. ++ ++=head1 RETURN VALUES ++ ++X509_set_sm2_id() does not return a value. ++ ++=head1 SEE ALSO ++ ++L, L ++ ++=head1 COPYRIGHT ++ ++Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. ++ ++Licensed under the Apache License 2.0 (the "License"). You may not use ++this file except in compliance with the License. You can obtain a copy ++in the file LICENSE in the source distribution or at ++L. ++ ++=cut +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Add-test-cases-for-SM2-cert-verification.patch b/Backport-Add-test-cases-for-SM2-cert-verification.patch new file mode 100644 index 0000000000000000000000000000000000000000..d1e2c68720dae01409065a009490c99af3791f08 --- /dev/null +++ b/Backport-Add-test-cases-for-SM2-cert-verification.patch @@ -0,0 +1,127 @@ +From c08251384c0405c151a90b315b8f333c38c74eb2 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Wed, 13 Mar 2019 16:54:11 +0800 +Subject: [PATCH 05/15] Add test cases for SM2 cert verification + +This follows #8321 which added the SM2 certificate verification feature. +This commit adds some test cases for #8321. + +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/8465) +--- + test/certs/sm2-ca-cert.pem | 14 +++++++++++++ + test/certs/{sm2.crt => sm2.pem} | 0 + test/recipes/20-test_pkeyutl.t | 37 +++++++++++++-------------------- + test/recipes/25-test_verify.t | 14 ++++++++++++- + 4 files changed, 42 insertions(+), 23 deletions(-) + create mode 100644 test/certs/sm2-ca-cert.pem + rename test/certs/{sm2.crt => sm2.pem} (100%) + +diff --git a/test/certs/sm2-ca-cert.pem b/test/certs/sm2-ca-cert.pem +new file mode 100644 +index 0000000..5677ac6 +--- /dev/null ++++ b/test/certs/sm2-ca-cert.pem +@@ -0,0 +1,14 @@ ++-----BEGIN CERTIFICATE----- ++MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT ++AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl ++c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe ++Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw ++CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn ++MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG ++SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU ++5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW ++BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU ++5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI ++ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X ++YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3 ++-----END CERTIFICATE----- +diff --git a/test/certs/sm2.crt b/test/certs/sm2.pem +similarity index 100% +rename from test/certs/sm2.crt +rename to test/certs/sm2.pem +diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t +index 1457530..a36d41e 100644 +--- a/test/recipes/20-test_pkeyutl.t ++++ b/test/recipes/20-test_pkeyutl.t +@@ -17,32 +17,25 @@ setup("test_pkeyutl"); + + plan tests => 2; + +-sub sign +-{ +- # Utilize the sm2.crt as the TBS file +- return run(app(([ 'openssl', 'pkeyutl', '-sign', +- '-in', srctop_file('test', 'certs', 'sm2.crt'), +- '-inkey', srctop_file('test', 'certs', 'sm2.key'), +- '-out', 'signature.sm2', '-rawin', +- '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))); +-} +- +-sub verify +-{ +- # Utilize the sm2.crt as the TBS file +- return run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', +- '-in', srctop_file('test', 'certs', 'sm2.crt'), +- '-inkey', srctop_file('test', 'certs', 'sm2.crt'), +- '-sigfile', 'signature.sm2', '-rawin', +- '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))); +-} ++# For the tests below we use the cert itself as the TBS file + + SKIP: { + skip "Skipping tests that require EC, SM2 or SM3", 2 + if disabled("ec") || disabled("sm2") || disabled("sm3"); + +- ok(sign, "Sign a piece of data using SM2"); +- ok(verify, "Verify an SM2 signature against a piece of data"); ++ # SM2 ++ ok(run(app(([ 'openssl', 'pkeyutl', '-sign', ++ '-in', srctop_file('test', 'certs', 'sm2.pem'), ++ '-inkey', srctop_file('test', 'certs', 'sm2.key'), ++ '-out', 'signature.dat', '-rawin', ++ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))), ++ "Sign a piece of data using SM2"); ++ ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', ++ '-in', srctop_file('test', 'certs', 'sm2.pem'), ++ '-inkey', srctop_file('test', 'certs', 'sm2.pem'), ++ '-sigfile', 'signature.dat', '-rawin', ++ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))), ++ "Verify an SM2 signature against a piece of data"); + } + +-unlink 'signature.sm2'; ++unlink 'signature.dat'; +diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t +index ffa48ed..b340833 100644 +--- a/test/recipes/25-test_verify.t ++++ b/test/recipes/25-test_verify.t +@@ -27,7 +27,7 @@ sub verify { + run(app([@args])); + } + +-plan tests => 146; ++plan tests => 148; + + # Canonical success + ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), +@@ -409,3 +409,15 @@ SKIP: { + "ED25519 signature"); + + } ++ ++SKIP: { ++ skip "SM2 is not supported by this OpenSSL build", 1 ++ if disabled("sm2"); ++ ++ # Test '-sm2-id' and '-sm2-hex-id' option ++ ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-id", "1234567812345678"), ++ "SM2 ID test"); ++ ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-hex-id", ++ "31323334353637383132333435363738"), ++ "SM2 hex ID test"); ++} +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Fix-a-document-description-in-apps-req.patch b/Backport-Fix-a-document-description-in-apps-req.patch new file mode 100644 index 0000000000000000000000000000000000000000..421d83b47ce2f26531b424b73e268f733d7dd029 --- /dev/null +++ b/Backport-Fix-a-document-description-in-apps-req.patch @@ -0,0 +1,29 @@ +From 7e64be50900c4aa8cd040c4e3999540883bdeeb6 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Thu, 26 Sep 2019 10:57:23 +0800 +Subject: [PATCH 13/15] Fix a document description in apps/req + +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/9958) +--- + doc/man1/req.pod | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/doc/man1/req.pod b/doc/man1/req.pod +index 7b00bad..e117ec6 100644 +--- a/doc/man1/req.pod ++++ b/doc/man1/req.pod +@@ -348,8 +348,8 @@ string is required by the SM2 signature algorithm for signing and verification. + + =item B<-sm2-hex-id> + +-Specify a binary ID string to use when signing or verifying using an SM2 +-certificate. The argument for this option is string of hexadecimal digits. ++Specify a binary ID string to use when verifying an SM2 certificate request. The ++argument for this option is string of hexadecimal digits. + + =back + +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Fix-a-double-free-issue-when-signing-SM2-cert.patch b/Backport-Fix-a-double-free-issue-when-signing-SM2-cert.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7e27cde1fbcd965520bc6c4bf3ba3a4eda4021b --- /dev/null +++ b/Backport-Fix-a-double-free-issue-when-signing-SM2-cert.patch @@ -0,0 +1,121 @@ +From a63238684c1d2e15f417f766f44418a8b52ef383 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Sat, 21 Sep 2019 00:32:57 +0800 +Subject: [PATCH 12/15] Fix a double free issue when signing SM2 cert + +If the SM2 ID value has not been passed correctly when signing an SM2 +certificate/certificate request, a double free occurs. For instance: + + openssl req -x509 ... -sm2-id 1234567812345678 + +The '-sm2-id' should not be used in this scenario, while the '-sigopt' is +the correct one to use. Documentation has also been updated to make the +options more clear. + +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/9958) +--- + apps/req.c | 48 ++++++++++++++++++++++++++++++------------------ + doc/man1/req.pod | 4 ++-- + 2 files changed, 32 insertions(+), 20 deletions(-) + +diff --git a/apps/req.c b/apps/req.c +index 96f1edd..95dd0e4 100644 +--- a/apps/req.c ++++ b/apps/req.c +@@ -1756,15 +1756,19 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, + #endif + + rv = do_sign_init(mctx, pkey, md, sigopts); +- if (rv > 0) ++ if (rv > 0) { + rv = X509_sign_ctx(x, mctx); + #ifndef OPENSSL_NO_SM2 +- /* only in SM2 case we need to free the pctx explicitly */ +- if (ec_pkey_is_sm2(pkey)) { +- pctx = EVP_MD_CTX_pkey_ctx(mctx); +- EVP_PKEY_CTX_free(pctx); +- } ++ /* ++ * only in SM2 case we need to free the pctx explicitly ++ * if do_sign_init() fails, pctx is already freed in it ++ */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } + #endif ++ } + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +@@ -1779,15 +1783,19 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, + #endif + + rv = do_sign_init(mctx, pkey, md, sigopts); +- if (rv > 0) ++ if (rv > 0) { + rv = X509_REQ_sign_ctx(x, mctx); + #ifndef OPENSSL_NO_SM2 +- /* only in SM2 case we need to free the pctx explicitly */ +- if (ec_pkey_is_sm2(pkey)) { +- pctx = EVP_MD_CTX_pkey_ctx(mctx); +- EVP_PKEY_CTX_free(pctx); +- } ++ /* ++ * only in SM2 case we need to free the pctx explicitly ++ * if do_sign_init() fails, pctx is already freed in it ++ */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } + #endif ++ } + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +@@ -1802,15 +1810,19 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, + #endif + + rv = do_sign_init(mctx, pkey, md, sigopts); +- if (rv > 0) ++ if (rv > 0) { + rv = X509_CRL_sign_ctx(x, mctx); + #ifndef OPENSSL_NO_SM2 +- /* only in SM2 case we need to free the pctx explicitly */ +- if (ec_pkey_is_sm2(pkey)) { +- pctx = EVP_MD_CTX_pkey_ctx(mctx); +- EVP_PKEY_CTX_free(pctx); +- } ++ /* ++ * only in SM2 case we need to free the pctx explicitly ++ * if do_sign_init() fails, no need to double free pctx ++ */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } + #endif ++ } + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +diff --git a/doc/man1/req.pod b/doc/man1/req.pod +index 3b9fcc3..7b00bad 100644 +--- a/doc/man1/req.pod ++++ b/doc/man1/req.pod +@@ -343,8 +343,8 @@ for key generation operations. + + =item B<-sm2-id> + +-Specify the ID string to use when verifying an SM2 certificate. The ID string is +-required by the SM2 signature algorithm for signing and verification. ++Specify the ID string to use when verifying an SM2 certificate request. The ID ++string is required by the SM2 signature algorithm for signing and verification. + + =item B<-sm2-hex-id> + +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Fix-a-memleak-in-apps-verify.patch b/Backport-Fix-a-memleak-in-apps-verify.patch new file mode 100644 index 0000000000000000000000000000000000000000..53c211811e25a91da6ec0f10ec80882d3bc1800c --- /dev/null +++ b/Backport-Fix-a-memleak-in-apps-verify.patch @@ -0,0 +1,43 @@ +From 1c243548ef736329b08344ad9191803e5a93ec17 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Wed, 13 Mar 2019 18:04:05 +0800 +Subject: [PATCH 07/15] Fix a memleak in apps/verify + +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/8465) +--- + apps/verify.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/apps/verify.c b/apps/verify.c +index 09b31cf..5052d80 100644 +--- a/apps/verify.c ++++ b/apps/verify.c +@@ -80,6 +80,7 @@ int verify_main(int argc, char **argv) + OPTION_CHOICE o; + unsigned char *sm2_id = NULL; + size_t sm2_idlen = 0; ++ int sm2_free = 0; + + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) + goto end; +@@ -174,6 +175,7 @@ int verify_main(int argc, char **argv) + break; + case OPT_SM2HEXID: + /* try to parse the input as hex string first */ ++ sm2_free = 1; + sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen); + if (sm2_id == NULL) { + BIO_printf(bio_err, "Invalid hex string input\n"); +@@ -216,6 +218,8 @@ int verify_main(int argc, char **argv) + } + + end: ++ if (sm2_free) ++ OPENSSL_free(sm2_id); + X509_VERIFY_PARAM_free(vpm); + X509_STORE_free(store); + sk_X509_pop_free(untrusted, X509_free); +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Fix-no-ec-no-sm2-and-no-sm3.patch b/Backport-Fix-no-ec-no-sm2-and-no-sm3.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e1a9f3782668d64fdfd639d5dcf773112ef04dc --- /dev/null +++ b/Backport-Fix-no-ec-no-sm2-and-no-sm3.patch @@ -0,0 +1,67 @@ +From 380cf570be1ded495141e16ceab7afb7f7c57ab7 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 28 Feb 2019 13:47:26 +0000 +Subject: [PATCH 02/15] Fix no-ec, no-sm2 and no-sm3 + +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/8372) +--- + apps/pkeyutl.c | 11 +++++++---- + test/recipes/20-test_pkeyutl.t | 9 +++++++-- + 2 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c +index bca0464..1d3d57b 100644 +--- a/apps/pkeyutl.c ++++ b/apps/pkeyutl.c +@@ -473,14 +473,16 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, + } + ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + } else { +- EC_KEY *eckey = NULL; +- const EC_GROUP *group = NULL; +- int nid; +- + if (pkey == NULL) + goto end; ++ ++#ifndef OPENSSL_NO_EC + /* SM2 needs a special treatment */ + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { ++ EC_KEY *eckey = NULL; ++ const EC_GROUP *group = NULL; ++ int nid; ++ + if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL + || (group = EC_KEY_get0_group(eckey)) == NULL + || (nid = EC_GROUP_get_curve_name(group)) == 0) +@@ -488,6 +490,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, + if (nid == NID_sm2) + EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); + } ++#endif + *pkeysize = EVP_PKEY_size(pkey); + ctx = EVP_PKEY_CTX_new(pkey, impl); + if (ppkey != NULL) +diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t +index a051138..1457530 100644 +--- a/test/recipes/20-test_pkeyutl.t ++++ b/test/recipes/20-test_pkeyutl.t +@@ -37,7 +37,12 @@ sub verify + '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))); + } + +-ok(sign, "Sign a piece of data using SM2"); +-ok(verify, "Verify an SM2 signature against a piece of data"); ++SKIP: { ++ skip "Skipping tests that require EC, SM2 or SM3", 2 ++ if disabled("ec") || disabled("sm2") || disabled("sm3"); ++ ++ ok(sign, "Sign a piece of data using SM2"); ++ ok(verify, "Verify an SM2 signature against a piece of data"); ++} + + unlink 'signature.sm2'; +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Guard-some-SM2-functions-with-OPENSSL_NO_SM2.patch b/Backport-Guard-some-SM2-functions-with-OPENSSL_NO_SM2.patch new file mode 100644 index 0000000000000000000000000000000000000000..87b3bfd4add5c25537a4fb2b4bfc878d952a5fd5 --- /dev/null +++ b/Backport-Guard-some-SM2-functions-with-OPENSSL_NO_SM2.patch @@ -0,0 +1,44 @@ +From 908570d02b683195ddfdc8e8c324638bfaa0d2c2 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 14 Mar 2019 11:14:38 +0000 +Subject: [PATCH 04/15] Guard some SM2 functions with OPENSSL_NO_SM2 + +Fixes the no-ec build + +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/8481) +--- + include/openssl/x509.h | 2 ++ + util/libcrypto.num | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 5f17057..5c88251 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -573,8 +573,10 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); + int X509_get_signature_nid(const X509 *x); + ++# ifndef OPENSSL_NO_SM2 + void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); ++# endif + + int X509_trusted(const X509 *x); + int X509_alias_set1(X509 *x, const unsigned char *name, int len); +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 8635ac4..233d1c7 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4626,5 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION: + FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION: + FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: + FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: +-X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION: +-X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION: ++X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 ++X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2 +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Make-X509_set_sm2_id-consistent-with-other-setters.patch b/Backport-Make-X509_set_sm2_id-consistent-with-other-setters.patch new file mode 100644 index 0000000000000000000000000000000000000000..daeeee816c3497ad6418c902fa9ab471475a1e14 --- /dev/null +++ b/Backport-Make-X509_set_sm2_id-consistent-with-other-setters.patch @@ -0,0 +1,320 @@ +From 0717cc33d72b011cce4f53661c58d628b684275c Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Mon, 1 Apr 2019 10:21:53 +0900 +Subject: [PATCH 09/15] Make X509_set_sm2_id consistent with other setters + +This commit makes the X509_set_sm2_id to 'set0' behaviour, which means +the memory management is passed to X509 and user doesn't need to free +the sm2_id parameter later. API name also changes to X509_set0_sm2_id. + +Document and test case are also updated. + +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/8626) +--- + apps/verify.c | 40 +++++++++++++++++++----------- + crypto/x509/x_all.c | 5 +++- + crypto/x509/x_x509.c | 13 +++++++--- + doc/man3/X509_get0_sm2_id.pod | 12 ++++++--- + include/crypto/x509.h | 2 +- + include/openssl/x509.h | 2 +- + test/verify_extra_test.c | 46 +++++++++++++++++++++++++++++++++++ + util/libcrypto.num | 2 +- + 8 files changed, 97 insertions(+), 25 deletions(-) + +diff --git a/apps/verify.c b/apps/verify.c +index 5052d80..9000567 100644 +--- a/apps/verify.c ++++ b/apps/verify.c +@@ -246,27 +246,37 @@ static int check(X509_STORE *ctx, const char *file, + + if (sm2id != NULL) { + #ifndef OPENSSL_NO_SM2 +- ASN1_OCTET_STRING v; ++ ASN1_OCTET_STRING *v; + +- v.data = sm2id; +- v.length = sm2idlen; ++ v = ASN1_OCTET_STRING_new(); ++ if (v == NULL) { ++ BIO_printf(bio_err, "error: SM2 ID allocation failed\n"); ++ goto end; ++ } + +- X509_set_sm2_id(x, &v); ++ if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) { ++ BIO_printf(bio_err, "error: setting SM2 ID failed\n"); ++ ASN1_OCTET_STRING_free(v); ++ goto end; ++ } ++ ++ X509_set0_sm2_id(x, v); + #endif + } + + csc = X509_STORE_CTX_new(); + if (csc == NULL) { +- printf("error %s: X.509 store context allocation failed\n", +- (file == NULL) ? "stdin" : file); ++ BIO_printf(bio_err, "error %s: X.509 store context allocation failed\n", ++ (file == NULL) ? "stdin" : file); + goto end; + } + + X509_STORE_set_flags(ctx, vflags); + if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) { + X509_STORE_CTX_free(csc); +- printf("error %s: X.509 store context initialization failed\n", +- (file == NULL) ? "stdin" : file); ++ BIO_printf(bio_err, ++ "error %s: X.509 store context initialization failed\n", ++ (file == NULL) ? "stdin" : file); + goto end; + } + if (tchain != NULL) +@@ -275,28 +285,30 @@ static int check(X509_STORE *ctx, const char *file, + X509_STORE_CTX_set0_crls(csc, crls); + i = X509_verify_cert(csc); + if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) { +- printf("%s: OK\n", (file == NULL) ? "stdin" : file); ++ BIO_printf(bio_out, "%s: OK\n", (file == NULL) ? "stdin" : file); + ret = 1; + if (show_chain) { + int j; + + chain = X509_STORE_CTX_get1_chain(csc); + num_untrusted = X509_STORE_CTX_get_num_untrusted(csc); +- printf("Chain:\n"); ++ BIO_printf(bio_out, "Chain:\n"); + for (j = 0; j < sk_X509_num(chain); j++) { + X509 *cert = sk_X509_value(chain, j); +- printf("depth=%d: ", j); ++ BIO_printf(bio_out, "depth=%d: ", j); + X509_NAME_print_ex_fp(stdout, + X509_get_subject_name(cert), + 0, get_nameopt()); + if (j < num_untrusted) +- printf(" (untrusted)"); +- printf("\n"); ++ BIO_printf(bio_out, " (untrusted)"); ++ BIO_printf(bio_out, "\n"); + } + sk_X509_pop_free(chain, X509_free); + } + } else { +- printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file); ++ BIO_printf(bio_err, ++ "error %s: verification failed\n", ++ (file == NULL) ? "stdin" : file); + } + X509_STORE_CTX_free(csc); + +diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c +index 60a2892..9c8aea5 100644 +--- a/crypto/x509/x_all.c ++++ b/crypto/x509/x_all.c +@@ -72,7 +72,10 @@ static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) + ret = 0; + goto err; + } +- if (EVP_PKEY_CTX_set1_id(pctx, x->sm2_id.data, x->sm2_id.length) != 1) { ++ /* NOTE: we tolerate no actual ID, to provide maximum flexibility */ ++ if (x->sm2_id != NULL ++ && EVP_PKEY_CTX_set1_id(pctx, x->sm2_id->data, ++ x->sm2_id->length) != 1) { + X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); + ret = 0; + goto err; +diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c +index 1beab78..fb03bb2 100644 +--- a/crypto/x509/x_x509.c ++++ b/crypto/x509/x_x509.c +@@ -72,6 +72,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + #ifndef OPENSSL_NO_RFC3779 + ret->rfc3779_addr = NULL; + ret->rfc3779_asid = NULL; ++#endif ++#ifndef OPENSSL_NO_SM2 ++ ret->sm2_id = NULL; + #endif + ret->aux = NULL; + ret->crldp = NULL; +@@ -91,6 +94,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + #ifndef OPENSSL_NO_RFC3779 + sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); + ASIdentifiers_free(ret->rfc3779_asid); ++#endif ++#ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING_free(ret->sm2_id); + #endif + break; + +@@ -247,13 +253,14 @@ int X509_get_signature_nid(const X509 *x) + } + + #ifndef OPENSSL_NO_SM2 +-void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id) ++void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id) + { +- x->sm2_id = *sm2_id; ++ ASN1_OCTET_STRING_free(x->sm2_id); ++ x->sm2_id = sm2_id; + } + + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x) + { +- return &x->sm2_id; ++ return x->sm2_id; + } + #endif +diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod +index 84da71e..9698c86 100644 +--- a/doc/man3/X509_get0_sm2_id.pod ++++ b/doc/man3/X509_get0_sm2_id.pod +@@ -2,20 +2,24 @@ + + =head1 NAME + +-X509_get0_sm2_id, X509_set_sm2_id - get or set SM2 ID for certificate operations ++X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operations + + =head1 SYNOPSIS + + #include + + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); +- void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); ++ void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); + + =head1 DESCRIPTION + + X509_get0_sm2_id() gets the ID value of an SM2 certificate B by returning an + B object which should not be freed by the caller. +-X509_set_sm2_id() sets the B value to an SM2 certificate B. ++ ++X509_set0_sm2_id() sets the B value to an SM2 certificate B. Calling ++this function transfers the memory management of the value to the X509 object, ++and therefore the value that has been passed in should not be freed by the ++caller after this function has been called. + + =head1 NOTES + +@@ -25,7 +29,7 @@ ability to set and retrieve the SM2 ID value. + + =head1 RETURN VALUES + +-X509_set_sm2_id() does not return a value. ++X509_set0_sm2_id() does not return a value. + + =head1 SEE ALSO + +diff --git a/include/crypto/x509.h b/include/crypto/x509.h +index 418c427..5c314a8 100644 +--- a/include/crypto/x509.h ++++ b/include/crypto/x509.h +@@ -186,7 +186,7 @@ struct x509_st { + CRYPTO_RWLOCK *lock; + volatile int ex_cached; + # ifndef OPENSSL_NO_SM2 +- ASN1_OCTET_STRING sm2_id; ++ ASN1_OCTET_STRING *sm2_id; + # endif + } /* X509 */ ; + +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 5c88251..a02cf50 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -574,7 +574,7 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig, + int X509_get_signature_nid(const X509 *x); + + # ifndef OPENSSL_NO_SM2 +-void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); ++void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); + # endif + +diff --git a/test/verify_extra_test.c b/test/verify_extra_test.c +index b9959e0..763ea4f 100644 +--- a/test/verify_extra_test.c ++++ b/test/verify_extra_test.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -231,6 +232,48 @@ static int test_self_signed_bad(void) + return test_self_signed(bad_f, 0); + } + ++#ifndef OPENSSL_NO_SM2 ++static int test_sm2_id(void) ++{ ++ /* we only need an X509 structure, no matter if it's a real SM2 cert */ ++ X509 *x = NULL; ++ BIO *bio = NULL; ++ int ret = 0; ++ ASN1_OCTET_STRING *v = NULL, *v2 = NULL; ++ char *sm2id = "this is an ID"; ++ ++ bio = BIO_new_file(bad_f, "r"); ++ if (bio == NULL) ++ goto err; ++ ++ x = PEM_read_bio_X509(bio, NULL, 0, NULL); ++ if (x == NULL) ++ goto err; ++ ++ v = ASN1_OCTET_STRING_new(); ++ if (v == NULL) ++ goto err; ++ ++ if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) { ++ ASN1_OCTET_STRING_free(v); ++ goto err; ++ } ++ ++ X509_set0_sm2_id(x, v); ++ ++ v2 = X509_get0_sm2_id(x); ++ if (!TEST_ptr(v2) ++ || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0)) ++ goto err; ++ ++ ret = 1; ++ err: ++ X509_free(x); ++ BIO_free(bio); ++ return ret; ++} ++#endif ++ + int setup_tests(void) + { + if (!TEST_ptr(roots_f = test_get_argument(0)) +@@ -245,5 +288,8 @@ int setup_tests(void) + ADD_TEST(test_store_ctx); + ADD_TEST(test_self_signed_good); + ADD_TEST(test_self_signed_bad); ++#ifndef OPENSSL_NO_SM2 ++ ADD_TEST(test_sm2_id); ++#endif + return 1; + } +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 233d1c7..d7abe91 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4626,5 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION: + FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION: + FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: + FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: +-X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 ++X509_set0_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 + X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2 +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-SM3-acceleration-with-SM3-hardware-instruction-on-aa.patch b/Backport-SM3-acceleration-with-SM3-hardware-instruction-on-aa.patch new file mode 100644 index 0000000000000000000000000000000000000000..722d5061beb145474c72e3731cdfdf6f0eee823f --- /dev/null +++ b/Backport-SM3-acceleration-with-SM3-hardware-instruction-on-aa.patch @@ -0,0 +1,492 @@ +From 4d2e328357ac4b468d4762a5a5f615d7e7bf46a6 Mon Sep 17 00:00:00 2001 +From: Xu Yizhou +Date: Thu, 27 Oct 2022 20:49:34 +0800 +Subject: [PATCH 1/3] SM3 acceleration with SM3 hardware instruction on aarch64 + +This patch contains the following two PRs, + +1. SM3 acceleration with SM3 hardware instruction on aarch64 + +SM3 hardware instruction is optional feature of crypto extension for +aarch64. This implementation accelerates SM3 via SM3 instructions. For +the platform not supporting SM3 instruction, the original C +implementation still works. Thanks to AliBaba for testing and reporting +the following perf numbers for Yitian710: + +Benchmark on T-Head Yitian-710 2.75GHz: + +Before: +type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes +sm3 49297.82k 121062.63k 223106.05k 283371.52k 307574.10k 309400.92k + +After (33% - 74% faster): +type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes +sm3 65640.01k 179121.79k 359854.59k 481448.96k 534055.59k 538274.47k + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17454) + +2. Fix sm3ss1 translation issue in sm3-armv8.pl + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/17542) + +Signed-off-by: Xu Yizhou +--- + Configurations/00-base-templates.conf | 1 + + Configure | 4 + + crypto/arm64cpuid.pl | 7 + + crypto/arm_arch.h | 1 + + crypto/armcap.c | 10 + + crypto/sm3/asm/sm3-armv8.pl | 280 ++++++++++++++++++++++++++ + crypto/sm3/build.info | 15 +- + crypto/sm3/sm3_local.h | 16 +- + 8 files changed, 332 insertions(+), 2 deletions(-) + create mode 100644 crypto/sm3/asm/sm3-armv8.pl + +diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf +index 1d35012..a67ae65 100644 +--- a/Configurations/00-base-templates.conf ++++ b/Configurations/00-base-templates.conf +@@ -322,6 +322,7 @@ my %targets=( + poly1305_asm_src=> "poly1305-armv8.S", + keccak1600_asm_src => "keccak1600-armv8.S", + sm4_asm_src => "vpsm4_ex-armv8.S", ++ sm3_asm_src => "sm3-armv8.S", + }, + parisc11_asm => { + template => 1, +diff --git a/Configure b/Configure +index 3bfe360..fce460d 100755 +--- a/Configure ++++ b/Configure +@@ -1423,6 +1423,9 @@ unless ($disabled{asm}) { + if ($target{sm4_asm_src} ne "") { + push @{$config{lib_defines}}, "VPSM4_EX_ASM"; + } ++ if ($target{sm3_asm_src} ne "") { ++ push @{$config{lib_defines}}, "SM3_ASM"; ++ } + } + + my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); +@@ -3379,6 +3382,7 @@ sub print_table_entry + "multilib", + "build_scheme", + "sm4_asm_src", ++ "sm3_asm_src", + ); + + if ($type eq "TABLE") { +diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl +index 319927e..1e9b167 100755 +--- a/crypto/arm64cpuid.pl ++++ b/crypto/arm64cpuid.pl +@@ -78,6 +78,13 @@ _armv8_sha512_probe: + ret + .size _armv8_sha512_probe,.-_armv8_sha512_probe + ++.globl _armv8_sm3_probe ++.type _armv8_sm3_probe,%function ++_armv8_sm3_probe: ++ .long 0xce63c004 // sm3partw1 v4.4s, v0.4s, v3.4s ++ ret ++.size _armv8_sm3_probe,.-_armv8_sm3_probe ++ + .globl OPENSSL_cleanse + .type OPENSSL_cleanse,%function + .align 5 +diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h +index 8b71055..8839b21 100644 +--- a/crypto/arm_arch.h ++++ b/crypto/arm_arch.h +@@ -80,5 +80,6 @@ extern unsigned int OPENSSL_armcap_P; + # define ARMV8_SHA256 (1<<4) + # define ARMV8_PMULL (1<<5) + # define ARMV8_SHA512 (1<<6) ++# define ARMV8_SM3 (1<<9) + + #endif +diff --git a/crypto/armcap.c b/crypto/armcap.c +index 48c5d4d..8b2f4a5 100644 +--- a/crypto/armcap.c ++++ b/crypto/armcap.c +@@ -47,6 +47,7 @@ void _armv8_sha1_probe(void); + void _armv8_sha256_probe(void); + void _armv8_pmull_probe(void); + # ifdef __aarch64__ ++void _armv8_sm3_probe(void); + void _armv8_sha512_probe(void); + # endif + uint32_t _armv7_tick(void); +@@ -130,6 +131,7 @@ static unsigned long getauxval(unsigned long key) + # define HWCAP_CE_PMULL (1 << 4) + # define HWCAP_CE_SHA1 (1 << 5) + # define HWCAP_CE_SHA256 (1 << 6) ++# define HWCAP_CE_SM3 (1 << 18) + # define HWCAP_CE_SHA512 (1 << 21) + # endif + +@@ -190,6 +192,9 @@ void OPENSSL_cpuid_setup(void) + # ifdef __aarch64__ + if (hwcap & HWCAP_CE_SHA512) + OPENSSL_armcap_P |= ARMV8_SHA512; ++ ++ if (hwcap & HWCAP_CE_SM3) ++ OPENSSL_armcap_P |= ARMV8_SM3; + # endif + } + # endif +@@ -233,6 +238,11 @@ void OPENSSL_cpuid_setup(void) + _armv8_sha512_probe(); + OPENSSL_armcap_P |= ARMV8_SHA512; + } ++ ++ if (sigsetjmp(ill_jmp, 1) == 0) { ++ _armv8_sm3_probe(); ++ OPENSSL_armcap_P |= ARMV8_SM3; ++ } + # endif + } + # endif +diff --git a/crypto/sm3/asm/sm3-armv8.pl b/crypto/sm3/asm/sm3-armv8.pl +new file mode 100644 +index 0000000..677ca52 +--- /dev/null ++++ b/crypto/sm3/asm/sm3-armv8.pl +@@ -0,0 +1,280 @@ ++#! /usr/bin/env perl ++# Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++# ++# This module implements support for Armv8 SM3 instructions ++ ++# $output is the last argument if it looks like a file (it has an extension) ++# $flavour is the first argument if it doesn't look like a file ++$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; ++$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or ++die "can't locate arm-xlate.pl"; ++ ++open OUT,"| \"$^X\" $xlate $flavour \"$output\"" ++ or die "can't call $xlate: $!"; ++*STDOUT=*OUT; ++ ++# Message expanding: ++# Wj <- P1(W[j-16]^W[j-9]^(W[j-3]<<<15))^(W[j-13]<<<7)^W[j-6] ++# Input: s0, s1, s2, s3 ++# s0 = w0 | w1 | w2 | w3 ++# s1 = w4 | w5 | w6 | w7 ++# s2 = w8 | w9 | w10 | w11 ++# s3 = w12 | w13 | w14 | w15 ++# Output: s4 ++sub msg_exp () { ++my $s0 = shift; ++my $s1 = shift; ++my $s2 = shift; ++my $s3 = shift; ++my $s4 = shift; ++my $vtmp1 = shift; ++my $vtmp2 = shift; ++$code.=<<___; ++ // s4 = w7 | w8 | w9 | w10 ++ ext $s4.16b, $s1.16b, $s2.16b, #12 ++ // vtmp1 = w3 | w4 | w5 | w6 ++ ext $vtmp1.16b, $s0.16b, $s1.16b, #12 ++ // vtmp2 = w10 | w11 | w12 | w13 ++ ext $vtmp2.16b, $s2.16b, $s3.16b, #8 ++ sm3partw1 $s4.4s, $s0.4s, $s3.4s ++ sm3partw2 $s4.4s, $vtmp2.4s, $vtmp1.4s ++___ ++} ++ ++# A round of compresson function ++# Input: ++# ab - choose instruction among sm3tt1a, sm3tt1b, sm3tt2a, sm3tt2b ++# vstate0 - vstate1, store digest status(A - H) ++# vconst0 - vconst1, interleaved used to store Tj <<< j ++# vtmp - temporary register ++# vw - for sm3tt1ab, vw = s0 eor s1 ++# s0 - for sm3tt2ab, just be s0 ++# i, choose wj' or wj from vw ++sub round () { ++my $ab = shift; ++my $vstate0 = shift; ++my $vstate1 = shift; ++my $vconst0 = shift; ++my $vconst1 = shift; ++my $vtmp = shift; ++my $vw = shift; ++my $s0 = shift; ++my $i = shift; ++$code.=<<___; ++ sm3ss1 $vtmp.4s, $vstate0.4s, $vconst0.4s, $vstate1.4s ++ shl $vconst1.4s, $vconst0.4s, #1 ++ sri $vconst1.4s, $vconst0.4s, #31 ++ sm3tt1$ab $vstate0.4s, $vtmp.4s, $vw.4s[$i] ++ sm3tt2$ab $vstate1.4s, $vtmp.4s, $s0.4s[$i] ++___ ++} ++ ++sub qround () { ++my $ab = shift; ++my $vstate0 = shift; ++my $vstate1 = shift; ++my $vconst0 = shift; ++my $vconst1 = shift; ++my $vtmp1 = shift; ++my $vtmp2 = shift; ++my $s0 = shift; ++my $s1 = shift; ++my $s2 = shift; ++my $s3 = shift; ++my $s4 = shift; ++ if($s4) { ++ &msg_exp($s0, $s1, $s2, $s3, $s4, $vtmp1, $vtmp2); ++ } ++$code.=<<___; ++ eor $vtmp1.16b, $s0.16b, $s1.16b ++___ ++ &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2, ++ $vtmp1, $s0, 0); ++ &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2, ++ $vtmp1, $s0, 1); ++ &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2, ++ $vtmp1, $s0, 2); ++ &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2, ++ $vtmp1, $s0, 3); ++} ++ ++$code=<<___; ++#include "arm_arch.h" ++.arch armv8.2-a ++.text ++___ ++ ++{{{ ++my ($pstate,$pdata,$num)=("x0","x1","w2"); ++my ($state1,$state2)=("v5","v6"); ++my ($sconst1, $sconst2)=("s16","s17"); ++my ($vconst1, $vconst2)=("v16","v17"); ++my ($s0,$s1,$s2,$s3,$s4)=map("v$_",(0..4)); ++my ($bkstate1,$bkstate2)=("v18","v19"); ++my ($vconst_tmp1,$vconst_tmp2)=("v20","v21"); ++my ($vtmp1,$vtmp2)=("v22","v23"); ++my $constaddr="x8"; ++# void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num) ++$code.=<<___; ++.globl ossl_hwsm3_block_data_order ++.type ossl_hwsm3_block_data_order,%function ++.align 5 ++ossl_hwsm3_block_data_order: ++ // load state ++ ld1 {$state1.4s-$state2.4s}, [$pstate] ++ rev64 $state1.4s, $state1.4s ++ rev64 $state2.4s, $state2.4s ++ ext $state1.16b, $state1.16b, $state1.16b, #8 ++ ext $state2.16b, $state2.16b, $state2.16b, #8 ++ ++ adr $constaddr, .Tj ++ ldp $sconst1, $sconst2, [$constaddr] ++ ++.Loop: ++ // load input ++ ld1 {$s0.16b-$s3.16b}, [$pdata], #64 ++ sub $num, $num, #1 ++ ++ mov $bkstate1.16b, $state1.16b ++ mov $bkstate2.16b, $state2.16b ++ ++#ifndef __ARMEB__ ++ rev32 $s0.16b, $s0.16b ++ rev32 $s1.16b, $s1.16b ++ rev32 $s2.16b, $s2.16b ++ rev32 $s3.16b, $s3.16b ++#endif ++ ++ ext $vconst_tmp1.16b, $vconst1.16b, $vconst1.16b, #4 ++___ ++ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s0,$s1,$s2,$s3,$s4); ++ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s1,$s2,$s3,$s4,$s0); ++ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s2,$s3,$s4,$s0,$s1); ++ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s3,$s4,$s0,$s1,$s2); ++ ++$code.=<<___; ++ ext $vconst_tmp1.16b, $vconst2.16b, $vconst2.16b, #4 ++___ ++ ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s4,$s0,$s1,$s2,$s3); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s0,$s1,$s2,$s3,$s4); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s1,$s2,$s3,$s4,$s0); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s2,$s3,$s4,$s0,$s1); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s3,$s4,$s0,$s1,$s2); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s4,$s0,$s1,$s2,$s3); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s0,$s1,$s2,$s3,$s4); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s1,$s2,$s3,$s4,$s0); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s2,$s3,$s4,$s0,$s1); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s3,$s4); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s4,$s0); ++ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2, ++ $s0,$s1); ++ ++$code.=<<___; ++ eor $state1.16b, $state1.16b, $bkstate1.16b ++ eor $state2.16b, $state2.16b, $bkstate2.16b ++ ++ // any remained blocks? ++ cbnz $num, .Loop ++ ++ // save state ++ rev64 $state1.4s, $state1.4s ++ rev64 $state2.4s, $state2.4s ++ ext $state1.16b, $state1.16b, $state1.16b, #8 ++ ext $state2.16b, $state2.16b, $state2.16b, #8 ++ st1 {$state1.4s-$state2.4s}, [$pstate] ++ ret ++.size ossl_hwsm3_block_data_order,.-ossl_hwsm3_block_data_order ++ ++.align 3 ++.Tj: ++.word 0x79cc4519, 0x9d8a7a87 ++___ ++}}} ++ ++######################################### ++my %sm3partopcode = ( ++ "sm3partw1" => 0xce60C000, ++ "sm3partw2" => 0xce60C400); ++ ++my %sm3ss1opcode = ( ++ "sm3ss1" => 0xce400000); ++ ++my %sm3ttopcode = ( ++ "sm3tt1a" => 0xce408000, ++ "sm3tt1b" => 0xce408400, ++ "sm3tt2a" => 0xce408800, ++ "sm3tt2b" => 0xce408C00); ++ ++sub unsm3part { ++ my ($mnemonic,$arg)=@_; ++ ++ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)/o ++ && ++ sprintf ".inst\t0x%08x\t//%s %s", ++ $sm3partopcode{$mnemonic}|$1|($2<<5)|($3<<16), ++ $mnemonic,$arg; ++} ++ ++sub unsm3ss1 { ++ my ($mnemonic,$arg)=@_; ++ ++ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)/o ++ && ++ sprintf ".inst\t0x%08x\t//%s %s", ++ $sm3ss1opcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<10), ++ $mnemonic,$arg; ++} ++ ++sub unsm3tt { ++ my ($mnemonic,$arg)=@_; ++ ++ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*\[([0-3])\]/o ++ && ++ sprintf ".inst\t0x%08x\t//%s %s", ++ $sm3ttopcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<12), ++ $mnemonic,$arg; ++} ++ ++open SELF,$0; ++while() { ++ next if (/^#!/); ++ last if (!s/^#/\/\// and !/^$/); ++ print; ++} ++close SELF; ++ ++foreach(split("\n",$code)) { ++ s/\`([^\`]*)\`/eval($1)/ge; ++ ++ s/\b(sm3partw[1-2])\s+([qv].*)/unsm3part($1,$2)/ge; ++ s/\b(sm3ss1)\s+([qv].*)/unsm3ss1($1,$2)/ge; ++ s/\b(sm3tt[1-2][a-b])\s+([qv].*)/unsm3tt($1,$2)/ge; ++ print $_,"\n"; ++} ++ ++close STDOUT or die "error closing STDOUT: $!"; +diff --git a/crypto/sm3/build.info b/crypto/sm3/build.info +index 6009b19..e113729 100644 +--- a/crypto/sm3/build.info ++++ b/crypto/sm3/build.info +@@ -1,2 +1,15 @@ + LIBS=../../libcrypto +-SOURCE[../../libcrypto]=sm3.c m_sm3.c ++SOURCE[../../libcrypto]=\ ++ sm3.c m_sm3.c {- $target{sm3_asm_src} -} ++ ++GENERATE[sm3-armv8.S]=asm/sm3-armv8.pl $(PERLASM_SCHEME) ++INCLUDE[sm3-armv8.o]=.. ++ ++BEGINRAW[Makefile] ++##### SM3 assembler implementations ++ ++# GNU make "catch all" ++{- $builddir -}/sm3-%.S: {- $sourcedir -}/asm/sm3-%.pl ++ CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ ++ ++ENDRAW[Makefile] +\ No newline at end of file +diff --git a/crypto/sm3/sm3_local.h b/crypto/sm3/sm3_local.h +index 7171de5..aafff63 100644 +--- a/crypto/sm3/sm3_local.h ++++ b/crypto/sm3/sm3_local.h +@@ -32,7 +32,21 @@ + ll=(c)->G; (void)HOST_l2c(ll, (s)); \ + ll=(c)->H; (void)HOST_l2c(ll, (s)); \ + } while (0) +-#define HASH_BLOCK_DATA_ORDER sm3_block_data_order ++ ++#if defined(SM3_ASM) ++# if defined(__aarch64__) ++# include "crypto/arm_arch.h" ++# define HWSM3_CAPABLE (OPENSSL_armcap_P & ARMV8_SM3) ++void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num); ++# endif ++#endif ++ ++#if defined(HWSM3_CAPABLE) ++# define HASH_BLOCK_DATA_ORDER (HWSM3_CAPABLE ? ossl_hwsm3_block_data_order \ ++ : sm3_block_data_order) ++#else ++# define HASH_BLOCK_DATA_ORDER sm3_block_data_order ++#endif + + void sm3_transform(SM3_CTX *c, const unsigned char *data); + +-- +2.36.1 + diff --git a/Backport-SM4-optimization-for-ARM-by-HW-instruction.patch b/Backport-SM4-optimization-for-ARM-by-HW-instruction.patch new file mode 100644 index 0000000000000000000000000000000000000000..f525e708169046c40aebbcf61924f116e5ee2038 --- /dev/null +++ b/Backport-SM4-optimization-for-ARM-by-HW-instruction.patch @@ -0,0 +1,1032 @@ +From 4f7e522f7fda2c55c4915396d08f8c9cf3b3fba8 Mon Sep 17 00:00:00 2001 +From: Xu Yizhou +Date: Fri, 28 Oct 2022 11:24:28 +0800 +Subject: [PATCH 2/3] SM4 optimization for ARM by HW instruction + +This patch is a copy of the following PR, with +some extra supporting code. + +1. SM4 optimization for ARM by HW instruction + +This patch implements the SM4 optimization for ARM processor, +using SM4 HW instruction, which is an optional feature of +crypto extension for aarch64 V8. + +Tested on some modern ARM micro-architectures with SM4 support, the +performance uplift can be observed around 8X~40X over existing +C implementation in openssl. Algorithms that can be parallelized +(like CTR, ECB, CBC decryption) are on higher end, with algorithm +like CBC encryption on lower end (due to inter-block dependency) + +Perf data on Yitian-710 2.75GHz hardware, before and after optimization: + +Before: +type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes +SM4-CTR 105787.80k 107837.87k 108380.84k 108462.08k 108549.46k 108554.92k +SM4-ECB 111924.58k 118173.76k 119776.00k 120093.70k 120264.02k 120274.94k +SM4-CBC 106428.09k 109190.98k 109674.33k 109774.51k 109827.41k 109827.41k + +After (7.4x - 36.6x faster): +type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes +SM4-CTR 781979.02k 2432994.28k 3437753.86k 3834177.88k 3963715.58k 3974556.33k +SM4-ECB 937590.69k 2941689.02k 3945751.81k 4328655.87k 4459181.40k 4468692.31k +SM4-CBC 890639.88k 1027746.58k 1050621.78k 1056696.66k 1058613.93k 1058701.31k + +Signed-off-by: Daniel Hu + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17455\) + +Signed-off-by: Xu Yizhou +--- + Configurations/00-base-templates.conf | 2 +- + Configure | 3 +- + crypto/arm64cpuid.pl | 7 + + crypto/arm_arch.h | 1 + + crypto/armcap.c | 10 + + crypto/evp/e_sm4.c | 88 ++-- + crypto/sm4/asm/sm4-armv8.pl | 629 ++++++++++++++++++++++++++ + crypto/sm4/build.info | 13 +- + include/crypto/sm4_platform.h | 70 +++ + 9 files changed, 788 insertions(+), 35 deletions(-) + create mode 100644 crypto/sm4/asm/sm4-armv8.pl + create mode 100644 include/crypto/sm4_platform.h + +diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf +index a67ae65..a26d081 100644 +--- a/Configurations/00-base-templates.conf ++++ b/Configurations/00-base-templates.conf +@@ -321,7 +321,7 @@ my %targets=( + chacha_asm_src => "chacha-armv8.S", + poly1305_asm_src=> "poly1305-armv8.S", + keccak1600_asm_src => "keccak1600-armv8.S", +- sm4_asm_src => "vpsm4_ex-armv8.S", ++ sm4_asm_src => "sm4-armv8.S vpsm4_ex-armv8.S", + sm3_asm_src => "sm3-armv8.S", + }, + parisc11_asm => { +diff --git a/Configure b/Configure +index fce460d..d013204 100755 +--- a/Configure ++++ b/Configure +@@ -1421,7 +1421,8 @@ unless ($disabled{asm}) { + push @{$config{lib_defines}}, "POLY1305_ASM"; + } + if ($target{sm4_asm_src} ne "") { +- push @{$config{lib_defines}}, "VPSM4_EX_ASM"; ++ push @{$config{lib_defines}}, "SM4_ASM" if ($target{sm4_asm_src} =~ m/sm4/); ++ push @{$config{lib_defines}}, "VPSM4_EX_ASM" if ($target{sm4_asm_src} =~ m/vpsm4_ex/); + } + if ($target{sm3_asm_src} ne "") { + push @{$config{lib_defines}}, "SM3_ASM"; +diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl +index 1e9b167..341167b 100755 +--- a/crypto/arm64cpuid.pl ++++ b/crypto/arm64cpuid.pl +@@ -71,6 +71,13 @@ _armv8_pmull_probe: + ret + .size _armv8_pmull_probe,.-_armv8_pmull_probe + ++.globl _armv8_sm4_probe ++.type _armv8_sm4_probe,%function ++_armv8_sm4_probe: ++ .long 0xcec08400 // sm4e v0.4s, v0.4s ++ ret ++.size _armv8_sm4_probe,.-_armv8_sm4_probe ++ + .globl _armv8_sha512_probe + .type _armv8_sha512_probe,%function + _armv8_sha512_probe: +diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h +index 8839b21..0f6f7ca 100644 +--- a/crypto/arm_arch.h ++++ b/crypto/arm_arch.h +@@ -81,5 +81,6 @@ extern unsigned int OPENSSL_armcap_P; + # define ARMV8_PMULL (1<<5) + # define ARMV8_SHA512 (1<<6) + # define ARMV8_SM3 (1<<9) ++# define ARMV8_SM4 (1<<10) + + #endif +diff --git a/crypto/armcap.c b/crypto/armcap.c +index 8b2f4a5..73bcad1 100644 +--- a/crypto/armcap.c ++++ b/crypto/armcap.c +@@ -48,6 +48,7 @@ void _armv8_sha256_probe(void); + void _armv8_pmull_probe(void); + # ifdef __aarch64__ + void _armv8_sm3_probe(void); ++void _armv8_sm4_probe(void); + void _armv8_sha512_probe(void); + # endif + uint32_t _armv7_tick(void); +@@ -132,6 +133,7 @@ static unsigned long getauxval(unsigned long key) + # define HWCAP_CE_SHA1 (1 << 5) + # define HWCAP_CE_SHA256 (1 << 6) + # define HWCAP_CE_SM3 (1 << 18) ++# define HWCAP_CE_SM4 (1 << 19) + # define HWCAP_CE_SHA512 (1 << 21) + # endif + +@@ -190,6 +192,9 @@ void OPENSSL_cpuid_setup(void) + OPENSSL_armcap_P |= ARMV8_SHA256; + + # ifdef __aarch64__ ++ if (hwcap & HWCAP_CE_SM4) ++ OPENSSL_armcap_P |= ARMV8_SM4; ++ + if (hwcap & HWCAP_CE_SHA512) + OPENSSL_armcap_P |= ARMV8_SHA512; + +@@ -234,6 +239,11 @@ void OPENSSL_cpuid_setup(void) + OPENSSL_armcap_P |= ARMV8_SHA256; + } + # if defined(__aarch64__) && !defined(__APPLE__) ++ if (sigsetjmp(ill_jmp, 1) == 0) { ++ _armv8_sm4_probe(); ++ OPENSSL_armcap_P |= ARMV8_SM4; ++ } ++ + if (sigsetjmp(ill_jmp, 1) == 0) { + _armv8_sha512_probe(); + OPENSSL_armcap_P |= ARMV8_SHA512; +diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c +index 169d6c7..eaa5ba0 100644 +--- a/crypto/evp/e_sm4.c ++++ b/crypto/evp/e_sm4.c +@@ -15,17 +15,11 @@ + # include + # include "crypto/sm4.h" + # include "crypto/evp.h" ++# include "crypto/sm4_platform.h" + # include "evp_local.h" + # include "modes_local.h" + +-#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) +-# include "arm_arch.h" +-# if __ARM_MAX_ARCH__>=7 +-# if defined(VPSM4_EX_ASM) +-# define VPSM4_EX_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) +-# endif +-# endif +-#endif ++ + + typedef struct { + union { +@@ -35,28 +29,11 @@ typedef struct { + block128_f block; + union { + ecb128_f ecb; ++ cbc128_f cbc; ++ ctr128_f ctr; + } stream; + } EVP_SM4_KEY; + +-#ifdef VPSM4_EX_CAPABLE +-void vpsm4_ex_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); +-void vpsm4_ex_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); +-#define vpsm4_ex_encrypt SM4_encrypt +-#define vpsm4_ex_decrypt SM4_encrypt +-void vpsm4_ex_ecb_encrypt( +- const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key, const int enc); +-/* xts mode in GB/T 17964-2021 */ +-void vpsm4_ex_xts_encrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, +- const SM4_KEY *key2, const uint8_t iv[16]); +-void vpsm4_ex_xts_decrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, +- const SM4_KEY *key2, const uint8_t iv[16]); +-/* xts mode in IEEE Std 1619-2007 */ +-void vpsm4_ex_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, +- const SM4_KEY *key2, const uint8_t iv[16]); +-void vpsm4_ex_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, +- const SM4_KEY *key2, const uint8_t iv[16]); +-#endif +- + # define BLOCK_CIPHER_generic(nid,blocksize,ivlen,nmode,mode,MODE,flags) \ + static const EVP_CIPHER sm4_##mode = { \ + nid##_##nmode,blocksize,128/8,ivlen, \ +@@ -84,6 +61,21 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + + mode = EVP_CIPHER_CTX_mode(ctx); + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { ++#ifdef HWSM4_CAPABLE ++ if (HWSM4_CAPABLE) { ++ HWSM4_set_decrypt_key(key, &dat->ks.ks); ++ dat->block = (block128_f) HWSM4_decrypt; ++ dat->stream.cbc = NULL; ++# ifdef HWSM4_cbc_encrypt ++ if (mode == EVP_CIPH_CBC_MODE) ++ dat->stream.cbc = (cbc128_f) HWSM4_cbc_encrypt; ++# endif ++# ifdef HWSM4_ecb_encrypt ++ if (mode == EVP_CIPH_ECB_MODE) ++ dat->stream.ecb = (ecb128_f) HWSM4_ecb_encrypt; ++# endif ++ } else ++#endif + #ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + vpsm4_ex_set_decrypt_key(key, &dat->ks.ks); +@@ -97,6 +89,29 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); + } + } else { ++#ifdef HWSM4_CAPABLE ++ if (HWSM4_CAPABLE) { ++ HWSM4_set_encrypt_key(key, &dat->ks.ks); ++ dat->block = (block128_f) HWSM4_encrypt; ++ dat->stream.cbc = NULL; ++# ifdef HWSM4_cbc_encrypt ++ if (mode == EVP_CIPH_CBC_MODE) ++ dat->stream.cbc = (cbc128_f) HWSM4_cbc_encrypt; ++ else ++# endif ++# ifdef HWSM4_ecb_encrypt ++ if (mode == EVP_CIPH_ECB_MODE) ++ dat->stream.ecb = (ecb128_f) HWSM4_ecb_encrypt; ++ else ++# endif ++# ifdef HWSM4_ctr32_encrypt_blocks ++ if (mode == EVP_CIPH_CTR_MODE) ++ dat->stream.ctr = (ctr128_f) HWSM4_ctr32_encrypt_blocks; ++ else ++# endif ++ (void)0; /* terminate potentially open 'else' */ ++ } else ++#endif + #ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + vpsm4_ex_set_encrypt_key(key, &dat->ks.ks); +@@ -118,7 +133,10 @@ static int sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + { + EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); + +- if (EVP_CIPHER_CTX_encrypting(ctx)) ++ if (dat->stream.cbc) ++ (*dat->stream.cbc) (in, out, len, &dat->ks.ks, ctx->iv, ++ EVP_CIPHER_CTX_encrypting(ctx)); ++ else if (EVP_CIPHER_CTX_encrypting(ctx)) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks.ks, + EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + else +@@ -183,10 +201,16 @@ static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + return 0; + num = (unsigned int)n; + +- CRYPTO_ctr128_encrypt(in, out, len, &dat->ks.ks, +- ctx->iv, +- EVP_CIPHER_CTX_buf_noconst(ctx), &num, +- dat->block); ++ if (dat->stream.ctr) ++ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ++ ctx->iv, ++ EVP_CIPHER_CTX_buf_noconst(ctx), ++ &num, dat->stream.ctr); ++ else ++ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks.ks, ++ ctx->iv, ++ EVP_CIPHER_CTX_buf_noconst(ctx), &num, ++ dat->block); + EVP_CIPHER_CTX_set_num(ctx, num); + return 1; + } +diff --git a/crypto/sm4/asm/sm4-armv8.pl b/crypto/sm4/asm/sm4-armv8.pl +new file mode 100644 +index 0000000..dbacad2 +--- /dev/null ++++ b/crypto/sm4/asm/sm4-armv8.pl +@@ -0,0 +1,629 @@ ++#! /usr/bin/env perl ++# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++# ++# This module implements support for SM4 hw support on aarch64 ++# Oct 2021 ++# ++ ++# $output is the last argument if it looks like a file (it has an extension) ++# $flavour is the first argument if it doesn't look like a file ++$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; ++$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or ++die "can't locate arm-xlate.pl"; ++ ++open OUT,"| \"$^X\" $xlate $flavour \"$output\"" ++ or die "can't call $xlate: $!"; ++*STDOUT=*OUT; ++ ++$prefix="sm4_v8"; ++my @rks=map("v$_",(0..7)); ++ ++sub rev32() { ++my $dst = shift; ++my $src = shift; ++$code.=<<___; ++#ifndef __ARMEB__ ++ rev32 $dst.16b,$src.16b ++#endif ++___ ++} ++ ++sub enc_blk () { ++my $data = shift; ++$code.=<<___; ++ sm4e $data.4s,@rks[0].4s ++ sm4e $data.4s,@rks[1].4s ++ sm4e $data.4s,@rks[2].4s ++ sm4e $data.4s,@rks[3].4s ++ sm4e $data.4s,@rks[4].4s ++ sm4e $data.4s,@rks[5].4s ++ sm4e $data.4s,@rks[6].4s ++ sm4e $data.4s,@rks[7].4s ++ rev64 $data.4S,$data.4S ++ ext $data.16b,$data.16b,$data.16b,#8 ++___ ++} ++ ++sub enc_4blks () { ++my $data0 = shift; ++my $data1 = shift; ++my $data2 = shift; ++my $data3 = shift; ++$code.=<<___; ++ sm4e $data0.4s,@rks[0].4s ++ sm4e $data1.4s,@rks[0].4s ++ sm4e $data2.4s,@rks[0].4s ++ sm4e $data3.4s,@rks[0].4s ++ ++ sm4e $data0.4s,@rks[1].4s ++ sm4e $data1.4s,@rks[1].4s ++ sm4e $data2.4s,@rks[1].4s ++ sm4e $data3.4s,@rks[1].4s ++ ++ sm4e $data0.4s,@rks[2].4s ++ sm4e $data1.4s,@rks[2].4s ++ sm4e $data2.4s,@rks[2].4s ++ sm4e $data3.4s,@rks[2].4s ++ ++ sm4e $data0.4s,@rks[3].4s ++ sm4e $data1.4s,@rks[3].4s ++ sm4e $data2.4s,@rks[3].4s ++ sm4e $data3.4s,@rks[3].4s ++ ++ sm4e $data0.4s,@rks[4].4s ++ sm4e $data1.4s,@rks[4].4s ++ sm4e $data2.4s,@rks[4].4s ++ sm4e $data3.4s,@rks[4].4s ++ ++ sm4e $data0.4s,@rks[5].4s ++ sm4e $data1.4s,@rks[5].4s ++ sm4e $data2.4s,@rks[5].4s ++ sm4e $data3.4s,@rks[5].4s ++ ++ sm4e $data0.4s,@rks[6].4s ++ sm4e $data1.4s,@rks[6].4s ++ sm4e $data2.4s,@rks[6].4s ++ sm4e $data3.4s,@rks[6].4s ++ ++ sm4e $data0.4s,@rks[7].4s ++ rev64 $data0.4S,$data0.4S ++ sm4e $data1.4s,@rks[7].4s ++ ext $data0.16b,$data0.16b,$data0.16b,#8 ++ rev64 $data1.4S,$data1.4S ++ sm4e $data2.4s,@rks[7].4s ++ ext $data1.16b,$data1.16b,$data1.16b,#8 ++ rev64 $data2.4S,$data2.4S ++ sm4e $data3.4s,@rks[7].4s ++ ext $data2.16b,$data2.16b,$data2.16b,#8 ++ rev64 $data3.4S,$data3.4S ++ ext $data3.16b,$data3.16b,$data3.16b,#8 ++___ ++} ++ ++$code=<<___; ++#include "arm_arch.h" ++.arch armv8-a+crypto ++.text ++___ ++ ++{{{ ++$code.=<<___; ++.align 6 ++.Lck: ++ .long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 ++ .long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 ++ .long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 ++ .long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 ++ .long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 ++ .long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 ++ .long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 ++ .long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 ++.Lfk: ++ .long 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc ++___ ++}}} ++ ++{{{ ++my ($key,$keys)=("x0","x1"); ++my ($tmp)=("x2"); ++my ($key0,$key1,$key2,$key3,$key4,$key5,$key6,$key7)=map("v$_",(0..7)); ++my ($const0,$const1,$const2,$const3,$const4,$const5,$const6,$const7)=map("v$_",(16..23)); ++my ($fkconst) = ("v24"); ++$code.=<<___; ++.globl ${prefix}_set_encrypt_key ++.type ${prefix}_set_encrypt_key,%function ++.align 5 ++${prefix}_set_encrypt_key: ++ ld1 {$key0.4s},[$key] ++ adr $tmp,.Lfk ++ ld1 {$fkconst.4s},[$tmp] ++ adr $tmp,.Lck ++ ld1 {$const0.4s,$const1.4s,$const2.4s,$const3.4s},[$tmp],64 ++___ ++ &rev32($key0, $key0); ++$code.=<<___; ++ ld1 {$const4.4s,$const5.4s,$const6.4s,$const7.4s},[$tmp] ++ eor $key0.16b,$key0.16b,$fkconst.16b; ++ sm4ekey $key0.4S,$key0.4S,$const0.4S ++ sm4ekey $key1.4S,$key0.4S,$const1.4S ++ sm4ekey $key2.4S,$key1.4S,$const2.4S ++ sm4ekey $key3.4S,$key2.4S,$const3.4S ++ sm4ekey $key4.4S,$key3.4S,$const4.4S ++ st1 {$key0.4s,$key1.4s,$key2.4s,$key3.4s},[$keys],64 ++ sm4ekey $key5.4S,$key4.4S,$const5.4S ++ sm4ekey $key6.4S,$key5.4S,$const6.4S ++ sm4ekey $key7.4S,$key6.4S,$const7.4S ++ st1 {$key4.4s,$key5.4s,$key6.4s,$key7.4s},[$keys] ++ ret ++.size ${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key ++___ ++}}} ++ ++{{{ ++my ($key,$keys)=("x0","x1"); ++my ($tmp)=("x2"); ++my ($key7,$key6,$key5,$key4,$key3,$key2,$key1,$key0)=map("v$_",(0..7)); ++my ($const0,$const1,$const2,$const3,$const4,$const5,$const6,$const7)=map("v$_",(16..23)); ++my ($fkconst) = ("v24"); ++$code.=<<___; ++.globl ${prefix}_set_decrypt_key ++.type ${prefix}_set_decrypt_key,%function ++.align 5 ++${prefix}_set_decrypt_key: ++ ld1 {$key0.4s},[$key] ++ adr $tmp,.Lfk ++ ld1 {$fkconst.4s},[$tmp] ++ adr $tmp, .Lck ++ ld1 {$const0.4s,$const1.4s,$const2.4s,$const3.4s},[$tmp],64 ++___ ++ &rev32($key0, $key0); ++$code.=<<___; ++ ld1 {$const4.4s,$const5.4s,$const6.4s,$const7.4s},[$tmp] ++ eor $key0.16b, $key0.16b,$fkconst.16b; ++ sm4ekey $key0.4S,$key0.4S,$const0.4S ++ sm4ekey $key1.4S,$key0.4S,$const1.4S ++ sm4ekey $key2.4S,$key1.4S,$const2.4S ++ rev64 $key0.4s,$key0.4s ++ rev64 $key1.4s,$key1.4s ++ ext $key0.16b,$key0.16b,$key0.16b,#8 ++ ext $key1.16b,$key1.16b,$key1.16b,#8 ++ sm4ekey $key3.4S,$key2.4S,$const3.4S ++ sm4ekey $key4.4S,$key3.4S,$const4.4S ++ rev64 $key2.4s,$key2.4s ++ rev64 $key3.4s,$key3.4s ++ ext $key2.16b,$key2.16b,$key2.16b,#8 ++ ext $key3.16b,$key3.16b,$key3.16b,#8 ++ sm4ekey $key5.4S,$key4.4S,$const5.4S ++ sm4ekey $key6.4S,$key5.4S,$const6.4S ++ rev64 $key4.4s,$key4.4s ++ rev64 $key5.4s,$key5.4s ++ ext $key4.16b,$key4.16b,$key4.16b,#8 ++ ext $key5.16b,$key5.16b,$key5.16b,#8 ++ sm4ekey $key7.4S,$key6.4S,$const7.4S ++ rev64 $key6.4s, $key6.4s ++ rev64 $key7.4s, $key7.4s ++ ext $key6.16b,$key6.16b,$key6.16b,#8 ++ ext $key7.16b,$key7.16b,$key7.16b,#8 ++ st1 {$key7.4s,$key6.4s,$key5.4s,$key4.4s},[$keys],64 ++ st1 {$key3.4s,$key2.4s,$key1.4s,$key0.4s},[$keys] ++ ret ++.size ${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key ++___ ++}}} ++ ++{{{ ++sub gen_block () { ++my $dir = shift; ++my ($inp,$out,$rk)=map("x$_",(0..2)); ++my ($data)=("v16"); ++$code.=<<___; ++.globl ${prefix}_${dir}crypt ++.type ${prefix}_${dir}crypt,%function ++.align 5 ++${prefix}_${dir}crypt: ++ ld1 {$data.4s},[$inp] ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk],64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk] ++___ ++ &rev32($data,$data); ++ &enc_blk($data); ++ &rev32($data,$data); ++$code.=<<___; ++ st1 {$data.4s},[$out] ++ ret ++.size ${prefix}_${dir}crypt,.-${prefix}_${dir}crypt ++___ ++} ++ ++&gen_block("en"); ++&gen_block("de"); ++}}} ++ ++{{{ ++my ($inp,$out,$len,$rk)=map("x$_",(0..3)); ++my ($enc) = ("w4"); ++my @dat=map("v$_",(16..23)); ++$code.=<<___; ++.globl ${prefix}_ecb_encrypt ++.type ${prefix}_ecb_encrypt,%function ++.align 5 ++${prefix}_ecb_encrypt: ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk],#64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk] ++1: ++ cmp $len,#64 ++ b.lt 1f ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64 ++ cmp $len,#128 ++ b.lt 2f ++ ld1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$inp],#64 ++ // 8 blocks ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &enc_4blks(@dat[4],@dat[5],@dat[6],@dat[7]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++$code.=<<___; ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++___ ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++$code.=<<___; ++ st1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$out],#64 ++ subs $len,$len,#128 ++ b.gt 1b ++ ret ++ // 4 blocks ++2: ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++$code.=<<___; ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ subs $len,$len,#64 ++ b.gt 1b ++1: ++ subs $len,$len,#16 ++ b.lt 1f ++ ld1 {@dat[0].4s},[$inp],#16 ++___ ++ &rev32(@dat[0],@dat[0]); ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ st1 {@dat[0].4s},[$out],#16 ++ b.ne 1b ++1: ++ ret ++.size ${prefix}_ecb_encrypt,.-${prefix}_ecb_encrypt ++___ ++}}} ++ ++{{{ ++my ($inp,$out,$len,$rk,$ivp)=map("x$_",(0..4)); ++my ($enc) = ("w5"); ++my @dat=map("v$_",(16..23)); ++my @in=map("v$_",(24..31)); ++my ($ivec) = ("v8"); ++$code.=<<___; ++.globl ${prefix}_cbc_encrypt ++.type ${prefix}_cbc_encrypt,%function ++.align 5 ++${prefix}_cbc_encrypt: ++ stp d8,d9,[sp, #-16]! ++ ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk],#64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk] ++ ld1 {$ivec.4s},[$ivp] ++ cmp $enc,#0 ++ b.eq .Ldec ++1: ++ cmp $len, #64 ++ b.lt 1f ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64 ++ eor @dat[0].16b,@dat[0].16b,$ivec.16b ++___ ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &enc_blk(@dat[0]); ++$code.=<<___; ++ eor @dat[1].16b,@dat[1].16b,@dat[0].16b ++___ ++ &enc_blk(@dat[1]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor @dat[2].16b,@dat[2].16b,@dat[1].16b ++___ ++ &enc_blk(@dat[2]); ++ &rev32(@dat[1],@dat[1]); ++$code.=<<___; ++ eor @dat[3].16b,@dat[3].16b,@dat[2].16b ++___ ++ &enc_blk(@dat[3]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++$code.=<<___; ++ mov $ivec.16b,@dat[3].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ subs $len,$len,#64 ++ b.ne 1b ++1: ++ subs $len,$len,#16 ++ b.lt 3f ++ ld1 {@dat[0].4s},[$inp],#16 ++ eor $ivec.16b,$ivec.16b,@dat[0].16b ++___ ++ &rev32($ivec,$ivec); ++ &enc_blk($ivec); ++ &rev32($ivec,$ivec); ++$code.=<<___; ++ st1 {$ivec.16b},[$out],#16 ++ b.ne 1b ++ b 3f ++.Ldec: ++1: ++ cmp $len, #64 ++ b.lt 1f ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp] ++ ld1 {@in[0].4s,@in[1].4s,@in[2].4s,@in[3].4s},[$inp],#64 ++ cmp $len,#128 ++ b.lt 2f ++ // 8 blocks mode ++ ld1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$inp] ++ ld1 {@in[4].4s,@in[5].4s,@in[6].4s,@in[7].4s},[$inp],#64 ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],$dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],$dat[7]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &enc_4blks(@dat[4],@dat[5],@dat[6],@dat[7]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++$code.=<<___; ++ eor @dat[0].16b,@dat[0].16b,$ivec.16b ++ eor @dat[1].16b,@dat[1].16b,@in[0].16b ++ eor @dat[2].16b,@dat[2].16b,@in[1].16b ++ mov $ivec.16b,@in[7].16b ++ eor @dat[3].16b,$dat[3].16b,@in[2].16b ++ eor @dat[4].16b,$dat[4].16b,@in[3].16b ++ eor @dat[5].16b,$dat[5].16b,@in[4].16b ++ eor @dat[6].16b,$dat[6].16b,@in[5].16b ++ eor @dat[7].16b,$dat[7].16b,@in[6].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ st1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$out],#64 ++ subs $len,$len,128 ++ b.gt 1b ++ b 3f ++ // 4 blocks mode ++2: ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],$dat[3]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++$code.=<<___; ++ eor @dat[0].16b,@dat[0].16b,$ivec.16b ++ eor @dat[1].16b,@dat[1].16b,@in[0].16b ++ mov $ivec.16b,@in[3].16b ++ eor @dat[2].16b,@dat[2].16b,@in[1].16b ++ eor @dat[3].16b,$dat[3].16b,@in[2].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ subs $len,$len,#64 ++ b.gt 1b ++1: ++ subs $len,$len,#16 ++ b.lt 3f ++ ld1 {@dat[0].4s},[$inp],#16 ++ mov @in[0].16b,@dat[0].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor @dat[0].16b,@dat[0].16b,$ivec.16b ++ mov $ivec.16b,@in[0].16b ++ st1 {@dat[0].16b},[$out],#16 ++ b.ne 1b ++3: ++ // save back IV ++ st1 {$ivec.16b},[$ivp] ++ ldp d8,d9,[sp],#16 ++ ret ++.size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt ++___ ++}}} ++ ++{{{ ++my ($inp,$out,$len,$rk,$ivp)=map("x$_",(0..4)); ++my ($ctr)=("w5"); ++my @dat=map("v$_",(16..23)); ++my @in=map("v$_",(24..31)); ++my ($ivec)=("v8"); ++$code.=<<___; ++.globl ${prefix}_ctr32_encrypt_blocks ++.type ${prefix}_ctr32_encrypt_blocks,%function ++.align 5 ++${prefix}_ctr32_encrypt_blocks: ++ stp d8,d9,[sp, #-16]! ++ ++ ld1 {$ivec.4s},[$ivp] ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk],64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk] ++___ ++ &rev32($ivec,$ivec); ++$code.=<<___; ++ mov $ctr,$ivec.s[3] ++1: ++ cmp $len,#4 ++ b.lt 1f ++ ld1 {@in[0].4s,@in[1].4s,@in[2].4s,@in[3].4s},[$inp],#64 ++ mov @dat[0].16b,$ivec.16b ++ mov @dat[1].16b,$ivec.16b ++ mov @dat[2].16b,$ivec.16b ++ mov @dat[3].16b,$ivec.16b ++ add $ctr,$ctr,#1 ++ mov $dat[1].s[3],$ctr ++ add $ctr,$ctr,#1 ++ mov @dat[2].s[3],$ctr ++ add $ctr,$ctr,#1 ++ mov @dat[3].s[3],$ctr ++ cmp $len,#8 ++ b.lt 2f ++ ld1 {@in[4].4s,@in[5].4s,@in[6].4s,@in[7].4s},[$inp],#64 ++ mov @dat[4].16b,$ivec.16b ++ mov @dat[5].16b,$ivec.16b ++ mov @dat[6].16b,$ivec.16b ++ mov @dat[7].16b,$ivec.16b ++ add $ctr,$ctr,#1 ++ mov $dat[4].s[3],$ctr ++ add $ctr,$ctr,#1 ++ mov @dat[5].s[3],$ctr ++ add $ctr,$ctr,#1 ++ mov @dat[6].s[3],$ctr ++ add $ctr,$ctr,#1 ++ mov @dat[7].s[3],$ctr ++___ ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &enc_4blks(@dat[4],@dat[5],@dat[6],@dat[7]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++$code.=<<___; ++ eor @dat[0].16b,@dat[0].16b,@in[0].16b ++ eor @dat[1].16b,@dat[1].16b,@in[1].16b ++ eor @dat[2].16b,@dat[2].16b,@in[2].16b ++ eor @dat[3].16b,@dat[3].16b,@in[3].16b ++ eor @dat[4].16b,@dat[4].16b,@in[4].16b ++ eor @dat[5].16b,@dat[5].16b,@in[5].16b ++ eor @dat[6].16b,@dat[6].16b,@in[6].16b ++ eor @dat[7].16b,@dat[7].16b,@in[7].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ st1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$out],#64 ++ subs $len,$len,#8 ++ b.eq 3f ++ add $ctr,$ctr,#1 ++ mov $ivec.s[3],$ctr ++ b 1b ++2: ++___ ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++$code.=<<___; ++ eor @dat[0].16b,@dat[0].16b,@in[0].16b ++ eor @dat[1].16b,@dat[1].16b,@in[1].16b ++ eor @dat[2].16b,@dat[2].16b,@in[2].16b ++ eor @dat[3].16b,@dat[3].16b,@in[3].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ subs $len,$len,#4 ++ b.eq 3f ++ add $ctr,$ctr,#1 ++ mov $ivec.s[3],$ctr ++ b 1b ++1: ++ subs $len,$len,#1 ++ b.lt 3f ++ mov $dat[0].16b,$ivec.16b ++ ld1 {@in[0].4s},[$inp],#16 ++___ ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor $dat[0].16b,$dat[0].16b,@in[0].16b ++ st1 {$dat[0].4s},[$out],#16 ++ b.eq 3f ++ add $ctr,$ctr,#1 ++ mov $ivec.s[3],$ctr ++ b 1b ++3: ++ ldp d8,d9,[sp],#16 ++ ret ++.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks ++___ ++}}} ++######################################## ++{ my %opcode = ( ++ "sm4e" => 0xcec08400, ++ "sm4ekey" => 0xce60c800); ++ ++ sub unsm4 { ++ my ($mnemonic,$arg)=@_; ++ ++ $arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o ++ && ++ sprintf ".inst\t0x%08x\t//%s %s", ++ $opcode{$mnemonic}|$1|($2<<5)|($3<<16), ++ $mnemonic,$arg; ++ } ++} ++ ++open SELF,$0; ++while() { ++ next if (/^#!/); ++ last if (!s/^#/\/\// and !/^$/); ++ print; ++} ++close SELF; ++ ++foreach(split("\n",$code)) { ++ s/\`([^\`]*)\`/eval($1)/ge; ++ ++ s/\b(sm4\w+)\s+([qv].*)/unsm4($1,$2)/ge; ++ print $_,"\n"; ++} ++ ++close STDOUT or die "error closing STDOUT: $!"; +diff --git a/crypto/sm4/build.info b/crypto/sm4/build.info +index bb042c5..4d26ede 100644 +--- a/crypto/sm4/build.info ++++ b/crypto/sm4/build.info +@@ -2,6 +2,17 @@ LIBS=../../libcrypto + SOURCE[../../libcrypto]=\ + sm4.c {- $target{sm4_asm_src} -} + ++GENERATE[sm4-armv8.S]=asm/sm4-armv8.pl $(PERLASM_SCHEME) ++INCLUDE[sm4-armv8.o]=.. + + GENERATE[vpsm4_ex-armv8.S]=asm/vpsm4_ex-armv8.pl $(PERLASM_SCHEME) +-INCLUDE[vpsm4_ex-armv8.o]=.. +\ No newline at end of file ++INCLUDE[vpsm4_ex-armv8.o]=.. ++ ++BEGINRAW[Makefile] ++##### SM4 assembler implementations ++ ++# GNU make "catch all" ++{- $builddir -}/sm4-%.S: {- $sourcedir -}/asm/sm4-%.pl ++ CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ ++ ++ENDRAW[Makefile] +diff --git a/include/crypto/sm4_platform.h b/include/crypto/sm4_platform.h +new file mode 100644 +index 0000000..2f5a6cf +--- /dev/null ++++ b/include/crypto/sm4_platform.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the Apache License 2.0 (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#ifndef OSSL_SM4_PLATFORM_H ++# define OSSL_SM4_PLATFORM_H ++# pragma once ++ ++# if defined(OPENSSL_CPUID_OBJ) ++# if (defined(__arm__) || defined(__arm) || defined(__aarch64__)) ++# include "arm_arch.h" ++# if __ARM_MAX_ARCH__>=7 ++# if defined(VPSM4_EX_ASM) ++# define VPSM4_EX_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) ++# endif ++# define HWSM4_CAPABLE (OPENSSL_armcap_P & ARMV8_SM4) ++# define HWSM4_set_encrypt_key sm4_v8_set_encrypt_key ++# define HWSM4_set_decrypt_key sm4_v8_set_decrypt_key ++# define HWSM4_encrypt sm4_v8_encrypt ++# define HWSM4_decrypt sm4_v8_decrypt ++# define HWSM4_cbc_encrypt sm4_v8_cbc_encrypt ++# define HWSM4_ecb_encrypt sm4_v8_ecb_encrypt ++# define HWSM4_ctr32_encrypt_blocks sm4_v8_ctr32_encrypt_blocks ++# endif ++# endif ++# endif /* OPENSSL_CPUID_OBJ */ ++ ++# if defined(HWSM4_CAPABLE) ++int HWSM4_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); ++int HWSM4_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); ++void HWSM4_encrypt(const unsigned char *in, unsigned char *out, ++ const SM4_KEY *key); ++void HWSM4_decrypt(const unsigned char *in, unsigned char *out, ++ const SM4_KEY *key); ++void HWSM4_cbc_encrypt(const unsigned char *in, unsigned char *out, ++ size_t length, const SM4_KEY *key, ++ unsigned char *ivec, const int enc); ++void HWSM4_ecb_encrypt(const unsigned char *in, unsigned char *out, ++ size_t length, const SM4_KEY *key, ++ const int enc); ++void HWSM4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, ++ size_t len, const void *key, ++ const unsigned char ivec[16]); ++# endif /* HWSM4_CAPABLE */ ++ ++#ifdef VPSM4_EX_CAPABLE ++void vpsm4_ex_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); ++void vpsm4_ex_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); ++#define vpsm4_ex_encrypt SM4_encrypt ++#define vpsm4_ex_decrypt SM4_encrypt ++void vpsm4_ex_ecb_encrypt( ++ const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key, const int enc); ++/* xts mode in GB/T 17964-2021 */ ++void vpsm4_ex_xts_encrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void vpsm4_ex_xts_decrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++/* xts mode in IEEE Std 1619-2007 */ ++void vpsm4_ex_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void vpsm4_ex_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++#endif /* VPSM4_EX_CAPABLE */ ++ ++#endif /* OSSL_SM4_PLATFORM_H */ +\ No newline at end of file +-- +2.36.1 + diff --git a/Backport-Skip-the-correct-number-of-tests-if-SM2-is-disabled.patch b/Backport-Skip-the-correct-number-of-tests-if-SM2-is-disabled.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0e5f9d266eb773a0439b8fe5eeb7a65801005ac --- /dev/null +++ b/Backport-Skip-the-correct-number-of-tests-if-SM2-is-disabled.patch @@ -0,0 +1,30 @@ +From f0dd65378296590d87250bf2130bad567483ee3d Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 3 Apr 2019 09:44:41 +0100 +Subject: [PATCH 08/15] Skip the correct number of tests if SM2 is disabled + +Fixes no-sm2 (and also no-sm3 and no-ec) + +Reviewed-by: Richard Levitte +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/8650) +--- + test/recipes/25-test_verify.t | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t +index b340833..d254bd8 100644 +--- a/test/recipes/25-test_verify.t ++++ b/test/recipes/25-test_verify.t +@@ -411,7 +411,7 @@ SKIP: { + } + + SKIP: { +- skip "SM2 is not supported by this OpenSSL build", 1 ++ skip "SM2 is not supported by this OpenSSL build", 2 + if disabled("sm2"); + + # Test '-sm2-id' and '-sm2-hex-id' option +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Support-SM2-certificate-signing.patch b/Backport-Support-SM2-certificate-signing.patch new file mode 100644 index 0000000000000000000000000000000000000000..11e84cc2fa0014df44a341b8362bb08b6073a3c9 --- /dev/null +++ b/Backport-Support-SM2-certificate-signing.patch @@ -0,0 +1,1189 @@ +From 0bacd53ecedfef3ca8af4a8884c46ec8e47c83fa Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Wed, 5 Jun 2019 14:46:48 +0800 +Subject: [PATCH 10/15] Support SM2 certificate signing + +SM2 certificate signing request can be created and signed by OpenSSL +now, both in library and apps. + +Documentation and test cases are added. + +Reviewed-by: Tim Hudson +Reviewed-by: Shane Lontis +(Merged from https://github.com/openssl/openssl/pull/9085) +--- + CHANGES | 3 + + apps/ca.c | 68 ++++++++++++- + apps/req.c | 149 ++++++++++++++++++++++++++-- + crypto/asn1/a_sign.c | 13 ++- + crypto/ec/ec_pmeth.c | 3 +- + crypto/err/openssl.txt | 3 + + crypto/x509/x509_err.c | 4 + + crypto/x509/x_all.c | 85 ++++++++++++---- + crypto/x509/x_req.c | 38 ++++++- + crypto/x509/x_x509.c | 3 + + doc/man1/ca.pod | 16 +++ + doc/man1/req.pod | 21 ++++ + doc/man3/X509_get0_sm2_id.pod | 12 ++- + include/crypto/x509.h | 3 + + include/openssl/x509.h | 2 + + include/openssl/x509err.h | 3 + + test/certs/sm2-csr.pem | 9 ++ + test/certs/sm2-root.crt | 14 +++ + test/certs/sm2-root.key | 5 + + test/recipes/25-test_req.t | 21 +++- + test/recipes/70-test_verify_extra.t | 3 +- + test/recipes/80-test_ca.t | 20 +++- + test/verify_extra_test.c | 45 ++++++++- + util/libcrypto.num | 2 + + 24 files changed, 501 insertions(+), 44 deletions(-) + create mode 100644 test/certs/sm2-csr.pem + create mode 100644 test/certs/sm2-root.crt + create mode 100644 test/certs/sm2-root.key + +diff --git a/CHANGES b/CHANGES +index 9d58cb0..6ab70fe 100644 +--- a/CHANGES ++++ b/CHANGES +@@ -9,6 +9,9 @@ + + Changes between 1.1.1l and 1.1.1m [14 Dec 2021] + ++ *) Support SM2 signing and verification schemes with X509 certificate. ++ [Paul Yang] ++ + *) Avoid loading of a dynamic engine twice. + + [Bernd Edlinger] +diff --git a/apps/ca.c b/apps/ca.c +index 390ac37..795ee2c 100755 +--- a/apps/ca.c ++++ b/apps/ca.c +@@ -96,7 +96,8 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, + const char *enddate, + long days, int batch, const char *ext_sect, CONF *conf, + int verbose, unsigned long certopt, unsigned long nameopt, +- int default_op, int ext_copy, int selfsign); ++ int default_op, int ext_copy, int selfsign, ++ unsigned char *sm2_id, size_t sm2idlen); + static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, + const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, + STACK_OF(CONF_VALUE) *policy, CA_DB *db, +@@ -147,7 +148,7 @@ typedef enum OPTION_choice { + OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, + OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, + OPT_RAND_SERIAL, +- OPT_R_ENUM, ++ OPT_R_ENUM, OPT_SM2ID, OPT_SM2HEXID, + /* Do not change the order here; see related case statements below */ + OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE + } OPTION_CHOICE; +@@ -217,6 +218,12 @@ const OPTIONS ca_options[] = { + OPT_R_OPTIONS, + #ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, ++#endif ++#ifndef OPENSSL_NO_SM2 ++ {"sm2-id", OPT_SM2ID, 's', ++ "Specify an ID string to verify an SM2 certificate request"}, ++ {"sm2-hex-id", OPT_SM2HEXID, 's', ++ "Specify a hex ID string to verify an SM2 certificate request"}, + #endif + {NULL} + }; +@@ -262,6 +269,9 @@ int ca_main(int argc, char **argv) + REVINFO_TYPE rev_type = REV_NONE; + X509_REVOKED *r = NULL; + OPTION_CHOICE o; ++ unsigned char *sm2_id = NULL; ++ size_t sm2_idlen = 0; ++ int sm2_free = 0; + + prog = opt_init(argc, argv, ca_options); + while ((o = opt_next()) != OPT_EOF) { +@@ -425,6 +435,30 @@ opthelp: + case OPT_ENGINE: + e = setup_engine(opt_arg(), 0); + break; ++ case OPT_SM2ID: ++ /* we assume the input is not a hex string */ ++ if (sm2_id != NULL) { ++ BIO_printf(bio_err, ++ "Use one of the options 'sm2-hex-id' or 'sm2-id'\n"); ++ goto end; ++ } ++ sm2_id = (unsigned char *)opt_arg(); ++ sm2_idlen = strlen((const char *)sm2_id); ++ break; ++ case OPT_SM2HEXID: ++ /* try to parse the input as hex string first */ ++ if (sm2_id != NULL) { ++ BIO_printf(bio_err, ++ "Use one of the options 'sm2-hex-id' or 'sm2-id'\n"); ++ goto end; ++ } ++ sm2_free = 1; ++ sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen); ++ if (sm2_id == NULL) { ++ BIO_printf(bio_err, "Invalid hex string input\n"); ++ goto end; ++ } ++ break; + } + } + end_of_options: +@@ -913,7 +947,8 @@ end_of_options: + j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db, + serial, subj, chtype, multirdn, email_dn, startdate, + enddate, days, batch, extensions, conf, verbose, +- certopt, get_nameopt(), default_op, ext_copy, selfsign); ++ certopt, get_nameopt(), default_op, ext_copy, selfsign, ++ sm2_id, sm2_idlen); + if (j < 0) + goto end; + if (j > 0) { +@@ -932,7 +967,8 @@ end_of_options: + j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db, + serial, subj, chtype, multirdn, email_dn, startdate, + enddate, days, batch, extensions, conf, verbose, +- certopt, get_nameopt(), default_op, ext_copy, selfsign); ++ certopt, get_nameopt(), default_op, ext_copy, selfsign, ++ sm2_id, sm2_idlen); + if (j < 0) + goto end; + if (j > 0) { +@@ -1230,6 +1266,8 @@ end_of_options: + ret = 0; + + end: ++ if (sm2_free) ++ OPENSSL_free(sm2_id); + if (ret) + ERR_print_errors(bio_err); + BIO_free_all(Sout); +@@ -1268,7 +1306,8 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, + const char *enddate, + long days, int batch, const char *ext_sect, CONF *lconf, + int verbose, unsigned long certopt, unsigned long nameopt, +- int default_op, int ext_copy, int selfsign) ++ int default_op, int ext_copy, int selfsign, ++ unsigned char *sm2id, size_t sm2idlen) + { + X509_REQ *req = NULL; + BIO *in = NULL; +@@ -1300,6 +1339,25 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, + BIO_printf(bio_err, "error unpacking public key\n"); + goto end; + } ++ if (sm2id != NULL) { ++#ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING *v; ++ ++ v = ASN1_OCTET_STRING_new(); ++ if (v == NULL) { ++ BIO_printf(bio_err, "error: SM2 ID allocation failed\n"); ++ goto end; ++ } ++ ++ if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) { ++ BIO_printf(bio_err, "error: setting SM2 ID failed\n"); ++ ASN1_OCTET_STRING_free(v); ++ goto end; ++ } ++ ++ X509_REQ_set0_sm2_id(req, v); ++#endif ++ } + i = X509_REQ_verify(req, pktmp); + pktmp = NULL; + if (i < 0) { +diff --git a/apps/req.c b/apps/req.c +index a603907..96f1edd 100644 +--- a/apps/req.c ++++ b/apps/req.c +@@ -90,7 +90,7 @@ typedef enum OPTION_choice { + OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, + OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509, + OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS, +- OPT_REQEXTS, OPT_PRECERT, OPT_MD, ++ OPT_REQEXTS, OPT_PRECERT, OPT_MD, OPT_SM2ID, OPT_SM2HEXID, + OPT_R_ENUM + } OPTION_CHOICE; + +@@ -145,6 +145,12 @@ const OPTIONS req_options[] = { + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"keygen_engine", OPT_KEYGEN_ENGINE, 's', + "Specify engine to be used for key generation operations"}, ++#endif ++#ifndef OPENSSL_NO_SM2 ++ {"sm2-id", OPT_SM2ID, 's', ++ "Specify an ID string to verify an SM2 certificate request"}, ++ {"sm2-hex-id", OPT_SM2HEXID, 's', ++ "Specify a hex ID string to verify an SM2 certificate request"}, + #endif + {NULL} + }; +@@ -242,6 +248,9 @@ int req_main(int argc, char **argv) + int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0; + long newkey = -1; + unsigned long chtype = MBSTRING_ASC, reqflag = 0; ++ unsigned char *sm2_id = NULL; ++ size_t sm2_idlen = 0; ++ int sm2_free = 0; + + #ifndef OPENSSL_NO_DES + cipher = EVP_des_ede3_cbc(); +@@ -417,6 +426,29 @@ int req_main(int argc, char **argv) + goto opthelp; + digest = md_alg; + break; ++ case OPT_SM2ID: ++ if (sm2_id != NULL) { ++ BIO_printf(bio_err, ++ "Use one of the options 'sm2-hex-id' or 'sm2-id'\n"); ++ goto end; ++ } ++ sm2_id = (unsigned char *)opt_arg(); ++ sm2_idlen = strlen((const char *)sm2_id); ++ break; ++ case OPT_SM2HEXID: ++ if (sm2_id != NULL) { ++ BIO_printf(bio_err, ++ "Use one of the options 'sm2-hex-id' or 'sm2-id'\n"); ++ goto end; ++ } ++ /* try to parse the input as hex string first */ ++ sm2_free = 1; ++ sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen); ++ if (sm2_id == NULL) { ++ BIO_printf(bio_err, "Invalid hex string input\n"); ++ goto end; ++ } ++ break; + } + } + argc = opt_num_rest(); +@@ -849,6 +881,26 @@ int req_main(int argc, char **argv) + goto end; + } + ++ if (sm2_id != NULL) { ++#ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING *v; ++ ++ v = ASN1_OCTET_STRING_new(); ++ if (v == NULL) { ++ BIO_printf(bio_err, "error: SM2 ID allocation failed\n"); ++ goto end; ++ } ++ ++ if (!ASN1_OCTET_STRING_set(v, sm2_id, sm2_idlen)) { ++ BIO_printf(bio_err, "error: setting SM2 ID failed\n"); ++ ASN1_OCTET_STRING_free(v); ++ goto end; ++ } ++ ++ X509_REQ_set0_sm2_id(req, v); ++#endif ++ } ++ + i = X509_REQ_verify(req, tpubkey); + + if (i < 0) { +@@ -957,6 +1009,8 @@ int req_main(int argc, char **argv) + } + ret = 0; + end: ++ if (sm2_free) ++ OPENSSL_free(sm2_id); + if (ret) { + ERR_print_errors(bio_err); + } +@@ -1611,14 +1665,58 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) + return 1; + } + ++#ifndef OPENSSL_NO_SM2 ++static int ec_pkey_is_sm2(EVP_PKEY *pkey) ++{ ++ EC_KEY *eckey = NULL; ++ const EC_GROUP *group = NULL; ++ ++ if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) ++ return 1; ++ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC ++ && (eckey = EVP_PKEY_get0_EC_KEY(pkey)) != NULL ++ && (group = EC_KEY_get0_group(eckey)) != NULL ++ && EC_GROUP_get_curve_name(group) == NID_sm2) ++ return 1; ++ return 0; ++} ++#endif ++ + static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, + const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) + { + EVP_PKEY_CTX *pkctx = NULL; +- int i, def_nid; ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_CTX *pctx = NULL; ++#endif ++ int i, def_nid, ret = 0; + + if (ctx == NULL) +- return 0; ++ goto err; ++#ifndef OPENSSL_NO_SM2 ++ if (ec_pkey_is_sm2(pkey)) { ++ /* initialize some SM2-specific code */ ++ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ BIO_printf(bio_err, "Internal error.\n"); ++ goto err; ++ } ++ pctx = EVP_PKEY_CTX_new(pkey, NULL); ++ if (pctx == NULL) { ++ BIO_printf(bio_err, "memory allocation failure.\n"); ++ goto err; ++ } ++ /* set SM2 ID from sig options before calling the real init routine */ ++ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { ++ char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); ++ if (pkey_ctrl_string(pctx, sigopt) <= 0) { ++ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ++ ERR_print_errors(bio_err); ++ goto err; ++ } ++ } ++ EVP_MD_CTX_set_pkey_ctx(ctx, pctx); ++ } ++#endif + /* + * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory + * for this algorithm. +@@ -1629,16 +1727,23 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, + md = NULL; + } + if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) +- return 0; ++ goto err; + for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { + char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); + if (pkey_ctrl_string(pkctx, sigopt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); + ERR_print_errors(bio_err); +- return 0; ++ goto err; + } + } +- return 1; ++ ++ ret = 1; ++ err: ++#ifndef OPENSSL_NO_SM2 ++ if (!ret) ++ EVP_PKEY_CTX_free(pctx); ++#endif ++ return ret; + } + + int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, +@@ -1646,10 +1751,20 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, + { + int rv; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_CTX *pctx = NULL; ++#endif + + rv = do_sign_init(mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_sign_ctx(x, mctx); ++#ifndef OPENSSL_NO_SM2 ++ /* only in SM2 case we need to free the pctx explicitly */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } ++#endif + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +@@ -1659,9 +1774,20 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, + { + int rv; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_CTX *pctx = NULL; ++#endif ++ + rv = do_sign_init(mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_REQ_sign_ctx(x, mctx); ++#ifndef OPENSSL_NO_SM2 ++ /* only in SM2 case we need to free the pctx explicitly */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } ++#endif + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +@@ -1671,9 +1797,20 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, + { + int rv; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_CTX *pctx = NULL; ++#endif ++ + rv = do_sign_init(mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_CRL_sign_ctx(x, mctx); ++#ifndef OPENSSL_NO_SM2 ++ /* only in SM2 case we need to free the pctx explicitly */ ++ if (ec_pkey_is_sm2(pkey)) { ++ pctx = EVP_MD_CTX_pkey_ctx(mctx); ++ EVP_PKEY_CTX_free(pctx); ++ } ++#endif + EVP_MD_CTX_free(mctx); + return rv > 0 ? 1 : 0; + } +diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c +index 72381b6..c29080b 100644 +--- a/crypto/asn1/a_sign.c ++++ b/crypto/asn1/a_sign.c +@@ -145,7 +145,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0, outll = 0; + int signid, paramtype, buf_len = 0; +- int rv; ++ int rv, pkey_id; + + type = EVP_MD_CTX_md(ctx); + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); +@@ -184,9 +184,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); + goto err; + } +- if (!OBJ_find_sigid_by_algs(&signid, +- EVP_MD_nid(type), +- pkey->ameth->pkey_id)) { ++ ++ pkey_id = ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_id(pkey) == NID_sm2 ? NID_sm2 : ++#endif ++ pkey->ameth->pkey_id; ++ ++ if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) { + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + goto err; +diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c +index 77876a0..591f27a 100644 +--- a/crypto/ec/ec_pmeth.c ++++ b/crypto/ec/ec_pmeth.c +@@ -327,7 +327,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 && +- EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) { ++ EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512 && ++ EVP_MD_type((const EVP_MD *)p2) != NID_sm3) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + return 0; + } +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index 5e71e65..b93cace 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -1711,6 +1711,7 @@ X509_F_BUILD_CHAIN:106:build_chain + X509_F_BY_FILE_CTRL:101:by_file_ctrl + X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints + X509_F_CHECK_POLICY:145:check_policy ++X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2 + X509_F_DANE_I2D:107:dane_i2d + X509_F_DIR_CTRL:102:dir_ctrl + X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject +@@ -1755,6 +1756,8 @@ X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key + X509_F_X509_REQ_PRINT_EX:121:X509_REQ_print_ex + X509_F_X509_REQ_PRINT_FP:122:X509_REQ_print_fp + X509_F_X509_REQ_TO_X509:123:X509_REQ_to_X509 ++X509_F_X509_REQ_VERIFY:163:X509_REQ_verify ++X509_F_X509_REQ_VERIFY_SM2:164:x509_req_verify_sm2 + X509_F_X509_STORE_ADD_CERT:124:X509_STORE_add_cert + X509_F_X509_STORE_ADD_CRL:125:X509_STORE_add_crl + X509_F_X509_STORE_ADD_LOOKUP:157:X509_STORE_add_lookup +diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c +index c91ad7c..f02793b 100644 +--- a/crypto/x509/x509_err.c ++++ b/crypto/x509/x509_err.c +@@ -20,6 +20,7 @@ static const ERR_STRING_DATA X509_str_functs[] = { + {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0), + "check_name_constraints"}, + {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"}, ++ {ERR_PACK(ERR_LIB_X509, X509_F_COMMON_VERIFY_SM2, 0), "common_verify_sm2"}, + {ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"}, + {ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"}, + {ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0), +@@ -87,6 +88,9 @@ static const ERR_STRING_DATA X509_str_functs[] = { + {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"}, ++ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY, 0), "X509_REQ_verify"}, ++ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY_SM2, 0), ++ "x509_req_verify_sm2"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0), + "X509_STORE_add_cert"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0), +diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c +index 9c8aea5..5c371f5 100644 +--- a/crypto/x509/x_all.c ++++ b/crypto/x509/x_all.c +@@ -24,86 +24,105 @@ + # include "crypto/asn1.h" + # include "crypto/evp.h" + +-static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) ++static int common_verify_sm2(void *data, EVP_PKEY *pkey, ++ int mdnid, int pknid, int req) + { ++ X509 *x = NULL; ++ X509_REQ *r = NULL; + EVP_MD_CTX *ctx = NULL; + unsigned char *buf_in = NULL; + int ret = -1, inl = 0; + size_t inll = 0; + EVP_PKEY_CTX *pctx = NULL; + const EVP_MD *type = EVP_get_digestbynid(mdnid); ++ ASN1_BIT_STRING *signature = NULL; ++ ASN1_OCTET_STRING *sm2_id = NULL; ++ ASN1_VALUE *tbv = NULL; + + if (type == NULL) { +- X509err(X509_F_X509_VERIFY_SM2, ++ X509err(X509_F_COMMON_VERIFY_SM2, + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + if (pkey == NULL) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + +- if (x->signature.type == V_ASN1_BIT_STRING && x->signature.flags & 0x7) { +- X509err(X509_F_X509_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); ++ if (req == 1) { ++ r = (X509_REQ *)data; ++ signature = r->signature; ++ sm2_id = r->sm2_id; ++ tbv = (ASN1_VALUE *)&r->req_info; ++ } else { ++ x = (X509 *)data; ++ signature = &x->signature; ++ sm2_id = x->sm2_id; ++ tbv = (ASN1_VALUE *)&x->cert_info; ++ } ++ ++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ++ X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return -1; + } + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Check public key OID matches public key type */ + if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { +- X509err(X509_F_X509_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE); ++ X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + + if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* NOTE: we tolerate no actual ID, to provide maximum flexibility */ +- if (x->sm2_id != NULL +- && EVP_PKEY_CTX_set1_id(pctx, x->sm2_id->data, +- x->sm2_id->length) != 1) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ if (sm2_id != NULL ++ && EVP_PKEY_CTX_set1_id(pctx, sm2_id->data, sm2_id->length) != 1) { ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + EVP_MD_CTX_set_pkey_ctx(ctx, pctx); + + if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + +- inl = ASN1_item_i2d((ASN1_VALUE *)&x->cert_info, &buf_in, ++ inl = ASN1_item_i2d(tbv, &buf_in, ++ req == 1 ? ++ ASN1_ITEM_rptr(X509_REQ_INFO) : + ASN1_ITEM_rptr(X509_CINF)); + if (inl <= 0) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_INTERNAL_ERROR); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_INTERNAL_ERROR); + goto err; + } + if (buf_in == NULL) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE); + goto err; + } + inll = inl; + +- ret = EVP_DigestVerify(ctx, x->signature.data, +- (size_t)x->signature.length, buf_in, inl); ++ ret = EVP_DigestVerify(ctx, signature->data, ++ (size_t)signature->length, buf_in, inl); + if (ret <= 0) { +- X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB); + goto err; + } + ret = 1; +@@ -113,6 +132,18 @@ static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) + EVP_PKEY_CTX_free(pctx); + return ret; + } ++ ++static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) ++{ ++ return common_verify_sm2(x, pkey, mdnid, pknid, 0); ++} ++ ++static int x509_req_verify_sm2(X509_REQ *x, EVP_PKEY *pkey, ++ int mdnid, int pknid) ++{ ++ return common_verify_sm2(x, pkey, mdnid, pknid, 1); ++} ++ + #endif + + int X509_verify(X509 *a, EVP_PKEY *r) +@@ -142,6 +173,20 @@ int X509_verify(X509 *a, EVP_PKEY *r) + + int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) + { ++#ifndef OPENSSL_NO_SM2 ++ int mdnid, pknid; ++ ++ /* Convert signature OID into digest and public key OIDs */ ++ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm), ++ &mdnid, &pknid)) { ++ X509err(X509_F_X509_REQ_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); ++ return 0; ++ } ++ ++ if (pknid == NID_sm2) ++ return x509_req_verify_sm2(a, r, mdnid, pknid); ++#endif ++ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + &a->sig_alg, a->signature, &a->req_info, r)); + } +diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c +index d2b02f6..de4ff2c 100644 +--- a/crypto/x509/x_req.c ++++ b/crypto/x509/x_req.c +@@ -45,6 +45,29 @@ static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + return 1; + } + ++static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ++ void *exarg) ++{ ++#ifndef OPENSSL_NO_SM2 ++ X509_REQ *ret = (X509_REQ *)*pval; ++ ++ switch (operation) { ++ case ASN1_OP_D2I_PRE: ++ ASN1_OCTET_STRING_free(ret->sm2_id); ++ /* fall thru */ ++ case ASN1_OP_NEW_POST: ++ ret->sm2_id = NULL; ++ break; ++ ++ case ASN1_OP_FREE_POST: ++ ASN1_OCTET_STRING_free(ret->sm2_id); ++ break; ++ } ++#endif ++ ++ return 1; ++} ++ + ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { + ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), +@@ -57,7 +80,7 @@ ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { + + IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) + +-ASN1_SEQUENCE_ref(X509_REQ, 0) = { ++ASN1_SEQUENCE_ref(X509_REQ, req_cb) = { + ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO), + ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) +@@ -66,3 +89,16 @@ ASN1_SEQUENCE_ref(X509_REQ, 0) = { + IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) + + IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) ++ ++#ifndef OPENSSL_NO_SM2 ++void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id) ++{ ++ ASN1_OCTET_STRING_free(x->sm2_id); ++ x->sm2_id = sm2_id; ++} ++ ++ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x) ++{ ++ return x->sm2_id; ++} ++#endif +diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c +index fb03bb2..8c27265 100644 +--- a/crypto/x509/x_x509.c ++++ b/crypto/x509/x_x509.c +@@ -53,6 +53,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); + ASIdentifiers_free(ret->rfc3779_asid); + #endif ++#ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING_free(ret->sm2_id); ++#endif + + /* fall thru */ + +diff --git a/doc/man1/ca.pod b/doc/man1/ca.pod +index 4380d86..1a6c53e 100644 +--- a/doc/man1/ca.pod ++++ b/doc/man1/ca.pod +@@ -57,6 +57,8 @@ B B + [B<-multivalue-rdn>] + [B<-rand file...>] + [B<-writerand file>] ++[B<-sm2-id string>] ++[B<-sm2-hex-id hex-string>] + + =head1 DESCRIPTION + +@@ -303,6 +305,16 @@ all others. + Writes random data to the specified I upon exit. + This can be used with a subsequent B<-rand> flag. + ++=item B<-sm2-id> ++ ++Specify the ID string to use when verifying an SM2 certificate. The ID string is ++required by the SM2 signature algorithm for signing and verification. ++ ++=item B<-sm2-hex-id> ++ ++Specify a binary ID string to use when signing or verifying using an SM2 ++certificate. The argument for this option is string of hexadecimal digits. ++ + =back + + =head1 CRL OPTIONS +@@ -600,6 +612,10 @@ Sign a certificate request: + + openssl ca -in req.pem -out newcert.pem + ++Sign an SM2 certificate request: ++ ++ openssl ca -in sm2.csr -out sm2.crt -md sm3 -sigopt "sm2_id:1234567812345678" -sm2-id "1234567812345678" ++ + Sign a certificate request, using CA extensions: + + openssl ca -in req.pem -extensions v3_ca -out newcert.pem +diff --git a/doc/man1/req.pod b/doc/man1/req.pod +index 539b843..3b9fcc3 100644 +--- a/doc/man1/req.pod ++++ b/doc/man1/req.pod +@@ -50,6 +50,8 @@ B B + [B<-batch>] + [B<-verbose>] + [B<-engine id>] ++[B<-sm2-id string>] ++[B<-sm2-hex-id hex-string>] + + =head1 DESCRIPTION + +@@ -339,6 +341,16 @@ for all available algorithms. + Specifies an engine (by its unique B string) which would be used + for key generation operations. + ++=item B<-sm2-id> ++ ++Specify the ID string to use when verifying an SM2 certificate. The ID string is ++required by the SM2 signature algorithm for signing and verification. ++ ++=item B<-sm2-hex-id> ++ ++Specify a binary ID string to use when signing or verifying using an SM2 ++certificate. The argument for this option is string of hexadecimal digits. ++ + =back + + =head1 CONFIGURATION FILE FORMAT +@@ -534,6 +546,15 @@ Generate a self signed root certificate: + + openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem + ++Create an SM2 private key and then generate a certificate request from it: ++ ++ openssl ecparam -genkey -name SM2 -out sm2.key ++ openssl req -new -key sm2.key -out sm2.csr -sm3 -sigopt "sm2_id:1234567812345678" ++ ++Examine and verify an SM2 certificate request: ++ ++ openssl req -verify -in sm2.csr -sm3 -sm2-id 1234567812345678 ++ + Example of a file pointed to by the B option: + + 1.2.3.4 shortName A longer Name +diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod +index 9698c86..d8a85d7 100644 +--- a/doc/man3/X509_get0_sm2_id.pod ++++ b/doc/man3/X509_get0_sm2_id.pod +@@ -2,7 +2,9 @@ + + =head1 NAME + +-X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operations ++X509_get0_sm2_id, X509_set0_sm2_id, ++X509_REQ_get0_sm2_id, X509_REQ_set0_sm2_id ++- get or set SM2 ID for certificate operations + + =head1 SYNOPSIS + +@@ -10,6 +12,8 @@ X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operation + + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); + void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); ++ ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x); ++ void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id); + + =head1 DESCRIPTION + +@@ -21,6 +25,10 @@ this function transfers the memory management of the value to the X509 object, + and therefore the value that has been passed in should not be freed by the + caller after this function has been called. + ++X509_REQ_get0_sm2_id() and X509_REQ_set0_sm2_id() have the same functionality ++as X509_get0_sm2_id() and X509_set0_sm2_id() except that they deal with ++B objects instead of B. ++ + =head1 NOTES + + SM2 signature algorithm requires an ID value when generating and verifying a +@@ -29,7 +37,7 @@ ability to set and retrieve the SM2 ID value. + + =head1 RETURN VALUES + +-X509_set0_sm2_id() does not return a value. ++X509_set0_sm2_id() and X509_REQ_set0_sm2_id() do not return a value. + + =head1 SEE ALSO + +diff --git a/include/crypto/x509.h b/include/crypto/x509.h +index 5c314a8..a6e812a 100644 +--- a/include/crypto/x509.h ++++ b/include/crypto/x509.h +@@ -73,6 +73,9 @@ struct X509_req_st { + ASN1_BIT_STRING *signature; /* signature */ + CRYPTO_REF_COUNT references; + CRYPTO_RWLOCK *lock; ++# ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING *sm2_id; ++# endif + }; + + struct X509_crl_info_st { +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index a02cf50..42e9eee 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -576,6 +576,8 @@ int X509_get_signature_nid(const X509 *x); + # ifndef OPENSSL_NO_SM2 + void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); + ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); ++void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id); ++ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x); + # endif + + int X509_trusted(const X509 *x); +diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h +index 06d75f0..0a84ef0 100644 +--- a/include/openssl/x509err.h ++++ b/include/openssl/x509err.h +@@ -26,6 +26,7 @@ int ERR_load_X509_strings(void); + # define X509_F_BY_FILE_CTRL 101 + # define X509_F_CHECK_NAME_CONSTRAINTS 149 + # define X509_F_CHECK_POLICY 145 ++# define X509_F_COMMON_VERIFY_SM2 165 + # define X509_F_DANE_I2D 107 + # define X509_F_DIR_CTRL 102 + # define X509_F_GET_CERT_BY_SUBJECT 103 +@@ -70,6 +71,8 @@ int ERR_load_X509_strings(void); + # define X509_F_X509_REQ_PRINT_EX 121 + # define X509_F_X509_REQ_PRINT_FP 122 + # define X509_F_X509_REQ_TO_X509 123 ++# define X509_F_X509_REQ_VERIFY 163 ++# define X509_F_X509_REQ_VERIFY_SM2 164 + # define X509_F_X509_STORE_ADD_CERT 124 + # define X509_F_X509_STORE_ADD_CRL 125 + # define X509_F_X509_STORE_ADD_LOOKUP 157 +diff --git a/test/certs/sm2-csr.pem b/test/certs/sm2-csr.pem +new file mode 100644 +index 0000000..a6dcca8 +--- /dev/null ++++ b/test/certs/sm2-csr.pem +@@ -0,0 +1,9 @@ ++-----BEGIN CERTIFICATE REQUEST----- ++MIIBMTCB1wIBADB1MQswCQYDVQQGEwJDTjERMA8GA1UECAwITGlhb25pbmcxETAP ++BgNVBAcMCFNoZW55YW5nMQwwCgYDVQQKDANUZXQxDDAKBgNVBAsMA1RldDELMAkG ++A1UEAwwCb28xFzAVBgkqhkiG9w0BCQEWCG9vQG9vLm9vMFkwEwYHKoZIzj0CAQYI ++KoEcz1UBgi0DQgAE1NjdOpldcjTkuZpdGDNyHAnhK9cB2RZ7jAmFzt7jgEs9OHSg ++rb3crjz+qGZfqyJ5AyZulQ7gdARzb1H55jvw5qAAMAoGCCqBHM9VAYN1A0kAMEYC ++IQCacUXA8kyTTDwEm89Yz9qjsbfd8/N32lnzKxuKCcXJwQIhAIpugCbfeWuPxUQO ++7AvQS3yxBp1yn0FbTT2XVSyYy6To ++-----END CERTIFICATE REQUEST----- +diff --git a/test/certs/sm2-root.crt b/test/certs/sm2-root.crt +new file mode 100644 +index 0000000..5677ac6 +--- /dev/null ++++ b/test/certs/sm2-root.crt +@@ -0,0 +1,14 @@ ++-----BEGIN CERTIFICATE----- ++MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT ++AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl ++c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe ++Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw ++CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn ++MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG ++SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU ++5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW ++BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU ++5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI ++ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X ++YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3 ++-----END CERTIFICATE----- +diff --git a/test/certs/sm2-root.key b/test/certs/sm2-root.key +new file mode 100644 +index 0000000..4bda65b +--- /dev/null ++++ b/test/certs/sm2-root.key +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQglktdVbLA5tyXMc+9 ++KV4ikyDaFZNnXqfNAzUVqTlqn8GhRANCAAR0WJ6hK6HwXVz6bb7zu/gUlScXKR7k ++xp2flD621OZFRFDGlJzTnjCWZf70RopmQpvwJEXiZkX529eREh0frLKe ++-----END PRIVATE KEY----- +diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t +index 383120c..8289959 100644 +--- a/test/recipes/25-test_req.t ++++ b/test/recipes/25-test_req.t +@@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; + + setup("test_req"); + +-plan tests => 14; ++plan tests => 15; + + require_ok(srctop_file('test','recipes','tconversion.pl')); + +@@ -181,6 +181,25 @@ subtest "generating certificate requests" => sub { + "Verifying signature on request"); + }; + ++subtest "generating SM2 certificate requests" => sub { ++ plan tests => 2; ++ ++ SKIP: { ++ skip "SM2 is not supported by this OpenSSL build", 2 ++ if disabled("sm2"); ++ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), ++ "-new", "-key", srctop_file("test", "certs", "sm2.key"), ++ "-sigopt", "sm2_id:1234567812345678", ++ "-out", "testreq.pem", "-sm3"])), ++ "Generating SM2 certificate request"); ++ ++ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), ++ "-verify", "-in", "testreq.pem", "-noout", ++ "-sm2-id", "1234567812345678", "-sm3"])), ++ "Verifying signature on SM2 certificate request"); ++ } ++}; ++ + my @openssl_args = ("req", "-config", srctop_file("apps", "openssl.cnf")); + + run_conversion('req conversions', +diff --git a/test/recipes/70-test_verify_extra.t b/test/recipes/70-test_verify_extra.t +index 8c7c957..1571115 100644 +--- a/test/recipes/70-test_verify_extra.t ++++ b/test/recipes/70-test_verify_extra.t +@@ -17,4 +17,5 @@ ok(run(test(["verify_extra_test", + srctop_file("test", "certs", "roots.pem"), + srctop_file("test", "certs", "untrusted.pem"), + srctop_file("test", "certs", "bad.pem"), +- srctop_file("test", "certs", "rootCA.pem")]))); ++ srctop_file("test", "certs", "rootCA.pem"), ++ srctop_file("test", "certs", "sm2-csr.pem")]))); +diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t +index 557777e..92557cf 100644 +--- a/test/recipes/80-test_ca.t ++++ b/test/recipes/80-test_ca.t +@@ -23,7 +23,7 @@ my $std_openssl_cnf = + + rmtree("demoCA", { safe => 0 }); + +-plan tests => 5; ++plan tests => 6; + SKIP: { + $ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "CAss.cnf").'"'; + skip "failed creating CA structure", 4 +@@ -51,9 +51,25 @@ plan tests => 5; + 'creating new pre-certificate'); + } + ++SKIP: { ++ skip "SM2 is not supported by this OpenSSL build", 1 ++ if disabled("sm2"); ++ ++ is(yes(cmdstr(app(["openssl", "ca", "-config", ++ srctop_file("test", "CAss.cnf"), ++ "-in", srctop_file("test", "certs", "sm2-csr.pem"), ++ "-out", "sm2-test.crt", ++ "-sigopt", "sm2_id:1234567812345678", ++ "-sm2-id", "1234567812345678", ++ "-md", "sm3", ++ "-cert", srctop_file("test", "certs", "sm2-root.crt"), ++ "-keyfile", srctop_file("test", "certs", "sm2-root.key")]))), ++ 0, ++ "Signing SM2 certificate request"); ++} + + rmtree("demoCA", { safe => 0 }); +-unlink "newcert.pem", "newreq.pem", "newkey.pem"; ++unlink "newcert.pem", "newreq.pem", "newkey.pem", "sm2-test.crt"; + + + sub yes { +diff --git a/test/verify_extra_test.c b/test/verify_extra_test.c +index 763ea4f..d69653c 100644 +--- a/test/verify_extra_test.c ++++ b/test/verify_extra_test.c +@@ -20,6 +20,7 @@ static const char *roots_f; + static const char *untrusted_f; + static const char *bad_f; + static const char *good_f; ++static const char *req_f; + + static X509 *load_cert_pem(const char *file) + { +@@ -272,6 +273,46 @@ static int test_sm2_id(void) + BIO_free(bio); + return ret; + } ++ ++static int test_req_sm2_id(void) ++{ ++ /* we only need an X509_REQ structure, no matter if it's a real SM2 cert */ ++ X509_REQ *x = NULL; ++ BIO *bio = NULL; ++ int ret = 0; ++ ASN1_OCTET_STRING *v = NULL, *v2 = NULL; ++ char *sm2id = "this is an ID"; ++ ++ bio = BIO_new_file(req_f, "r"); ++ if (bio == NULL) ++ goto err; ++ ++ x = PEM_read_bio_X509_REQ(bio, NULL, 0, NULL); ++ if (x == NULL) ++ goto err; ++ ++ v = ASN1_OCTET_STRING_new(); ++ if (v == NULL) ++ goto err; ++ ++ if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) { ++ ASN1_OCTET_STRING_free(v); ++ goto err; ++ } ++ ++ X509_REQ_set0_sm2_id(x, v); ++ ++ v2 = X509_REQ_get0_sm2_id(x); ++ if (!TEST_ptr(v2) ++ || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0)) ++ goto err; ++ ++ ret = 1; ++ err: ++ X509_REQ_free(x); ++ BIO_free(bio); ++ return ret; ++} + #endif + + int setup_tests(void) +@@ -279,7 +320,8 @@ int setup_tests(void) + if (!TEST_ptr(roots_f = test_get_argument(0)) + || !TEST_ptr(untrusted_f = test_get_argument(1)) + || !TEST_ptr(bad_f = test_get_argument(2)) +- || !TEST_ptr(good_f = test_get_argument(3))) { ++ || !TEST_ptr(good_f = test_get_argument(3)) ++ || !TEST_ptr(req_f = test_get_argument(4))) { + TEST_error("usage: verify_extra_test roots.pem untrusted.pem bad.pem good.pem\n"); + return 0; + } +@@ -290,6 +332,7 @@ int setup_tests(void) + ADD_TEST(test_self_signed_bad); + #ifndef OPENSSL_NO_SM2 + ADD_TEST(test_sm2_id); ++ ADD_TEST(test_req_sm2_id); + #endif + return 1; + } +diff --git a/util/libcrypto.num b/util/libcrypto.num +index d7abe91..81a6388 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4628,3 +4628,5 @@ FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: + FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: + X509_set0_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 + X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2 ++X509_REQ_get0_sm2_id 6385 1_1_1m EXIST::FUNCTION:SM2 ++X509_REQ_set0_sm2_id 6386 1_1_1m EXIST::FUNCTION:SM2 +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Support-SM2-certificate-verification.patch b/Backport-Support-SM2-certificate-verification.patch new file mode 100644 index 0000000000000000000000000000000000000000..87c5aded3062def070e7787f9f0ef5df1384e076 --- /dev/null +++ b/Backport-Support-SM2-certificate-verification.patch @@ -0,0 +1,579 @@ +From 7d86ccd1282aeff8f6d564c5d37625ffcc048f2d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=A8=E6=B4=8B?= +Date: Fri, 26 Oct 2018 21:34:08 +0800 +Subject: [PATCH 03/15] Support SM2 certificate verification + +Reviewed-by: Tim Hudson +(Merged from https://github.com/openssl/openssl/pull/8321) +--- + apps/verify.c | 45 +++++++++++++-- + crypto/asn1/a_verify.c | 3 +- + crypto/err/openssl.txt | 2 + + crypto/objects/obj_dat.h | 17 ++++-- + crypto/objects/obj_mac.num | 1 + + crypto/objects/obj_xref.h | 4 +- + crypto/objects/obj_xref.txt | 2 + + crypto/objects/objects.txt | 2 + + crypto/x509/x509_err.c | 2 + + crypto/x509/x_all.c | 110 ++++++++++++++++++++++++++++++++++++ + crypto/x509/x_x509.c | 12 ++++ + fuzz/oids.txt | 1 + + include/crypto/x509.h | 5 +- + include/openssl/obj_mac.h | 7 ++- + include/openssl/x509.h | 3 + + include/openssl/x509err.h | 2 + + util/libcrypto.num | 2 + + 17 files changed, 204 insertions(+), 16 deletions(-) + +diff --git a/apps/verify.c b/apps/verify.c +index 1f93856..09b31cf 100644 +--- a/apps/verify.c ++++ b/apps/verify.c +@@ -21,7 +21,8 @@ + static int cb(int ok, X509_STORE_CTX *ctx); + static int check(X509_STORE *ctx, const char *file, + STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, +- STACK_OF(X509_CRL) *crls, int show_chain); ++ STACK_OF(X509_CRL) *crls, int show_chain, ++ unsigned char *sm2id, size_t sm2idlen); + static int v_verbose = 0, vflags = 0; + + typedef enum OPTION_choice { +@@ -29,7 +30,7 @@ typedef enum OPTION_choice { + OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, + OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN, + OPT_V_ENUM, OPT_NAMEOPT, +- OPT_VERBOSE ++ OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID + } OPTION_CHOICE; + + const OPTIONS verify_options[] = { +@@ -56,6 +57,12 @@ const OPTIONS verify_options[] = { + OPT_V_OPTIONS, + #ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, ++#endif ++#ifndef OPENSSL_NO_SM2 ++ {"sm2-id", OPT_SM2ID, 's', ++ "Specify an ID string to verify an SM2 certificate"}, ++ {"sm2-hex-id", OPT_SM2HEXID, 's', ++ "Specify a hex ID string to verify an SM2 certificate"}, + #endif + {NULL} + }; +@@ -71,6 +78,8 @@ int verify_main(int argc, char **argv) + int noCApath = 0, noCAfile = 0; + int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; + OPTION_CHOICE o; ++ unsigned char *sm2_id = NULL; ++ size_t sm2_idlen = 0; + + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) + goto end; +@@ -158,6 +167,19 @@ int verify_main(int argc, char **argv) + case OPT_VERBOSE: + v_verbose = 1; + break; ++ case OPT_SM2ID: ++ /* we assume the input is not a hex string */ ++ sm2_id = (unsigned char *)opt_arg(); ++ sm2_idlen = strlen((const char *)sm2_id); ++ break; ++ case OPT_SM2HEXID: ++ /* try to parse the input as hex string first */ ++ sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen); ++ if (sm2_id == NULL) { ++ BIO_printf(bio_err, "Invalid hex string input\n"); ++ goto end; ++ } ++ break; + } + } + argc = opt_num_rest(); +@@ -183,12 +205,13 @@ int verify_main(int argc, char **argv) + + ret = 0; + if (argc < 1) { +- if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1) ++ if (check(store, NULL, untrusted, trusted, crls, show_chain, ++ sm2_id, sm2_idlen) != 1) + ret = -1; + } else { + for (i = 0; i < argc; i++) + if (check(store, argv[i], untrusted, trusted, crls, +- show_chain) != 1) ++ show_chain, sm2_id, sm2_idlen) != 1) + ret = -1; + } + +@@ -204,7 +227,8 @@ int verify_main(int argc, char **argv) + + static int check(X509_STORE *ctx, const char *file, + STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, +- STACK_OF(X509_CRL) *crls, int show_chain) ++ STACK_OF(X509_CRL) *crls, int show_chain, ++ unsigned char *sm2id, size_t sm2idlen) + { + X509 *x = NULL; + int i = 0, ret = 0; +@@ -216,6 +240,17 @@ static int check(X509_STORE *ctx, const char *file, + if (x == NULL) + goto end; + ++ if (sm2id != NULL) { ++#ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING v; ++ ++ v.data = sm2id; ++ v.length = sm2idlen; ++ ++ X509_set_sm2_id(x, &v); ++#endif ++ } ++ + csc = X509_STORE_CTX_new(); + if (csc == NULL) { + printf("error %s: X.509 store context allocation failed\n", +diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c +index 4b5f542..f543aa1 100644 +--- a/crypto/asn1/a_verify.c ++++ b/crypto/asn1/a_verify.c +@@ -94,7 +94,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + int mdnid, pknid; + size_t inll = 0; + +- if (!pkey) { ++ if (pkey == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } +@@ -150,7 +150,6 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ret = 0; + goto err; + } +- + } + + inl = ASN1_item_i2d(asn, &buf_in, it); +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index 902e97b..5e71e65 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -1766,8 +1766,10 @@ X509_F_X509_STORE_NEW:158:X509_STORE_new + X509_F_X509_TO_X509_REQ:126:X509_to_X509_REQ + X509_F_X509_TRUST_ADD:133:X509_TRUST_add + X509_F_X509_TRUST_SET:141:X509_TRUST_set ++X509_F_X509_VERIFY:161:X509_verify + X509_F_X509_VERIFY_CERT:127:X509_verify_cert + X509_F_X509_VERIFY_PARAM_NEW:159:X509_VERIFY_PARAM_new ++X509_F_X509_VERIFY_SM2:162:x509_verify_sm2 + + #Reason codes + ASN1_R_ADDING_OBJECT:171:adding object +diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h +index 24b49a2..eb4cce4 100644 +--- a/crypto/objects/obj_dat.h ++++ b/crypto/objects/obj_dat.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by crypto/objects/obj_dat.pl + * +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at +@@ -10,7 +10,7 @@ + */ + + /* Serialized OID's */ +-static const unsigned char so[7762] = { ++static const unsigned char so[7770] = { + 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +@@ -1076,9 +1076,10 @@ static const unsigned char so[7762] = { + 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */ ++ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7761] OBJ_SM2_with_SM3 */ + }; + +-#define NUM_NID 1195 ++#define NUM_NID 1196 + static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"UNDEF", "undefined", NID_undef}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, +@@ -2275,9 +2276,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"magma-mac", "magma-mac", NID_magma_mac}, + {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]}, + {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]}, ++ {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7761]}, + }; + +-#define NUM_SN 1186 ++#define NUM_SN 1187 + static const unsigned int sn_objs[NUM_SN] = { + 364, /* "AD_DVCS" */ + 419, /* "AES-128-CBC" */ +@@ -2543,6 +2545,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1100, /* "SHAKE128" */ + 1101, /* "SHAKE256" */ + 1172, /* "SM2" */ ++ 1195, /* "SM2-SM3" */ + 1143, /* "SM3" */ + 1134, /* "SM4-CBC" */ + 1137, /* "SM4-CFB" */ +@@ -3467,7 +3470,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1093, /* "x509ExtAdmission" */ + }; + +-#define NUM_LN 1186 ++#define NUM_LN 1187 + static const unsigned int ln_objs[NUM_LN] = { + 363, /* "AD Time Stamping" */ + 405, /* "ANSI X9.62" */ +@@ -3623,6 +3626,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 1119, /* "RSA-SHA3-512" */ + 188, /* "S/MIME" */ + 167, /* "S/MIME Capabilities" */ ++ 1195, /* "SM2-with-SM3" */ + 1006, /* "SNILS" */ + 387, /* "SNMPv2" */ + 1025, /* "SSH Client" */ +@@ -4657,7 +4661,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 125, /* "zlib compression" */ + }; + +-#define NUM_OBJ 1071 ++#define NUM_OBJ 1072 + static const unsigned int obj_objs[NUM_OBJ] = { + 0, /* OBJ_undef 0 */ + 181, /* OBJ_iso 1 */ +@@ -5126,6 +5130,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { + 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ + 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ + 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ ++ 1195, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ + 1144, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ + 776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ + 777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ +diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num +index 1b6a9c6..8b797b0 100644 +--- a/crypto/objects/obj_mac.num ++++ b/crypto/objects/obj_mac.num +@@ -1192,3 +1192,4 @@ magma_cfb 1191 + magma_mac 1192 + hmacWithSHA512_224 1193 + hmacWithSHA512_256 1194 ++SM2_with_SM3 1195 +diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h +index 5c3561a..1acfcde 100644 +--- a/crypto/objects/obj_xref.h ++++ b/crypto/objects/obj_xref.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by objxref.pl + * +- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -79,6 +79,7 @@ static const nid_triple sigoid_srt[] = { + {NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption}, + {NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption}, + {NID_RSA_SHA3_512, NID_sha3_512, NID_rsaEncryption}, ++ {NID_SM2_with_SM3, NID_sm3, NID_sm2}, + }; + + static const nid_triple *const sigoid_srt_xref[] = { +@@ -125,4 +126,5 @@ static const nid_triple *const sigoid_srt_xref[] = { + &sigoid_srt[45], + &sigoid_srt[46], + &sigoid_srt[47], ++ &sigoid_srt[48], + }; +diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt +index ca3e744..f3dd8ed 100644 +--- a/crypto/objects/obj_xref.txt ++++ b/crypto/objects/obj_xref.txt +@@ -64,3 +64,5 @@ dhSinglePass_cofactorDH_sha224kdf_scheme sha224 dh_cofactor_kdf + dhSinglePass_cofactorDH_sha256kdf_scheme sha256 dh_cofactor_kdf + dhSinglePass_cofactorDH_sha384kdf_scheme sha384 dh_cofactor_kdf + dhSinglePass_cofactorDH_sha512kdf_scheme sha512 dh_cofactor_kdf ++ ++SM2_with_SM3 sm3 sm2 +diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt +index c49d4c5..be9da47 100644 +--- a/crypto/objects/objects.txt ++++ b/crypto/objects/objects.txt +@@ -385,6 +385,8 @@ sm-scheme 301 : SM2 : sm2 + sm-scheme 401 : SM3 : sm3 + sm-scheme 504 : RSA-SM3 : sm3WithRSAEncryption + ++sm-scheme 501 : SM2-SM3 : SM2-with-SM3 ++ + # From RFC4231 + rsadsi 2 8 : : hmacWithSHA224 + rsadsi 2 9 : : hmacWithSHA256 +diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c +index bdd1e67..c91ad7c 100644 +--- a/crypto/x509/x509_err.c ++++ b/crypto/x509/x509_err.c +@@ -105,9 +105,11 @@ static const ERR_STRING_DATA X509_str_functs[] = { + {ERR_PACK(ERR_LIB_X509, X509_F_X509_TO_X509_REQ, 0), "X509_to_X509_REQ"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_ADD, 0), "X509_TRUST_add"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_SET, 0), "X509_TRUST_set"}, ++ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY, 0), "X509_verify"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, 0), "X509_verify_cert"}, + {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_PARAM_NEW, 0), + "X509_VERIFY_PARAM_new"}, ++ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_SM2, 0), "x509_verify_sm2"}, + {0, NULL} + }; + +diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c +index a4e9cda..60a2892 100644 +--- a/crypto/x509/x_all.c ++++ b/crypto/x509/x_all.c +@@ -19,10 +19,120 @@ + #include + #include + ++#ifndef OPENSSL_NO_SM2 ++ ++# include "crypto/asn1.h" ++# include "crypto/evp.h" ++ ++static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) ++{ ++ EVP_MD_CTX *ctx = NULL; ++ unsigned char *buf_in = NULL; ++ int ret = -1, inl = 0; ++ size_t inll = 0; ++ EVP_PKEY_CTX *pctx = NULL; ++ const EVP_MD *type = EVP_get_digestbynid(mdnid); ++ ++ if (type == NULL) { ++ X509err(X509_F_X509_VERIFY_SM2, ++ ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); ++ goto err; ++ } ++ ++ if (pkey == NULL) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER); ++ return -1; ++ } ++ ++ if (x->signature.type == V_ASN1_BIT_STRING && x->signature.flags & 0x7) { ++ X509err(X509_F_X509_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); ++ return -1; ++ } ++ ++ ctx = EVP_MD_CTX_new(); ++ if (ctx == NULL) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ /* Check public key OID matches public key type */ ++ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { ++ X509err(X509_F_X509_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE); ++ goto err; ++ } ++ ++ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ ret = 0; ++ goto err; ++ } ++ pctx = EVP_PKEY_CTX_new(pkey, NULL); ++ if (pctx == NULL) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ ret = 0; ++ goto err; ++ } ++ if (EVP_PKEY_CTX_set1_id(pctx, x->sm2_id.data, x->sm2_id.length) != 1) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ ret = 0; ++ goto err; ++ } ++ EVP_MD_CTX_set_pkey_ctx(ctx, pctx); ++ ++ if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ ret = 0; ++ goto err; ++ } ++ ++ inl = ASN1_item_i2d((ASN1_VALUE *)&x->cert_info, &buf_in, ++ ASN1_ITEM_rptr(X509_CINF)); ++ if (inl <= 0) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ if (buf_in == NULL) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ inll = inl; ++ ++ ret = EVP_DigestVerify(ctx, x->signature.data, ++ (size_t)x->signature.length, buf_in, inl); ++ if (ret <= 0) { ++ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB); ++ goto err; ++ } ++ ret = 1; ++ err: ++ OPENSSL_clear_free(buf_in, inll); ++ EVP_MD_CTX_free(ctx); ++ EVP_PKEY_CTX_free(pctx); ++ return ret; ++} ++#endif ++ + int X509_verify(X509 *a, EVP_PKEY *r) + { ++#ifndef OPENSSL_NO_SM2 ++ int mdnid, pknid; ++#endif ++ + if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature)) + return 0; ++ ++#ifndef OPENSSL_NO_SM2 ++ /* Convert signature OID into digest and public key OIDs */ ++ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm), ++ &mdnid, &pknid)) { ++ X509err(X509_F_X509_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); ++ return 0; ++ } ++ ++ if (pknid == NID_sm2) ++ return x509_verify_sm2(a, r, mdnid, pknid); ++#endif ++ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, + &a->signature, &a->cert_info, r)); + } +diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c +index 7aa8b77..1beab78 100644 +--- a/crypto/x509/x_x509.c ++++ b/crypto/x509/x_x509.c +@@ -245,3 +245,15 @@ int X509_get_signature_nid(const X509 *x) + { + return OBJ_obj2nid(x->sig_alg.algorithm); + } ++ ++#ifndef OPENSSL_NO_SM2 ++void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id) ++{ ++ x->sm2_id = *sm2_id; ++} ++ ++ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x) ++{ ++ return &x->sm2_id; ++} ++#endif +diff --git a/fuzz/oids.txt b/fuzz/oids.txt +index eda55e4..8dfdea9 100644 +--- a/fuzz/oids.txt ++++ b/fuzz/oids.txt +@@ -1063,3 +1063,4 @@ OBJ_id_tc26_gost_3410_2012_256_paramSetC="\x2A\x85\x03\x07\x01\x02\x01\x01\x03" + OBJ_id_tc26_gost_3410_2012_256_paramSetD="\x2A\x85\x03\x07\x01\x02\x01\x01\x04" + OBJ_hmacWithSHA512_224="\x2A\x86\x48\x86\xF7\x0D\x02\x0C" + OBJ_hmacWithSHA512_256="\x2A\x86\x48\x86\xF7\x0D\x02\x0D" ++OBJ_SM2_with_SM3="\x2A\x81\x1C\xCF\x55\x01\x83\x75" +diff --git a/include/crypto/x509.h b/include/crypto/x509.h +index 243ea74..418c427 100644 +--- a/include/crypto/x509.h ++++ b/include/crypto/x509.h +@@ -177,7 +177,7 @@ struct x509_st { + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +-#ifndef OPENSSL_NO_RFC3779 ++# ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; + # endif +@@ -185,6 +185,9 @@ struct x509_st { + X509_CERT_AUX *aux; + CRYPTO_RWLOCK *lock; + volatile int ex_cached; ++# ifndef OPENSSL_NO_SM2 ++ ASN1_OCTET_STRING sm2_id; ++# endif + } /* X509 */ ; + + /* +diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h +index eb812ed..9b125c1 100644 +--- a/include/openssl/obj_mac.h ++++ b/include/openssl/obj_mac.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by crypto/objects/objects.pl + * +- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at +@@ -1179,6 +1179,11 @@ + #define NID_sm3WithRSAEncryption 1144 + #define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L + ++#define SN_SM2_with_SM3 "SM2-SM3" ++#define LN_SM2_with_SM3 "SM2-with-SM3" ++#define NID_SM2_with_SM3 1195 ++#define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L ++ + #define LN_hmacWithSHA224 "hmacWithSHA224" + #define NID_hmacWithSHA224 798 + #define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 3ff86ec..5f17057 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -573,6 +573,9 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); + int X509_get_signature_nid(const X509 *x); + ++void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id); ++ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x); ++ + int X509_trusted(const X509 *x); + int X509_alias_set1(X509 *x, const unsigned char *name, int len); + int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h +index cd08673..06d75f0 100644 +--- a/include/openssl/x509err.h ++++ b/include/openssl/x509err.h +@@ -81,8 +81,10 @@ int ERR_load_X509_strings(void); + # define X509_F_X509_TO_X509_REQ 126 + # define X509_F_X509_TRUST_ADD 133 + # define X509_F_X509_TRUST_SET 141 ++# define X509_F_X509_VERIFY 161 + # define X509_F_X509_VERIFY_CERT 127 + # define X509_F_X509_VERIFY_PARAM_NEW 159 ++# define X509_F_X509_VERIFY_SM2 162 + + /* + * X509 reason codes. +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 1566231..8635ac4 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4626,3 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION: + FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION: + FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: + FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: ++X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION: ++X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION: +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Support-parsing-of-SM2-ID-in-hexdecimal.patch b/Backport-Support-parsing-of-SM2-ID-in-hexdecimal.patch new file mode 100644 index 0000000000000000000000000000000000000000..1e0f5917ca14b1a64239d0719f9fdecf66974947 --- /dev/null +++ b/Backport-Support-parsing-of-SM2-ID-in-hexdecimal.patch @@ -0,0 +1,127 @@ +From 1d9e832e41858b13a96899d842afd183f1c66c48 Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Tue, 30 Jul 2019 23:05:44 +0800 +Subject: [PATCH 11/15] Support parsing of SM2 ID in hexdecimal + +The current EVP_PEKY_ctrl for SM2 has no capability of parsing an ID +input in hexdecimal. + +The newly added ctrl string is called: sm2_hex_id + +Test cases and documentation are updated. + +Reviewed-by: Tim Hudson +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/9584) +--- + crypto/sm2/sm2_pmeth.c | 19 +++++++++++++++++++ + doc/man1/pkeyutl.pod | 7 +++++++ + include/openssl/ec.h | 1 - + test/recipes/25-test_req.t | 15 +++++++++++++-- + 4 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c +index 837bdc1..9551d70 100644 +--- a/crypto/sm2/sm2_pmeth.c ++++ b/crypto/sm2/sm2_pmeth.c +@@ -232,6 +232,10 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { ++ uint8_t *hex_id; ++ long hex_len = 0; ++ int ret = 0; ++ + if (strcmp(type, "ec_paramgen_curve") == 0) { + int nid = NID_undef; + +@@ -255,6 +259,21 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, + } else if (strcmp(type, "sm2_id") == 0) { + return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, + (int)strlen(value), (void *)value); ++ } else if (strcmp(type, "sm2_hex_id") == 0) { ++ /* ++ * TODO(3.0): reconsider the name "sm2_hex_id", OR change ++ * OSSL_PARAM_construct_from_text() / OSSL_PARAM_allocate_from_text() ++ * to handle infix "_hex_" ++ */ ++ hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len); ++ if (hex_id == NULL) { ++ SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++ } ++ ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len, ++ (void *)hex_id); ++ OPENSSL_free(hex_id); ++ return ret; + } + + return -2; +diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod +index f0f80af..1a742ab 100644 +--- a/doc/man1/pkeyutl.pod ++++ b/doc/man1/pkeyutl.pod +@@ -329,6 +329,13 @@ This sets the ID string used in SM2 sign or verify operations. While verifying + an SM2 signature, the ID string must be the same one used when signing the data. + Otherwise the verification will fail. + ++=item B ++ ++This sets the ID string used in SM2 sign or verify operations. While verifying ++an SM2 signature, the ID string must be the same one used when signing the data. ++Otherwise the verification will fail. The ID string provided with this option ++should be a valid hexadecimal value. ++ + =back + + =head1 EXAMPLES +diff --git a/include/openssl/ec.h b/include/openssl/ec.h +index 24baf53..e8c8869 100644 +--- a/include/openssl/ec.h ++++ b/include/openssl/ec.h +@@ -1444,7 +1444,6 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + # define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) +- + # define EVP_PKEY_CTX_get1_id(ctx, id) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) +diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t +index 8289959..d53e577 100644 +--- a/test/recipes/25-test_req.t ++++ b/test/recipes/25-test_req.t +@@ -182,10 +182,10 @@ subtest "generating certificate requests" => sub { + }; + + subtest "generating SM2 certificate requests" => sub { +- plan tests => 2; ++ plan tests => 4; + + SKIP: { +- skip "SM2 is not supported by this OpenSSL build", 2 ++ skip "SM2 is not supported by this OpenSSL build", 4 + if disabled("sm2"); + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-new", "-key", srctop_file("test", "certs", "sm2.key"), +@@ -197,6 +197,17 @@ subtest "generating SM2 certificate requests" => sub { + "-verify", "-in", "testreq.pem", "-noout", + "-sm2-id", "1234567812345678", "-sm3"])), + "Verifying signature on SM2 certificate request"); ++ ++ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), ++ "-new", "-key", srctop_file("test", "certs", "sm2.key"), ++ "-sigopt", "sm2_hex_id:DEADBEEF", ++ "-out", "testreq.pem", "-sm3"])), ++ "Generating SM2 certificate request with hex id"); ++ ++ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), ++ "-verify", "-in", "testreq.pem", "-noout", ++ "-sm2-hex-id", "DEADBEEF", "-sm3"])), ++ "Verifying signature on SM2 certificate request"); + } + }; + +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Support-raw-input-data-in-apps-pkeyutl.patch b/Backport-Support-raw-input-data-in-apps-pkeyutl.patch new file mode 100644 index 0000000000000000000000000000000000000000..cd973db8caeb1a119027a5af1be0bb803e74c73a --- /dev/null +++ b/Backport-Support-raw-input-data-in-apps-pkeyutl.patch @@ -0,0 +1,482 @@ +From b14bf717ccb166cce13173a817106effb02f6c2e Mon Sep 17 00:00:00 2001 +From: Paul Yang +Date: Wed, 16 Jan 2019 16:16:28 +0800 +Subject: [PATCH 01/15] Support raw input data in apps/pkeyutl + +Some signature algorithms require special treatment for digesting, such +as SM2. This patch adds the ability of handling raw input data in +apps/pkeyutl other than accepting only pre-hashed input data. + +Beside, SM2 requries an ID string when signing or verifying a piece of data, +this patch also adds the ability for apps/pkeyutil to specify that ID +string. + +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/8186) +--- + apps/pkeyutl.c | 168 +++++++++++++++++++++++++++++---- + crypto/sm2/sm2_pmeth.c | 3 + + doc/man1/pkeyutl.pod | 45 +++++++++ + test/certs/sm2.crt | 13 +++ + test/certs/sm2.key | 5 + + test/recipes/20-test_pkeyutl.t | 43 +++++++++ + 6 files changed, 260 insertions(+), 17 deletions(-) + create mode 100644 test/certs/sm2.crt + create mode 100644 test/certs/sm2.key + create mode 100644 test/recipes/20-test_pkeyutl.t + +diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c +index 831e14d..bca0464 100644 +--- a/apps/pkeyutl.c ++++ b/apps/pkeyutl.c +@@ -22,7 +22,7 @@ + static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, + const char *keyfile, int keyform, int key_type, + char *passinarg, int pkey_op, ENGINE *e, +- const int impl); ++ const int impl, EVP_PKEY **ppkey); + + static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, + ENGINE *e); +@@ -31,6 +31,11 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, + unsigned char *out, size_t *poutlen, + const unsigned char *in, size_t inlen); + ++static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx, ++ const EVP_MD *md, EVP_PKEY *pkey, BIO *in, ++ unsigned char *sig, int siglen, ++ unsigned char **out, size_t *poutlen); ++ + typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT, +@@ -38,12 +43,15 @@ typedef enum OPTION_choice { + OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, + OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, + OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN, +- OPT_R_ENUM ++ OPT_R_ENUM, OPT_RAWIN, OPT_DIGEST + } OPTION_CHOICE; + + const OPTIONS pkeyutl_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, ++ {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, ++ {"digest", OPT_DIGEST, 's', ++ "Specify the digest algorithm when signing the raw input data"}, + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"pubin", OPT_PUBIN, '-', "Input is a public key"}, + {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, +@@ -80,6 +88,7 @@ int pkeyutl_main(int argc, char **argv) + BIO *in = NULL, *out = NULL; + ENGINE *e = NULL; + EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *pkey = NULL; + char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; + char hexdump = 0, asn1parse = 0, rev = 0, *prog; + unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; +@@ -94,6 +103,8 @@ int pkeyutl_main(int argc, char **argv) + const char *kdfalg = NULL; + int kdflen = 0; + STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; ++ int rawin = 0; ++ const EVP_MD *md = NULL; + + prog = opt_init(argc, argv, pkeyutl_options); + while ((o = opt_next()) != OPT_EOF) { +@@ -192,12 +203,39 @@ int pkeyutl_main(int argc, char **argv) + goto end; + } + break; ++ case OPT_RAWIN: ++ rawin = 1; ++ break; ++ case OPT_DIGEST: ++ if (!opt_md(opt_arg(), &md)) ++ goto end; ++ break; + } + } + argc = opt_num_rest(); + if (argc != 0) + goto opthelp; + ++ if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) { ++ BIO_printf(bio_err, ++ "%s: -rawin can only be used with -sign or -verify\n", ++ prog); ++ goto opthelp; ++ } ++ ++ if (md != NULL && !rawin) { ++ BIO_printf(bio_err, ++ "%s: -digest can only be used with -rawin\n", ++ prog); ++ goto opthelp; ++ } ++ ++ if (rawin && rev) { ++ BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n", ++ prog); ++ goto opthelp; ++ } ++ + if (kdfalg != NULL) { + if (kdflen == 0) { + BIO_printf(bio_err, +@@ -214,7 +252,7 @@ int pkeyutl_main(int argc, char **argv) + goto opthelp; + } + ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, +- passinarg, pkey_op, e, engine_impl); ++ passinarg, pkey_op, e, engine_impl, &pkey); + if (ctx == NULL) { + BIO_printf(bio_err, "%s: Error initializing context\n", prog); + ERR_print_errors(bio_err); +@@ -277,7 +315,8 @@ int pkeyutl_main(int argc, char **argv) + } + } + +- if (in != NULL) { ++ /* Raw input data is handled elsewhere */ ++ if (in != NULL && !rawin) { + /* Read the input data */ + buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); + if (buf_inlen < 0) { +@@ -296,8 +335,9 @@ int pkeyutl_main(int argc, char **argv) + } + } + +- /* Sanity check the input */ +- if (buf_inlen > EVP_MAX_MD_SIZE ++ /* Sanity check the input if the input is not raw */ ++ if (!rawin ++ && buf_inlen > EVP_MAX_MD_SIZE + && (pkey_op == EVP_PKEY_OP_SIGN + || pkey_op == EVP_PKEY_OP_VERIFY)) { + BIO_printf(bio_err, +@@ -306,8 +346,13 @@ int pkeyutl_main(int argc, char **argv) + } + + if (pkey_op == EVP_PKEY_OP_VERIFY) { +- rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, +- buf_in, (size_t)buf_inlen); ++ if (rawin) { ++ rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, sig, siglen, ++ NULL, 0); ++ } else { ++ rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, ++ buf_in, (size_t)buf_inlen); ++ } + if (rv == 1) { + BIO_puts(out, "Signature Verified Successfully\n"); + ret = 0; +@@ -320,14 +365,20 @@ int pkeyutl_main(int argc, char **argv) + buf_outlen = kdflen; + rv = 1; + } else { +- rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, +- buf_in, (size_t)buf_inlen); +- } +- if (rv > 0 && buf_outlen != 0) { +- buf_out = app_malloc(buf_outlen, "buffer output"); +- rv = do_keyop(ctx, pkey_op, +- buf_out, (size_t *)&buf_outlen, +- buf_in, (size_t)buf_inlen); ++ if (rawin) { ++ /* rawin allocates the buffer in do_raw_keyop() */ ++ rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, NULL, 0, ++ &buf_out, (size_t *)&buf_outlen); ++ } else { ++ rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, ++ buf_in, (size_t)buf_inlen); ++ if (rv > 0 && buf_outlen != 0) { ++ buf_out = app_malloc(buf_outlen, "buffer output"); ++ rv = do_keyop(ctx, pkey_op, ++ buf_out, (size_t *)&buf_outlen, ++ buf_in, (size_t)buf_inlen); ++ } ++ } + } + if (rv <= 0) { + if (pkey_op != EVP_PKEY_OP_DERIVE) { +@@ -364,7 +415,7 @@ int pkeyutl_main(int argc, char **argv) + static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, + const char *keyfile, int keyform, int key_type, + char *passinarg, int pkey_op, ENGINE *e, +- const int engine_impl) ++ const int engine_impl, EVP_PKEY **ppkey) + { + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; +@@ -422,10 +473,25 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, + } + ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + } else { ++ EC_KEY *eckey = NULL; ++ const EC_GROUP *group = NULL; ++ int nid; ++ + if (pkey == NULL) + goto end; ++ /* SM2 needs a special treatment */ ++ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { ++ if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL ++ || (group = EC_KEY_get0_group(eckey)) == NULL ++ || (nid = EC_GROUP_get_curve_name(group)) == 0) ++ goto end; ++ if (nid == NID_sm2) ++ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); ++ } + *pkeysize = EVP_PKEY_size(pkey); + ctx = EVP_PKEY_CTX_new(pkey, impl); ++ if (ppkey != NULL) ++ *ppkey = pkey; + EVP_PKEY_free(pkey); + } + +@@ -522,3 +588,71 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, + } + return rv; + } ++ ++#define TBUF_MAXSIZE 2048 ++ ++static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx, ++ const EVP_MD *md, EVP_PKEY *pkey, BIO *in, ++ unsigned char *sig, int siglen, ++ unsigned char **out, size_t *poutlen) ++{ ++ int rv = 0; ++ EVP_MD_CTX *mctx = NULL; ++ unsigned char tbuf[TBUF_MAXSIZE]; ++ int tbuf_len = 0; ++ ++ if ((mctx = EVP_MD_CTX_new()) == NULL) { ++ BIO_printf(bio_err, "Error: out of memory\n"); ++ return rv; ++ } ++ EVP_MD_CTX_set_pkey_ctx(mctx, ctx); ++ ++ switch(pkey_op) { ++ case EVP_PKEY_OP_VERIFY: ++ if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1) ++ goto end; ++ for (;;) { ++ tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); ++ if (tbuf_len == 0) ++ break; ++ if (tbuf_len < 0) { ++ BIO_printf(bio_err, "Error reading raw input data\n"); ++ goto end; ++ } ++ rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)tbuf_len); ++ if (rv != 1) { ++ BIO_printf(bio_err, "Error verifying raw input data\n"); ++ goto end; ++ } ++ } ++ rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); ++ break; ++ case EVP_PKEY_OP_SIGN: ++ if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1) ++ goto end; ++ for (;;) { ++ tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); ++ if (tbuf_len == 0) ++ break; ++ if (tbuf_len < 0) { ++ BIO_printf(bio_err, "Error reading raw input data\n"); ++ goto end; ++ } ++ rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)tbuf_len); ++ if (rv != 1) { ++ BIO_printf(bio_err, "Error signing raw input data\n"); ++ goto end; ++ } ++ } ++ rv = EVP_DigestSignFinal(mctx, NULL, poutlen); ++ if (rv == 1 && out != NULL) { ++ *out = app_malloc(*poutlen, "buffer output"); ++ rv = EVP_DigestSignFinal(mctx, *out, poutlen); ++ } ++ break; ++ } ++ ++ end: ++ EVP_MD_CTX_free(mctx); ++ return rv; ++} +diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c +index 0e722b9..837bdc1 100644 +--- a/crypto/sm2/sm2_pmeth.c ++++ b/crypto/sm2/sm2_pmeth.c +@@ -252,6 +252,9 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, + else + return -2; + return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); ++ } else if (strcmp(type, "sm2_id") == 0) { ++ return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, ++ (int)strlen(value), (void *)value); + } + + return -2; +diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod +index f6fd48d..f0f80af 100644 +--- a/doc/man1/pkeyutl.pod ++++ b/doc/man1/pkeyutl.pod +@@ -10,6 +10,8 @@ pkeyutl - public key algorithm utility + B B + [B<-help>] + [B<-in file>] ++[B<-rawin>] ++[B<-digest algorithm>] + [B<-out file>] + [B<-sigfile file>] + [B<-inkey file>] +@@ -54,6 +56,23 @@ Print out a usage message. + This specifies the input filename to read data from or standard input + if this option is not specified. + ++=item B<-rawin> ++ ++This indicates that the input data is raw data, which is not hashed by any ++message digest algorithm. The user can specify a digest algorithm by using ++the B<-digest> option. This option can only be used with B<-sign> and ++B<-verify>. ++ ++=item B<-digest algorithm> ++ ++This specifies the digest algorithm which is used to hash the input data before ++signing or verifying it with the input key. This option could be omitted if the ++signature algorithm does not require one (for instance, EdDSA). If this option ++is omitted but the signature algorithm requires one, a default value will be ++used. For signature algorithms like RSA, DSA and ECDSA, SHA-256 will be the ++default digest algorithm. For SM2, it will be SM3. If this option is present, ++then the B<-rawin> option must be also specified to B. ++ + =item B<-out filename> + + Specifies the output filename to write to or standard output by +@@ -296,6 +315,22 @@ the B<-pkeyopt> B option. + The X25519 and X448 algorithms support key derivation only. Currently there are + no additional options. + ++=head1 SM2 ++ ++The SM2 algorithm supports sign, verify, encrypt and decrypt operations. For ++the sign and verify operations, SM2 requires an ID string to be passed in. The ++following B value is supported: ++ ++=over 4 ++ ++=item B ++ ++This sets the ID string used in SM2 sign or verify operations. While verifying ++an SM2 signature, the ID string must be the same one used when signing the data. ++Otherwise the verification will fail. ++ ++=back ++ + =head1 EXAMPLES + + Sign some data using a private key: +@@ -329,6 +364,16 @@ Decrypt some data using a private key with OAEP padding using SHA256: + openssl pkeyutl -decrypt -in file -inkey key.pem -out secret \ + -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 + ++Sign some data using an L private key and a specific ID: ++ ++ openssl pkeyutl -sign -in file -inkey sm2.key -out sig -rawin -digest sm3 \ ++ -pkeyopt sm2_id:someid ++ ++Verify some data using an L certificate and a specific ID: ++ ++ openssl pkeyutl -verify -certin -in file -inkey sm2.cert -sigfile sig \ ++ -rawin -digest sm3 -pkeyopt sm2_id:someid ++ + =head1 SEE ALSO + + L, L, L +diff --git a/test/certs/sm2.crt b/test/certs/sm2.crt +new file mode 100644 +index 0000000..189abb1 +--- /dev/null ++++ b/test/certs/sm2.crt +@@ -0,0 +1,13 @@ ++-----BEGIN CERTIFICATE----- ++MIIB6DCCAY6gAwIBAgIJAKH2BR6ITHZeMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT ++AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl ++c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe ++Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMG8xCzAJBgNVBAYTAkNOMQsw ++CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn ++MRAwDgYDVQQLDAdUZXN0IE9VMRswGQYDVQQDDBJUZXN0IFNNMiBTaWduIENlcnQw ++WTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQwqeNkWp7fiu1KZnuDkAucpM8piEzE ++TL1ymrcrOBvv8mhNNkeb20asbWgFQI2zOrSM99/sXGn9rM2/usM/MlcaoxowGDAJ ++BgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEA9edBnAqT ++TNuGIUIvXsj6/nP+AzXA9HGtAIY4nrqW8LkCIHyZzhRTlxYtgfqkDl0OK5QQRCZH ++OZOfmtx613VyzXwc ++-----END CERTIFICATE----- +diff --git a/test/certs/sm2.key b/test/certs/sm2.key +new file mode 100644 +index 0000000..1efd364 +--- /dev/null ++++ b/test/certs/sm2.key +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgSKhk+4xGyDI+IS2H ++WVfFPDxh1qv5+wtrddaIsGNXGZihRANCAAQwqeNkWp7fiu1KZnuDkAucpM8piEzE ++TL1ymrcrOBvv8mhNNkeb20asbWgFQI2zOrSM99/sXGn9rM2/usM/Mlca ++-----END PRIVATE KEY----- +diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t +new file mode 100644 +index 0000000..a051138 +--- /dev/null ++++ b/test/recipes/20-test_pkeyutl.t +@@ -0,0 +1,43 @@ ++#! /usr/bin/env perl ++# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++use strict; ++use warnings; ++ ++use File::Spec; ++use OpenSSL::Test qw/:DEFAULT srctop_file/; ++use OpenSSL::Test::Utils; ++ ++setup("test_pkeyutl"); ++ ++plan tests => 2; ++ ++sub sign ++{ ++ # Utilize the sm2.crt as the TBS file ++ return run(app(([ 'openssl', 'pkeyutl', '-sign', ++ '-in', srctop_file('test', 'certs', 'sm2.crt'), ++ '-inkey', srctop_file('test', 'certs', 'sm2.key'), ++ '-out', 'signature.sm2', '-rawin', ++ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))); ++} ++ ++sub verify ++{ ++ # Utilize the sm2.crt as the TBS file ++ return run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', ++ '-in', srctop_file('test', 'certs', 'sm2.crt'), ++ '-inkey', srctop_file('test', 'certs', 'sm2.crt'), ++ '-sigfile', 'signature.sm2', '-rawin', ++ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))); ++} ++ ++ok(sign, "Sign a piece of data using SM2"); ++ok(verify, "Verify an SM2 signature against a piece of data"); ++ ++unlink 'signature.sm2'; +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-Update-expired-SCT-certificates.patch b/Backport-Update-expired-SCT-certificates.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6e14ad18e08673edbd590eb4f97798f9cf5934a --- /dev/null +++ b/Backport-Update-expired-SCT-certificates.patch @@ -0,0 +1,191 @@ +From acb105a848fd0a282550f6132dc131575cc5a655 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Wed, 1 Jun 2022 12:47:44 +0200 +Subject: [PATCH 14/15] Update expired SCT certificates + +Reviewed-by: Matt Caswell +Reviewed-by: Dmitry Belyavskiy +(Merged from https://github.com/openssl/openssl/pull/18446) +--- + test/certs/embeddedSCTs1-key.pem | 38 ++++++++++++++++--------- + test/certs/embeddedSCTs1.pem | 35 ++++++++++++----------- + test/certs/embeddedSCTs1.sct | 12 ++++---- + test/certs/embeddedSCTs1_issuer-key.pem | 15 ++++++++++ + test/certs/embeddedSCTs1_issuer.pem | 30 +++++++++---------- + 5 files changed, 79 insertions(+), 51 deletions(-) + create mode 100644 test/certs/embeddedSCTs1_issuer-key.pem + +diff --git a/test/certs/embeddedSCTs1-key.pem b/test/certs/embeddedSCTs1-key.pem +index e3e66d5..28dd206 100644 +--- a/test/certs/embeddedSCTs1-key.pem ++++ b/test/certs/embeddedSCTs1-key.pem +@@ -1,15 +1,27 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICWwIBAAKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/BH634c4VyVui+A7k +-WL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWkEM2cW9tdSSdyba8X +-EPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWwFAn/Xdh+tQIDAQAB +-AoGAK/daG0vt6Fkqy/hdrtSJSKUVRoGRmS2nnba4Qzlwzh1+x2kdbMFuaOu2a37g +-PvmeQclheKZ3EG1+Jb4yShwLcBCV6pkRJhOKuhvqGnjngr6uBH4gMCjpZVj7GDMf +-flYHhdJCs3Cz/TY0wKN3o1Fldil2DHR/AEOc1nImeSp5/EUCQQDjKS3W957kYtTU +-X5BeRjvg03Ug8tJq6IFuhTFvUJ+XQ5bAc0DmxAbQVKqRS7Wje59zTknVvS+MFdeQ +-pz4dGuV7AkEA1y0X2yarIls+0A/S1uwkvwRTIkfS+QwFJ1zVya8sApRdKAcidIzA +-b70hkKLilU9+LrXg5iZdFp8l752qJiw9jwJAXjItN/7mfH4fExGto+or2kbVQxxt +-9LcFNPc2UJp2ExuL37HrL8YJrUnukOF8KJaSwBWuuFsC5GwKP4maUCdfEQJAUwBR +-83c3DEmmMRvpeH4erpA8gTyzZN3+HvDwhpvLnjMcvBQEdnDUykVqbSBnxrCjO+Fs +-n1qtDczWFVf8Cj2GgQJAQ14Awx32Cn9sF+3M+sEVtlAf6CqiEbkYeYdSCbsplMmZ +-1UoaxiwXY3z+B7epsRnnPR3KaceAlAxw2/zQJMFNOQ== ++MIIEpQIBAAKCAQEAuIjpA4/iCpDA2mjywI5zG6IBX6bNcRQYDsB7Cv0VonNXtJBw ++XxMENP4jVpvEmWpJ5iMBknGHV+XWBkngYapczIsY4LGn6aMU6ySABBVQpNOQSRfT ++48xGGPR9mzOBG/yplmpFOVq1j+b65lskvAXKYaLFpFn3oY/pBSdcCNBP8LypVXAJ ++b3IqEXsBL/ErgHG9bgIRP8VxBAaryCz77kLzAXkfHL2LfSGIfNONyEKB3xI94S4L ++eouOSoWL1VkEfJs87vG4G5xoXw3KOHyiueQUUlMnu8p+Bx0xPVKPEsLje3R9k0rG ++a5ca7dXAn9UypKKp25x4NXpnjGX5txVEYfNvqQIDAQABAoIBAE0zqhh9Z5n3+Vbm ++tTht4CZdXqm/xQ9b0rzJNjDgtN5j1vuJuhlsgUQSVoJzZIqydvw7BPtZV8AkPagf ++3Cm/9lb0kpHegVsziRrfCFes+zIZ+LE7sMAKxADIuIvnvkoRKHnvN8rI8lCj16/r ++zbCD06mJSZp6sSj8ZgZr8wsU63zRGt1TeGM67uVW4agphfzuKGlXstPLsSMwknpF ++nxFS2TYbitxa9oH76oCpEk5fywYsYgUP4TdzOzfVAgMzNSu0FobvWl0CECB+G3RQ ++XQ5VWbYkFoj5XbE5kYz6sYHMQWL1NQpglUp+tAQ1T8Nca0CvbSpD77doRGm7UqYw ++ziVQKokCgYEA6BtHwzyD1PHdAYtOcy7djrpnIMaiisSxEtMhctoxg8Vr2ePEvMpZ ++S1ka8A1Pa9GzjaUk+VWKWsTf+VkmMHGtpB1sv8S7HjujlEmeQe7p8EltjstvLDmi ++BhAA7ixvZpXXjQV4GCVdUVu0na6gFGGueZb2FHEXB8j1amVwleJj2lcCgYEAy4f3 ++2wXqJfz15+YdJPpG9BbH9d/plKJm5ID3p2ojAGo5qvVuIJMNJA4elcfHDwzCWVmn ++MtR/WwtxYVVmy1BAnmk6HPSYc3CStvv1800vqN3fyJWtZ1P+8WBVZWZzIQdjdiaU ++JSRevPnjQGc+SAZQQIk1yVclbz5790yuXsdIxf8CgYEApqlABC5lsvfga4Vt1UMn ++j57FAkHe4KmPRCcZ83A88ZNGd/QWhkD9kR7wOsIz7wVqWiDkxavoZnjLIi4jP9HA ++jwEZ3zER8wl70bRy0IEOtZzj8A6fSzAu6Q+Au4RokU6yse3lZ+EcepjQvhBvnXLu ++ZxxAojj6AnsHzVf9WYJvlI0CgYEAoATIw/TEgRV/KNHs/BOiEWqP0Co5dVix2Nnk ++3EVAO6VIrbbE3OuAm2ZWeaBWSujXLHSmVfpoHubCP6prZVI1W9aTkAxmh+xsDV3P ++o3h+DiBTP1seuGx7tr7spQqFXeR3OH9gXktYCO/W0d3aQ7pjAjpehWv0zJ+ty2MI ++fQ/lkXUCgYEAgbP+P5UmY7Fqm/mi6TprEJ/eYktji4Ne11GDKGFQCfjF5RdKhdw1 ++5+elGhZes+cpzu5Ak6zBDu4bviT+tRTWJu5lVLEzlHHv4nAU7Ks5Aj67ApH21AnP ++RtlATdhWOt5Dkdq1WSpDfz5bvWgvyBx9D66dSmQdbKKe2dH327eQll4= + -----END RSA PRIVATE KEY----- +diff --git a/test/certs/embeddedSCTs1.pem b/test/certs/embeddedSCTs1.pem +index d1e8512..d2a111f 100644 +--- a/test/certs/embeddedSCTs1.pem ++++ b/test/certs/embeddedSCTs1.pem +@@ -1,20 +1,21 @@ + -----BEGIN CERTIFICATE----- +-MIIDWTCCAsKgAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk ++MIIDeDCCAuGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJHQjEk + MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX +-YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw +-MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu +-c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G +-CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/ +-BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk +-EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw +-FAn/Xdh+tQIDAQABo4IBOjCCATYwHQYDVR0OBBYEFCAxVBryXAX/2GWLaEN5T16Q +-Nve0MH0GA1UdIwR2MHSAFF+diA3Ic+ZU1PgN2OawwSS0R8NVoVmkVzBVMQswCQYD +-VQQGEwJHQjEkMCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4w +-DAYDVQQIEwVXYWxlczEQMA4GA1UEBxMHRXJ3IFdlboIBADAJBgNVHRMEAjAAMIGK +-BgorBgEEAdZ5AgQCBHwEegB4AHYA3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4L +-vT9012QAAAE92yffkwAABAMARzBFAiBIL2dRrzXbplQ2vh/WZA89v5pBQpSVkkUw +-KI+j5eI+BgIhAOTtwNs6xXKx4vXoq2poBlOYfc9BAn3+/6EFUZ2J7b8IMA0GCSqG +-SIb3DQEBBQUAA4GBAIoMS+8JnUeSea+goo5on5HhxEIb4tJpoupspOghXd7dyhUE +-oR58h8S3foDw6XkDUmjyfKIOFmgErlVvMWmB+Wo5Srer/T4lWsAERRP+dlcMZ5Wr +-5HAxM9MD+J86+mu8/FFzGd/ZW5NCQSEfY0A1w9B4MHpoxgdaLiDInza4kQyg ++YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAgFw0yMDAxMjUxMTUwMTNaGA8yMTIwMDEy ++NjExNTAxM1owGTEXMBUGA1UEAwwOc2VydmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3 ++DQEBAQUAA4IBDwAwggEKAoIBAQC4iOkDj+IKkMDaaPLAjnMbogFfps1xFBgOwHsK ++/RWic1e0kHBfEwQ0/iNWm8SZaknmIwGScYdX5dYGSeBhqlzMixjgsafpoxTrJIAE ++FVCk05BJF9PjzEYY9H2bM4Eb/KmWakU5WrWP5vrmWyS8BcphosWkWfehj+kFJ1wI ++0E/wvKlVcAlvcioRewEv8SuAcb1uAhE/xXEEBqvILPvuQvMBeR8cvYt9IYh8043I ++QoHfEj3hLgt6i45KhYvVWQR8mzzu8bgbnGhfDco4fKK55BRSUye7yn4HHTE9Uo8S ++wuN7dH2TSsZrlxrt1cCf1TKkoqnbnHg1emeMZfm3FURh82+pAgMBAAGjggEMMIIB ++CDAdBgNVHQ4EFgQUtMa8XD5ylrF9AqCdnPEhXa63H2owHwYDVR0jBBgwFoAUX52I ++Dchz5lTU+A3Y5rDBJLRHw1UwCQYDVR0TBAIwADATBgNVHSUEDDAKBggrBgEFBQcD ++ATCBigYKKwYBBAHWeQIEAgR8BHoAeAB2AN8cLsEVAJRSR6lhaDJd3Fx5Wej3xtOI ++/AAuC70/dNdkAAABb15m6AAAAAQDAEcwRQIgfDPo8RArm/vcSEZ608Q1u+XQ55QB ++u67SZEuZxLpbUM0CIQDRsgcTud4PDy8Cgg+lHeAS7UxgSKBbWAznYOuorwNewzAZ ++BgNVHREEEjAQgg5zZXJ2ZXIuZXhhbXBsZTANBgkqhkiG9w0BAQsFAAOBgQCWFKKR ++RNkDRzB25NK07OLkbzebhnpKtbP4i3blRx1HAvTSamf/3uuHI7kfiPJorJymJpT1 ++IuJvSVKyMu1qONWBimiBfiyGL7+le1izHEJIP5lVTbddfzSIBIvrlHHcWIOL3H+W ++YT6yTEIzJuO07Xp61qnB1CE2TrinUWlyC46Zkw== + -----END CERTIFICATE----- +diff --git a/test/certs/embeddedSCTs1.sct b/test/certs/embeddedSCTs1.sct +index 59362dc..35c9eb9 100644 +--- a/test/certs/embeddedSCTs1.sct ++++ b/test/certs/embeddedSCTs1.sct +@@ -2,11 +2,11 @@ Signed Certificate Timestamp: + Version : v1 (0x0) + Log ID : DF:1C:2E:C1:15:00:94:52:47:A9:61:68:32:5D:DC:5C: + 79:59:E8:F7:C6:D3:88:FC:00:2E:0B:BD:3F:74:D7:64 +- Timestamp : Apr 5 17:04:16.275 2013 GMT ++ Timestamp : Jan 1 00:00:00.000 2020 GMT + Extensions: none + Signature : ecdsa-with-SHA256 +- 30:45:02:20:48:2F:67:51:AF:35:DB:A6:54:36:BE:1F: +- D6:64:0F:3D:BF:9A:41:42:94:95:92:45:30:28:8F:A3: +- E5:E2:3E:06:02:21:00:E4:ED:C0:DB:3A:C5:72:B1:E2: +- F5:E8:AB:6A:68:06:53:98:7D:CF:41:02:7D:FE:FF:A1: +- 05:51:9D:89:ED:BF:08 +\ No newline at end of file ++ 30:45:02:20:7C:33:E8:F1:10:2B:9B:FB:DC:48:46:7A: ++ D3:C4:35:BB:E5:D0:E7:94:01:BB:AE:D2:64:4B:99:C4: ++ BA:5B:50:CD:02:21:00:D1:B2:07:13:B9:DE:0F:0F:2F: ++ 02:82:0F:A5:1D:E0:12:ED:4C:60:48:A0:5B:58:0C:E7: ++ 60:EB:A8:AF:03:5E:C3 +\ No newline at end of file +diff --git a/test/certs/embeddedSCTs1_issuer-key.pem b/test/certs/embeddedSCTs1_issuer-key.pem +new file mode 100644 +index 0000000..9326e38 +--- /dev/null ++++ b/test/certs/embeddedSCTs1_issuer-key.pem +@@ -0,0 +1,15 @@ ++-----BEGIN RSA PRIVATE KEY----- ++MIICXAIBAAKBgQDVimhTYhCicRmTbneDIRgcKkATxtB7jHbrkVfT0PtLO1FuzsvR ++yY2RxS90P6tjXVUJnNE6uvMa5UFEJFGnTHgW8iQ8+EjPKDHM5nugSlojgZ88ujfm ++JNnDvbKZuDnd/iYx0ss6hPx7srXFL8/BT/9Ab1zURmnLsvfP34b7arnRsQIDAQAB ++AoGAJLR6xEJp+5IXRFlLn7WTkFvO0ddtxJ7bXhiIkTctyruyfqp7LF9Jv1G2m3PK ++QPUtBc73w/GYkfnwIwdfJbOmPHL7XyEGHZYmEXgIgEtw6LXvAv0G5JpUnNwsSBfL ++GfSQqI5Z5ytyzlJXkMcTGA2kTgNAYc73h4EnU+pwUnDPdAECQQD2aj+4LtYk1XPq ++r3gjgI6MoGvgYJfPmAtZhxxVbhXQKciFUCAcBiwlQdHIdLWE9j65ctmZRWidKifr ++4O4nz+TBAkEA3djNW/rTQq5fKZy+mCF1WYnIU/3yhJaptzRqLm7AHqe7+hdrGXJw +++mCtU8T3L/Ms8bH1yFBZhmkp1PbR8gl48QJAQo70YyWThiN5yfxXcQ96cZWrTdIJ ++b3NcLXSHPLQdhDqlBQ1dfvRT3ERpC8IqfZ2d162kBPhwh3MpkVcSPQK0gQJAC/dY ++xGBYKt2a9nSk9zG+0bCT5Kvq++ngh6hFHfINXNnxUsEWns3EeEzkrIMQTj7QqszN ++lBt5aL2dawZRNrv6EQJBAOo4STF9KEwQG0HLC/ryh1FeB0OBA5yIepXze+eJVKei ++T0cCECOQJKfWHEzYJYDJhyEFF/sYp9TXwKSDjOifrsU= ++-----END RSA PRIVATE KEY----- +diff --git a/test/certs/embeddedSCTs1_issuer.pem b/test/certs/embeddedSCTs1_issuer.pem +index 1fa449d..6aa9455 100644 +--- a/test/certs/embeddedSCTs1_issuer.pem ++++ b/test/certs/embeddedSCTs1_issuer.pem +@@ -1,18 +1,18 @@ + -----BEGIN CERTIFICATE----- +-MIIC0DCCAjmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk ++MIIC0jCCAjugAwIBAgIBADANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJHQjEk + MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX +-YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw +-MDAwMDBaMFUxCzAJBgNVBAYTAkdCMSQwIgYDVQQKExtDZXJ0aWZpY2F0ZSBUcmFu +-c3BhcmVuY3kgQ0ExDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGf +-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVimhTYhCicRmTbneDIRgcKkATxtB7 +-jHbrkVfT0PtLO1FuzsvRyY2RxS90P6tjXVUJnNE6uvMa5UFEJFGnTHgW8iQ8+EjP +-KDHM5nugSlojgZ88ujfmJNnDvbKZuDnd/iYx0ss6hPx7srXFL8/BT/9Ab1zURmnL +-svfP34b7arnRsQIDAQABo4GvMIGsMB0GA1UdDgQWBBRfnYgNyHPmVNT4DdjmsMEk +-tEfDVTB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkG +-A1UEBhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEO +-MAwGA1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwDAYDVR0TBAUwAwEB +-/zANBgkqhkiG9w0BAQUFAAOBgQAGCMxKbWTyIF4UbASydvkrDvqUpdryOvw4BmBt +-OZDQoeojPUApV2lGOwRmYef6HReZFSCa6i4Kd1F2QRIn18ADB8dHDmFYT9czQiRy +-f1HWkLxHqd81TbD26yWVXeGJPE3VICskovPkQNJ0tU4b03YmnKliibduyqQQkOFP +-OwqULg== ++YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAgFw0yMjA2MDExMDM4MDJaGA8yMTIyMDUw ++ODEwMzgwMlowVTELMAkGA1UEBhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRy ++YW5zcGFyZW5jeSBDQTEOMAwGA1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW4w ++gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANWKaFNiEKJxGZNud4MhGBwqQBPG ++0HuMduuRV9PQ+0s7UW7Oy9HJjZHFL3Q/q2NdVQmc0Tq68xrlQUQkUadMeBbyJDz4 ++SM8oMczme6BKWiOBnzy6N+Yk2cO9spm4Od3+JjHSyzqE/HuytcUvz8FP/0BvXNRG ++acuy98/fhvtqudGxAgMBAAGjga8wgawwHQYDVR0OBBYEFF+diA3Ic+ZU1PgN2Oaw ++wSS0R8NVMH0GA1UdIwR2MHSAFF+diA3Ic+ZU1PgN2OawwSS0R8NVoVmkVzBVMQsw ++CQYDVQQGEwJHQjEkMCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENB ++MQ4wDAYDVQQIEwVXYWxlczEQMA4GA1UEBxMHRXJ3IFdlboIBADAMBgNVHRMEBTAD ++AQH/MA0GCSqGSIb3DQEBCwUAA4GBAD0aYh9OkFYfXV7kBfhrtD0PJG2U47OV/1qq +++uFpqB0S1WO06eJT0pzYf1ebUcxjBkajbJZm/FHT85VthZ1lFHsky87aFD8XlJCo ++2IOhKOkvvWKPUdFLoO/ZVXqEVKkcsS1eXK1glFvb07eJZya3JVG0KdMhV2YoDg6c ++Doud4XrO + -----END CERTIFICATE----- +-- +2.20.1 (Apple Git-117) + diff --git a/Backport-ct_test.c-Update-the-epoch-time.patch b/Backport-ct_test.c-Update-the-epoch-time.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba61024baee3c72f80def06cac3a1f006d9edff7 --- /dev/null +++ b/Backport-ct_test.c-Update-the-epoch-time.patch @@ -0,0 +1,28 @@ +From 7dbefac7fa259eee188017f6dbcfd11376fe6345 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Wed, 1 Jun 2022 13:06:46 +0200 +Subject: [PATCH 15/15] ct_test.c: Update the epoch time + +Reviewed-by: Matt Caswell +Reviewed-by: Dmitry Belyavskiy +(Merged from https://github.com/openssl/openssl/pull/18446) +--- + test/ct_test.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/ct_test.c b/test/ct_test.c +index 78d11ca..535897d 100644 +--- a/test/ct_test.c ++++ b/test/ct_test.c +@@ -63,7 +63,7 @@ static CT_TEST_FIXTURE *set_up(const char *const test_case_name) + if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))) + goto end; + fixture->test_case_name = test_case_name; +- fixture->epoch_time_in_ms = 1473269626000ULL; /* Sep 7 17:33:46 2016 GMT */ ++ fixture->epoch_time_in_ms = 1580335307000ULL; /* Wed 29 Jan 2020 10:01:47 PM UTC */ + if (!TEST_ptr(fixture->ctlog_store = CTLOG_STORE_new()) + || !TEST_int_eq( + CTLOG_STORE_load_default_file(fixture->ctlog_store), 1)) +-- +2.20.1 (Apple Git-117) + diff --git a/CVE-2022-0778-Add-a-negative-testcase-for-BN_mod_sqrt.patch b/CVE-2022-0778-Add-a-negative-testcase-for-BN_mod_sqrt.patch new file mode 100644 index 0000000000000000000000000000000000000000..b066c77c4f093338e088175dfe4914a2b4e3ae2f --- /dev/null +++ b/CVE-2022-0778-Add-a-negative-testcase-for-BN_mod_sqrt.patch @@ -0,0 +1,58 @@ +From 3ef5c3034e5c545f34d6929568f3f2b10ac4bdf0 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Mon, 28 Feb 2022 18:26:35 +0100 +Subject: [PATCH] Add a negative testcase for BN_mod_sqrt + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + test/bntest.c | 11 ++++++++++- + test/recipes/10-test_bn_data/bnmod.txt | 12 ++++++++++++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/test/bntest.c b/test/bntest.c +index 390dd80073..1cab660bca 100644 +--- a/test/bntest.c ++++ b/test/bntest.c +@@ -1729,8 +1729,17 @@ static int file_modsqrt(STANZA *s) + || !TEST_ptr(ret2 = BN_new())) + goto err; + ++ if (BN_is_negative(mod_sqrt)) { ++ /* A negative testcase */ ++ if (!TEST_ptr_null(BN_mod_sqrt(ret, a, p, ctx))) ++ goto err; ++ ++ st = 1; ++ goto err; ++ } ++ + /* There are two possible answers. */ +- if (!TEST_true(BN_mod_sqrt(ret, a, p, ctx)) ++ if (!TEST_ptr(BN_mod_sqrt(ret, a, p, ctx)) + || !TEST_true(BN_sub(ret2, p, ret))) + goto err; + +diff --git a/test/recipes/10-test_bn_data/bnmod.txt b/test/recipes/10-test_bn_data/bnmod.txt +index 5ea4d031f2..e28cc6bfb0 100644 +--- a/test/recipes/10-test_bn_data/bnmod.txt ++++ b/test/recipes/10-test_bn_data/bnmod.txt +@@ -2799,3 +2799,15 @@ P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186 + A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81 + P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f ++ ++# Negative testcases for BN_mod_sqrt() ++ ++# This one triggers an infinite loop with unfixed implementation ++# It should just fail. ++ModSqrt = -1 ++A = 20a7ee ++P = 460201 ++ ++ModSqrt = -1 ++A = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ed ++P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f +-- +2.27.0 + diff --git a/CVE-2022-0778-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch b/CVE-2022-0778-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch new file mode 100644 index 0000000000000000000000000000000000000000..653b8fba621d07cb8b7a4d1dfff33ceb8a57be91 --- /dev/null +++ b/CVE-2022-0778-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch @@ -0,0 +1,69 @@ +From 3118eb64934499d93db3230748a452351d1d9a65 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Mon, 28 Feb 2022 18:26:21 +0100 +Subject: [PATCH] Fix possible infinite loop in BN_mod_sqrt() + +The calculation in some cases does not finish for non-prime p. + +This fixes CVE-2022-0778. + +Based on patch by David Benjamin . + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + crypto/bn/bn_sqrt.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c +index 1723d5ded5..53b0f55985 100644 +--- a/crypto/bn/bn_sqrt.c ++++ b/crypto/bn/bn_sqrt.c +@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + /* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number +- * Theory", algorithm 1.5.1). 'p' must be prime! ++ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or ++ * an incorrect "result" will be returned. + */ + { + BIGNUM *ret = in; +@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + goto vrfy; + } + +- /* find smallest i such that b^(2^i) = 1 */ +- i = 1; +- if (!BN_mod_sqr(t, b, p, ctx)) +- goto end; +- while (!BN_is_one(t)) { +- i++; +- if (i == e) { +- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); +- goto end; ++ /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */ ++ for (i = 1; i < e; i++) { ++ if (i == 1) { ++ if (!BN_mod_sqr(t, b, p, ctx)) ++ goto end; ++ ++ } else { ++ if (!BN_mod_mul(t, t, t, p, ctx)) ++ goto end; + } +- if (!BN_mod_mul(t, t, t, p, ctx)) +- goto end; ++ if (BN_is_one(t)) ++ break; ++ } ++ /* If not found, a is not a square or p is not prime. */ ++ if (i >= e) { ++ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); ++ goto end; + } + + /* t := y^2^(e - i - 1) */ +-- +2.27.0 + diff --git a/CVE-2022-1292.patch b/CVE-2022-1292.patch new file mode 100644 index 0000000000000000000000000000000000000000..9e38095689f2f79b4891f101d0b27262ba5e3c6f --- /dev/null +++ b/CVE-2022-1292.patch @@ -0,0 +1,76 @@ +From e5fd1728ef4c7a5bf7c7a7163ca60370460a6e23 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 26 Apr 2022 12:40:24 +0200 +Subject: [PATCH] c_rehash: Do not use shell to invoke openssl + +Except on VMS where it is safe. + +This fixes CVE-2022-1292. + +Reviewed-by: Matthias St. Pierre +Reviewed-by: Matt Caswell +--- + tools/c_rehash.in | 29 +++++++++++++++++++++++++---- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/tools/c_rehash.in b/tools/c_rehash.in +index fa7c6c9..83c1cc8 100644 +--- a/tools/c_rehash.in ++++ b/tools/c_rehash.in +@@ -152,6 +152,23 @@ sub check_file { + return ($is_cert, $is_crl); + } + ++sub compute_hash { ++ my $fh; ++ if ( $^O eq "VMS" ) { ++ # VMS uses the open through shell ++ # The file names are safe there and list form is unsupported ++ if (!open($fh, "-|", join(' ', @_))) { ++ print STDERR "Cannot compute hash on '$fname'\n"; ++ return; ++ } ++ } else { ++ if (!open($fh, "-|", @_)) { ++ print STDERR "Cannot compute hash on '$fname'\n"; ++ return; ++ } ++ } ++ return (<$fh>, <$fh>); ++} + + # Link a certificate to its subject name hash value, each hash is of + # the form . where n is an integer. If the hash value already exists +@@ -161,10 +178,12 @@ sub check_file { + + sub link_hash_cert { + my $fname = $_[0]; +- $fname =~ s/\"/\\\"/g; +- my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`; ++ my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash, ++ "-fingerprint", "-noout", ++ "-in", $fname); + chomp $hash; + chomp $fprint; ++ return if !$hash; + $fprint =~ s/^.*=//; + $fprint =~ tr/://d; + my $suffix = 0; +@@ -202,10 +221,12 @@ sub link_hash_cert { + + sub link_hash_crl { + my $fname = $_[0]; +- $fname =~ s/'/'\\''/g; +- my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`; ++ my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash, ++ "-fingerprint", "-noout", ++ "-in", $fname); + chomp $hash; + chomp $fprint; ++ return if !$hash; + $fprint =~ s/^.*=//; + $fprint =~ tr/://d; + my $suffix = 0; +-- +1.8.3.1 + diff --git a/CVE-2022-2068-Fix-file-operations-in-c_rehash.patch b/CVE-2022-2068-Fix-file-operations-in-c_rehash.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b2d6eaa61e6c51676e5f725b56667e32277f6ab --- /dev/null +++ b/CVE-2022-2068-Fix-file-operations-in-c_rehash.patch @@ -0,0 +1,257 @@ +From 9639817dac8bbbaa64d09efad7464ccc405527c7 Mon Sep 17 00:00:00 2001 +From: Daniel Fiala +Date: Sun, 29 May 2022 20:11:24 +0200 +Subject: [PATCH] Fix file operations in c_rehash. + +CVE-2022-2068 + +Reviewed-by: Matt Caswell +Reviewed-by: Richard Levitte +--- + tools/c_rehash.in | 216 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 107 insertions(+), 109 deletions(-) + +diff --git a/tools/c_rehash.in b/tools/c_rehash.in +index cfd18f5..9d2a6f6 100644 +--- a/tools/c_rehash.in ++++ b/tools/c_rehash.in +@@ -104,52 +104,78 @@ foreach (@dirlist) { + } + exit($errorcount); + ++sub copy_file { ++ my ($src_fname, $dst_fname) = @_; ++ ++ if (open(my $in, "<", $src_fname)) { ++ if (open(my $out, ">", $dst_fname)) { ++ print $out $_ while (<$in>); ++ close $out; ++ } else { ++ warn "Cannot open $dst_fname for write, $!"; ++ } ++ close $in; ++ } else { ++ warn "Cannot open $src_fname for read, $!"; ++ } ++} ++ + sub hash_dir { +- my %hashlist; +- print "Doing $_[0]\n"; +- chdir $_[0]; +- opendir(DIR, "."); +- my @flist = sort readdir(DIR); +- closedir DIR; +- if ( $removelinks ) { +- # Delete any existing symbolic links +- foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { +- if (-l $_) { +- print "unlink $_" if $verbose; +- unlink $_ || warn "Can't unlink $_, $!\n"; +- } +- } +- } +- FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) { +- # Check to see if certificates and/or CRLs present. +- my ($cert, $crl) = check_file($fname); +- if (!$cert && !$crl) { +- print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n"; +- next; +- } +- link_hash_cert($fname) if ($cert); +- link_hash_crl($fname) if ($crl); +- } ++ my $dir = shift; ++ my %hashlist; ++ ++ print "Doing $dir\n"; ++ ++ if (!chdir $dir) { ++ print STDERR "WARNING: Cannot chdir to '$dir', $!\n"; ++ return; ++ } ++ ++ opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n"; ++ my @flist = sort readdir(DIR); ++ closedir DIR; ++ if ( $removelinks ) { ++ # Delete any existing symbolic links ++ foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { ++ if (-l $_) { ++ print "unlink $_\n" if $verbose; ++ unlink $_ || warn "Can't unlink $_, $!\n"; ++ } ++ } ++ } ++ FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) { ++ # Check to see if certificates and/or CRLs present. ++ my ($cert, $crl) = check_file($fname); ++ if (!$cert && !$crl) { ++ print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n"; ++ next; ++ } ++ link_hash_cert($fname) if ($cert); ++ link_hash_crl($fname) if ($crl); ++ } ++ ++ chdir $pwd; + } + + sub check_file { +- my ($is_cert, $is_crl) = (0,0); +- my $fname = $_[0]; +- open IN, $fname; +- while() { +- if (/^-----BEGIN (.*)-----/) { +- my $hdr = $1; +- if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { +- $is_cert = 1; +- last if ($is_crl); +- } elsif ($hdr eq "X509 CRL") { +- $is_crl = 1; +- last if ($is_cert); +- } +- } +- } +- close IN; +- return ($is_cert, $is_crl); ++ my ($is_cert, $is_crl) = (0,0); ++ my $fname = $_[0]; ++ ++ open(my $in, "<", $fname); ++ while(<$in>) { ++ if (/^-----BEGIN (.*)-----/) { ++ my $hdr = $1; ++ if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { ++ $is_cert = 1; ++ last if ($is_crl); ++ } elsif ($hdr eq "X509 CRL") { ++ $is_crl = 1; ++ last if ($is_cert); ++ } ++ } ++ } ++ close $in; ++ return ($is_cert, $is_crl); + } + + sub compute_hash { +@@ -177,76 +203,48 @@ sub compute_hash { + # certificate fingerprints + + sub link_hash_cert { +- my $fname = $_[0]; +- my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash, +- "-fingerprint", "-noout", +- "-in", $fname); +- chomp $hash; +- chomp $fprint; +- return if !$hash; +- $fprint =~ s/^.*=//; +- $fprint =~ tr/://d; +- my $suffix = 0; +- # Search for an unused hash filename +- while(exists $hashlist{"$hash.$suffix"}) { +- # Hash matches: if fingerprint matches its a duplicate cert +- if ($hashlist{"$hash.$suffix"} eq $fprint) { +- print STDERR "WARNING: Skipping duplicate certificate $fname\n"; +- return; +- } +- $suffix++; +- } +- $hash .= ".$suffix"; +- if ($symlink_exists) { +- print "link $fname -> $hash\n" if $verbose; +- symlink $fname, $hash || warn "Can't symlink, $!"; +- } else { +- print "copy $fname -> $hash\n" if $verbose; +- if (open($in, "<", $fname)) { +- if (open($out,">", $hash)) { +- print $out $_ while (<$in>); +- close $out; +- } else { +- warn "can't open $hash for write, $!"; +- } +- close $in; +- } else { +- warn "can't open $fname for read, $!"; +- } +- } +- $hashlist{$hash} = $fprint; ++ link_hash($_[0], 'cert'); + } + + # Same as above except for a CRL. CRL links are of the form .r + + sub link_hash_crl { +- my $fname = $_[0]; +- my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash, +- "-fingerprint", "-noout", +- "-in", $fname); +- chomp $hash; +- chomp $fprint; +- return if !$hash; +- $fprint =~ s/^.*=//; +- $fprint =~ tr/://d; +- my $suffix = 0; +- # Search for an unused hash filename +- while(exists $hashlist{"$hash.r$suffix"}) { +- # Hash matches: if fingerprint matches its a duplicate cert +- if ($hashlist{"$hash.r$suffix"} eq $fprint) { +- print STDERR "WARNING: Skipping duplicate CRL $fname\n"; +- return; +- } +- $suffix++; +- } +- $hash .= ".r$suffix"; +- if ($symlink_exists) { +- print "link $fname -> $hash\n" if $verbose; +- symlink $fname, $hash || warn "Can't symlink, $!"; +- } else { +- print "cp $fname -> $hash\n" if $verbose; +- system ("cp", $fname, $hash); +- warn "Can't copy, $!" if ($? >> 8) != 0; +- } +- $hashlist{$hash} = $fprint; ++ link_hash($_[0], 'crl'); ++} ++ ++sub link_hash { ++ my ($fname, $type) = @_; ++ my $is_cert = $type eq 'cert'; ++ ++ my ($hash, $fprint) = compute_hash($openssl, ++ $is_cert ? "x509" : "crl", ++ $is_cert ? $x509hash : $crlhash, ++ "-fingerprint", "-noout", ++ "-in", $fname); ++ chomp $hash; ++ chomp $fprint; ++ return if !$hash; ++ $fprint =~ s/^.*=//; ++ $fprint =~ tr/://d; ++ my $suffix = 0; ++ # Search for an unused hash filename ++ my $crlmark = $is_cert ? "" : "r"; ++ while(exists $hashlist{"$hash.$crlmark$suffix"}) { ++ # Hash matches: if fingerprint matches its a duplicate cert ++ if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) { ++ my $what = $is_cert ? 'certificate' : 'CRL'; ++ print STDERR "WARNING: Skipping duplicate $what $fname\n"; ++ return; ++ } ++ $suffix++; ++ } ++ $hash .= ".$crlmark$suffix"; ++ if ($symlink_exists) { ++ print "link $fname -> $hash\n" if $verbose; ++ symlink $fname, $hash || warn "Can't symlink, $!"; ++ } else { ++ print "copy $fname -> $hash\n" if $verbose; ++ copy_file($fname, $hash); ++ } ++ $hashlist{$hash} = $fprint; + } +-- +1.8.3.1 + diff --git a/CVE-2022-2097-Fix-AES-OCB-encrypt-decrypt-for-x86-AES-NI.patch b/CVE-2022-2097-Fix-AES-OCB-encrypt-decrypt-for-x86-AES-NI.patch new file mode 100644 index 0000000000000000000000000000000000000000..05d71ab798b5f73b311b9617e92c230a39d047fc --- /dev/null +++ b/CVE-2022-2097-Fix-AES-OCB-encrypt-decrypt-for-x86-AES-NI.patch @@ -0,0 +1,73 @@ +From 919925673d6c9cfed3c1085497f5dfbbed5fc431 Mon Sep 17 00:00:00 2001 +From: Alex Chernyakhovsky +Date: Thu, 16 Jun 2022 12:00:22 +1000 +Subject: [PATCH] Fix AES OCB encrypt/decrypt for x86 AES-NI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +aesni_ocb_encrypt and aesni_ocb_decrypt operate by having a fast-path +that performs operations on 6 16-byte blocks concurrently (the +"grandloop") and then proceeds to handle the "short" tail (which can +be anywhere from 0 to 5 blocks) that remain. + +As part of initialization, the assembly initializes $len to the true +length, less 96 bytes and converts it to a pointer so that the $inp +can be compared to it. Each iteration of "grandloop" checks to see if +there's a full 96-byte chunk to process, and if so, continues. Once +this has been exhausted, it falls through to "short", which handles +the remaining zero to five blocks. + +Unfortunately, the jump at the end of "grandloop" had a fencepost +error, doing a `jb` ("jump below") rather than `jbe` (jump below or +equal). This should be `jbe`, as $inp is pointing to the *end* of the +chunk currently being handled. If $inp == $len, that means that +there's a whole 96-byte chunk waiting to be handled. If $inp > $len, +then there's 5 or fewer 16-byte blocks left to be handled, and the +fall-through is intended. + +The net effect of `jb` instead of `jbe` is that the last 16-byte block +of the last 96-byte chunk was completely omitted. The contents of +`out` in this position were never written to. Additionally, since +those bytes were never processed, the authentication tag generated is +also incorrect. + +The same fencepost error, and identical logic, exists in both +aesni_ocb_encrypt and aesni_ocb_decrypt. + +This addresses CVE-2022-2097. + +Co-authored-by: Alejandro Sedeño +Co-authored-by: David Benjamin + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +--- + crypto/aes/asm/aesni-x86.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl +index fe2b265..812758e 100644 +--- a/crypto/aes/asm/aesni-x86.pl ++++ b/crypto/aes/asm/aesni-x86.pl +@@ -2027,7 +2027,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out); + &movdqu (&QWP(-16*2,$out,$inp),$inout4); + &movdqu (&QWP(-16*1,$out,$inp),$inout5); + &cmp ($inp,$len); # done yet? +- &jb (&label("grandloop")); ++ &jbe (&label("grandloop")); + + &set_label("short"); + &add ($len,16*6); +@@ -2453,7 +2453,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out); + &pxor ($rndkey1,$inout5); + &movdqu (&QWP(-16*1,$out,$inp),$inout5); + &cmp ($inp,$len); # done yet? +- &jb (&label("grandloop")); ++ &jbe (&label("grandloop")); + + &set_label("short"); + &add ($len,16*6); +-- +1.8.3.1 + diff --git a/Feature-PKCS7-sign-and-verify-support-SM2-algorithm.patch b/Feature-PKCS7-sign-and-verify-support-SM2-algorithm.patch new file mode 100644 index 0000000000000000000000000000000000000000..fc588ada8c238200a07988b1edb18fa5973c8bbc --- /dev/null +++ b/Feature-PKCS7-sign-and-verify-support-SM2-algorithm.patch @@ -0,0 +1,74 @@ +From fa3d5b8af929c296f4d684345dedf1e2b4b390e2 Mon Sep 17 00:00:00 2001 +From: gaoyusong +Date: Fri, 30 Sep 2022 12:10:15 +0800 +Subject: [PATCH] PKCS7 sign and verify support SM2 algorithm + +Signed-off-by: Huaxin Lu +--- + crypto/pkcs7/pk7_doit.c | 23 +++++++++++++++++++++-- + crypto/sm2/sm2_pmeth.c | 1 + + 2 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c +index f63fbc5..916a35a 100644 +--- a/crypto/pkcs7/pk7_doit.c ++++ b/crypto/pkcs7/pk7_doit.c +@@ -946,6 +946,9 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ATTRIBUTE) *sk; + BIO *btmp; + EVP_PKEY *pkey; ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_CTX *pctx = NULL; ++#endif + + mdc_tmp = EVP_MD_CTX_new(); + if (mdc_tmp == NULL) { +@@ -1013,7 +1016,19 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + goto err; + } + +- if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL)) ++ pkey = X509_get0_pubkey(x509); ++ if (!pkey) { ++ ret = -1; ++ goto err; ++ } ++ ++ ret = ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_is_sm2(pkey) ? ++ EVP_DigestVerifyInit(mdc_tmp, &pctx, EVP_get_digestbynid(md_type), NULL, pkey) : ++#endif ++ EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL); ++ if (!ret) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, +@@ -1036,7 +1051,11 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + goto err; + } + +- i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); ++ i = ++#ifndef OPENSSL_NO_SM2 ++ EVP_PKEY_is_sm2(pkey) ? EVP_DigestVerifyFinal(mdc_tmp, os->data, os->length) : ++#endif ++ EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); + ret = -1; +diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c +index 1998812..53cdbe9 100644 +--- a/crypto/sm2/sm2_pmeth.c ++++ b/crypto/sm2/sm2_pmeth.c +@@ -221,6 +221,7 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: ++ case EVP_PKEY_CTRL_PKCS7_SIGN: + /* nothing to be inited, this is to suppress the error... */ + return 1; + +-- +2.33.0 + diff --git a/Feature-SM4-XTS-optimization-for-ARM-by-HW-instruction.patch b/Feature-SM4-XTS-optimization-for-ARM-by-HW-instruction.patch new file mode 100644 index 0000000000000000000000000000000000000000..fef2d8f49a1316f6461156d035bea02a1dffcbfb --- /dev/null +++ b/Feature-SM4-XTS-optimization-for-ARM-by-HW-instruction.patch @@ -0,0 +1,621 @@ +From 3f0898b2aea424f18f58a182803478f25548674e Mon Sep 17 00:00:00 2001 +From: Xu Yizhou +Date: Wed, 2 Nov 2022 11:13:07 +0800 +Subject: [PATCH 3/3] SM4 XTS optimization for ARM by HW instruction + +This patch implements the SM4 XTS optimization for ARM processor, +using SM4 HW instruction, which is an optional feature of +crypto extension for aarch64 V8. + +Signed-off-by: Xu Yizhou +--- + crypto/evp/e_sm4.c | 28 ++ + crypto/sm4/asm/sm4-armv8.pl | 498 +++++++++++++++++++++++++++++++++- + include/crypto/sm4_platform.h | 14 + + 3 files changed, 537 insertions(+), 3 deletions(-) + +diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c +index eaa5ba0..da4dbd3 100644 +--- a/crypto/evp/e_sm4.c ++++ b/crypto/evp/e_sm4.c +@@ -281,6 +281,34 @@ static int sm4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + xctx->stream_gb = NULL; + xctx->stream = NULL; ++#ifdef HWSM4_CAPABLE ++ if (HWSM4_CAPABLE) { ++ if (enc) { ++ HWSM4_set_encrypt_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) HWSM4_encrypt; ++# ifdef HWSM4_xts_encrypt_gb ++ xctx->stream_gb = HWSM4_xts_encrypt_gb; ++# endif ++# ifdef HWSM4_xts_encrypt ++ xctx->stream = HWSM4_xts_encrypt; ++# endif ++ } else { ++ HWSM4_set_decrypt_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) HWSM4_decrypt; ++# ifdef HWSM4_xts_decrypt_gb ++ xctx->stream_gb = HWSM4_xts_decrypt_gb; ++# endif ++# ifdef HWSM4_xts_decrypt ++ xctx->stream = HWSM4_xts_decrypt; ++# endif ++ } ++ HWSM4_set_encrypt_key(key + bytes, &xctx->ks2.ks); ++ xctx->xts.block2 = (block128_f) HWSM4_encrypt; ++ ++ xctx->xts.key1 = &xctx->ks1; ++ break; ++ } else ++#endif + #ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + if (enc) { +diff --git a/crypto/sm4/asm/sm4-armv8.pl b/crypto/sm4/asm/sm4-armv8.pl +index dbacad2..923c1c0 100644 +--- a/crypto/sm4/asm/sm4-armv8.pl ++++ b/crypto/sm4/asm/sm4-armv8.pl +@@ -11,9 +11,9 @@ + # Oct 2021 + # + +-# $output is the last argument if it looks like a file (it has an extension) ++# $outut is the last argument if it looks like a file (it has an extension) + # $flavour is the first argument if it doesn't look like a file +-$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; ++$outut = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + + $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +@@ -21,7 +21,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or + die "can't locate arm-xlate.pl"; + +-open OUT,"| \"$^X\" $xlate $flavour \"$output\"" ++open OUT,"| \"$^X\" $xlate $flavour \"$outut\"" + or die "can't call $xlate: $!"; + *STDOUT=*OUT; + +@@ -110,6 +110,120 @@ $code.=<<___; + ___ + } + ++sub mov_reg_to_vec() { ++ my $src0 = shift; ++ my $src1 = shift; ++ my $desv = shift; ++$code.=<<___; ++ mov $desv.d[0],$src0 ++ mov $desv.d[1],$src1 ++#ifdef __ARMEB__ ++ rev32 $desv.16b,$desv.16b ++#endif ++___ ++} ++ ++sub mov_vec_to_reg() { ++ my $srcv = shift; ++ my $des0 = shift; ++ my $des1 = shift; ++$code.=<<___; ++ mov $des0,$srcv.d[0] ++ mov $des1,$srcv.d[1] ++___ ++} ++ ++sub compute_tweak() { ++ my $src0 = shift; ++ my $src1 = shift; ++ my $des0 = shift; ++ my $des1 = shift; ++ my $tmp0 = shift; ++ my $tmp1 = shift; ++ my $magic = shift; ++$code.=<<___; ++ extr x$tmp1,$src1,$src1,#32 ++ extr $des1,$src1,$src0,#63 ++ and w$tmp0,w$magic,w$tmp1,asr#31 ++ eor $des0,x$tmp0,$src0,lsl#1 ++___ ++} ++ ++sub compute_tweak_vec() { ++ my $src = shift; ++ my $des = shift; ++ my $tmp0 = shift; ++ my $tmp1 = shift; ++ my $magic = shift; ++ &rbit($tmp1,$src); ++$code.=<<___; ++ shl $des.16b, $tmp1.16b, #1 ++ ext $tmp0.16b, $tmp1.16b, $tmp1.16b,#15 ++ ushr $tmp0.16b, $tmp0.16b, #7 ++ mul $tmp0.16b, $tmp0.16b, $magic.16b ++ eor $des.16b, $des.16b, $tmp0.16b ++___ ++ &rbit($des,$des); ++} ++ ++sub mov_en_to_enc(){ ++ my $en = shift; ++ my $enc = shift; ++ if ($en eq "en") { ++$code.=<<___; ++ mov $enc,1 ++___ ++ } else { ++$code.=<<___; ++ mov $enc,0 ++___ ++ } ++} ++ ++sub rbit() { ++ my $dst = shift; ++ my $src = shift; ++ ++ if ($src and ("$src" ne "$dst")) { ++ if ($standard eq "_gb") { ++$code.=<<___; ++ rbit $dst.16b,$src.16b ++___ ++ } else { ++$code.=<<___; ++ mov $dst.16b,$src.16b ++___ ++ } ++ } else { ++ if ($standard eq "_gb") { ++$code.=<<___; ++ rbit $dst.16b,$src.16b ++___ ++ } ++ } ++} ++ ++sub rev32_armeb() { ++ my $dst = shift; ++ my $src = shift; ++ ++ if ($src and ("$src" ne "$dst")) { ++$code.=<<___; ++#ifdef __ARMEB__ ++ rev32 $dst.16b,$src.16b ++#else ++ mov $dst.16b,$src.16b ++#endif ++___ ++ } else { ++$code.=<<___; ++#ifdef __ARMEB__ ++ rev32 $dst.16b,$dst.16b ++#endif ++___ ++ } ++} ++ + $code=<<___; + #include "arm_arch.h" + .arch armv8-a+crypto +@@ -595,6 +709,384 @@ $code.=<<___; + .size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks + ___ + }}} ++ ++ ++{{{ ++my ($inp,$out,$len,$rk1,$rk2,$ivp)=map("x$_",(0..5)); ++my ($blocks)=("x2"); ++my ($enc)=("x6"); ++my ($remain)=("x7"); ++my @twx=map("x$_",(9..24)); ++my $lastBlk=("x25"); ++ ++my @tweak=map("v$_",(8..15)); ++my @dat=map("v$_",(16..23)); ++my $lastTweak=("v24"); ++ ++# x/w/v/q registers for compute tweak ++my ($magic)=("8"); ++my ($tmp0,$tmp1)=("26","27"); ++my ($qMagic,$vMagic)=("q25","v25"); ++my ($vTmp0,$vTmp1)=("v26","v27"); ++ ++sub gen_xts_do_cipher() { ++$code.=<<___; ++.globl ${prefix}_xts_do_cipher${standard} ++.type ${prefix}_xts_do_cipher${standard},%function ++.align 5 ++${prefix}_xts_do_cipher${standard}: ++ mov w$magic,0x87 ++ ldr $qMagic, =0x01010101010101010101010101010187 ++ // used to encrypt the XORed plaintext blocks ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk2],#64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk2] ++ ld1 {@tweak[0].4s}, [$ivp] ++___ ++ &rev32(@tweak[0],@tweak[0]); ++ &enc_blk(@tweak[0]); ++ &rev32(@tweak[0],@tweak[0]); ++$code.=<<___; ++ // used to encrypt the initial vector to yield the initial tweak ++ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk1],#64 ++ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk1] ++ ++ and $remain,$len,#0x0F ++ // convert length into blocks ++ lsr $blocks,$len,4 ++ cmp $blocks,#1 // $len must be at least 16 ++ b.lt 99f ++ ++ cmp $remain,0 // if $len is a multiple of 16 ++ b.eq .xts_encrypt_blocks${standard} ++ // if $len is not a multiple of 16 ++ subs $blocks,$blocks,#1 ++ b.eq .only_2blks_tweak${standard} // if $len is less than 32 ++ ++.xts_encrypt_blocks${standard}: ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rev32_armeb(@tweak[0],@tweak[0]); ++ &mov_vec_to_reg(@tweak[0],@twx[0],@twx[1]); ++ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13],$tmp0,$tmp1,$magic); ++ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15],$tmp0,$tmp1,$magic); ++$code.=<<___; ++1: ++ cmp $blocks,#8 ++___ ++ &mov_reg_to_vec(@twx[0],@twx[1],@tweak[0]); ++ &compute_tweak(@twx[14],@twx[15],@twx[0],@twx[1],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[2],@twx[3],@tweak[1]); ++ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[4],@twx[5],@tweak[2]); ++ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[6],@twx[7],@tweak[3]); ++ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[8],@twx[9],@tweak[4]); ++ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[10],@twx[11],@tweak[5]); ++ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[12],@twx[13],@tweak[6]); ++ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13],$tmp0,$tmp1,$magic); ++ &mov_reg_to_vec(@twx[14],@twx[15],@tweak[7]); ++ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15],$tmp0,$tmp1,$magic); ++$code.=<<___; ++ b.lt 2f ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++ &rbit(@tweak[3],@tweak[3]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b ++ ld1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$inp],#64 ++___ ++ &rbit(@tweak[4],@tweak[4]); ++ &rbit(@tweak[5],@tweak[5]); ++ &rbit(@tweak[6],@tweak[6]); ++ &rbit(@tweak[7],@tweak[7]); ++$code.=<<___; ++ eor @dat[4].16b, @dat[4].16b, @tweak[4].16b ++ eor @dat[5].16b, @dat[5].16b, @tweak[5].16b ++ eor @dat[6].16b, @dat[6].16b, @tweak[6].16b ++ eor @dat[7].16b, @dat[7].16b, @tweak[7].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &enc_4blks(@dat[4],@dat[5],@dat[6],@dat[7]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &rev32(@dat[4],@dat[4]); ++ &rev32(@dat[5],@dat[5]); ++ &rev32(@dat[6],@dat[6]); ++ &rev32(@dat[7],@dat[7]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b ++ eor @dat[4].16b, @dat[4].16b, @tweak[4].16b ++ eor @dat[5].16b, @dat[5].16b, @tweak[5].16b ++ eor @dat[6].16b, @dat[6].16b, @tweak[6].16b ++ eor @dat[7].16b, @dat[7].16b, @tweak[7].16b ++ ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[7].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ st1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$out],#64 ++ subs $blocks,$blocks,#8 ++ b.eq 100f ++ b 1b ++2: ++ // process 4 blocks ++ cmp $blocks,#4 ++ b.lt 1f ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++ &rbit(@tweak[3],@tweak[3]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &rev32(@dat[3],@dat[3]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64 ++ sub $blocks,$blocks,#4 ++ mov @tweak[0].16b,@tweak[4].16b ++ mov @tweak[1].16b,@tweak[5].16b ++ mov @tweak[2].16b,@tweak[6].16b ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[3].16b ++1: ++ // process last block ++ cmp $blocks,#1 ++ b.lt 100f ++ b.gt 1f ++ ld1 {@dat[0].4s},[$inp],#16 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ st1 {@dat[0].4s},[$out],#16 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[0].16b ++ b 100f ++1: // process last 2 blocks ++ cmp $blocks,#2 ++ b.gt 1f ++ ld1 {@dat[0].4s,@dat[1].4s},[$inp],#32 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ st1 {@dat[0].4s,@dat[1].4s},[$out],#32 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[1].16b ++ b 100f ++1: // process last 3 blocks ++ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s},[$inp],#48 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]); ++ &rev32(@dat[0],@dat[0]); ++ &rev32(@dat[1],@dat[1]); ++ &rev32(@dat[2],@dat[2]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b ++ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b ++ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b ++ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s},[$out],#48 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[2].16b ++100: ++ cmp $remain,0 ++ b.eq 99f ++ ++// This brance calculates the last two tweaks, ++// while the encryption/decryption length is larger than 32 ++.last_2blks_tweak${standard}: ++___ ++ &rev32_armeb($lastTweak,$lastTweak); ++ &compute_tweak_vec($lastTweak,@tweak[1],$vTmp0,$vTmp1,$vMagic); ++ &compute_tweak_vec(@tweak[1],@tweak[2],$vTmp0,$vTmp1,$vMagic); ++$code.=<<___; ++ b .check_dec${standard} ++ ++ ++// This brance calculates the last two tweaks, ++// while the encryption/decryption length is less than 32, who only need two tweaks ++.only_2blks_tweak${standard}: ++ mov @tweak[1].16b,@tweak[0].16b ++___ ++ &rev32_armeb(@tweak[1],@tweak[1]); ++ &compute_tweak_vec(@tweak[1],@tweak[2],$vTmp0,$vTmp1,$vMagic); ++$code.=<<___; ++ b .check_dec${standard} ++ ++ ++// Determine whether encryption or decryption is required. ++// The last two tweaks need to be swapped for decryption. ++.check_dec${standard}: ++ // encryption:1 decryption:0 ++ cmp $enc,1 ++ b.eq .prcess_last_2blks${standard} ++ mov $vTmp0.16B,@tweak[1].16b ++ mov @tweak[1].16B,@tweak[2].16b ++ mov @tweak[2].16B,$vTmp0.16b ++ ++.prcess_last_2blks${standard}: ++___ ++ &rev32_armeb(@tweak[1],@tweak[1]); ++ &rev32_armeb(@tweak[2],@tweak[2]); ++$code.=<<___; ++ ld1 {@dat[0].4s},[$inp],#16 ++ eor @dat[0].16b, @dat[0].16b, @tweak[1].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[1].16b ++ st1 {@dat[0].4s},[$out],#16 ++ ++ sub $lastBlk,$out,16 ++ .loop${standard}: ++ subs $remain,$remain,1 ++ ldrb w$tmp0,[$lastBlk,$remain] ++ ldrb w$tmp1,[$inp,$remain] ++ strb w$tmp1,[$lastBlk,$remain] ++ strb w$tmp0,[$out,$remain] ++ b.gt .loop${standard} ++ ld1 {@dat[0].4s}, [$lastBlk] ++ eor @dat[0].16b, @dat[0].16b, @tweak[2].16b ++___ ++ &rev32(@dat[0],@dat[0]); ++ &enc_blk(@dat[0]); ++ &rev32(@dat[0],@dat[0]); ++$code.=<<___; ++ eor @dat[0].16b, @dat[0].16b, @tweak[2].16b ++ st1 {@dat[0].4s}, [$lastBlk] ++99: ++ ret ++.size ${prefix}_xts_do_cipher${standard},.-${prefix}_xts_do_cipher${standard} ++___ ++} #end of gen_xts_do_cipher ++ ++}}} ++ ++{{{ ++my ($enc)=("w6"); ++ ++sub gen_xts_cipher() { ++ my $en = shift; ++$code.=<<___; ++.globl ${prefix}_xts_${en}crypt${standard} ++.type ${prefix}_xts_${en}crypt${standard},%function ++.align 5 ++${prefix}_xts_${en}crypt${standard}: ++ stp x15, x16, [sp, #-0x10]! ++ stp x17, x18, [sp, #-0x10]! ++ stp x19, x20, [sp, #-0x10]! ++ stp x21, x22, [sp, #-0x10]! ++ stp x23, x24, [sp, #-0x10]! ++ stp x25, x26, [sp, #-0x10]! ++ stp x27, x28, [sp, #-0x10]! ++ stp x29, x30, [sp, #-0x10]! ++ stp d8, d9, [sp, #-0x10]! ++ stp d10, d11, [sp, #-0x10]! ++ stp d12, d13, [sp, #-0x10]! ++ stp d14, d15, [sp, #-0x10]! ++___ ++ &mov_en_to_enc($en,$enc); ++$code.=<<___; ++ bl ${prefix}_xts_do_cipher${standard} ++ ldp d14, d15, [sp], #0x10 ++ ldp d12, d13, [sp], #0x10 ++ ldp d10, d11, [sp], #0x10 ++ ldp d8, d9, [sp], #0x10 ++ ldp x29, x30, [sp], #0x10 ++ ldp x27, x28, [sp], #0x10 ++ ldp x25, x26, [sp], #0x10 ++ ldp x23, x24, [sp], #0x10 ++ ldp x21, x22, [sp], #0x10 ++ ldp x19, x20, [sp], #0x10 ++ ldp x17, x18, [sp], #0x10 ++ ldp x15, x16, [sp], #0x10 ++ ret ++.size ${prefix}_xts_${en}crypt${standard},.-${prefix}_xts_${en}crypt${standard} ++___ ++ ++} # end of gen_xts_cipher ++$standard="_gb"; ++&gen_xts_do_cipher(); ++&gen_xts_cipher("en"); ++&gen_xts_cipher("de"); ++$standard=""; ++&gen_xts_do_cipher(); ++&gen_xts_cipher("en"); ++&gen_xts_cipher("de"); ++}}} + ######################################## + { my %opcode = ( + "sm4e" => 0xcec08400, +diff --git a/include/crypto/sm4_platform.h b/include/crypto/sm4_platform.h +index 2f5a6cf..0bde96f 100644 +--- a/include/crypto/sm4_platform.h ++++ b/include/crypto/sm4_platform.h +@@ -26,6 +26,10 @@ + # define HWSM4_cbc_encrypt sm4_v8_cbc_encrypt + # define HWSM4_ecb_encrypt sm4_v8_ecb_encrypt + # define HWSM4_ctr32_encrypt_blocks sm4_v8_ctr32_encrypt_blocks ++# define HWSM4_xts_encrypt_gb sm4_v8_xts_encrypt_gb ++# define HWSM4_xts_decrypt_gb sm4_v8_xts_decrypt_gb ++# define HWSM4_xts_encrypt sm4_v8_xts_encrypt ++# define HWSM4_xts_decrypt sm4_v8_xts_decrypt + # endif + # endif + # endif /* OPENSSL_CPUID_OBJ */ +@@ -46,6 +50,16 @@ void HWSM4_ecb_encrypt(const unsigned char *in, unsigned char *out, + void HWSM4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + const unsigned char ivec[16]); ++/* xts mode in GB/T 17964-2021 */ ++void HWSM4_xts_encrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void HWSM4_xts_decrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++/* xts mode in IEEE Std 1619-2007 */ ++void HWSM4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void HWSM4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); + # endif /* HWSM4_CAPABLE */ + + #ifdef VPSM4_EX_CAPABLE +-- +2.36.1 + diff --git a/Feature-Support-TLCP-protocol.patch b/Feature-Support-TLCP-protocol.patch new file mode 100644 index 0000000000000000000000000000000000000000..b510e6dbddd710cbc365623b4ff11c4ed405009d --- /dev/null +++ b/Feature-Support-TLCP-protocol.patch @@ -0,0 +1,6353 @@ +From 897ef4d611facba29cde86fac6d161984d524da4 Mon Sep 17 00:00:00 2001 +From: s_c_c +Date: Mon, 27 Jun 2022 10:28:38 +0800 +Subject: [PATCH] Support TLCP protocol + +TLCP_method(), TLCP_server_method(), TLCP_client_method() are the GM version-specific methods for TLCP protocol. +Valid TLCP ciphersuite names are ECDHE-SM4-CBC-SM3 and ECC-SM4-CBC-SM3. Additionally enable-tlcp(argument to Configure) was required. +--- + Configure | 7 +- + apps/s_client.c | 60 +- + crypto/dh/dh_err.c | 8 +- + crypto/dsa/dsa_err.c | 8 +- + crypto/err/openssl.txt | 34 +- + crypto/evp/evp_err.c | 6 +- + crypto/evp/p_lib.c | 18 + + crypto/rsa/rsa_err.c | 23 +- + crypto/sm2/build.info | 2 +- + crypto/sm2/sm2_err.c | 4 +- + crypto/sm2/sm2_kep.c | 254 ++++++ + crypto/sm2/sm2_pmeth.c | 4 + + doc/man1/s_client.pod | 9 + + doc/man3/EVP_PKEY_set1_RSA.pod | 9 +- + doc/man3/SSL_CTX_new.pod | 19 +- + doc/man3/SSL_CTX_set_options.pod | 4 +- + doc/man3/SSL_CTX_use_certificate.pod | 56 +- + doc/man7/ssl.pod | 40 + + include/crypto/sm2.h | 1 + + include/crypto/sm2err.h | 12 +- + include/openssl/dherr.h | 15 +- + include/openssl/dsaerr.h | 18 +- + include/openssl/evp.h | 4 + + include/openssl/evperr.h | 17 +- + include/openssl/rsaerr.h | 32 +- + include/openssl/sm2.h | 20 + + include/openssl/ssl.h | 71 ++ + include/openssl/sslerr.h | 33 +- + include/openssl/tls1.h | 20 + + include/openssl/x509.h | 4 + + include/openssl/x509err.h | 4 +- + ssl/methods.c | 36 + + ssl/record/ssl3_record.c | 4 + + ssl/s3_lib.c | 126 +++ + ssl/ssl_asn1.c | 3 +- + ssl/ssl_cert.c | 18 + + ssl/ssl_cert_table.h | 6 +- + ssl/ssl_ciph.c | 46 +- + ssl/ssl_err.c | 54 +- + ssl/ssl_lib.c | 81 +- + ssl/ssl_local.h | 69 +- + ssl/ssl_rsa.c | 541 +++++++++++++ + ssl/ssl_sess.c | 3 + + ssl/ssl_stat.c | 28 + + ssl/statem/extensions.c | 6 +- + ssl/statem/extensions_clnt.c | 3 + + ssl/statem/extensions_srvr.c | 6 +- + ssl/statem/statem.c | 4 + + ssl/statem/statem_clnt.c | 434 ++++++++++ + ssl/statem/statem_lib.c | 182 ++++- + ssl/statem/statem_srvr.c | 445 ++++++++++- + ssl/t1_enc.c | 84 ++ + ssl/t1_lib.c | 130 ++- + test/build.info | 6 +- + test/ciphername_test.c | 3 + + test/recipes/85-test_tlcp.t | 34 + + .../85-test_tlcp_data/ecdsa-client-cert.pem | 12 + + .../85-test_tlcp_data/ecdsa-client-key.pem | 5 + + .../85-test_tlcp_data/ecdsa-root-cert.pem | 14 + + .../85-test_tlcp_data/ecdsa-server-cert.pem | 12 + + .../85-test_tlcp_data/ecdsa-server-key.pem | 5 + + .../85-test_tlcp_data/sm2-client-enc-cert.pem | 12 + + .../85-test_tlcp_data/sm2-client-enc-key.pem | 5 + + .../85-test_tlcp_data/sm2-client-sig-cert.pem | 12 + + .../85-test_tlcp_data/sm2-client-sig-key.pem | 5 + + .../85-test_tlcp_data/sm2-root-cert.pem | 14 + + .../85-test_tlcp_data/sm2-server-enc-cert.pem | 12 + + .../85-test_tlcp_data/sm2-server-enc-key.pem | 5 + + .../85-test_tlcp_data/sm2-server-sig-cert.pem | 12 + + .../85-test_tlcp_data/sm2-server-sig-key.pem | 5 + + test/sm2_internal_test.c | 111 +++ + test/tlcptest.c | 746 ++++++++++++++++++ + util/libcrypto.num | 2 + + util/libssl.num | 17 + + 74 files changed, 4065 insertions(+), 109 deletions(-) + create mode 100644 crypto/sm2/sm2_kep.c + create mode 100644 include/openssl/sm2.h + create mode 100644 test/recipes/85-test_tlcp.t + create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-client-key.pem + create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/ecdsa-server-key.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-root-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem + create mode 100644 test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem + create mode 100644 test/tlcptest.c + +diff --git a/Configure b/Configure +index 4236e6c..a41c897 100755 +--- a/Configure ++++ b/Configure +@@ -425,6 +425,7 @@ my @disablables = ( + "stdio", + "tests", + "threads", ++ "tlcp", + "tls", + "ts", + "ubsan", +@@ -469,6 +470,7 @@ our %disabled = ( # "what" => "comment" + "ssl-trace" => "default", + "ssl3" => "default", + "ssl3-method" => "default", ++ "tlcp" => "default", + "ubsan" => "default", + "unit-test" => "default", + "weak-ssl-ciphers" => "default", +@@ -512,8 +514,9 @@ my @disable_cascades = ( + "apps" => [ "tests" ], + "tests" => [ "external-tests" ], + "comp" => [ "zlib" ], +- "ec" => [ "tls1_3", "sm2" ], +- "sm3" => [ "sm2" ], ++ "ec" => [ "tls1_3", "sm2", "tlcp" ], ++ "sm3" => [ "sm2", "tlcp" ], ++ "sm2" => [ "tlcp" ], + sub { !$disabled{"unit-test"} } => [ "heartbeats" ], + + sub { !$disabled{"msan"} } => [ "asm" ], +diff --git a/apps/s_client.c b/apps/s_client.c +index 121cd14..a41f98a 100644 +--- a/apps/s_client.c ++++ b/apps/s_client.c +@@ -578,6 +578,7 @@ typedef enum OPTION_choice { + OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, OPT_SRP_LATEUSER, + OPT_SRP_MOREGROUPS, + #endif ++ OPT_TLCP, OPT_DCERT, OPT_DKEY, OPT_DPASS, + OPT_SSL3, OPT_SSL_CONFIG, + OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, + OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, +@@ -738,6 +739,12 @@ const OPTIONS s_client_options[] = { + #ifndef OPENSSL_NO_TLS1_3 + {"tls1_3", OPT_TLS1_3, '-', "Just use TLSv1.3"}, + #endif ++#ifndef OPENSSL_NO_TCLP ++ {"tlcp", OPT_TLCP, '-', "Just use TLCP"}, ++ {"dcert", OPT_DCERT, '<', "Encryption certificate file to use (usually for TLCP)"}, ++ {"dkey", OPT_DKEY, '<', "Encryption private key file to use (usually for TLCP)"}, ++ {"dpass", OPT_DPASS, 's', "Encryption private key file pass phrase source"}, ++#endif + #ifndef OPENSSL_NO_DTLS + {"dtls", OPT_DTLS, '-', "Use any version of DTLS"}, + {"timeout", OPT_TIMEOUT, '-', +@@ -836,7 +843,7 @@ static const OPT_PAIR services[] = { + + #define IS_PROT_FLAG(o) \ + (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ +- || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) ++ || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 || o == OPT_TLCP) + + /* Free |*dest| and optionally set it to a copy of |source|. */ + static void freeandcopy(char **dest, const char *source) +@@ -982,6 +989,10 @@ int s_client_main(int argc, char **argv) + #ifndef OPENSSL_NO_SCTP + int sctp_label_bug = 0; + #endif ++ char *s_dcert_file = NULL, *s_dkey_file = NULL; ++ char *dpassarg = NULL, *dpass = NULL; ++ X509 *s_dcert = NULL; ++ EVP_PKEY *s_dkey = NULL; + + FD_ZERO(&readfds); + FD_ZERO(&writefds); +@@ -1318,6 +1329,14 @@ int s_client_main(int argc, char **argv) + socket_type = SOCK_STREAM; + #ifndef OPENSSL_NO_DTLS + isdtls = 0; ++#endif ++ break; ++ case OPT_TLCP: ++ min_version = TLCP_VERSION; ++ max_version = TLCP_VERSION; ++ socket_type = SOCK_STREAM; ++#ifndef OPENSSL_NO_DTLS ++ isdtls = 0; + #endif + break; + case OPT_DTLS: +@@ -1381,6 +1400,15 @@ int s_client_main(int argc, char **argv) + case OPT_KEY: + key_file = opt_arg(); + break; ++ case OPT_DCERT: ++ s_dcert_file = opt_arg(); ++ break; ++ case OPT_DPASS: ++ dpassarg = opt_arg(); ++ break; ++ case OPT_DKEY: ++ s_dkey_file = opt_arg(); ++ break; + case OPT_RECONNECT: + reconnect = 5; + break; +@@ -1650,7 +1678,7 @@ int s_client_main(int argc, char **argv) + next_proto.data = NULL; + #endif + +- if (!app_passwd(passarg, NULL, &pass, NULL)) { ++ if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } +@@ -1681,6 +1709,26 @@ int s_client_main(int argc, char **argv) + goto end; + } + ++ if (s_dcert_file != NULL) { ++ if (s_dkey_file == NULL) ++ s_dkey_file = s_dcert_file; ++ ++ s_dkey = load_key(s_dkey_file, key_format, 0, dpass, e, ++ "Encrypt certificate private key file"); ++ if (s_dkey == NULL) { ++ ERR_print_errors(bio_err); ++ goto end; ++ } ++ ++ s_dcert = load_cert(s_dcert_file, key_format, ++ "Encrypt server certificate file"); ++ ++ if (s_dcert == NULL) { ++ ERR_print_errors(bio_err); ++ goto end; ++ } ++ } ++ + if (crl_file != NULL) { + X509_CRL *crl; + crl = load_crl(crl_file, crl_format); +@@ -1932,6 +1980,11 @@ int s_client_main(int argc, char **argv) + + if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain)) + goto end; ++ ++ if (s_dcert != NULL) { ++ if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, chain, build_chain)) ++ goto end; ++ } + + if (!noservername) { + tlsextcbp.biodebug = bio_err; +@@ -3146,6 +3199,9 @@ int s_client_main(int argc, char **argv) + EVP_PKEY_free(key); + sk_X509_pop_free(chain, X509_free); + OPENSSL_free(pass); ++ X509_free(s_dcert); ++ EVP_PKEY_free(s_dkey); ++ OPENSSL_free(dpass); + #ifndef OPENSSL_NO_SRP + OPENSSL_free(srp_arg.srppassin); + #endif +diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c +index 9778138..c7ac6ae 100644 +--- a/crypto/dh/dh_err.c ++++ b/crypto/dh/dh_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -26,8 +26,8 @@ static const ERR_STRING_DATA DH_str_functs[] = { + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0), + "dh_cms_set_shared_info"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_COMPUTE_KEY, 0), "DH_compute_key"}, +- {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_KEY, 0), "DH_generate_key"}, +- {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_PARAMETERS_EX, 0), "DH_generate_parameters_ex"}, ++ {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_PARAMETERS_EX, 0), ++ "DH_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_DUP, 0), "DH_meth_dup"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_NEW, 0), "DH_meth_new"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_SET1_NAME, 0), "DH_meth_set1_name"}, +@@ -78,11 +78,11 @@ static const ERR_STRING_DATA DH_str_reasons[] = { + {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"}, ++ {ERR_PACK(ERR_LIB_DH, 0, DH_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), + "not suitable generator"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "no private value"}, +- {ERR_PACK(ERR_LIB_DH, 0, DH_R_NON_FIPS_METHOD), "non FIPS method"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), + "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, +diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c +index d85d221..26210c5 100644 +--- a/crypto/dsa/dsa_err.c ++++ b/crypto/dsa/dsa_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -24,7 +24,8 @@ static const ERR_STRING_DATA DSA_str_functs[] = { + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, 0), "DSA_do_sign"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_VERIFY, 0), "DSA_do_verify"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_KEY, 0), "DSA_generate_key"}, +- {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_PARAMETERS_EX, 0), "DSA_generate_parameters_ex"}, ++ {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_PARAMETERS_EX, 0), ++ "DSA_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_DUP, 0), "DSA_meth_dup"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_NEW, 0), "DSA_meth_new"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_SET1_NAME, 0), "DSA_meth_set1_name"}, +@@ -60,8 +61,9 @@ static const ERR_STRING_DATA DSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY), + "missing private key"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, ++ {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NON_FIPS_DSA_METHOD), ++ "non fips dsa method"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set"}, +- {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NON_FIPS_DSA_METHOD), "non FIPS DSA method"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR), + "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_Q_NOT_PRIME), "q not prime"}, +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index b93cace..3ea4c02 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -1,4 +1,4 @@ +-# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. ++# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + # + # Licensed under the OpenSSL license (the "License"). You may not use + # this file except in compliance with the License. You can obtain a copy +@@ -1102,6 +1102,7 @@ SM2_F_PKEY_SM2_CTRL_STR:110:pkey_sm2_ctrl_str + SM2_F_PKEY_SM2_DIGEST_CUSTOM:114:pkey_sm2_digest_custom + SM2_F_PKEY_SM2_INIT:111:pkey_sm2_init + SM2_F_PKEY_SM2_SIGN:112:pkey_sm2_sign ++SM2_F_SM2_COMPUTE_KEY:116:SM2_compute_key + SM2_F_SM2_COMPUTE_MSG_HASH:100:sm2_compute_msg_hash + SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest + SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest +@@ -1184,7 +1185,7 @@ SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:* + SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\ + ossl_statem_server_post_process_message + SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work +-SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640: ++SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:ossl_statem_server_pre_work + SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message + SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition + SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\ +@@ -1270,6 +1271,10 @@ SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH:551:\ + SSL_F_SSL_CTX_USE_CERTIFICATE:171:SSL_CTX_use_certificate + SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1:172:SSL_CTX_use_certificate_ASN1 + SSL_F_SSL_CTX_USE_CERTIFICATE_FILE:173:SSL_CTX_use_certificate_file ++SSL_F_SSL_CTX_USE_GM_CERTIFICATE:641:SSL_CTX_use_gm_certificate ++SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1:642:SSL_CTX_use_gm_certificate_ASN1 ++SSL_F_SSL_CTX_USE_GM_PRIVATEKEY:643:SSL_CTX_use_gm_PrivateKey ++SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1:644:SSL_CTX_use_gm_PrivateKey_ASN1 + SSL_F_SSL_CTX_USE_PRIVATEKEY:174:SSL_CTX_use_PrivateKey + SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1:175:SSL_CTX_use_PrivateKey_ASN1 + SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE:176:SSL_CTX_use_PrivateKey_file +@@ -1296,7 +1301,9 @@ SSL_F_SSL_GET_SIGN_PKEY:183:* + SSL_F_SSL_HANDSHAKE_HASH:560:ssl_handshake_hash + SSL_F_SSL_INIT_WBIO_BUFFER:184:ssl_init_wbio_buffer + SSL_F_SSL_KEY_UPDATE:515:SSL_key_update ++SSL_F_SSL_LOAD_CERT_FILE:645:ssl_load_cert_file + SSL_F_SSL_LOAD_CLIENT_CA_FILE:185:SSL_load_client_CA_file ++SSL_F_SSL_LOAD_PKEY_FILE:646:ssl_load_pkey_file + SSL_F_SSL_LOG_MASTER_SECRET:498:* + SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE:499:ssl_log_rsa_client_key_exchange + SSL_F_SSL_MODULE_INIT:392:ssl_module_init +@@ -1330,11 +1337,14 @@ SSL_F_SSL_SET_CERT_AND_KEY:621:ssl_set_cert_and_key + SSL_F_SSL_SET_CIPHER_LIST:271:SSL_set_cipher_list + SSL_F_SSL_SET_CT_VALIDATION_CALLBACK:399:SSL_set_ct_validation_callback + SSL_F_SSL_SET_FD:192:SSL_set_fd ++SSL_F_SSL_SET_GM_CERT_AND_KEY:647:ssl_set_gm_cert_and_key + SSL_F_SSL_SET_PKEY:193:ssl_set_pkey + SSL_F_SSL_SET_RFD:194:SSL_set_rfd + SSL_F_SSL_SET_SESSION:195:SSL_set_session + SSL_F_SSL_SET_SESSION_ID_CONTEXT:218:SSL_set_session_id_context + SSL_F_SSL_SET_SESSION_TICKET_EXT:294:SSL_set_session_ticket_ext ++SSL_F_SSL_SET_SIGN_ENC_CERT:648:ssl_set_sign_enc_cert ++SSL_F_SSL_SET_SIGN_ENC_PKEY:649:ssl_set_sign_enc_pkey + SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH:550:SSL_set_tlsext_max_fragment_length + SSL_F_SSL_SET_WFD:196:SSL_set_wfd + SSL_F_SSL_SHUTDOWN:224:SSL_shutdown +@@ -1345,6 +1355,10 @@ SSL_F_SSL_UNDEFINED_VOID_FUNCTION:244:ssl_undefined_void_function + SSL_F_SSL_USE_CERTIFICATE:198:SSL_use_certificate + SSL_F_SSL_USE_CERTIFICATE_ASN1:199:SSL_use_certificate_ASN1 + SSL_F_SSL_USE_CERTIFICATE_FILE:200:SSL_use_certificate_file ++SSL_F_SSL_USE_GM_CERTIFICATE:650:SSL_use_gm_certificate ++SSL_F_SSL_USE_GM_CERTIFICATE_ASN1:651:SSL_use_gm_certificate_ASN1 ++SSL_F_SSL_USE_GM_PRIVATEKEY:652:SSL_use_gm_PrivateKey ++SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1:653:SSL_use_gm_PrivateKey_ASN1 + SSL_F_SSL_USE_PRIVATEKEY:201:SSL_use_PrivateKey + SSL_F_SSL_USE_PRIVATEKEY_ASN1:202:SSL_use_PrivateKey_ASN1 + SSL_F_SSL_USE_PRIVATEKEY_FILE:203:SSL_use_PrivateKey_file +@@ -1361,6 +1375,20 @@ SSL_F_SSL_WRITE_EARLY_FINISH:527:* + SSL_F_SSL_WRITE_EX:433:SSL_write_ex + SSL_F_SSL_WRITE_INTERNAL:524:ssl_write_internal + SSL_F_STATE_MACHINE:353:state_machine ++SSL_F_TLCP_CHOOSE_SIGALG:662:tlcp_choose_sigalg ++SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE:663:tlcp_construct_cke_sm2dhe ++SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC:658:tlcp_construct_cke_sm2ecc ++SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE:654:tlcp_construct_client_key_exchange ++SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE:655:tlcp_construct_server_key_exchange ++SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE:664:tlcp_construct_ske_sm2dhe ++SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC:659:tlcp_construct_ske_sm2ecc ++SSL_F_TLCP_DERIVE:665:tlcp_derive ++SSL_F_TLCP_PROCESS_CKE_SM2DHE:666:tlcp_process_cke_sm2dhe ++SSL_F_TLCP_PROCESS_CKE_SM2ECC:660:tlcp_process_cke_sm2ecc ++SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE:656:tlcp_process_client_key_exchange ++SSL_F_TLCP_PROCESS_KEY_EXCHANGE:657:tlcp_process_key_exchange ++SSL_F_TLCP_PROCESS_SKE_SM2DHE:667:tlcp_process_ske_sm2dhe ++SSL_F_TLCP_PROCESS_SKE_SM2ECC:661:tlcp_process_ske_sm2ecc + SSL_F_TLS12_CHECK_PEER_SIGALG:333:tls12_check_peer_sigalg + SSL_F_TLS12_COPY_SIGALGS:533:tls12_copy_sigalgs + SSL_F_TLS13_CHANGE_CIPHER_STATE:440:tls13_change_cipher_state +@@ -1769,7 +1797,7 @@ X509_F_X509_STORE_NEW:158:X509_STORE_new + X509_F_X509_TO_X509_REQ:126:X509_to_X509_REQ + X509_F_X509_TRUST_ADD:133:X509_TRUST_add + X509_F_X509_TRUST_SET:141:X509_TRUST_set +-X509_F_X509_VERIFY:161:X509_verify ++X509_F_X509_VERIFY:166:X509_verify + X509_F_X509_VERIFY_CERT:127:X509_verify_cert + X509_F_X509_VERIFY_PARAM_NEW:159:X509_VERIFY_PARAM_new + X509_F_X509_VERIFY_SM2:162:x509_verify_sm2 +diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c +index daf7fdc..e3c9e05 100644 +--- a/crypto/evp/evp_err.c ++++ b/crypto/evp/evp_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -187,7 +187,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { + "different key types"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), + "different parameters"}, +- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DISABLED_FOR_FIPS), "disabled for FIPS"}, ++ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DISABLED_FOR_FIPS), "disabled for fips"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION), + "error loading section"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_SETTING_FIPS_MODE), +@@ -279,8 +279,6 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { + "wrap mode not allowed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH), + "wrong final block length"}, +- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE), +- "xts data unit is too large"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS), + "xts duplicated keys"}, + {0, NULL} +diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c +index 1f36cb2..9e25ae1 100644 +--- a/crypto/evp/p_lib.c ++++ b/crypto/evp/p_lib.c +@@ -459,6 +459,24 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len) + } + #endif + ++# ifndef OPENSSL_NO_SM2 ++int EVP_PKEY_is_sm2(EVP_PKEY *pkey) ++{ ++ EC_KEY *eckey; ++ const EC_GROUP *group; ++ if (pkey == NULL) { ++ return 0; ++ } ++ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC ++ && (eckey = EVP_PKEY_get0_EC_KEY(pkey)) != NULL ++ && (group = EC_KEY_get0_group(eckey)) != NULL ++ && EC_GROUP_get_curve_name(group) == NID_sm2) { ++ return 1; ++ } ++ return EVP_PKEY_id(pkey) == EVP_PKEY_SM2; ++} ++# endif ++ + #ifndef OPENSSL_NO_RSA + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) + { +diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c +index cf43265..888fd07 100644 +--- a/crypto/rsa/rsa_err.c ++++ b/crypto/rsa/rsa_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -34,7 +34,8 @@ static const ERR_STRING_DATA RSA_str_functs[] = { + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_KEY_EX, 0), "RSA_generate_key_ex"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_KEY_EX, 0), ++ "RSA_generate_key_ex"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_MULTI_PRIME_KEY, 0), + "RSA_generate_multi_prime_key"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, +@@ -93,16 +94,21 @@ static const ERR_STRING_DATA RSA_str_functs[] = { + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, 0), ++ "RSA_private_decrypt"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, 0), ++ "RSA_private_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, 0), "RSA_private_decrypt"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, 0), "RSA_private_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_DECRYPT, 0), "RSA_public_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_ENCRYPT, 0), "RSA_public_encrypt"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_DEFAULT_METHOD, 0), ++ "RSA_set_default_method"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_METHOD, 0), "RSA_set_method"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), + "RSA_sign_ASN1_OCTET_STRING"}, +@@ -111,8 +117,6 @@ static const ERR_STRING_DATA RSA_str_functs[] = { + "RSA_verify_ASN1_OCTET_STRING"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), + "RSA_verify_PKCS1_PSS_mgf1"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_DEFAULT_METHOD, 0), "RSA_set_default_method"}, +- {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_METHOD, 0), "RSA_set_method"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, + {0, NULL} + }; +@@ -193,8 +197,9 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D), + "mp exponent not congruent to d"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime"}, ++ {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NON_FIPS_RSA_METHOD), ++ "non fips rsa method"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, +- {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NON_FIPS_RSA_METHOD), "non FIPS rsa method"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), + "null before block missing"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), +@@ -204,7 +209,7 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), + "oaep decoding error"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), +- "operation not allowed in FIPS mode"}, ++ "operation not allowed in fips mode"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), +diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info +index be76d96..adaf5f3 100644 +--- a/crypto/sm2/build.info ++++ b/crypto/sm2/build.info +@@ -1,5 +1,5 @@ + LIBS=../../libcrypto + SOURCE[../../libcrypto]=\ +- sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c ++ sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c sm2_kep.c + + +diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c +index e5973e9..f5f75cb 100644 +--- a/crypto/sm2/sm2_err.c ++++ b/crypto/sm2/sm2_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -21,6 +21,7 @@ static const ERR_STRING_DATA SM2_str_functs[] = { + "pkey_sm2_digest_custom"}, + {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"}, + {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"}, ++ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_KEY, 0), "SM2_compute_key"}, + {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0), + "sm2_compute_msg_hash"}, + {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0), +@@ -51,6 +52,7 @@ static const ERR_STRING_DATA SM2_str_reasons[] = { + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"}, ++ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PRIVATE_VALUE), "no private value"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"}, + {0, NULL} + }; +diff --git a/crypto/sm2/sm2_kep.c b/crypto/sm2/sm2_kep.c +new file mode 100644 +index 0000000..a7bd681 +--- /dev/null ++++ b/crypto/sm2/sm2_kep.c +@@ -0,0 +1,254 @@ ++/* ++ * Copyright 2019 The BabaSSL Project Authors. All Rights Reserved. ++ */ ++ ++#include "internal/cryptlib.h" ++#include ++#include ++#include ++#include "crypto/sm2.h" ++#include "crypto/ec.h" /* ecdh_KDF_X9_63() */ ++#include "crypto/sm2err.h" ++ ++ ++#ifndef OPENSSL_NO_SM2 ++int SM2_compute_key(void *out, size_t outlen, int server, ++ const char *peer_uid, int peer_uid_len, ++ const char *self_uid, int self_uid_len, ++ const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, ++ const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, ++ const EVP_MD *md) ++{ ++ BN_CTX *ctx = NULL; ++ EC_POINT *UorV = NULL; ++ const EC_POINT *Rs, *Rp; ++ BIGNUM *Xs = NULL, *Xp = NULL, *h = NULL, *t = NULL, *two_power_w = NULL, *order = NULL; ++ const BIGNUM *priv_key, *r; ++ const EC_GROUP *group; ++ int w; ++ int ret = -1; ++ size_t buflen, len; ++ unsigned char *buf = NULL; ++ size_t elemet_len, idx; ++ ++ if (outlen > INT_MAX) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ if (peer_pub_key == NULL || self_eckey == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, SM2_R_NO_PRIVATE_VALUE); ++ goto err; ++ } ++ ++ priv_key = EC_KEY_get0_private_key(self_eckey); ++ if (priv_key == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, SM2_R_NO_PRIVATE_VALUE); ++ goto err; ++ } ++ ++ if (peer_ecdhe_key == NULL || self_ecdhe_key == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_PASSED_NULL_PARAMETER); ++ goto err; ++ } ++ ++ Rs = EC_KEY_get0_public_key(self_ecdhe_key); ++ Rp = EC_KEY_get0_public_key(peer_ecdhe_key); ++ r = EC_KEY_get0_private_key(self_ecdhe_key); ++ ++ if (Rs == NULL || Rp == NULL || r == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_PASSED_NULL_PARAMETER); ++ goto err; ++ } ++ ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ BN_CTX_start(ctx); ++ Xs = BN_CTX_get(ctx); ++ Xp = BN_CTX_get(ctx); ++ h = BN_CTX_get(ctx); ++ t = BN_CTX_get(ctx); ++ two_power_w = BN_CTX_get(ctx); ++ order = BN_CTX_get(ctx); ++ ++ if (order == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ group = EC_KEY_get0_group(self_eckey); ++ ++ if (!EC_GROUP_get_order(group, order, ctx) ++ || !EC_GROUP_get_cofactor(group, h, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ w = (BN_num_bits(order) + 1) / 2 - 1; ++ if (!BN_lshift(two_power_w, BN_value_one(), w)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ /*Third: Caculate -- X = 2 ^ w + (x & (2 ^ w - 1)) = 2 ^ w + (x mod 2 ^ w)*/ ++ UorV = EC_POINT_new(group); ++ if (UorV == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ /*Test peer public key On curve*/ ++ if (!EC_POINT_is_on_curve(group, Rp, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ /*Get x*/ ++ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ++ == NID_X9_62_prime_field) { ++ if (!EC_POINT_get_affine_coordinates_GFp(group, Rs, Xs, NULL, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ if (!EC_POINT_get_affine_coordinates_GFp(group, Rp, Xp, NULL, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ } ++ ++ /*x mod 2 ^ w*/ ++ /*Caculate Self x*/ ++ if (!BN_nnmod(Xs, Xs, two_power_w, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ if (!BN_add(Xs, Xs, two_power_w)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ /*Caculate Peer x*/ ++ if (!BN_nnmod(Xp, Xp, two_power_w, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ if (!BN_add(Xp, Xp, two_power_w)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ /*Forth: Caculate t*/ ++ if (!BN_mod_mul(t, Xs, r, order, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ if (!BN_mod_add(t, t, priv_key, order, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ /*Fifth: Caculate V or U*/ ++ if (!BN_mul(t, t, h, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_BN_LIB); ++ goto err; ++ } ++ ++ /* [x]R */ ++ if (!EC_POINT_mul(group, UorV, NULL, Rp, Xp, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ /* P + [x]R */ ++ if (!EC_POINT_add(group, UorV, UorV, ++ EC_KEY_get0_public_key(peer_pub_key), ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ if (!EC_POINT_mul(group, UorV, NULL, UorV, t, ctx)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ if (EC_POINT_is_at_infinity(group, UorV)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ /*Sixth: Caculate Key -- Need Xuorv, Yuorv, Zc, Zs, klen*/ ++ ++ elemet_len = (size_t)((EC_GROUP_get_degree(group) + 7) / 8); ++ buflen = elemet_len * 2 + 32 * 2 + 1; /*add 1 byte tag*/ ++ buf = (unsigned char *)OPENSSL_zalloc(buflen + 10); ++ if (buf == NULL) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ /*1 : Get public key for UorV, Notice: the first byte is a tag, not a valid char*/ ++ idx = EC_POINT_point2oct(group, UorV, 4, buf, buflen, ctx); ++ if (!idx) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ len = EVP_MD_size(md); ++ ++ /* Z_A || Z_B, server is initiator(Z_A), client is responder(Z_B) */ ++ if (server) { ++ if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, ++ (const uint8_t *)self_uid, ++ self_uid_len, self_eckey)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ idx += len; ++ } ++ ++ if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, ++ (const uint8_t *)peer_uid, peer_uid_len, ++ peer_pub_key)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ idx += len; ++ ++ if (!server) { ++ if (!sm2_compute_z_digest((uint8_t *)(buf + idx), md, ++ (const uint8_t *)self_uid, ++ self_uid_len, self_eckey)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ idx += len; ++ } ++ ++ if (!ecdh_KDF_X9_63(out, outlen, (const unsigned char *)(buf + 1), idx - 1, ++ NULL, 0, md)) { ++ SM2err(SM2_F_SM2_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ ret = outlen; ++ ++ err: ++ EC_POINT_free(UorV); ++ OPENSSL_free(buf); ++ if (ctx != NULL) ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ ++ return ret; ++} ++ ++#endif +diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c +index 9551d70..1998812 100644 +--- a/crypto/sm2/sm2_pmeth.c ++++ b/crypto/sm2/sm2_pmeth.c +@@ -287,6 +287,10 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) + const EVP_MD *md = EVP_MD_CTX_md(mctx); + int mdlen = EVP_MD_size(md); + ++ if (!smctx->id_set) ++ (void)pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, SM2_DEFAULT_USERID_LEN ++ , (void *)SM2_DEFAULT_USERID); ++ + if (!smctx->id_set) { + /* + * An ID value must be set. The specifications are not clear whether a +diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod +index f1a2c4a..8fa82a1 100644 +--- a/doc/man1/s_client.pod ++++ b/doc/man1/s_client.pod +@@ -20,8 +20,10 @@ B B + [B<-verify depth>] + [B<-verify_return_error>] + [B<-cert filename>] ++[B<-dcert filename>] + [B<-certform DER|PEM>] + [B<-key filename>] ++[B<-dkey filename>] + [B<-keyform DER|PEM>] + [B<-cert_chain filename>] + [B<-build_chain>] +@@ -32,6 +34,7 @@ B B + [B<-xcertform PEM|DER>] + [B<-xkeyform PEM|DER>] + [B<-pass arg>] ++[B<-dpass arg>] + [B<-CApath directory>] + [B<-CAfile filename>] + [B<-chainCApath directory>] +@@ -91,6 +94,7 @@ B B + [B<-tls1_1>] + [B<-tls1_2>] + [B<-tls1_3>] ++[B<-tlcp>] + [B<-no_ssl3>] + [B<-no_tls1>] + [B<-no_tls1_1>] +@@ -214,6 +218,11 @@ ClientHello message. Cannot be used in conjunction with the B<-servername> or + The certificate to use, if one is requested by the server. The default is + not to use a certificate. + ++=item B<-dcert infile>, B<-dkey infile>, B<-dpass val> ++ ++Specify an encryption certificate, private key and passphrase ++respectively, usually for TLCP. ++ + =item B<-certform format> + + The certificate format to use: DER or PEM. PEM is the default. +diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod +index d571e58..f9ee16d 100644 +--- a/doc/man3/EVP_PKEY_set1_RSA.pod ++++ b/doc/man3/EVP_PKEY_set1_RSA.pod +@@ -9,7 +9,7 @@ EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, + EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH, + EVP_PKEY_get0_hmac, EVP_PKEY_get0_poly1305, EVP_PKEY_get0_siphash, + EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id, EVP_PKEY_set_alias_type, +-EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions ++EVP_PKEY_is_sm2, EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions + + =head1 SYNOPSIS + +@@ -45,6 +45,8 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions + int EVP_PKEY_type(int type); + int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); + ++ int EVP_PKEY_is_sm2(EVP_PKEY *pkey); ++ + ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); + int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine); + +@@ -93,6 +95,9 @@ EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a + different set of algorithms than the default. This is currently used + to support SM2 keys, which use an identical encoding to ECDSA. + ++EVP_PKEY_is_sm2() can be used to determine whether the B is ++SM2 curve. ++ + =head1 NOTES + + In accordance with the OpenSSL naming convention the key obtained +@@ -134,6 +139,8 @@ EVP_PKEY_set1_engine() returns 1 for success and 0 for failure. + + EVP_PKEY_set_alias_type() returns 1 for success and 0 for error. + ++EVP_PKEY_is_sm2() returns 1 for success and 0 for error. ++ + =head1 EXAMPLES + + After loading an ECC key, it is possible to convert it to using SM2 +diff --git a/doc/man3/SSL_CTX_new.pod b/doc/man3/SSL_CTX_new.pod +index a6c036c..23f93f6 100644 +--- a/doc/man3/SSL_CTX_new.pod ++++ b/doc/man3/SSL_CTX_new.pod +@@ -9,7 +9,8 @@ TLSv1_1_method, TLSv1_1_server_method, TLSv1_1_client_method, TLS_method, + TLS_server_method, TLS_client_method, SSLv23_method, SSLv23_server_method, + SSLv23_client_method, DTLS_method, DTLS_server_method, DTLS_client_method, + DTLSv1_method, DTLSv1_server_method, DTLSv1_client_method, +-DTLSv1_2_method, DTLSv1_2_server_method, DTLSv1_2_client_method ++DTLSv1_2_method, DTLSv1_2_server_method, DTLSv1_2_client_method, ++TLCP_method, TLCP_server_method, TLCP_client_method, + - create a new SSL_CTX object as framework for TLS/SSL or DTLS enabled + functions + +@@ -68,6 +69,12 @@ functions + const SSL_METHOD *DTLSv1_2_client_method(void); + #endif + ++ #ifndef OPENSSL_NO_TLCP ++ const SSL_METHOD *TLCP_method(void); ++ const SSL_METHOD *TLCP_server_method(void); ++ const SSL_METHOD *TLCP_client_method(void); ++ #endif ++ + =head1 DESCRIPTION + + SSL_CTX_new() creates a new B object as framework to +@@ -93,6 +100,8 @@ These are the general-purpose I SSL/TLS methods. + The actual protocol version used will be negotiated to the highest version + mutually supported by the client and the server. + The supported protocols are SSLv3, TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3. ++TLS_method() and TLS_server_method() can aslo support TLCP protocol ++by using TLCP_client_method(). + Applications should use these methods, and avoid the version-specific + methods described below, which are deprecated. + +@@ -141,6 +150,12 @@ These methods are deprecated. + These are the version-specific methods for DTLSv1. + These methods are deprecated. + ++=item TLCP_method(), TLCP_server_method(), TLCP_client_method() ++ ++These are the GM version-specific methods for TLCP protocol. ++Valid TLCP ciphersuite names are ECDHE-SM4-CBC-SM3 and ECC-SM4-CBC-SM3. ++B(argument to Configure) was required. ++ + =back + + SSL_CTX_new() initializes the list of ciphers, the session cache setting, the +@@ -162,7 +177,7 @@ allow newer protocols like TLS 1.0, TLS 1.1, TLS 1.2 or TLS 1.3. + + The list of protocols available can also be limited using the + B, B, B, +-B, B and B ++B, B, B and B + options of the + L or L functions, but this approach + is not recommended. Clients should avoid creating "holes" in the set of +diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod +index 969e036..304e966 100644 +--- a/doc/man3/SSL_CTX_set_options.pod ++++ b/doc/man3/SSL_CTX_set_options.pod +@@ -114,11 +114,11 @@ preferences. When not set, the SSL server will always follow the clients + preferences. When set, the SSL/TLS server will choose following its + own preferences. + +-=item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, ++=item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, SSL_OP_NO_TLCP + SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3, SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2 + + These options turn off the SSLv3, TLSv1, TLSv1.1, TLSv1.2 or TLSv1.3 protocol +-versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS, ++versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS, TLCP + respectively. + As of OpenSSL 1.1.0, these options are deprecated, use + L and +diff --git a/doc/man3/SSL_CTX_use_certificate.pod b/doc/man3/SSL_CTX_use_certificate.pod +index b065d8f..7a717e7 100644 +--- a/doc/man3/SSL_CTX_use_certificate.pod ++++ b/doc/man3/SSL_CTX_use_certificate.pod +@@ -12,7 +12,12 @@ SSL_CTX_use_RSAPrivateKey_ASN1, SSL_CTX_use_RSAPrivateKey_file, + SSL_use_PrivateKey_file, SSL_use_PrivateKey_ASN1, SSL_use_PrivateKey, + SSL_use_RSAPrivateKey, SSL_use_RSAPrivateKey_ASN1, + SSL_use_RSAPrivateKey_file, SSL_CTX_check_private_key, SSL_check_private_key, +-SSL_CTX_use_cert_and_key, SSL_use_cert_and_key ++SSL_CTX_use_cert_and_key, SSL_use_cert_and_key, ++SSL_CTX_use_gm_certificate, SSL_CTX_use_gm_certificate_ASN1, SSL_CTX_use_gm_certificate_file, ++SSL_use_gm_certificate, SSL_use_gm_certificate_ASN1, SSL_use_gm_certificate_file, ++SSL_CTX_use_gm_PrivateKey, SSL_CTX_use_gm_PrivateKey_ASN1, SSL_CTX_use_gm_PrivateKey_file, ++SSL_use_gm_PrivateKey, SSL_use_gm_PrivateKey_ASN1, SSL_use_gm_PrivateKey_file, ++SSL_CTX_use_gm_cert_and_key, SSL_use_gm_cert_and_key + - load certificate and key data + + =head1 SYNOPSIS +@@ -26,6 +31,13 @@ SSL_CTX_use_cert_and_key, SSL_use_cert_and_key + int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len); + int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + ++ int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage); ++ int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d, int usage); ++ int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, int type, int usage); ++ int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage); ++ int SSL_use_gm_certificate_ASN1(SSL *ssl, unsigned char *d, int len, int usage); ++ int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage); ++ + int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); + int SSL_use_certificate_chain_file(SSL *ssl, const char *file); + +@@ -43,12 +55,23 @@ SSL_CTX_use_cert_and_key, SSL_use_cert_and_key + int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); + int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); + ++ int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); ++ int SSL_CTX_use_gm_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d, ++ long len, int usage); ++ int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, int type, int usage); ++ int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage); ++ int SSL_use_gm_PrivateKey_ASN1(int pk, SSL *ssl, unsigned char *d, long len, int usage); ++ int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage); ++ + int SSL_CTX_check_private_key(const SSL_CTX *ctx); + int SSL_check_private_key(const SSL *ssl); + + int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); + int SSL_use_cert_and_key(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); + ++ int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); ++ int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); ++ + =head1 DESCRIPTION + + These functions load the certificates and private keys into the SSL_CTX +@@ -81,6 +104,21 @@ SSL_use_certificate_file() loads the certificate from B into B. + See the NOTES section on why SSL_CTX_use_certificate_chain_file() + should be preferred. + ++SSL_CTX_use_gm_certificate() loads the certificate B into B ++and specify B. SSL_use_gm_certificate() loads B into B ++and specify B. The B should be SSL_USAGE_SIG or SSL_USAGE_ENC. ++ ++SSL_CTX_use_gm_certificate_ASN1() loads the ASN1 encoded certificate from ++the memory location B (with length B) into B and specify B, ++SSL_use_gm_certificate_ASN1() loads the ASN1 encoded certificate into B ++and specify B. ++ ++SSL_CTX_use_gm_certificate_file() loads the first certificate stored in B ++into B and specify B. The formatting B of the certificate must ++be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. ++SSL_use_gm_certificate_file() loads the certificate from B into B ++and specify B. ++ + SSL_CTX_use_certificate_chain_file() loads a certificate chain from + B into B. The certificates must be in PEM format and must + be sorted starting with the subject's certificate (actual client or server +@@ -127,6 +165,22 @@ B to B. SSL_use_PrivateKey_file() adds the first private key found + in B to B; SSL_use_RSAPrivateKey_file() adds the first private + RSA key found to B. + ++SSL_CTX_use_gm_PrivateKey() adds B as private key to B and ++specify B. SSL_CTX_use_gm_PrivateKey_ASN1() adds the private key of ++type B stored at memory location B (length B) to B and ++specify B. SSL_CTX_use_gm_PrivateKey_file() adds the first private ++key found in B to B. The formatting B of the private key ++must be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. ++ ++SSL_use_PrivateKey() adds B as private key to B and sprcify B. ++SSL_use_gm_PrivateKey_ASN1() adds the private key to B and sprcify B. ++SSL_use_gm_PrivateKey_file() adds the first private key found in B to B ++and sprcify B. ++ ++SSL_CTX_use_gm_cert_and_key() and SSL_use_gm_cert_and_key() assign the X.509 ++certificate B, private key B, and certificate B onto the ++corresponding B or B and specify B. ++ + SSL_CTX_check_private_key() checks the consistency of a private key with + the corresponding certificate loaded into B. If more than one + key/certificate pair (RSA/DSA) is installed, the last item installed will +diff --git a/doc/man7/ssl.pod b/doc/man7/ssl.pod +index d439860..8d7293a 100644 +--- a/doc/man7/ssl.pod ++++ b/doc/man7/ssl.pod +@@ -183,6 +183,18 @@ Constructor for the SSLv3 SSL_METHOD structure for clients. + + Constructor for the SSLv3 SSL_METHOD structure for servers. + ++=item const SSL_METHOD *B(void); ++ ++Constructor for the TLCP SSL_METHOD structure for clients, servers or both. ++ ++=item const SSL_METHOD *B(void); ++ ++Constructor for the TLCP SSL_METHOD structure for clients. ++ ++=item const SSL_METHOD *B(void); ++ ++Constructor for the TLCP SSL_METHOD structure for servers. ++ + =back + + =head2 Dealing with Ciphers +@@ -393,6 +405,12 @@ Use the file path to locate trusted CA certificates. + + =item int B(SSL_CTX *ctx, const char *file, int type); + ++=item int B(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); ++ ++=item int B(int type, SSL_CTX *ctx, unsigned char *d, long len, int usage); ++ ++=item int B(SSL_CTX *ctx, const char *file, int type, int usage); ++ + =item int B(SSL_CTX *ctx, X509 *x); + + =item int B(SSL_CTX *ctx, int len, unsigned char *d); +@@ -401,6 +419,14 @@ Use the file path to locate trusted CA certificates. + + =item int B(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); + ++=item int B(SSL_CTX *ctx, X509 *x, int usage); ++ ++=item int B(SSL_CTX *ctx, int len, unsigned char *d, int usage); ++ ++=item int B(SSL_CTX *ctx, const char *file, int type, int usage); ++ ++=item int B(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); ++ + =item X509 *B(const SSL_CTX *ctx); + + =item EVP_PKEY *B(const SSL_CTX *ctx); +@@ -704,6 +730,12 @@ Returns the current handshake state. + + =item int B(SSL *ssl, const char *file, int type); + ++=item int B(SSL *ssl, EVP_PKEY *pkey, int usage); ++ ++=item int B(int type, SSL *ssl, unsigned char *d, long len, int usage); ++ ++=item int B(SSL *ssl, const char *file, int type, int usage); ++ + =item int B(SSL *ssl, X509 *x); + + =item int B(SSL *ssl, int len, unsigned char *d); +@@ -712,6 +744,14 @@ Returns the current handshake state. + + =item int B(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override); + ++=item int B(SSL *ssl, X509 *x, int usage); ++ ++=item int B(SSL *ssl, int len, unsigned char *d, int usage); ++ ++=item int B(SSL *ssl, const char *file, int type, int usage); ++ ++=item int B(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override, int usage); ++ + =item int B(const SSL *ssl); + + =item int B(const SSL *ssl); +diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h +index a7f5548..720bdd4 100644 +--- a/include/crypto/sm2.h ++++ b/include/crypto/sm2.h +@@ -19,6 +19,7 @@ + + /* The default user id as specified in GM/T 0009-2012 */ + # define SM2_DEFAULT_USERID "1234567812345678" ++# define SM2_DEFAULT_USERID_LEN 16 + + int sm2_compute_z_digest(uint8_t *out, + const EVP_MD *digest, +diff --git a/include/crypto/sm2err.h b/include/crypto/sm2err.h +index d1c0ee2..251c4f9 100644 +--- a/include/crypto/sm2err.h ++++ b/include/crypto/sm2err.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -8,12 +8,10 @@ + * https://www.openssl.org/source/license.html + */ + +-#ifndef OSSL_CRYPTO_SM2ERR_H +-# define OSSL_CRYPTO_SM2ERR_H ++#ifndef HEADER_SM2ERR_H ++# define HEADER_SM2ERR_H + +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # include + +@@ -33,6 +31,7 @@ int ERR_load_SM2_strings(void); + # define SM2_F_PKEY_SM2_DIGEST_CUSTOM 114 + # define SM2_F_PKEY_SM2_INIT 111 + # define SM2_F_PKEY_SM2_SIGN 112 ++# define SM2_F_SM2_COMPUTE_KEY 116 + # define SM2_F_SM2_COMPUTE_MSG_HASH 100 + # define SM2_F_SM2_COMPUTE_USERID_DIGEST 101 + # define SM2_F_SM2_COMPUTE_Z_DIGEST 113 +@@ -59,6 +58,7 @@ int ERR_load_SM2_strings(void); + # define SM2_R_INVALID_ENCODING 104 + # define SM2_R_INVALID_FIELD 105 + # define SM2_R_NO_PARAMETERS_SET 109 ++# define SM2_R_NO_PRIVATE_VALUE 113 + # define SM2_R_USER_ID_TOO_LARGE 106 + + # endif +diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h +index b2d62eb..e7fdb21 100644 +--- a/include/openssl/dherr.h ++++ b/include/openssl/dherr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -11,9 +11,7 @@ + #ifndef HEADER_DHERR_H + # define HEADER_DHERR_H + +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # include + +@@ -36,9 +34,8 @@ int ERR_load_DH_strings(void); + # define DH_F_DH_CMS_DECRYPT 114 + # define DH_F_DH_CMS_SET_PEERKEY 115 + # define DH_F_DH_CMS_SET_SHARED_INFO 116 +-# define DH_F_DH_COMPUTE_KEY 203 +-# define DH_F_DH_GENERATE_KEY 202 +-# define DH_F_DH_GENERATE_PARAMETERS_EX 201 ++# define DH_F_DH_COMPUTE_KEY 126 ++# define DH_F_DH_GENERATE_PARAMETERS_EX 127 + # define DH_F_DH_METH_DUP 117 + # define DH_F_DH_METH_NEW 118 + # define DH_F_DH_METH_SET1_NAME 119 +@@ -76,14 +73,14 @@ int ERR_load_DH_strings(void); + # define DH_R_INVALID_PARAMETER_NID 114 + # define DH_R_INVALID_PUBKEY 102 + # define DH_R_KDF_PARAMETER_ERROR 112 +-# define DH_R_KEY_SIZE_TOO_SMALL 201 + # define DH_R_KEYS_NOT_SET 108 ++# define DH_R_KEY_SIZE_TOO_SMALL 126 + # define DH_R_MISSING_PUBKEY 125 + # define DH_R_MODULUS_TOO_LARGE 103 ++# define DH_R_NON_FIPS_METHOD 127 + # define DH_R_NOT_SUITABLE_GENERATOR 120 + # define DH_R_NO_PARAMETERS_SET 107 + # define DH_R_NO_PRIVATE_VALUE 100 +-# define DH_R_NON_FIPS_METHOD 202 + # define DH_R_PARAMETER_ENCODING_ERROR 105 + # define DH_R_PEER_KEY_ERROR 111 + # define DH_R_SHARED_INFO_ERROR 113 +diff --git a/include/openssl/dsaerr.h b/include/openssl/dsaerr.h +index 19f650a..83f1b68 100644 +--- a/include/openssl/dsaerr.h ++++ b/include/openssl/dsaerr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -11,9 +11,7 @@ + #ifndef HEADER_DSAERR_H + # define HEADER_DSAERR_H + +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # include + +@@ -29,13 +27,13 @@ int ERR_load_DSA_strings(void); + */ + # define DSA_F_DSAPARAMS_PRINT 100 + # define DSA_F_DSAPARAMS_PRINT_FP 101 +-# define DSA_F_DSA_BUILTIN_KEYGEN 202 ++# define DSA_F_DSA_BUILTIN_KEYGEN 108 + # define DSA_F_DSA_BUILTIN_PARAMGEN 125 + # define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +-# define DSA_F_DSA_GENERATE_KEY 201 +-# define DSA_F_DSA_GENERATE_PARAMETERS_EX 200 + # define DSA_F_DSA_DO_SIGN 112 + # define DSA_F_DSA_DO_VERIFY 113 ++# define DSA_F_DSA_GENERATE_KEY 109 ++# define DSA_F_DSA_GENERATE_PARAMETERS_EX 110 + # define DSA_F_DSA_METH_DUP 127 + # define DSA_F_DSA_METH_NEW 128 + # define DSA_F_DSA_METH_SET1_NAME 129 +@@ -63,13 +61,13 @@ int ERR_load_DSA_strings(void); + # define DSA_R_DECODE_ERROR 104 + # define DSA_R_INVALID_DIGEST_TYPE 106 + # define DSA_R_INVALID_PARAMETERS 112 +-# define DSA_R_KEY_SIZE_INVALID 201 +-# define DSA_R_KEY_SIZE_TOO_SMALL 202 ++# define DSA_R_KEY_SIZE_INVALID 114 ++# define DSA_R_KEY_SIZE_TOO_SMALL 115 + # define DSA_R_MISSING_PARAMETERS 101 + # define DSA_R_MISSING_PRIVATE_KEY 111 + # define DSA_R_MODULUS_TOO_LARGE 103 ++# define DSA_R_NON_FIPS_DSA_METHOD 116 + # define DSA_R_NO_PARAMETERS_SET 107 +-# define DSA_R_NON_FIPS_DSA_METHOD 200 + # define DSA_R_PARAMETER_ENCODING_ERROR 105 + # define DSA_R_Q_NOT_PRIME 113 + # define DSA_R_SEED_LEN_SMALL 110 +diff --git a/include/openssl/evp.h b/include/openssl/evp.h +index 0f7fbd1..3116c1b 100644 +--- a/include/openssl/evp.h ++++ b/include/openssl/evp.h +@@ -1011,6 +1011,10 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); + const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len); + # endif + ++# ifndef OPENSSL_NO_SM2 ++int EVP_PKEY_is_sm2(EVP_PKEY *pkey); ++# endif ++ + # ifndef OPENSSL_NO_RSA + struct rsa_st; + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h +index bfa2e68..da604ca 100644 +--- a/include/openssl/evperr.h ++++ b/include/openssl/evperr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -22,15 +22,15 @@ int ERR_load_EVP_strings(void); + * EVP function codes. + */ + # define EVP_F_AESNI_INIT_KEY 165 +-# define EVP_F_AESNI_XTS_INIT_KEY 233 ++# define EVP_F_AESNI_XTS_INIT_KEY 207 + # define EVP_F_AES_GCM_CTRL 196 + # define EVP_F_AES_INIT_KEY 133 + # define EVP_F_AES_OCB_CIPHER 169 + # define EVP_F_AES_T4_INIT_KEY 178 +-# define EVP_F_AES_T4_XTS_INIT_KEY 234 ++# define EVP_F_AES_T4_XTS_INIT_KEY 208 + # define EVP_F_AES_WRAP_CIPHER 170 +-# define EVP_F_AES_XTS_CIPHER 229 +-# define EVP_F_AES_XTS_INIT_KEY 235 ++# define EVP_F_AES_XTS_CIPHER 210 ++# define EVP_F_AES_XTS_INIT_KEY 209 + # define EVP_F_ALG_MODULE_INIT 177 + # define EVP_F_ARIA_CCM_INIT_KEY 175 + # define EVP_F_ARIA_GCM_CTRL 197 +@@ -141,9 +141,9 @@ int ERR_load_EVP_strings(void); + # define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 + # define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 + # define EVP_R_DECODE_ERROR 114 +-# define EVP_R_DISABLED_FOR_FIPS 200 + # define EVP_R_DIFFERENT_KEY_TYPES 101 + # define EVP_R_DIFFERENT_PARAMETERS 153 ++# define EVP_R_DISABLED_FOR_FIPS 185 + # define EVP_R_ERROR_LOADING_SECTION 165 + # define EVP_R_ERROR_SETTING_FIPS_MODE 166 + # define EVP_R_EXPECTING_AN_HMAC_KEY 174 +@@ -186,7 +186,7 @@ int ERR_load_EVP_strings(void); + # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 + # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 + # define EVP_R_PUBLIC_KEY_NOT_RSA 106 +-# define EVP_R_TOO_LARGE 201 ++# define EVP_R_TOO_LARGE 186 + # define EVP_R_UNKNOWN_CIPHER 160 + # define EVP_R_UNKNOWN_DIGEST 161 + # define EVP_R_UNKNOWN_OPTION 169 +@@ -202,7 +202,6 @@ int ERR_load_EVP_strings(void); + # define EVP_R_UNSUPPORTED_SALT_TYPE 126 + # define EVP_R_WRAP_MODE_NOT_ALLOWED 170 + # define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +-# define EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE 191 +-# define EVP_R_XTS_DUPLICATED_KEYS 192 ++# define EVP_R_XTS_DUPLICATED_KEYS 183 + + #endif +diff --git a/include/openssl/rsaerr.h b/include/openssl/rsaerr.h +index a8bcfdf..6bbd265 100644 +--- a/include/openssl/rsaerr.h ++++ b/include/openssl/rsaerr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -11,9 +11,7 @@ + #ifndef HEADER_RSAERR_H + # define HEADER_RSAERR_H + +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # ifdef __cplusplus + extern "C" +@@ -25,7 +23,7 @@ int ERR_load_RSA_strings(void); + */ + # define RSA_F_CHECK_PADDING_MD 140 + # define RSA_F_ENCODE_PKCS1 146 +-# define RSA_F_FIPS_RSA_BUILTIN_KEYGEN 206 ++# define RSA_F_FIPS_RSA_BUILTIN_KEYGEN 168 + # define RSA_F_INT_RSA_VERIFY 145 + # define RSA_F_OLD_RSA_PRIV_DECODE 147 + # define RSA_F_PKEY_PSS_INIT 165 +@@ -40,8 +38,8 @@ int ERR_load_RSA_strings(void); + # define RSA_F_RSA_CHECK_KEY_EX 160 + # define RSA_F_RSA_CMS_DECRYPT 159 + # define RSA_F_RSA_CMS_VERIFY 158 +-# define RSA_F_RSA_GENERATE_KEY_EX 204 +-# define RSA_F_RSA_GENERATE_MULTI_PRIME_KEY 207 ++# define RSA_F_RSA_GENERATE_KEY_EX 169 ++# define RSA_F_RSA_GENERATE_MULTI_PRIME_KEY 170 + # define RSA_F_RSA_ITEM_VERIFY 148 + # define RSA_F_RSA_METH_DUP 161 + # define RSA_F_RSA_METH_NEW 162 +@@ -77,18 +75,18 @@ int ERR_load_RSA_strings(void); + # define RSA_F_RSA_PARAM_DECODE 164 + # define RSA_F_RSA_PRINT 115 + # define RSA_F_RSA_PRINT_FP 116 ++# define RSA_F_RSA_PRIVATE_DECRYPT 171 ++# define RSA_F_RSA_PRIVATE_ENCRYPT 172 + # define RSA_F_RSA_PRIV_DECODE 150 + # define RSA_F_RSA_PRIV_ENCODE 138 +-# define RSA_F_RSA_PRIVATE_DECRYPT 200 +-# define RSA_F_RSA_PRIVATE_ENCRYPT 201 + # define RSA_F_RSA_PSS_GET_PARAM 151 + # define RSA_F_RSA_PSS_TO_CTX 155 ++# define RSA_F_RSA_PUBLIC_DECRYPT 173 ++# define RSA_F_RSA_PUBLIC_ENCRYPT 174 + # define RSA_F_RSA_PUB_DECODE 139 +-# define RSA_F_RSA_PUBLIC_DECRYPT 202 +-# define RSA_F_RSA_PUBLIC_ENCRYPT 203 + # define RSA_F_RSA_SETUP_BLINDING 136 +-# define RSA_F_RSA_SET_DEFAULT_METHOD 205 +-# define RSA_F_RSA_SET_METHOD 204 ++# define RSA_F_RSA_SET_DEFAULT_METHOD 175 ++# define RSA_F_RSA_SET_METHOD 176 + # define RSA_F_RSA_SIGN 117 + # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 + # define RSA_F_RSA_VERIFY 119 +@@ -139,19 +137,19 @@ int ERR_load_RSA_strings(void); + # define RSA_R_KEY_PRIME_NUM_INVALID 165 + # define RSA_R_KEY_SIZE_TOO_SMALL 120 + # define RSA_R_LAST_OCTET_INVALID 134 +-# define RSA_R_MISSING_PRIVATE_KEY 179 + # define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 ++# define RSA_R_MISSING_PRIVATE_KEY 179 + # define RSA_R_MODULUS_TOO_LARGE 105 + # define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 + # define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 + # define RSA_R_MP_R_NOT_PRIME 170 ++# define RSA_R_NON_FIPS_RSA_METHOD 171 + # define RSA_R_NO_PUBLIC_EXPONENT 140 +-# define RSA_R_NON_FIPS_RSA_METHOD 200 + # define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 + # define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 + # define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 + # define RSA_R_OAEP_DECODING_ERROR 121 +-# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 201 ++# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 173 + # define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 + # define RSA_R_PADDING_CHECK_FAILED 114 + # define RSA_R_PKCS_DECODING_ERROR 159 +@@ -171,7 +169,7 @@ int ERR_load_RSA_strings(void); + # define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 + # define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 + # define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +-# define RSA_R_UNSUPPORTED_PARAMETERS 202 ++# define RSA_R_UNSUPPORTED_PARAMETERS 174 + # define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 + # define RSA_R_VALUE_MISSING 147 + # define RSA_R_WRONG_SIGNATURE_LENGTH 119 +diff --git a/include/openssl/sm2.h b/include/openssl/sm2.h +new file mode 100644 +index 0000000..505ebfc +--- /dev/null ++++ b/include/openssl/sm2.h +@@ -0,0 +1,20 @@ ++#ifndef HEADER_SM2_H ++# define HEADER_SM2_H ++ ++#include "ossl_typ.h" ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++int SM2_compute_key(void *out, size_t outlen, ++ int server, const char *peer_uid, int peer_uid_len, ++ const char *self_uid, int self_uid_len, ++ const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, ++ const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, ++ const EVP_MD *md); ++ ++# ifdef __cplusplus ++} ++# endif ++#endif +diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h +index fd0c5a9..a6acbc4 100644 +--- a/include/openssl/ssl.h ++++ b/include/openssl/ssl.h +@@ -300,6 +300,11 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + * Reserved value (until OpenSSL 1.2.0) 0x00000001U + * Reserved value (until OpenSSL 1.2.0) 0x00000002U + */ ++#ifndef OPENSSL_NO_TLCP ++/* Use reserved value for the position of enc cert, default is placed at the end */ ++# define SSL_OP_ENCCERT_SECOND_POSITION 0x00000002U ++#endif ++ + /* Allow initial connection to servers that don't support RI */ + # define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U + +@@ -383,8 +388,15 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + # define SSL_OP_NO_DTLSv1 0x04000000U + # define SSL_OP_NO_DTLSv1_2 0x08000000U + ++#ifndef OPENSSL_NO_TLCP ++/* Use reserved value for TCLP(GB/T 38636-2020) */ ++# define SSL_OP_NO_TLCP 0x00000001U ++# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_TLCP|SSL_OP_NO_SSLv3|\ ++ SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) ++#else + # define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) ++#endif + # define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) + + /* Disallow all renegotiation */ +@@ -1041,6 +1053,11 @@ typedef enum { + TLS_ST_SR_END_OF_EARLY_DATA + } OSSL_HANDSHAKE_STATE; + ++#ifndef OPENSSL_NO_TLCP ++# define SSL_USAGE_SIG 0 ++# define SSL_USAGE_ENC 1 ++#endif ++ + /* + * Most of the following state values are no longer used and are defined to be + * the closest equivalent value in the current state machine code. Not all +@@ -1177,6 +1194,19 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + /* fatal */ + # define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK + # define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL ++ ++/* These alert types are for TLCP */ ++# define SSL_AD_UNSUPPORTED_SITE2SITE TLCP_AD_UNSUPPORTED_SITE2SITE ++/* fatal */ ++# define SSL_AD_NO_AREA TLCP_AD_NO_AREA ++# define SSL_AD_UNSUPPORTED_AREATYPE TLCP_AD_UNSUPPORTED_AREATYPE ++# define SSL_AD_BAD_IBCPARAM TLCP_AD_BAD_IBCPARAM ++/* fatal */ ++# define SSL_AD_UNSUPPORTED_IBCPARAM TLCP_AD_UNSUPPORTED_IBCPARAM ++/* fatal */ ++# define SSL_AD_IDENTITY_NEED TLCP_AD_IDENTITY_NEED ++/* fatal */ ++ + # define SSL_ERROR_NONE 0 + # define SSL_ERROR_SSL 1 + # define SSL_ERROR_WANT_READ 2 +@@ -1560,9 +1590,20 @@ __owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); + __owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, + long len); + # endif ++# ifndef OPENSSL_NO_TLCP ++__owur int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage); ++__owur int SSL_use_gm_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, ++ long len, int usage); ++# endif + __owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); + __owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); ++# ifndef OPENSSL_NO_TLCP ++__owur int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage); ++__owur int SSL_use_gm_certificate_ASN1(SSL *ssl, const unsigned char *d, int len, int usage); ++__owur int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, ++ STACK_OF(X509) *chain, int override, int usage); ++# endif + __owur int SSL_use_certificate(SSL *ssl, X509 *x); + __owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + __owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, +@@ -1585,6 +1626,11 @@ __owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + __owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); + #endif + ++#ifndef OPENSSL_NO_TLCP ++__owur int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage); ++__owur int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage); ++#endif ++ + __owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); + __owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + +@@ -1592,6 +1638,13 @@ __owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + __owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, + int type); + #endif ++ ++#ifndef OPENSSL_NO_TLCP ++__owur int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, ++ int type, int usage); ++__owur int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, ++ int type, int usage); ++#endif + __owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); + __owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, +@@ -1695,6 +1748,18 @@ __owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + __owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); + # endif ++ ++# ifndef OPENSSL_NO_TLCP ++__owur int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage); ++__owur int SSL_CTX_use_gm_PrivateKey_ASN1(int pk, SSL_CTX *ctx, ++ const unsigned char *d, long len, int usage); ++__owur int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage); ++__owur int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, ++ const unsigned char *d, int usage); ++__owur int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, ++ STACK_OF(X509) *chain, int override, int usage); ++# endif ++ + __owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + __owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +@@ -1873,6 +1938,12 @@ __owur const SSL_METHOD *TLS_method(void); + __owur const SSL_METHOD *TLS_server_method(void); + __owur const SSL_METHOD *TLS_client_method(void); + ++#ifndef OPENSSL_NO_TLCP ++__owur const SSL_METHOD *TLCP_method(void); ++__owur const SSL_METHOD *TLCP_server_method(void); ++__owur const SSL_METHOD *TLCP_client_method(void); ++#endif ++ + # ifndef OPENSSL_NO_TLS1_METHOD + DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ + DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) +diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h +index 701d61c..aa5f56a 100644 +--- a/include/openssl/sslerr.h ++++ b/include/openssl/sslerr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -11,9 +11,7 @@ + #ifndef HEADER_SSLERR_H + # define HEADER_SSLERR_H + +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # ifdef __cplusplus + extern "C" +@@ -171,6 +169,10 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_CTX_USE_CERTIFICATE 171 + # define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 + # define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 ++# define SSL_F_SSL_CTX_USE_GM_CERTIFICATE 641 ++# define SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1 642 ++# define SSL_F_SSL_CTX_USE_GM_PRIVATEKEY 643 ++# define SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1 644 + # define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 + # define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 + # define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +@@ -197,7 +199,9 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_HANDSHAKE_HASH 560 + # define SSL_F_SSL_INIT_WBIO_BUFFER 184 + # define SSL_F_SSL_KEY_UPDATE 515 ++# define SSL_F_SSL_LOAD_CERT_FILE 645 + # define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 ++# define SSL_F_SSL_LOAD_PKEY_FILE 646 + # define SSL_F_SSL_LOG_MASTER_SECRET 498 + # define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499 + # define SSL_F_SSL_MODULE_INIT 392 +@@ -231,11 +235,14 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_SET_CIPHER_LIST 271 + # define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK 399 + # define SSL_F_SSL_SET_FD 192 ++# define SSL_F_SSL_SET_GM_CERT_AND_KEY 647 + # define SSL_F_SSL_SET_PKEY 193 + # define SSL_F_SSL_SET_RFD 194 + # define SSL_F_SSL_SET_SESSION 195 + # define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 + # define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 ++# define SSL_F_SSL_SET_SIGN_ENC_CERT 648 ++# define SSL_F_SSL_SET_SIGN_ENC_PKEY 649 + # define SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH 550 + # define SSL_F_SSL_SET_WFD 196 + # define SSL_F_SSL_SHUTDOWN 224 +@@ -246,6 +253,10 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_USE_CERTIFICATE 198 + # define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 + # define SSL_F_SSL_USE_CERTIFICATE_FILE 200 ++# define SSL_F_SSL_USE_GM_CERTIFICATE 650 ++# define SSL_F_SSL_USE_GM_CERTIFICATE_ASN1 651 ++# define SSL_F_SSL_USE_GM_PRIVATEKEY 652 ++# define SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1 653 + # define SSL_F_SSL_USE_PRIVATEKEY 201 + # define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 + # define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +@@ -262,6 +273,20 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_WRITE_EX 433 + # define SSL_F_SSL_WRITE_INTERNAL 524 + # define SSL_F_STATE_MACHINE 353 ++# define SSL_F_TLCP_CHOOSE_SIGALG 662 ++# define SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE 663 ++# define SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC 658 ++# define SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE 654 ++# define SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE 655 ++# define SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE 664 ++# define SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC 659 ++# define SSL_F_TLCP_DERIVE 665 ++# define SSL_F_TLCP_PROCESS_CKE_SM2DHE 666 ++# define SSL_F_TLCP_PROCESS_CKE_SM2ECC 660 ++# define SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE 656 ++# define SSL_F_TLCP_PROCESS_KEY_EXCHANGE 657 ++# define SSL_F_TLCP_PROCESS_SKE_SM2DHE 667 ++# define SSL_F_TLCP_PROCESS_SKE_SM2ECC 661 + # define SSL_F_TLS12_CHECK_PEER_SIGALG 333 + # define SSL_F_TLS12_COPY_SIGALGS 533 + # define SSL_F_TLS13_CHANGE_CIPHER_STATE 440 +diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h +index 76d9fda..f05382a 100644 +--- a/include/openssl/tls1.h ++++ b/include/openssl/tls1.h +@@ -24,6 +24,7 @@ extern "C" { + # define OPENSSL_TLS_SECURITY_LEVEL 1 + # endif + ++# define TLCP_VERSION 0x0101 + # define TLS1_VERSION 0x0301 + # define TLS1_1_VERSION 0x0302 + # define TLS1_2_VERSION 0x0303 +@@ -33,6 +34,9 @@ extern "C" { + /* Special value for method supporting multiple versions */ + # define TLS_ANY_VERSION 0x10000 + ++# define TLCP_VERSION_MAJOR 0x01 ++# define TLCP_VERSION_MINOR 0x01 ++ + # define TLS1_VERSION_MAJOR 0x03 + # define TLS1_VERSION_MINOR 0x01 + +@@ -73,6 +77,14 @@ extern "C" { + # define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ + # define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + ++/* TLCP(GB/T 38636-2020) alerts */ ++# define TLCP_AD_UNSUPPORTED_SITE2SITE 200 /* fatal */ ++# define TLCP_AD_NO_AREA 201 ++# define TLCP_AD_UNSUPPORTED_AREATYPE 202 ++# define TLCP_AD_BAD_IBCPARAM 203 /* fatal */ ++# define TLCP_AD_UNSUPPORTED_IBCPARAM 204 /* fatal */ ++# define TLCP_AD_IDENTITY_NEED 205 /* fatal */ ++ + /* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ + # define TLSEXT_TYPE_server_name 0 + # define TLSEXT_TYPE_max_fragment_length 1 +@@ -641,6 +653,10 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) + # define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E + # define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F + ++/* some TLCP ciphersuites from GB/T 38636-2020 */ ++# define TLCP_CK_ECDHE_SM2_WITH_SM4_CBC_SM3 0x0300E011 ++# define TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3 0x0300E013 ++ + /* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ + # define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" + # define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" +@@ -1127,6 +1143,10 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) + # define TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "RSA-PSK-ARIA128-GCM-SHA256" + # define TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "RSA-PSK-ARIA256-GCM-SHA384" + ++/* some TLCP ciphersuites from GB/T 38636-2020 */ ++# define TLCP_TXT_ECDHE_SM2_WITH_SM4_CBC_SM3 "ECDHE-SM4-CBC-SM3" ++# define TLCP_TXT_ECC_SM2_WITH_SM4_CBC_SM3 "ECC-SM4-CBC-SM3" ++ + # define TLS_CT_RSA_SIGN 1 + # define TLS_CT_DSS_SIGN 2 + # define TLS_CT_RSA_FIXED_DH 3 +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 42e9eee..f6e82f1 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -55,6 +55,10 @@ extern "C" { + # define X509v3_KU_ENCIPHER_ONLY 0x0001 + # define X509v3_KU_DECIPHER_ONLY 0x8000 + # define X509v3_KU_UNDEF 0xffff ++/* For TLCP sm2 certificates */ ++# define X509v3_KU_SM2_SIGN (X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_NON_REPUDIATION) ++# define X509v3_KU_SM2_ENC_ENCIPHERMENT (X509v3_KU_KEY_ENCIPHERMENT | X509v3_KU_DATA_ENCIPHERMENT) ++# define X509v3_KU_SM2_ENC_CIPHER_ONLY (X509v3_KU_ENCIPHER_ONLY | X509v3_KU_DECIPHER_ONLY) + + struct X509_algor_st { + ASN1_OBJECT *algorithm; +diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h +index 0a84ef0..1e51e04 100644 +--- a/include/openssl/x509err.h ++++ b/include/openssl/x509err.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -84,7 +84,7 @@ int ERR_load_X509_strings(void); + # define X509_F_X509_TO_X509_REQ 126 + # define X509_F_X509_TRUST_ADD 133 + # define X509_F_X509_TRUST_SET 141 +-# define X509_F_X509_VERIFY 161 ++# define X509_F_X509_VERIFY 166 + # define X509_F_X509_VERIFY_CERT 127 + # define X509_F_X509_VERIFY_PARAM_NEW 159 + # define X509_F_X509_VERIFY_SM2 162 +diff --git a/ssl/methods.c b/ssl/methods.c +index c5e8898..2a6cd73 100644 +--- a/ssl/methods.c ++++ b/ssl/methods.c +@@ -109,6 +109,25 @@ IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1, + IMPLEMENT_ssl3_meth_func(sslv3_client_method, + ssl_undefined_function, ossl_statem_connect) + #endif ++/*- ++ * TLCP methods ++ */ ++#ifndef OPENSSL_NO_TLCP ++IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, ++ tlcp_method, ++ ossl_statem_accept, ++ ossl_statem_connect, TLCP_enc_data) ++ ++IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, ++ tlcp_server_method, ++ ossl_statem_accept, ++ ssl_undefined_function, TLCP_enc_data) ++ ++IMPLEMENT_tls_meth_func(TLCP_VERSION, 0, SSL_OP_NO_TLCP, ++ tlcp_client_method, ++ ssl_undefined_function, ++ ossl_statem_connect, TLCP_enc_data) ++#endif + /*- + * DTLS methods + */ +@@ -207,6 +226,23 @@ const SSL_METHOD *TLSv1_1_client_method(void) + } + # endif + ++# ifndef OPENSSL_NO_TLCP ++const SSL_METHOD *TLCP_method(void) ++{ ++ return tlcp_method(); ++} ++ ++const SSL_METHOD *TLCP_server_method(void) ++{ ++ return tlcp_server_method(); ++} ++ ++const SSL_METHOD *TLCP_client_method(void) ++{ ++ return tlcp_client_method(); ++} ++# endif ++ + # ifndef OPENSSL_NO_TLS1_METHOD + const SSL_METHOD *TLSv1_method(void) + { +diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c +index f158544..af825b1 100644 +--- a/ssl/record/ssl3_record.c ++++ b/ssl/record/ssl3_record.c +@@ -309,7 +309,11 @@ int ssl3_get_record(SSL *s) + return -1; + } + ++#ifndef OPENSSL_NO_TLCP ++ if ((version >> 8) != SSL3_VERSION_MAJOR && (version != TLCP_VERSION)) { ++#else + if ((version >> 8) != SSL3_VERSION_MAJOR) { ++#endif + if (RECORD_LAYER_is_first_record(&s->rlayer)) { + /* Go back to start of packet, look at the five bytes + * that we have. */ +diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c +index 918cab0..5ecd953 100644 +--- a/ssl/s3_lib.c ++++ b/ssl/s3_lib.c +@@ -15,6 +15,8 @@ + #include "ssl_local.h" + #include + #include ++#include "include/crypto/sm2.h" ++#include + #include + #include "internal/cryptlib.h" + +@@ -2667,6 +2669,43 @@ static SSL_CIPHER ssl3_ciphers[] = { + }, + #endif /* OPENSSL_NO_GOST */ + ++#ifndef OPENSSL_NO_TLCP ++ { ++ 1, ++ TLCP_TXT_ECDHE_SM2_WITH_SM4_CBC_SM3, ++ NULL, ++ TLCP_CK_ECDHE_SM2_WITH_SM4_CBC_SM3, ++ SSL_kSM2DHE, ++ SSL_aSM2, ++ SSL_SM4CBC, ++ SSL_SM3, ++ TLCP_VERSION, ++ TLS1_2_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_SM3 | TLS1_PRF_SM3, ++ 128, ++ 128, ++ }, ++ { ++ 1, ++ TLCP_TXT_ECC_SM2_WITH_SM4_CBC_SM3, ++ NULL, ++ TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3, ++ SSL_kSM2ECC, ++ SSL_aSM2, ++ SSL_SM4CBC, ++ SSL_SM3, ++ TLCP_VERSION, ++ TLS1_2_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_SM3 | TLS1_PRF_SM3, ++ 128, ++ 128, ++ }, ++#endif /* OPENSSL_NO_TLCP */ ++ + #ifndef OPENSSL_NO_IDEA + { + 1, +@@ -4313,6 +4352,20 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + ret = tmp; + continue; + } ++#ifndef OPENSSL_NO_TLCP ++ /* Prefer ECC-SM4-CBC-SM3 while enabling TLCP */ ++ if (!(s->options & SSL_OP_NO_TLCP)) { ++ const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); ++ ++ if (tmp->id == TLCP_CK_ECC_SM2_WITH_SM4_CBC_SM3) { ++ ret = tmp; ++ break; ++ } ++ if (ret == NULL) ++ ret = tmp; ++ continue; ++ } ++#endif + ret = sk_SSL_CIPHER_value(allow, ii); + break; + } +@@ -4856,3 +4909,76 @@ EVP_PKEY *ssl_dh_to_pkey(DH *dh) + return ret; + } + #endif ++ ++#ifndef OPENSSL_NO_TLCP ++int tlcp_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey) ++{ ++ unsigned char *pms; ++ int pmslen = SSL_MAX_MASTER_KEY_LENGTH; ++ EC_KEY *tmp_peer_pub_key, *tmp_self_priv_key; ++ EC_KEY *self_priv_key, *peer_pub_key; ++ X509 *peer_enc_cert; ++ int ret; ++ ++ if ((tmp_self_priv_key = EVP_PKEY_get0_EC_KEY(privkey)) == NULL ++ || (tmp_peer_pub_key = EVP_PKEY_get0_EC_KEY(pubkey)) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if (s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if ((self_priv_key = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey)) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_EC_LIB); ++ return 0; ++ } ++ ++ peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); ++ if (peer_enc_cert == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if ((peer_pub_key = EVP_PKEY_get0_EC_KEY(X509_get0_pubkey(peer_enc_cert))) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ pms = OPENSSL_malloc(pmslen); ++ if (pms == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ if (SM2_compute_key(pms, pmslen, s->server, ++ SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN, ++ SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN, ++ tmp_peer_pub_key, tmp_self_priv_key, ++ peer_pub_key, self_priv_key, ++ EVP_sm3()) != pmslen) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_DERIVE, ++ ERR_R_INTERNAL_ERROR); ++ OPENSSL_free(pms); ++ return 0; ++ } ++ ++ if (s->server) { ++ ret = ssl_generate_master_secret(s, pms, (size_t)pmslen, 1); ++ } else { ++ s->s3->tmp.pms = pms; ++ s->s3->tmp.pmslen = pmslen; ++ ret = 1; ++ } ++ ++ return ret; ++} ++#endif +diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c +index 9264364..beb3c3b 100644 +--- a/ssl/ssl_asn1.c ++++ b/ssl/ssl_asn1.c +@@ -265,7 +265,8 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + + if ((as->ssl_version >> 8) != SSL3_VERSION_MAJOR + && (as->ssl_version >> 8) != DTLS1_VERSION_MAJOR +- && as->ssl_version != DTLS1_BAD_VER) { ++ && as->ssl_version != DTLS1_BAD_VER ++ && as->ssl_version != TLCP_VERSION) { + SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); + goto err; + } +diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c +index e7feda8..73d76a5 100644 +--- a/ssl/ssl_cert.c ++++ b/ssl/ssl_cert.c +@@ -937,18 +937,31 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, + return 0; + /* Level 3: forward secure ciphersuites only */ + if (level >= 3 && c->min_tls != TLS1_3_VERSION && ++#ifndef OPENSSL_NO_TLCP ++ !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH | SSL_kSM2DHE))) ++#else + !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH))) ++#endif + return 0; + break; + } + case SSL_SECOP_VERSION: + if (!SSL_IS_DTLS(s)) { ++#ifndef OPENSSL_NO_TLCP ++ /* SSLv3 not allowed at level 2 */ ++ if (nid <= SSL3_VERSION && nid != TLCP_VERSION && level >= 2) ++ return 0; ++ /* TLS v1.1 and above only for level 3 */ ++ if (nid <= TLS1_VERSION && nid != TLCP_VERSION && level >= 3) ++ return 0; ++#else + /* SSLv3 not allowed at level 2 */ + if (nid <= SSL3_VERSION && level >= 2) + return 0; + /* TLS v1.1 and above only for level 3 */ + if (nid <= TLS1_VERSION && level >= 3) + return 0; ++#endif + /* TLS v1.2 only for level 4 and above */ + if (nid <= TLS1_1_VERSION && level >= 4) + return 0; +@@ -1003,6 +1016,11 @@ const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) + { + int nid = EVP_PKEY_id(pk); + size_t tmpidx; ++#ifndef OPENSSL_NO_TLCP ++ if (EVP_PKEY_is_sm2((EVP_PKEY *)pk)) { ++ nid = NID_sm2; ++ } ++#endif + + if (nid == NID_undef) + return NULL; +diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h +index 0c47241..1e1864f 100644 +--- a/ssl/ssl_cert_table.h ++++ b/ssl/ssl_cert_table.h +@@ -19,5 +19,9 @@ static const SSL_CERT_LOOKUP ssl_cert_info [] = { + {NID_id_GostR3410_2012_256, SSL_aGOST12}, /* SSL_PKEY_GOST12_256 */ + {NID_id_GostR3410_2012_512, SSL_aGOST12}, /* SSL_PKEY_GOST12_512 */ + {EVP_PKEY_ED25519, SSL_aECDSA}, /* SSL_PKEY_ED25519 */ +- {EVP_PKEY_ED448, SSL_aECDSA} /* SSL_PKEY_ED448 */ ++ {EVP_PKEY_ED448, SSL_aECDSA}, /* SSL_PKEY_ED448 */ ++#ifndef OPENSSL_NO_TLCP ++ {EVP_PKEY_SM2, SSL_aSM2}, /* SSL_PKEY_SM2_SIGN */ ++ {EVP_PKEY_SM2, SSL_aSM2} /* SSL_PKEY_SM2_ENC */ ++#endif + }; +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index b8eba0c..b0d50b5 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -43,7 +43,12 @@ + #define SSL_ENC_CHACHA_IDX 19 + #define SSL_ENC_ARIA128GCM_IDX 20 + #define SSL_ENC_ARIA256GCM_IDX 21 ++#ifndef OPENSSL_NO_TLCP ++#define SSL_ENC_SM4CBC_IDX 22 ++#define SSL_ENC_NUM_IDX 23 ++#else + #define SSL_ENC_NUM_IDX 22 ++#endif + + /* NB: make sure indices in these tables match values above */ + +@@ -76,6 +81,9 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { + {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ + {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ + {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ ++#ifndef OPENSSL_NO_TLCP ++ {SSL_SM4CBC, NID_sm4_cbc}, /* SSL_ENC_SM4CBC_IDX 22*/ ++#endif + }; + + static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; +@@ -110,11 +118,17 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { + {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ + {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ + {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ +- {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ ++ {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ ++#ifndef OPENSSL_NO_TLCP ++ {SSL_SM3, NID_sm3} /* SSL_MD_SM3_IDX 12 */ ++#endif + }; + + static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { +- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ++#ifndef OPENSSL_NO_TLCP ++ NULL ++#endif + }; + + /* *INDENT-OFF* */ +@@ -172,7 +186,10 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { + /* GOST2012_512 */ + EVP_PKEY_HMAC, + /* MD5/SHA1, SHA224, SHA512 */ +- NID_undef, NID_undef, NID_undef ++ NID_undef, NID_undef, NID_undef, ++#ifndef OPENSSL_NO_TLCP ++ EVP_PKEY_HMAC ++#endif + }; + + static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; +@@ -1696,6 +1713,14 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) + case SSL_kANY: + kx = "any"; + break; ++#ifndef OPENSSL_NO_TLCP ++ case SSL_kSM2ECC: ++ kx = "SM2ECC"; ++ break; ++ case SSL_kSM2DHE: ++ kx = "SM2DHE"; ++ break; ++#endif + default: + kx = "unknown"; + } +@@ -1729,6 +1754,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) + case SSL_aANY: + au = "any"; + break; ++#ifndef OPENSSL_NO_TLCP ++ case SSL_aSM2: ++ au = "SM2"; ++ break; ++#endif + default: + au = "unknown"; + break; +@@ -1799,6 +1829,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) + case SSL_CHACHA20POLY1305: + enc = "CHACHA20/POLY1305(256)"; + break; ++#ifndef OPENSSL_NO_TLCP ++ case SSL_SM4CBC: ++ enc = "SM4CBC"; ++ break; ++#endif + default: + enc = "unknown"; + break; +@@ -1831,6 +1866,11 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) + case SSL_GOST12_512: + mac = "GOST2012"; + break; ++#ifndef OPENSSL_NO_TLCP ++ case SSL_SM3: ++ mac = "SM3"; ++ break; ++#endif + default: + mac = "unknown"; + break; +diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c +index 324f2cc..5a7c42a 100644 +--- a/ssl/ssl_err.c ++++ b/ssl/ssl_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -113,6 +113,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "ossl_statem_server_post_process_message"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_WORK, 0), + "ossl_statem_server_post_work"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PRE_WORK, 0), ++ "ossl_statem_server_pre_work"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, 0), + "ossl_statem_server_process_message"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, 0), +@@ -244,6 +246,14 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "SSL_CTX_use_certificate_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 0), + "SSL_CTX_use_certificate_file"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_CERTIFICATE, 0), ++ "SSL_CTX_use_gm_certificate"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1, 0), ++ "SSL_CTX_use_gm_certificate_ASN1"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, 0), ++ "SSL_CTX_use_gm_PrivateKey"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1, 0), ++ "SSL_CTX_use_gm_PrivateKey_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY, 0), + "SSL_CTX_use_PrivateKey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, 0), +@@ -285,8 +295,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_INIT_WBIO_BUFFER, 0), + "ssl_init_wbio_buffer"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_KEY_UPDATE, 0), "SSL_key_update"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_CERT_FILE, 0), "ssl_load_cert_file"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_CLIENT_CA_FILE, 0), + "SSL_load_client_CA_file"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_PKEY_FILE, 0), "ssl_load_pkey_file"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_MASTER_SECRET, 0), ""}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, 0), + "ssl_log_rsa_client_key_exchange"}, +@@ -331,6 +343,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CT_VALIDATION_CALLBACK, 0), + "SSL_set_ct_validation_callback"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_FD, 0), "SSL_set_fd"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_GM_CERT_AND_KEY, 0), ++ "ssl_set_gm_cert_and_key"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_PKEY, 0), "ssl_set_pkey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_RFD, 0), "SSL_set_rfd"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION, 0), "SSL_set_session"}, +@@ -338,6 +352,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "SSL_set_session_id_context"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION_TICKET_EXT, 0), + "SSL_set_session_ticket_ext"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SIGN_ENC_CERT, 0), ++ "ssl_set_sign_enc_cert"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SIGN_ENC_PKEY, 0), ++ "ssl_set_sign_enc_pkey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH, 0), + "SSL_set_tlsext_max_fragment_length"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_WFD, 0), "SSL_set_wfd"}, +@@ -355,6 +373,14 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "SSL_use_certificate_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_CERTIFICATE_FILE, 0), + "SSL_use_certificate_file"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_CERTIFICATE, 0), ++ "SSL_use_gm_certificate"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_CERTIFICATE_ASN1, 0), ++ "SSL_use_gm_certificate_ASN1"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_PRIVATEKEY, 0), ++ "SSL_use_gm_PrivateKey"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1, 0), ++ "SSL_use_gm_PrivateKey_ASN1"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY, 0), "SSL_use_PrivateKey"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY_ASN1, 0), + "SSL_use_PrivateKey_ASN1"}, +@@ -380,6 +406,32 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EX, 0), "SSL_write_ex"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_INTERNAL, 0), "ssl_write_internal"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_STATE_MACHINE, 0), "state_machine"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CHOOSE_SIGALG, 0), "tlcp_choose_sigalg"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, 0), ++ "tlcp_construct_cke_sm2dhe"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, 0), ++ "tlcp_construct_cke_sm2ecc"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE, 0), ++ "tlcp_construct_client_key_exchange"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE, 0), ++ "tlcp_construct_server_key_exchange"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, 0), ++ "tlcp_construct_ske_sm2dhe"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, 0), ++ "tlcp_construct_ske_sm2ecc"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_DERIVE, 0), "tlcp_derive"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CKE_SM2DHE, 0), ++ "tlcp_process_cke_sm2dhe"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CKE_SM2ECC, 0), ++ "tlcp_process_cke_sm2ecc"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE, 0), ++ "tlcp_process_client_key_exchange"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_KEY_EXCHANGE, 0), ++ "tlcp_process_key_exchange"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_SKE_SM2DHE, 0), ++ "tlcp_process_ske_sm2dhe"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLCP_PROCESS_SKE_SM2ECC, 0), ++ "tlcp_process_ske_sm2ecc"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_CHECK_PEER_SIGALG, 0), + "tls12_check_peer_sigalg"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_COPY_SIGALGS, 0), "tls12_copy_sigalgs"}, +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 78c4f99..27e5ed2 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -560,8 +560,14 @@ static int ssl_check_allowed_versions(int min_version, int max_version) + #ifdef OPENSSL_NO_TLS1_3 + || (min_version <= TLS1_3_VERSION && TLS1_3_VERSION <= max_version) + #endif +- ) ++ ) { ++#ifndef OPENSSL_NO_TLCP ++ if (min_version == TLCP_VERSION || max_version == TLCP_VERSION) { ++ return 1; ++ } ++#endif + return 0; ++ } + } + return 1; + } +@@ -3365,6 +3371,9 @@ void ssl_set_masks(SSL *s) + unsigned long mask_k, mask_a; + #ifndef OPENSSL_NO_EC + int have_ecc_cert, ecdsa_ok; ++#endif ++#ifndef OPENSSL_NO_TLCP ++ int tlcp_sm2_sign, tlcp_sm2_enc; + #endif + if (c == NULL) + return; +@@ -3380,14 +3389,23 @@ void ssl_set_masks(SSL *s) + dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_VALID; + #ifndef OPENSSL_NO_EC + have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; ++#endif ++#ifndef OPENSSL_NO_TLCP ++ tlcp_sm2_sign = ssl_has_cert(s, SSL_PKEY_SM2_SIGN); ++ tlcp_sm2_enc = ssl_has_cert(s, SSL_PKEY_SM2_ENC); + #endif + mask_k = 0; + mask_a = 0; + + #ifdef CIPHER_DEBUG ++#ifndef OPENSSL_NO_TLCP ++ fprintf(stderr, "dht=%d re=%d rs=%d ds=%d tss=%d tse=%d\n", ++ dh_tmp, rsa_enc, rsa_sign, dsa_sign, tlcp_sm2_sign, tlcp_sm2_enc); ++#else + fprintf(stderr, "dht=%d re=%d rs=%d ds=%d\n", + dh_tmp, rsa_enc, rsa_sign, dsa_sign); + #endif ++#endif + + #ifndef OPENSSL_NO_GOST + if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { +@@ -3457,6 +3475,14 @@ void ssl_set_masks(SSL *s) + mask_k |= SSL_kECDHE; + #endif + ++#ifndef OPENSSL_NO_TLCP ++ if (tlcp_sm2_sign) ++ mask_a |= SSL_aSM2; ++ ++ if (tlcp_sm2_enc) ++ mask_k |= SSL_kSM2ECC | SSL_kSM2DHE; ++#endif ++ + #ifndef OPENSSL_NO_PSK + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; +@@ -3786,6 +3812,11 @@ const char *ssl_protocol_to_string(int version) + case TLS1_VERSION: + return "TLSv1"; + ++#ifndef OPENSSL_NO_TLCP ++ case TLCP_VERSION: ++ return "TLCP"; ++#endif ++ + case SSL3_VERSION: + return "SSLv3"; + +@@ -5700,3 +5731,51 @@ void SSL_set_allow_early_data_cb(SSL *s, + s->allow_early_data_cb = cb; + s->allow_early_data_cb_data = arg; + } ++ ++#ifndef OPENSSL_NO_TLCP ++int ssl_is_sm2_cert(X509 *x) ++{ ++ return x && EVP_PKEY_is_sm2(X509_get0_pubkey(x)); ++} ++ ++int ssl_is_sm2_sign_usage(X509 *x) ++{ ++ return x && (X509_get_extension_flags(x) & EXFLAG_KUSAGE) && ++ (X509_get_key_usage(x) & X509v3_KU_SM2_SIGN); ++} ++ ++int ssl_is_sm2_enc_usage(X509 *x) ++{ ++ return x && (X509_get_extension_flags(x) & EXFLAG_KUSAGE) && ++ ((X509_get_key_usage(x) & X509v3_KU_SM2_ENC_ENCIPHERMENT) || ++ ((X509_get_key_usage(x) & X509v3_KU_SM2_ENC_CIPHER_ONLY) && ++ (X509_get_key_usage(x) & X509v3_KU_KEY_AGREEMENT)) ++ ); ++} ++ ++X509 *ssl_get_sm2_enc_cert(SSL *s, STACK_OF(X509) *chain) ++{ ++ X509 *x; ++ int i; ++ ++ for (i = sk_X509_num(chain) - 1; i >= 0 ; --i) { ++ x = sk_X509_value(chain, i); ++ if (ssl_is_sm2_cert(x) && ssl_is_sm2_enc_usage(x)) { ++ return x; ++ } ++ } ++ return NULL; ++} ++ ++int ssl_get_sm2_cert_id(X509 *x, size_t *id) ++{ ++ if (ssl_is_sm2_sign_usage(x) && !ssl_is_sm2_enc_usage(x)) { ++ *id = SSL_PKEY_SM2_SIGN; ++ return 1; ++ } else if (!ssl_is_sm2_sign_usage(x) && ssl_is_sm2_enc_usage(x)) { ++ *id = SSL_PKEY_SM2_ENC; ++ return 1; ++ } ++ return 0; ++} ++#endif +\ No newline at end of file +diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h +index a33cb9a..8135248 100644 +--- a/ssl/ssl_local.h ++++ b/ssl/ssl_local.h +@@ -177,6 +177,13 @@ + # define SSL_kECDHEPSK 0x00000080U + # define SSL_kDHEPSK 0x00000100U + ++#ifndef OPENSSL_NO_TLCP ++/* TLCP ECC*/ ++# define SSL_kSM2ECC 0x00000800U ++/* TLCP ECDHE */ ++# define SSL_kSM2DHE 0x00001000U ++#endif ++ + /* all PSK */ + + # define SSL_PSK (SSL_kPSK | SSL_kRSAPSK | SSL_kECDHEPSK | SSL_kDHEPSK) +@@ -203,9 +210,21 @@ + # define SSL_aGOST12 0x00000080U + /* Any appropriate signature auth (for TLS 1.3 ciphersuites) */ + # define SSL_aANY 0x00000000U ++ ++#ifndef OPENSSL_NO_TLCP ++/* SM2 auth */ ++# define SSL_aSM2 0x00000100U ++#endif ++ ++#ifndef OPENSSL_NO_TLCP ++/* All bits requiring a certificate */ ++#define SSL_aCERT \ ++ (SSL_aRSA | SSL_aDSS | SSL_aECDSA | SSL_aGOST01 | SSL_aGOST12 | SSL_aSM2) ++#else + /* All bits requiring a certificate */ + #define SSL_aCERT \ + (SSL_aRSA | SSL_aDSS | SSL_aECDSA | SSL_aGOST01 | SSL_aGOST12) ++#endif + + /* Bits for algorithm_enc (symmetric encryption) */ + # define SSL_DES 0x00000001U +@@ -231,6 +250,10 @@ + # define SSL_ARIA128GCM 0x00100000U + # define SSL_ARIA256GCM 0x00200000U + ++#ifndef OPENSSL_NO_TLCP ++# define SSL_SM4CBC 0x00800000U ++#endif ++ + # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) + # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) + # define SSL_AES (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM) +@@ -253,6 +276,10 @@ + # define SSL_GOST89MAC12 0x00000100U + # define SSL_GOST12_512 0x00000200U + ++#ifndef OPENSSL_NO_TLCP ++# define SSL_SM3 0x00000400U ++#endif ++ + /* + * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make + * sure to update this constant too +@@ -270,8 +297,12 @@ + # define SSL_MD_MD5_SHA1_IDX 9 + # define SSL_MD_SHA224_IDX 10 + # define SSL_MD_SHA512_IDX 11 ++#ifndef OPENSSL_NO_TLCP ++# define SSL_MD_SM3_IDX 12 ++# define SSL_MAX_DIGEST 13 ++#else + # define SSL_MAX_DIGEST 12 +- ++#endif + /* Bits for algorithm2 (handshake digests and other extra flags) */ + + /* Bits 0-7 are handshake MAC */ +@@ -283,6 +314,9 @@ + # define SSL_HANDSHAKE_MAC_GOST12_256 SSL_MD_GOST12_256_IDX + # define SSL_HANDSHAKE_MAC_GOST12_512 SSL_MD_GOST12_512_IDX + # define SSL_HANDSHAKE_MAC_DEFAULT SSL_HANDSHAKE_MAC_MD5_SHA1 ++#ifndef OPENSSL_NO_TLCP ++# define SSL_HANDSHAKE_MAC_SM3 SSL_MD_SM3_IDX ++#endif + + /* Bits 8-15 bits are PRF */ + # define TLS1_PRF_DGST_SHIFT 8 +@@ -293,6 +327,9 @@ + # define TLS1_PRF_GOST12_256 (SSL_MD_GOST12_256_IDX << TLS1_PRF_DGST_SHIFT) + # define TLS1_PRF_GOST12_512 (SSL_MD_GOST12_512_IDX << TLS1_PRF_DGST_SHIFT) + # define TLS1_PRF (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT) ++#ifndef OPENSSL_NO_TLCP ++# define TLS1_PRF_SM3 (SSL_MD_SM3_IDX << TLS1_PRF_DGST_SHIFT) ++#endif + + /* + * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also +@@ -318,6 +355,8 @@ + /* Check if an SSL structure is using DTLS */ + # define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + ++# define SSL_IS_TLCP(s) (s->version == TLCP_VERSION) ++ + /* Check if we are using TLSv1.3 */ + # define SSL_IS_TLS13(s) (!SSL_IS_DTLS(s) \ + && (s)->method->version >= TLS1_3_VERSION \ +@@ -383,7 +422,13 @@ + # define SSL_PKEY_GOST12_512 6 + # define SSL_PKEY_ED25519 7 + # define SSL_PKEY_ED448 8 ++#ifndef OPENSSL_NO_TLCP ++# define SSL_PKEY_SM2_SIGN 9 ++# define SSL_PKEY_SM2_ENC 10 ++# define SSL_PKEY_NUM 11 ++#else + # define SSL_PKEY_NUM 9 ++#endif + + /*- + * SSL_kRSA <- RSA_ENC +@@ -2027,6 +2072,9 @@ typedef enum downgrade_en { + #define TLSEXT_SIGALG_ecdsa_secp521r1_sha512 0x0603 + #define TLSEXT_SIGALG_ecdsa_sha224 0x0303 + #define TLSEXT_SIGALG_ecdsa_sha1 0x0203 ++#ifndef OPENSSL_NO_TLCP ++#define TLSEXT_SIGALG_sm2dsa_sm3 0x0708 ++#endif + #define TLSEXT_SIGALG_rsa_pss_rsae_sha256 0x0804 + #define TLSEXT_SIGALG_rsa_pss_rsae_sha384 0x0805 + #define TLSEXT_SIGALG_rsa_pss_rsae_sha512 0x0806 +@@ -2096,6 +2144,18 @@ __owur const SSL_METHOD *dtls_bad_ver_client_method(void); + __owur const SSL_METHOD *dtlsv1_2_method(void); + __owur const SSL_METHOD *dtlsv1_2_server_method(void); + __owur const SSL_METHOD *dtlsv1_2_client_method(void); ++# ifndef OPENSSL_NO_TLCP ++__owur const SSL_METHOD *tlcp_method(void); ++__owur const SSL_METHOD *tlcp_server_method(void); ++__owur const SSL_METHOD *tlcp_client_method(void); ++ ++/* TLCP helper functions */ ++__owur int ssl_is_sm2_cert(X509 *x); ++__owur int ssl_is_sm2_sign_usage(X509 *x); ++__owur int ssl_is_sm2_enc_usage(X509 *x); ++__owur X509 *ssl_get_sm2_enc_cert(SSL *s, STACK_OF(X509) *chain); ++__owur int ssl_get_sm2_cert_id(X509 *x, size_t *id); ++# endif + + extern const SSL3_ENC_METHOD TLSv1_enc_data; + extern const SSL3_ENC_METHOD TLSv1_1_enc_data; +@@ -2104,6 +2164,9 @@ extern const SSL3_ENC_METHOD TLSv1_3_enc_data; + extern const SSL3_ENC_METHOD SSLv3_enc_data; + extern const SSL3_ENC_METHOD DTLSv1_enc_data; + extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; ++# ifndef OPENSSL_NO_TLCP ++extern const SSL3_ENC_METHOD TLCP_enc_data; ++# endif + + /* + * Flags for SSL methods +@@ -2331,6 +2394,7 @@ __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, + __owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm); + __owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, + int genmaster); ++__owur int tlcp_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey); + __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh); + __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl); + __owur unsigned int ssl_get_split_send_fragment(const SSL *ssl); +@@ -2502,6 +2566,9 @@ __owur int tls13_export_keying_material_early(SSL *s, unsigned char *out, + __owur int tls1_alert_code(int code); + __owur int tls13_alert_code(int code); + __owur int ssl3_alert_code(int code); ++# ifndef OPENSSL_NO_TLCP ++__owur int tlcp_alert_code(int code); ++# endif + + # ifndef OPENSSL_NO_EC + __owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); +diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c +index 6457c0c..5a495ec 100644 +--- a/ssl/ssl_rsa.c ++++ b/ssl/ssl_rsa.c +@@ -19,6 +19,15 @@ + static int ssl_set_cert(CERT *c, X509 *x509); + static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); + ++#ifndef OPENSSL_NO_TLCP ++#include ++ ++static int ssl_set_sign_enc_pkey(CERT *c, EVP_PKEY *pkey, size_t id); ++static int ssl_set_sign_enc_cert(CERT *c, X509 *x, size_t id); ++static int ssl_load_pkey_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, EVP_PKEY **pkey); ++static int ssl_load_cert_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, X509 **x); ++#endif ++ + #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ + | SSL_EXT_CLIENT_HELLO \ + | SSL_EXT_TLS1_2_SERVER_HELLO \ +@@ -97,6 +106,99 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) + return ret; + } + ++#ifndef OPENSSL_NO_TLCP ++static int ssl_load_cert_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, X509 **x) ++{ ++ int j; ++ BIO *in; ++ int ret = 0; ++ *x = NULL; ++ ++ in = BIO_new(BIO_s_file()); ++ if (in == NULL) { ++ SSLerr(SSL_F_SSL_LOAD_CERT_FILE, ERR_R_BUF_LIB); ++ goto end; ++ } ++ ++ if (BIO_read_filename(in, file) <= 0) { ++ SSLerr(SSL_F_SSL_LOAD_CERT_FILE, ERR_R_SYS_LIB); ++ goto end; ++ } ++ if (type == SSL_FILETYPE_ASN1) { ++ j = ERR_R_ASN1_LIB; ++ *x = d2i_X509_bio(in, NULL); ++ } else if (type == SSL_FILETYPE_PEM) { ++ j = ERR_R_PEM_LIB; ++ pem_password_cb *cb = (ssl != NULL) ? ssl->default_passwd_callback : ++ ctx->default_passwd_callback; ++ void *userdata = (ssl != NULL) ? ssl->default_passwd_callback_userdata : ++ ctx->default_passwd_callback_userdata; ++ *x = PEM_read_bio_X509(in, NULL, cb, userdata); ++ } else { ++ SSLerr(SSL_F_SSL_LOAD_CERT_FILE, SSL_R_BAD_SSL_FILETYPE); ++ goto end; ++ } ++ ++ if (*x == NULL) { ++ SSLerr(SSL_F_SSL_LOAD_CERT_FILE, j); ++ goto end; ++ } ++ ret = 1; ++end: ++ BIO_free(in); ++ return ret; ++} ++ ++int SSL_use_gm_certificate(SSL *ssl, X509 *x, int usage) ++{ ++ int rv; ++ if (x == NULL) { ++ SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); ++ return 0; ++ } ++ rv = ssl_security_cert(ssl, NULL, x, 0, 1); ++ if (rv != 1) { ++ SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, rv); ++ return 0; ++ } ++ if (usage == SSL_USAGE_SIG) { ++ return ssl_set_sign_enc_cert(ssl->cert, x, SSL_PKEY_SM2_SIGN); ++ } else if (usage == SSL_USAGE_ENC) { ++ return ssl_set_sign_enc_cert(ssl->cert, x, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++} ++ ++int SSL_use_gm_certificate_ASN1(SSL *ssl, const unsigned char *d, int len, int usage) ++{ ++ X509 *x; ++ int ret; ++ ++ x = d2i_X509(NULL, &d, (long)len); ++ if (x == NULL) { ++ SSLerr(SSL_F_SSL_USE_GM_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); ++ return 0; ++ } ++ ++ ret = SSL_use_gm_certificate(ssl, x, usage); ++ X509_free(x); ++ return ret; ++} ++ ++int SSL_use_gm_certificate_file(SSL *ssl, const char *file, int type, int usage) ++{ ++ int ret; ++ X509 *x = NULL; ++ ret = ssl_load_cert_file(ssl, NULL, file, type, &x); ++ if (ret == 1) { ++ ret = SSL_use_gm_certificate(ssl, x, usage); ++ } ++ X509_free(x); ++ return ret; ++} ++#endif ++ + #ifndef OPENSSL_NO_RSA + int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) + { +@@ -162,6 +264,50 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) + return 1; + } + ++#ifndef OPENSSL_NO_TLCP ++int ssl_set_sign_enc_pkey(CERT *c, EVP_PKEY *pkey, size_t id) ++{ ++ if (id != SSL_PKEY_SM2_SIGN && id != SSL_PKEY_SM2_ENC) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++ } ++ ++ if (EVP_PKEY_is_sm2(pkey) == 0) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, SSL_R_UNKNOWN_PKEY_TYPE); ++ return 0; ++ } ++ ++ if (c->pkeys[id].x509 != NULL) { ++ EVP_PKEY *pktmp; ++ pktmp = X509_get0_pubkey(c->pkeys[id].x509); ++ if (pktmp == NULL) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_PKEY, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ /* ++ * The return code from EVP_PKEY_copy_parameters is deliberately ++ * ignored. Some EVP_PKEY types cannot do this. ++ */ ++ EVP_PKEY_copy_parameters(pktmp, pkey); ++ ERR_clear_error(); ++ ++ if (!X509_check_private_key(c->pkeys[id].x509, pkey)) { ++ X509_free(c->pkeys[id].x509); ++ c->pkeys[id].x509 = NULL; ++ return 0; ++ } ++ } ++ ++ EVP_PKEY_free(c->pkeys[id].privatekey); ++ EVP_PKEY_up_ref(pkey); ++ c->pkeys[id].privatekey = pkey; ++ if (id != SSL_PKEY_SM2_ENC) { ++ c->key = &(c->pkeys[id]); ++ } ++ return 1; ++} ++#endif ++ + #ifndef OPENSSL_NO_RSA + int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) + { +@@ -228,6 +374,17 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } ++#ifndef OPENSSL_NO_TLCP ++ if (EVP_PKEY_is_sm2(pkey)) { ++ if (X509_check_private_key(ssl->cert->pkeys[SSL_PKEY_SM2_SIGN].x509, pkey)) { ++ return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_SIGN); ++ } else if (X509_check_private_key(ssl->cert->pkeys[SSL_PKEY_SM2_ENC].x509, pkey)) { ++ return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++ } ++#endif + ret = ssl_set_pkey(ssl->cert, pkey); + return ret; + } +@@ -289,6 +446,94 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, + return ret; + } + ++#ifndef OPENSSL_NO_TLCP ++static int ssl_load_pkey_file(SSL *ssl, SSL_CTX *ctx, const char *file, int type, EVP_PKEY **pkey) ++{ ++ int j, ret = 0; ++ BIO *in; ++ *pkey = NULL; ++ ++ in = BIO_new(BIO_s_file()); ++ if (in == NULL) { ++ SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, ERR_R_BUF_LIB); ++ goto end; ++ } ++ ++ if (BIO_read_filename(in, file) <= 0) { ++ SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, ERR_R_SYS_LIB); ++ goto end; ++ } ++ if (type == SSL_FILETYPE_PEM) { ++ j = ERR_R_PEM_LIB; ++ pem_password_cb *cb = (ssl != NULL) ? ssl->default_passwd_callback : ++ ctx->default_passwd_callback; ++ void *userdata = (ssl != NULL) ? ssl->default_passwd_callback_userdata : ++ ctx->default_passwd_callback_userdata; ++ *pkey = PEM_read_bio_PrivateKey(in, NULL, cb, userdata); ++ } else if (type == SSL_FILETYPE_ASN1) { ++ j = ERR_R_ASN1_LIB; ++ *pkey = d2i_PrivateKey_bio(in, NULL); ++ } else { ++ SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, SSL_R_BAD_SSL_FILETYPE); ++ goto end; ++ } ++ if (*pkey == NULL) { ++ SSLerr(SSL_F_SSL_LOAD_PKEY_FILE, j); ++ goto end; ++ } ++ ret = 1; ++end: ++ BIO_free(in); ++ return ret; ++} ++ ++int SSL_use_gm_PrivateKey(SSL *ssl, EVP_PKEY *pkey, int usage) ++{ ++ if (pkey == NULL) { ++ SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); ++ return 0; ++ } ++ if (usage == SSL_USAGE_SIG) { ++ return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_SIGN); ++ } else if (usage == SSL_USAGE_ENC) { ++ return ssl_set_sign_enc_pkey(ssl->cert, pkey, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++} ++ ++int SSL_use_gm_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, ++ long len, int usage) ++{ ++ int ret; ++ const unsigned char *p; ++ EVP_PKEY *pkey; ++ ++ p = d; ++ if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { ++ SSLerr(SSL_F_SSL_USE_GM_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); ++ return 0; ++ } ++ ++ ret = SSL_use_gm_PrivateKey(ssl, pkey, usage); ++ EVP_PKEY_free(pkey); ++ return ret; ++} ++ ++int SSL_use_gm_PrivateKey_file(SSL *ssl, const char *file, int type, int usage) ++{ ++ int ret; ++ EVP_PKEY *pkey = NULL; ++ ++ ret = ssl_load_pkey_file(ssl, NULL, file, type, &pkey); ++ if (ret == 1) { ++ ret = SSL_use_gm_PrivateKey(ssl, pkey, usage); ++ } ++ EVP_PKEY_free(pkey); ++ return ret; ++} ++#endif ++ + int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) + { + int rv; +@@ -319,6 +564,12 @@ static int ssl_set_cert(CERT *c, X509 *x) + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } ++#ifndef OPENSSL_NO_TLCP ++ if (i == SSL_PKEY_SM2_SIGN && !ssl_get_sm2_cert_id(x, &i)) { ++ SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); ++ return 0; ++ } ++#endif + #ifndef OPENSSL_NO_EC + if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); +@@ -349,7 +600,13 @@ static int ssl_set_cert(CERT *c, X509 *x) + X509_free(c->pkeys[i].x509); + X509_up_ref(x); + c->pkeys[i].x509 = x; ++#ifndef OPENSSL_NO_TLCP ++ if (i != SSL_PKEY_SM2_ENC) { ++ c->key = &(c->pkeys[i]); ++ } ++#else + c->key = &(c->pkeys[i]); ++#endif + + return 1; + } +@@ -411,6 +668,109 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) + return ret; + } + ++#ifndef OPENSSL_NO_TLCP ++static int ssl_set_sign_enc_cert(CERT *c, X509 *x, size_t id) ++{ ++ EVP_PKEY *pkey; ++ ++ pkey = X509_get0_pubkey(x); ++ if (pkey == NULL) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_X509_LIB); ++ return 0; ++ } ++ ++ if (ssl_is_sm2_cert(x) == 0 || ++ (id == SSL_PKEY_SM2_ENC && !ssl_is_sm2_enc_usage(x)) || ++ (id == SSL_PKEY_SM2_SIGN && !ssl_is_sm2_sign_usage(x))) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); ++ return 0; ++ } ++ ++ if (id == SSL_PKEY_SM2_SIGN && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { ++ SSLerr(SSL_F_SSL_SET_SIGN_ENC_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); ++ return 0; ++ } ++ ++ if (c->pkeys[id].privatekey != NULL) { ++ /* ++ * The return code from EVP_PKEY_copy_parameters is deliberately ++ * ignored. Some EVP_PKEY types cannot do this. ++ */ ++ EVP_PKEY_copy_parameters(pkey, c->pkeys[id].privatekey); ++ ERR_clear_error(); ++ ++ if (!X509_check_private_key(x, c->pkeys[id].privatekey)) { ++ /* ++ * don't fail for a cert/key mismatch, just free current private ++ * key (when switching to a different cert & key, first this ++ * function should be used, then ssl_set_pkey ++ */ ++ EVP_PKEY_free(c->pkeys[id].privatekey); ++ c->pkeys[id].privatekey = NULL; ++ /* clear error queue */ ++ ERR_clear_error(); ++ } ++ } ++ ++ X509_free(c->pkeys[id].x509); ++ X509_up_ref(x); ++ c->pkeys[id].x509 = x; ++ if (id != SSL_PKEY_SM2_ENC) { ++ c->key = &(c->pkeys[id]); ++ } ++ return 1; ++} ++ ++int SSL_CTX_use_gm_certificate(SSL_CTX *ctx, X509 *x, int usage) ++{ ++ int rv; ++ if (x == NULL) { ++ SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); ++ return 0; ++ } ++ rv = ssl_security_cert(NULL, ctx, x, 0, 1); ++ if (rv != 1) { ++ SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, rv); ++ return 0; ++ } ++ if (usage == SSL_USAGE_SIG) { ++ return ssl_set_sign_enc_cert(ctx->cert, x, SSL_PKEY_SM2_SIGN); ++ } else if (usage == SSL_USAGE_ENC) { ++ return ssl_set_sign_enc_cert(ctx->cert, x, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++} ++ ++int SSL_CTX_use_gm_certificate_file(SSL_CTX *ctx, const char *file, int type, int usage) ++{ ++ int ret; ++ X509 *x = NULL; ++ ret = ssl_load_cert_file(NULL, ctx, file, type, &x); ++ if (ret == 1) { ++ ret = SSL_CTX_use_gm_certificate(ctx, x, usage); ++ } ++ X509_free(x); ++ return ret; ++} ++ ++int SSL_CTX_use_gm_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d, int usage) ++{ ++ X509 *x; ++ int ret; ++ ++ x = d2i_X509(NULL, &d, (long)len); ++ if (x == NULL) { ++ SSLerr(SSL_F_SSL_CTX_USE_GM_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); ++ return 0; ++ } ++ ++ ret = SSL_CTX_use_gm_certificate(ctx, x, usage); ++ X509_free(x); ++ return ret; ++} ++#endif ++ + #ifndef OPENSSL_NO_RSA + int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) + { +@@ -502,6 +862,17 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } ++#ifndef OPENSSL_NO_TLCP ++ if (EVP_PKEY_is_sm2(pkey)) { ++ if (X509_check_private_key(ctx->cert->pkeys[SSL_PKEY_SM2_SIGN].x509, pkey)) { ++ return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_SIGN); ++ } else if (X509_check_private_key(ctx->cert->pkeys[SSL_PKEY_SM2_ENC].x509, pkey)) { ++ return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++ } ++#endif + return ssl_set_pkey(ctx->cert, pkey); + } + +@@ -562,6 +933,54 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + return ret; + } + ++#ifndef OPENSSL_NO_TLCP ++int SSL_CTX_use_gm_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey, int usage) ++{ ++ if (pkey == NULL) { ++ SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); ++ return 0; ++ } ++ if (usage == SSL_USAGE_SIG) { ++ return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_SIGN); ++ } else if (usage == SSL_USAGE_ENC) { ++ return ssl_set_sign_enc_pkey(ctx->cert, pkey, SSL_PKEY_SM2_ENC); ++ } ++ SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ return 0; ++} ++ ++int SSL_CTX_use_gm_PrivateKey_file(SSL_CTX *ctx, const char *file, int type, int usage) ++{ ++ int ret; ++ EVP_PKEY *pkey = NULL; ++ ++ ret = ssl_load_pkey_file(NULL, ctx, file, type, &pkey); ++ if (ret == 1) { ++ ret = SSL_CTX_use_gm_PrivateKey(ctx, pkey, usage); ++ } ++ EVP_PKEY_free(pkey); ++ return ret; ++} ++ ++int SSL_CTX_use_gm_PrivateKey_ASN1(int type, SSL_CTX *ctx, ++ const unsigned char *d, long len, int usage) ++{ ++ int ret; ++ const unsigned char *p; ++ EVP_PKEY *pkey; ++ ++ p = d; ++ if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { ++ SSLerr(SSL_F_SSL_CTX_USE_GM_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); ++ return 0; ++ } ++ ++ ret = SSL_CTX_use_gm_PrivateKey(ctx, pkey, usage); ++ EVP_PKEY_free(pkey); ++ return ret; ++} ++#endif ++ + /* + * Read a file that contains our certificate in "PEM" format, possibly + * followed by a sequence of CA certificates that should be sent to the peer +@@ -1073,6 +1492,12 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr + SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto out; + } ++#ifndef OPENSSL_NO_TLCP ++ if (i == SSL_PKEY_SM2_SIGN && !ssl_get_sm2_cert_id(x509, &i)) { ++ SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); ++ return 0; ++ } ++#endif + + if (!override && (c->pkeys[i].x509 != NULL + || c->pkeys[i].privatekey != NULL +@@ -1101,7 +1526,13 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr + EVP_PKEY_up_ref(privatekey); + c->pkeys[i].privatekey = privatekey; + ++#ifndef OPENSSL_NO_TLCP ++ if (i != SSL_PKEY_SM2_ENC) { ++ c->key = &(c->pkeys[i]); ++ } ++#else + c->key = &(c->pkeys[i]); ++#endif + + ret = 1; + out: +@@ -1120,3 +1551,113 @@ int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + { + return ssl_set_cert_and_key(NULL, ctx, x509, privatekey, chain, override); + } ++ ++#ifndef OPENSSL_NO_TLCP ++static int ssl_set_gm_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, ++ STACK_OF(X509) *chain, int override, int usage) ++{ ++ int ret = 0; ++ size_t id; ++ int j; ++ int rv; ++ CERT *c = ssl != NULL ? ssl->cert : ctx->cert; ++ STACK_OF(X509) *dup_chain = NULL; ++ EVP_PKEY *pubkey = NULL; ++ ++ /* Do all security checks before anything else */ ++ rv = ssl_security_cert(ssl, ctx, x509, 0, 1); ++ if (rv != 1) { ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, rv); ++ goto out; ++ } ++ for (j = 0; j < sk_X509_num(chain); j++) { ++ rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); ++ if (rv != 1) { ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, rv); ++ goto out; ++ } ++ } ++ ++ pubkey = X509_get_pubkey(x509); /* bumps reference */ ++ if (pubkey == NULL) ++ goto out; ++ if (privatekey == NULL) { ++ privatekey = pubkey; ++ } else { ++ /* For RSA, which has no parameters, missing returns 0 */ ++ if (EVP_PKEY_missing_parameters(privatekey)) { ++ if (EVP_PKEY_missing_parameters(pubkey)) { ++ /* nobody has parameters? - error */ ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_MISSING_PARAMETERS); ++ goto out; ++ } else { ++ /* copy to privatekey from pubkey */ ++ EVP_PKEY_copy_parameters(privatekey, pubkey); ++ } ++ } else if (EVP_PKEY_missing_parameters(pubkey)) { ++ /* copy to pubkey from privatekey */ ++ EVP_PKEY_copy_parameters(pubkey, privatekey); ++ } /* else both have parameters */ ++ ++ /* check that key <-> cert match */ ++ if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); ++ goto out; ++ } ++ } ++ if (usage == SSL_USAGE_SIG) { ++ id = SSL_PKEY_SM2_SIGN; ++ } else if (usage == SSL_USAGE_ENC) { ++ id = SSL_PKEY_SM2_ENC; ++ } else { ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, ERR_R_PASSED_INVALID_ARGUMENT); ++ goto out; ++ } ++ ++ if (!override && (c->pkeys[id].x509 != NULL ++ || c->pkeys[id].privatekey != NULL ++ || c->pkeys[id].chain != NULL)) { ++ /* No override, and something already there */ ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, SSL_R_NOT_REPLACING_CERTIFICATE); ++ goto out; ++ } ++ ++ if (chain != NULL) { ++ dup_chain = X509_chain_up_ref(chain); ++ if (dup_chain == NULL) { ++ SSLerr(SSL_F_SSL_SET_GM_CERT_AND_KEY, ERR_R_MALLOC_FAILURE); ++ goto out; ++ } ++ } ++ ++ sk_X509_pop_free(c->pkeys[id].chain, X509_free); ++ c->pkeys[id].chain = dup_chain; ++ ++ X509_free(c->pkeys[id].x509); ++ X509_up_ref(x509); ++ c->pkeys[id].x509 = x509; ++ ++ EVP_PKEY_free(c->pkeys[id].privatekey); ++ EVP_PKEY_up_ref(privatekey); ++ c->pkeys[id].privatekey = privatekey; ++ if (id != SSL_PKEY_SM2_ENC) { ++ c->key = &(c->pkeys[id]); ++ } ++ ret = 1; ++ out: ++ EVP_PKEY_free(pubkey); ++ return ret; ++} ++ ++int SSL_use_gm_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, ++ STACK_OF(X509) *chain, int override, int usage) ++{ ++ return ssl_set_gm_cert_and_key(ssl, NULL, x509, privatekey, chain, override, usage); ++} ++ ++int SSL_CTX_use_gm_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, ++ STACK_OF(X509) *chain, int override, int usage) ++{ ++ return ssl_set_gm_cert_and_key(NULL, ctx, x509, privatekey, chain, override, usage); ++} ++#endif +\ No newline at end of file +diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c +index cda6b7c..fb354e6 100644 +--- a/ssl/ssl_sess.c ++++ b/ssl/ssl_sess.c +@@ -283,6 +283,9 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) + GEN_SESSION_CB cb = def_generate_session_id; + + switch (s->version) { ++#ifndef OPENSSL_NO_TLCP ++ case TLCP_VERSION: ++#endif + case SSL3_VERSION: + case TLS1_VERSION: + case TLS1_1_VERSION: +diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c +index ca51c03..1750bdb 100644 +--- a/ssl/ssl_stat.c ++++ b/ssl/ssl_stat.c +@@ -312,6 +312,20 @@ const char *SSL_alert_desc_string(int value) + return "BH"; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + return "UP"; ++#ifndef OPENSSL_NO_TLCP ++ case TLCP_AD_UNSUPPORTED_SITE2SITE: ++ return "U2"; ++ case TLCP_AD_NO_AREA: ++ return "NA"; ++ case TLCP_AD_UNSUPPORTED_AREATYPE: ++ return "AT"; ++ case TLCP_AD_BAD_IBCPARAM: ++ return "BI"; ++ case TLCP_AD_UNSUPPORTED_IBCPARAM: ++ return "UI"; ++ case TLCP_AD_IDENTITY_NEED: ++ return "IN"; ++#endif + default: + return "UK"; + } +@@ -382,6 +396,20 @@ const char *SSL_alert_desc_string_long(int value) + return "unknown PSK identity"; + case TLS1_AD_NO_APPLICATION_PROTOCOL: + return "no application protocol"; ++#ifndef OPENSSL_NO_TLCP ++ case TLCP_AD_UNSUPPORTED_SITE2SITE: ++ return "unsupported site2site"; ++ case TLCP_AD_NO_AREA: ++ return "no area"; ++ case TLCP_AD_UNSUPPORTED_AREATYPE: ++ return "unsupported areatype"; ++ case TLCP_AD_BAD_IBCPARAM: ++ return "bad ibcparam"; ++ case TLCP_AD_UNSUPPORTED_IBCPARAM: ++ return "unsupported ibcparam"; ++ case TLCP_AD_IDENTITY_NEED: ++ return "identity need"; ++#endif + default: + return "unknown"; + } +diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c +index 0f39275..a03b6cd 100644 +--- a/ssl/statem/extensions.c ++++ b/ssl/statem/extensions.c +@@ -1056,7 +1056,11 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) + && s->ext.ecpointformats_len > 0 + && s->ext.peer_ecpointformats != NULL + && s->ext.peer_ecpointformats_len > 0 +- && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) { ++ && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA) ++#ifndef OPENSSL_NO_TLCP ++ || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) ++#endif ++ )) { + /* we are using an ECC cipher */ + size_t i; + unsigned char *list = s->ext.peer_ecpointformats; +diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c +index 9d38ac2..23ca93e 100644 +--- a/ssl/statem/extensions_clnt.c ++++ b/ssl/statem/extensions_clnt.c +@@ -132,6 +132,9 @@ static int use_ecc(SSL *s) + alg_a = c->algorithm_auth; + if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) + || (alg_a & SSL_aECDSA) ++#ifndef OPENSSL_NO_TLCP ++ || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) ++#endif + || c->min_tls >= TLS1_3_VERSION) { + ret = 1; + break; +diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c +index 04f64f8..7c5e3bf 100644 +--- a/ssl/statem/extensions_srvr.c ++++ b/ssl/statem/extensions_srvr.c +@@ -1386,7 +1386,11 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, + { + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; +- int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) ++ int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA) ++#ifndef OPENSSL_NO_TLCP ++ || (alg_k & SSL_kSM2DHE) || (alg_a & SSL_aSM2) ++#endif ++ ) + && (s->ext.peer_ecpointformats != NULL); + const unsigned char *plist; + size_t plistlen; +diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c +index 20f5bd5..d1fc2cc 100644 +--- a/ssl/statem/statem.c ++++ b/ssl/statem/statem.c +@@ -361,7 +361,11 @@ static int state_machine(SSL *s, int server) + goto end; + } + } else { ++#ifndef OPENSSL_NO_TLCP ++ if ((s->version >> 8) != SSL3_VERSION_MAJOR && s->version != TLCP_VERSION) { ++#else + if ((s->version >> 8) != SSL3_VERSION_MAJOR) { ++#endif + SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, + ERR_R_INTERNAL_ERROR); + goto end; +diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c +index d1a3969..052a733 100644 +--- a/ssl/statem/statem_clnt.c ++++ b/ssl/statem/statem_clnt.c +@@ -61,6 +61,10 @@ static int key_exchange_expected(SSL *s) + { + long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) ++ return 1; ++#endif + /* + * Can't skip server key exchange if this is an ephemeral + * ciphersuite or for SRP +@@ -2252,8 +2256,277 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) + #endif + } + ++#ifndef OPENSSL_NO_TLCP ++static int tlcp_process_ske_sm2ecc(SSL *s, PACKET *pkt) ++{ ++ EVP_MD_CTX *md_ctx = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ unsigned char *encbuf = NULL; ++ unsigned char *tbs = NULL; ++ ++ PACKET signature; ++ X509 *peer_sign_cert; ++ X509 *peer_enc_cert; ++ EVP_PKEY *peer_sign_pkey; ++ const EVP_MD *md; ++ unsigned char *tmp; ++ int rv, ebuflen, tbslen; ++ ++ rv = 0; ++ peer_sign_cert = s->session->peer; ++ peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); ++ if (peer_sign_cert == NULL || peer_enc_cert == NULL ++ || !ssl_is_sm2_cert(peer_sign_cert) ++ || !ssl_is_sm2_sign_usage(peer_sign_cert)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2ECC, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ peer_sign_pkey = X509_get0_pubkey(peer_sign_cert); ++ if (!EVP_PKEY_set_alias_type(peer_sign_pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ /* Get the signature algorithm according to the peer sign key */ ++ if (SSL_USE_SIGALGS(s)) { ++ unsigned int sigalg; ++ ++ if (!PACKET_get_net_2(pkt, &sigalg)) { ++ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ SSL_R_LENGTH_TOO_SHORT); ++ goto err; ++ } ++ if (tls12_check_peer_sigalg(s, sigalg, peer_sign_pkey) <=0) { ++ /* SSLfatal() already called */ ++ goto err; ++ } ++ } else if (!tls1_set_peer_legacy_sigalg(s, peer_sign_pkey)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md) ++ || EVP_PKEY_size(peer_sign_pkey) < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (!PACKET_get_length_prefixed_2(pkt, &signature) ++ || PACKET_remaining(pkt) != 0 ++ || PACKET_remaining(&signature) > EVP_PKEY_size(peer_sign_pkey)) { ++ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ SSL_R_LENGTH_MISMATCH); ++ goto err; ++ } ++ ++ ebuflen = i2d_X509(peer_enc_cert, NULL); ++ if (ebuflen < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_BUF_LIB); ++ goto err; ++ } ++ ++ md_ctx = EVP_MD_CTX_new(); ++ encbuf = OPENSSL_malloc(ebuflen + 3); ++ if (md_ctx == NULL || encbuf == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ /* Encode the DER encoding of an X509 structure, reserve 3 bytes for length */ ++ tmp = encbuf; ++ l2n3(ebuflen, tmp); ++ ebuflen = i2d_X509(peer_enc_cert, &tmp); ++ if (ebuflen < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_BUF_LIB); ++ goto err; ++ } ++ ebuflen += 3; ++ ++ if (EVP_DigestVerifyInit(md_ctx, &pctx, md, NULL, peer_sign_pkey) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ ++ tbslen = construct_key_exchange_tbs(s, &tbs, encbuf, ebuflen); ++ if (tbslen == 0) { ++ goto err; ++ } ++ ++ rv = EVP_DigestVerify(md_ctx, PACKET_data(&signature), ++ PACKET_remaining(&signature), tbs, tbslen); ++ if (rv <= 0) { ++ SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLCP_PROCESS_SKE_SM2ECC, ++ SSL_R_BAD_SIGNATURE); ++ } ++err: ++ OPENSSL_free(encbuf); ++ OPENSSL_free(tbs); ++ EVP_MD_CTX_free(md_ctx); ++ return rv; ++} ++ ++static int tlcp_process_ske_sm2dhe(SSL *s, PACKET *pkt) ++{ ++ unsigned char *ecparams; ++ int ecparams_len; ++ PACKET pt_encoded; ++ PACKET signature; ++ EVP_PKEY *pkey; ++ EVP_PKEY_CTX *pctx; ++ EVP_PKEY_CTX *verify_ctx; ++ EVP_MD_CTX *md_ctx = NULL; ++ char *id = "1234567812345678"; ++ int ret = 0; ++ int max_sig_len; ++ ++ if(!PACKET_get_bytes(pkt, (const unsigned char**)&ecparams, 3) ++ || !PACKET_get_length_prefixed_1(pkt, &pt_encoded) ++ || !PACKET_get_length_prefixed_2(pkt, &signature) ++ ) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_SHORT); ++ return 0; ++ } ++ ++ if (PACKET_remaining(pkt) != 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_LONG); ++ return 0; ++ } ++ ++ // generate tmp pkey s->s3->peer_tmp with peer pub key ++ if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ if (EVP_PKEY_paramgen_init(pctx) <= 0 ++ || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2) <= 0 ++ || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); ++ goto end; ++ } ++ ++ if (s->s3->peer_tmp == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, ++ PACKET_data(&pt_encoded), PACKET_remaining(&pt_encoded))) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_BAD_ECPOINT); ++ goto end; ++ } ++ ++ // verify the msg using peer sign cert's pubkey ++ if ((pkey = X509_get0_pubkey(s->session->peer)) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ max_sig_len = EVP_PKEY_size(pkey); ++ if (PACKET_remaining(&signature) > max_sig_len) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_LENGTH_TOO_LONG); ++ goto end; ++ } ++ ++ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); ++ goto end; ++ } ++ ++ if ((md_ctx = EVP_MD_CTX_new()) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_MALLOC_FAILURE); ++ goto end; ++ } ++ ++ if (EVP_DigestVerifyInit(md_ctx, &verify_ctx, EVP_sm3(), NULL, pkey) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); ++ goto end; ++ } ++ ++ if (EVP_PKEY_CTX_set1_id(verify_ctx, id, strlen(id)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); ++ goto end; ++ } ++ ++ ecparams_len = PACKET_data(&pt_encoded) + PACKET_remaining(&pt_encoded) - ecparams; ++ if (EVP_DigestVerifyUpdate(md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestVerifyUpdate(md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestVerifyUpdate(md_ctx, ecparams, ecparams_len) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, ERR_R_EVP_LIB); ++ goto end; ++ } ++ ++ if (EVP_DigestVerifyFinal(md_ctx, ++ PACKET_data(&signature), PACKET_remaining(&signature)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_SKE_SM2DHE, SSL_R_BAD_SIGNATURE); ++ goto end; ++ } ++ ++ ret = 1; ++ ++end: ++ EVP_PKEY_CTX_free(pctx); ++ EVP_MD_CTX_free(md_ctx); ++ ++ return ret; ++} ++ ++static MSG_PROCESS_RETURN tlcp_process_key_exchange(SSL *s, PACKET *pkt) ++{ ++ unsigned long alg_k; ++ ++ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; ++ ++ if (alg_k & SSL_kSM2ECC) { ++ if (!tlcp_process_ske_sm2ecc(s, pkt)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ } else if (alg_k & SSL_kSM2DHE) { ++ if (!tlcp_process_ske_sm2dhe(s, pkt)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ } else { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ return MSG_PROCESS_CONTINUE_READING; ++err: ++ return MSG_PROCESS_ERROR; ++} ++#endif ++ + MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) + { ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) ++ return tlcp_process_key_exchange(s, pkt); ++#endif + long alg_k; + EVP_PKEY *pkey = NULL; + EVP_MD_CTX *md_ctx = NULL; +@@ -3315,8 +3588,169 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) + #endif + } + ++#ifndef OPENSSL_NO_TLCP ++static int tlcp_construct_cke_sm2ecc(SSL *s, WPACKET *pkt) ++{ ++ unsigned char *encdata = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ unsigned char *pms = NULL; ++ size_t pmslen = 0; ++ ++ X509 *peer_enc_cert; ++ EVP_PKEY *peer_enc_pkey; ++ size_t enclen; ++ ++ peer_enc_cert = ssl_get_sm2_enc_cert(s, s->session->peer_chain); ++ peer_enc_pkey = X509_get0_pubkey(peer_enc_cert); ++ if (peer_enc_cert == NULL || peer_enc_pkey == NULL ++ || !EVP_PKEY_set_alias_type(peer_enc_pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ pmslen = SSL_MAX_MASTER_KEY_LENGTH; ++ pms = OPENSSL_malloc(pmslen); ++ if (pms == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ ++ pms[0] = s->client_version >> 8; ++ pms[1] = s->client_version & 0xff; ++ if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (!WPACKET_start_sub_packet_u16(pkt)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ /* Encrypt premaster secret { client_version, random[46] }*/ ++ pctx = EVP_PKEY_CTX_new(peer_enc_pkey, NULL); ++ if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 ++ || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ if (!WPACKET_reserve_bytes(pkt, enclen, &encdata) ++ || EVP_PKEY_encrypt(pctx, encdata, &enclen, pms, pmslen) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ pkt->written += enclen; ++ pkt->curr += enclen; ++ EVP_PKEY_CTX_free(pctx); ++ pctx = NULL; ++ ++ if (!WPACKET_close(pkt)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_CKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ s->s3->tmp.pms = pms; ++ s->s3->tmp.pmslen = pmslen; ++ ++ return 1; ++err: ++ OPENSSL_clear_free(pms, pmslen); ++ EVP_PKEY_CTX_free(pctx); ++ return 0; ++} ++ ++static int tlcp_construct_cke_sm2dhe(SSL *s, WPACKET *pkt) ++{ ++ EVP_PKEY *skey, *ckey; ++ unsigned char * pt_encoded = NULL; ++ int pt_encoded_len; ++ int ret = 0; ++ ++ if ((skey = s->s3->peer_tmp) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE) ++ || !WPACKET_put_bytes_u8(pkt, 0) ++ || !WPACKET_put_bytes_u8(pkt, 41)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if ((ckey = ssl_generate_pkey(skey)) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if ((pt_encoded_len = EVP_PKEY_get1_tls_encodedpoint(ckey, &pt_encoded)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_EC_LIB); ++ goto end; ++ } ++ ++ if (!WPACKET_sub_memcpy_u8(pkt, pt_encoded, pt_encoded_len)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ if (!tlcp_derive(s, ckey, skey)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CKE_SM2DHE, ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ ret = 1; ++ ++end: ++ EVP_PKEY_free(ckey); ++ if (pt_encoded) { ++ OPENSSL_free(pt_encoded); ++ } ++ ++ return ret; ++} ++ ++static int tlcp_construct_client_key_exchange(SSL *s, WPACKET *pkt) ++{ ++ unsigned long alg_k; ++ ++ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; ++ ++ if (alg_k & SSL_kSM2ECC) { ++ if (!tlcp_construct_cke_sm2ecc(s, pkt)) ++ goto err; ++ } else if (alg_k & SSL_kSM2DHE) { ++ if (!tlcp_construct_cke_sm2dhe(s, pkt)) ++ goto err; ++ } else { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ return 1; ++err: ++ return 0; ++} ++#endif ++ + int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) + { ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) ++ return tlcp_construct_client_key_exchange(s, pkt); ++#endif + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; +diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c +index 695caab..777a474 100644 +--- a/ssl/statem/statem_lib.c ++++ b/ssl/statem/statem_lib.c +@@ -227,6 +227,29 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, + return 1; + } + ++#ifndef OPENSSL_NO_TLCP ++static int get_tbs_hash_data(void *hdata, size_t hdatalen, unsigned char *out, size_t *outlen) ++{ ++ EVP_MD_CTX *md_ctx; ++ int rv = 0; ++ ++ md_ctx = EVP_MD_CTX_new(); ++ if (md_ctx == NULL) ++ goto err; ++ ++ // TLCP is only used SM3 ++ if (!EVP_DigestInit(md_ctx, EVP_sm3()) ++ || !EVP_DigestUpdate(md_ctx, (const void *)hdata, hdatalen) ++ || !EVP_DigestFinal(md_ctx, out, (unsigned int *)outlen)) { ++ goto err; ++ } ++ rv = 1; ++err: ++ EVP_MD_CTX_free(md_ctx); ++ return rv; ++} ++#endif ++ + int tls_construct_cert_verify(SSL *s, WPACKET *pkt) + { + EVP_PKEY *pkey = NULL; +@@ -238,6 +261,9 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) + unsigned char *sig = NULL; + unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; + const SIGALG_LOOKUP *lu = s->s3->tmp.sigalg; ++#ifndef OPENSSL_NO_TLCP ++ unsigned char out[EVP_MAX_MD_SIZE] = {0}; ++#endif + + if (lu == NULL || s->s3->tmp.cert == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, +@@ -251,6 +277,15 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) + ERR_R_INTERNAL_ERROR); + goto err; + } ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s) && EVP_PKEY_is_sm2(pkey)) { ++ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ } ++#endif + + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) { +@@ -264,7 +299,17 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) + /* SSLfatal() already called */ + goto err; + } +- ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) { ++ if (!get_tbs_hash_data(hdata, hdatalen, out, &hdatalen)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ /* Use new hash data for sign */ ++ hdata = out; ++ } ++#endif + if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); +@@ -359,6 +404,9 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) + unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + EVP_PKEY_CTX *pctx = NULL; ++#ifndef OPENSSL_NO_TLCP ++ unsigned char out[EVP_MAX_MD_SIZE] = {0}; ++#endif + + if (mctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, +@@ -373,6 +421,15 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) + ERR_R_INTERNAL_ERROR); + goto err; + } ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s) && EVP_PKEY_is_sm2(pkey)) { ++ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ } ++#endif + + if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_CERT_VERIFY, +@@ -448,6 +505,17 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) + /* SSLfatal() already called */ + goto err; + } ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) { ++ if (!get_tbs_hash_data(hdata, hdatalen, out, &hdatalen)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ /* Use new hash data for verify */ ++ hdata = out; ++ } ++#endif + + #ifdef SSL_DEBUG + fprintf(stderr, "Using client verify alg %s\n", +@@ -907,6 +975,60 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) + return 1; + } + ++#ifndef OPENSSL_NO_TLCP ++static int ssl_add_sm2_cert_for_tlcp(SSL *s, STACK_OF(X509) *chain, WPACKET *pkt, X509 *sign_cert) ++{ ++ CERT_PKEY *enc_cpk; ++ X509 *x; ++ int i = 0; ++ int idx = 0; ++ int count; ++ X509 *enc_cert; ++ ++ enc_cpk = &s->cert->pkeys[SSL_PKEY_SM2_ENC]; ++ // server must have enc cert ++ if (s->server && (enc_cpk == NULL || enc_cpk->x509 == NULL)) ++ return 0; ++ ++ enc_cert = enc_cpk->x509; ++ ++ if (sign_cert != NULL) { ++ if (!ssl_add_cert_to_wpacket(s, pkt, sign_cert, idx++)) { ++ return 0; ++ } ++ } else { ++ if (!ssl_add_cert_to_wpacket(s, pkt, sk_X509_value(chain, i++), idx++)) { ++ return 0; ++ } ++ } ++ ++ // enc cert put the second position ++ if (enc_cert != NULL && (s->options & SSL_OP_ENCCERT_SECOND_POSITION)) { ++ if (!ssl_add_cert_to_wpacket(s, pkt, enc_cert, idx++)) { ++ return 0; ++ } ++ enc_cert = NULL; ++ } ++ ++ count = sk_X509_num(chain); ++ for (; i < count; i++) { ++ x = sk_X509_value(chain, i); ++ if (!ssl_add_cert_to_wpacket(s, pkt, x, idx++)) { ++ return 0; ++ } ++ } ++ ++ // enc cert in the last position ++ if (enc_cert) { ++ if (!ssl_add_cert_to_wpacket(s, pkt, enc_cpk->x509, idx++)) { ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++#endif ++ + /* Add certificate chain to provided WPACKET */ + static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) + { +@@ -972,6 +1094,14 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); + return 0; + } ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) { ++ if (!ssl_add_sm2_cert_for_tlcp(s, chain, pkt, NULL)) { ++ X509_STORE_CTX_free(xs_ctx); ++ return 0; ++ } ++ } else { ++#endif + chain_count = sk_X509_num(chain); + for (i = 0; i < chain_count; i++) { + x = sk_X509_value(chain, i); +@@ -982,6 +1112,9 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) + return 0; + } + } ++#ifndef OPENSSL_NO_TLCP ++ } ++#endif + X509_STORE_CTX_free(xs_ctx); + } else { + i = ssl_security_cert_chain(s, extra_certs, x, 0); +@@ -989,6 +1122,11 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); + return 0; + } ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) { ++ return ssl_add_sm2_cert_for_tlcp(s, extra_certs, pkt, x); ++ } else { ++#endif + if (!ssl_add_cert_to_wpacket(s, pkt, x, 0)) { + /* SSLfatal() already called */ + return 0; +@@ -1000,6 +1138,9 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) + return 0; + } + } ++#ifndef OPENSSL_NO_TLCP ++ } ++#endif + } + return 1; + } +@@ -1444,6 +1585,9 @@ static const version_info tls_version_table[] = { + #else + {TLS1_VERSION, NULL, NULL}, + #endif ++#ifndef OPENSSL_NO_TLCP ++ {TLCP_VERSION, tlcp_client_method, tlcp_server_method}, ++#endif + #ifndef OPENSSL_NO_SSL3 + {SSL3_VERSION, sslv3_client_method, sslv3_server_method}, + #else +@@ -1596,7 +1740,10 @@ int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) + } + + for (vent = table; +- vent->version != 0 && version_cmp(s, version, vent->version) <= 0; ++#ifndef OPENSSL_NO_TLCP ++ ((version == SSL3_VERSION) && (vent->version == TLCP_VERSION)) || ++#endif ++ (vent->version != 0 && version_cmp(s, version, vent->version) <= 0); + ++vent) { + if (vent->cmeth != NULL + && version_cmp(s, version, vent->version) == 0 +@@ -1675,8 +1822,11 @@ int ssl_set_version_bound(int method_version, int version, int *bound) + *bound = version; + return 1; + } +- ++#ifndef OPENSSL_NO_TLCP ++ valid_tls = version >= TLCP_VERSION && version <= TLS_MAX_VERSION; ++#else + valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION; ++#endif + valid_dtls = + DTLS_VERSION_LE(version, DTLS_MAX_VERSION) && + DTLS_VERSION_GE(version, DTLS1_BAD_VER); +@@ -1868,6 +2018,9 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) + const SSL_METHOD *method; + + if (vent->smeth == NULL || ++#ifndef OPENSSL_NO_TLCP ++ ((client_version != TLCP_VERSION) && (vent->version == TLCP_VERSION)) || ++#endif + version_cmp(s, client_version, vent->version) < 0) + continue; + method = vent->smeth(); +@@ -2097,6 +2250,11 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, + * A table entry with a NULL client method is still a hole in the + * "version capability" vector. + */ ++#ifndef OPENSSL_NO_TLCP ++ if (vent->version == TLCP_VERSION) { ++ continue; ++ } ++#endif + if (vent->cmeth == NULL) { + hole = 1; + tmp_real_max = 0; +@@ -2120,7 +2278,23 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, + hole = 0; + } + } +- ++#ifndef OPENSSL_NO_TLCP ++ if (version == 0 && s->method->version == TLS_ANY_VERSION) { ++ /* ++ * enable tlcp condition (when only sslv3 version, dont choose tlcp): ++ * 1. version is TLS_ANY_VERSION, and all tls/ssl protocol disabled ++ * 2. max version > sslv3 or max version == tlcp_version ++ * 3. s->options not set SSL_OP_NO_TLCP ++ */ ++ if ((s->max_proto_version > SSL3_VERSION ++ || s->max_proto_version == TLCP_VERSION ++ || s->max_proto_version == 0) ++ && (s->options & SSL_OP_NO_TLCP) == 0) { ++ *min_version = *max_version = TLCP_VERSION; ++ return 0; ++ } ++ } ++#endif + *max_version = version; + + /* Fail if everything is disabled */ +diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c +index d701c46..ef13eec 100644 +--- a/ssl/statem/statem_srvr.c ++++ b/ssl/statem/statem_srvr.c +@@ -325,6 +325,11 @@ static int send_server_key_exchange(SSL *s) + { + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + ++#ifndef OPENSSL_NO_TLCP ++ /* TLCP: send ServerKeyExchange */ ++ if (SSL_IS_TLCP(s)) ++ return 1; ++#endif + /* + * only send a ServerKeyExchange if DH or fortezza but we have a + * sign only certificate PSK: may send PSK identity hints For +@@ -2356,7 +2361,17 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) + } + } + #endif +- ++#ifndef OPENSSL_NO_TLCP ++ /* ++ * As described by TLCP, when using ecdhe algorithm, ++ * client is required to send a certificate, ++ * so we set VEERFY_PEER mode. ++ */ ++ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSM2DHE) { ++ SSL_set_verify(s, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT ++ | SSL_VERIFY_CLIENT_ONCE, NULL); ++ } ++#endif + return WORK_FINISHED_STOP; + err: + return WORK_ERROR; +@@ -2485,8 +2500,270 @@ int tls_construct_server_done(SSL *s, WPACKET *pkt) + return 1; + } + ++#ifndef OPENSSL_NO_TLCP ++static int tlcp_construct_ske_sm2ecc(SSL *s, WPACKET *pkt) ++{ ++ EVP_MD_CTX *md_ctx = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ unsigned char *encbuf = NULL; ++ unsigned char *tbs = NULL; ++ ++ const SIGALG_LOOKUP *lu; ++ EVP_PKEY *sign_pkey; ++ X509 *enc_cert; ++ const EVP_MD *md; ++ unsigned char *sigbytes1, *sigbytes2, *tmp; ++ size_t siglen, tbslen; ++ int rv, ebuflen; ++ ++ rv = 0; ++ lu = s->s3->tmp.sigalg; ++ sign_pkey = s->cert->pkeys[SSL_PKEY_SM2_SIGN].privatekey; ++ enc_cert = s->cert->pkeys[SSL_PKEY_SM2_ENC].x509; ++ ++ if (lu == NULL || sign_pkey == NULL || enc_cert == NULL ++ || !tls1_lookup_md(lu, &md)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (!EVP_PKEY_is_sm2(sign_pkey) ++ || !EVP_PKEY_set_alias_type(sign_pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ /* send signature algorithm */ ++ if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ ebuflen = i2d_X509(enc_cert, NULL); ++ if (ebuflen < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_BUF_LIB); ++ goto err; ++ } ++ ++ md_ctx = EVP_MD_CTX_new(); ++ encbuf = OPENSSL_malloc(ebuflen + 3); ++ if (md_ctx == NULL || encbuf == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ /* Encode the DER encoding of an X509 structure, reserve 3 bytes for length */ ++ tmp = encbuf; ++ l2n3(ebuflen, tmp); ++ ebuflen = i2d_X509(enc_cert, &tmp); ++ if (ebuflen < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_BUF_LIB); ++ goto err; ++ } ++ ebuflen += 3; ++ ++ siglen = EVP_PKEY_size(sign_pkey); ++ if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sigbytes1) ++ || EVP_DigestSignInit(md_ctx, &pctx, md, NULL, sign_pkey) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ /* ++ * As described by TLCP, client_random, server_random and encryption ++ * certificate are signed. ++ */ ++ tbslen = construct_key_exchange_tbs(s, &tbs, encbuf, ebuflen); ++ if (tbslen == 0) { ++ goto err; ++ } ++ ++ rv = EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen); ++ ++ if (rv <= 0 || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) ++ || sigbytes1 != sigbytes2) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++err: ++ OPENSSL_free(encbuf); ++ OPENSSL_free(tbs); ++ EVP_MD_CTX_free(md_ctx); ++ return rv; ++} ++ ++static int tlcp_construct_ske_sm2dhe(SSL *s, WPACKET *pkt) ++{ ++ EVP_PKEY_CTX *ctx; ++ EVP_PKEY *pkey; ++ EVP_MD_CTX *md_ctx = NULL; ++ unsigned char *pt; ++ int ptLen; ++ char *id = "1234567812345678"; ++ unsigned char *ecparam; ++ size_t ecparam_len = 0; ++ int ret = 0; ++ size_t siglen; ++ unsigned char *sig; ++ ++ ecparam = WPACKET_get_curr(pkt); ++ ++ // ECParam: NameCurved, curvedtype {NameCurved(3), curveid(41, rfc8898 defined, but this msg is ignored) ++ if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE) ++ || !WPACKET_put_bytes_u8(pkt, 0) ++ || !WPACKET_put_bytes_u8(pkt, 41)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ pkey = s->cert->pkeys[SSL_PKEY_SM2_SIGN].privatekey; ++ if (pkey == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if (s->s3->tmp.pkey != NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ s->s3->tmp.pkey = ssl_generate_pkey_group(s, 41); ++ if (s->s3->tmp.pkey == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ ptLen = EVP_PKEY_get1_tls_encodedpoint(s->s3->tmp.pkey, &pt); ++ if (ptLen == 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_EC_LIB); ++ return 0; ++ } ++ ++ if (!WPACKET_sub_memcpy_u8(pkt, pt, ptLen)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ OPENSSL_free(pt); ++ return 0; ++ } ++ OPENSSL_free(pt); ++ ecparam_len = WPACKET_get_curr(pkt) - ecparam; ++ ++ if (!EVP_PKEY_is_sm2(pkey) || !EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_EC_LIB); ++ goto err; ++ } ++ ++ md_ctx = EVP_MD_CTX_new(); ++ if (md_ctx == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ if (EVP_DigestSignInit(md_ctx, &ctx, EVP_sm3(), NULL, pkey) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (EVP_PKEY_CTX_set1_id(ctx, id, strlen(id)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_EC_LIB); ++ return 0; ++ } ++ ++ if (EVP_DigestSignUpdate(md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestSignUpdate(md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestSignUpdate(md_ctx, ecparam, ecparam_len) <= 0 ++ ) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ ++ if ((siglen = EVP_PKEY_size(pkey)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sig)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (EVP_DigestSignFinal(md_ctx, sig, &siglen) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ SSL_R_SIGNATURE_ALGORITHMS_ERROR); ++ goto err; ++ } ++ ++ unsigned char* sig2 = NULL; ++ if (!WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sig2) || sig != sig2) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CONSTRUCT_SKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ ret = 1; ++ ++err: ++ EVP_MD_CTX_free(md_ctx); ++ if (!ret && s->s3->tmp.pkey) { ++ EVP_PKEY_free(s->s3->tmp.pkey); ++ s->s3->tmp.pkey = NULL; ++ } ++ ++ return ret; ++} ++ ++static int tlcp_construct_server_key_exchange(SSL *s, WPACKET *pkt) ++{ ++ unsigned long alg_k; ++ ++ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; ++ ++ if (alg_k & SSL_kSM2ECC) { ++ if (!tlcp_construct_ske_sm2ecc(s, pkt)) ++ goto err; ++ } else if (alg_k & SSL_kSM2DHE) { ++ if (!tlcp_construct_ske_sm2dhe(s, pkt)) ++ goto err; ++ } else { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ return 1; ++err: ++ return 0; ++} ++#endif ++ + int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) + { ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) ++ return tlcp_construct_server_key_exchange(s, pkt); ++#endif + #ifndef OPENSSL_NO_DH + EVP_PKEY *pkdh = NULL; + #endif +@@ -3455,8 +3732,174 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) + #endif + } + ++#ifndef OPENSSL_NO_TLCP ++static int tlcp_process_cke_sm2ecc(SSL *s, PACKET *pkt) ++{ ++ EVP_PKEY_CTX *pctx = NULL; ++ int ret = 0; ++ ++ unsigned char premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; ++ EVP_PKEY *enc_prv_pkey; ++ PACKET enc_premaster; ++ size_t decrypt_len; ++ ++ enc_prv_pkey = s->cert->pkeys[SSL_PKEY_SM2_ENC].privatekey; ++ if (enc_prv_pkey == NULL || !EVP_PKEY_is_sm2(enc_prv_pkey) ++ || !EVP_PKEY_set_alias_type(enc_prv_pkey, EVP_PKEY_SM2)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ SSL_R_NO_PRIVATE_KEY_ASSIGNED); ++ return 0; ++ } ++ ++ if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster) ++ || PACKET_remaining(pkt) != 0) { ++ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ SSL_R_LENGTH_MISMATCH); ++ return 0; ++ } ++ ++ pctx = EVP_PKEY_CTX_new(enc_prv_pkey, NULL); ++ if (pctx == NULL || EVP_PKEY_decrypt_init(pctx) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ ++ /* Decrypt premaster secret { client_version, random[46] }*/ ++ decrypt_len = sizeof(premaster_secret); ++ if (EVP_PKEY_decrypt(pctx, premaster_secret, &decrypt_len, ++ PACKET_data(&enc_premaster), PACKET_remaining(&enc_premaster)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ ERR_R_EVP_LIB); ++ goto err; ++ } ++ if (decrypt_len != SSL_MAX_MASTER_KEY_LENGTH) { ++ SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ SSL_R_DECRYPTION_FAILED); ++ goto err; ++ } ++ ++ /* Check client version */ ++ if (constant_time_eq_8(premaster_secret[0], (unsigned)(s->client_version >> 8)) == 0 || ++ constant_time_eq_8(premaster_secret[1], (unsigned)(s->client_version & 0xff)) == 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2ECC, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ if (!ssl_generate_master_secret(s, premaster_secret, ++ sizeof(premaster_secret), 0)) { ++ /* SSLfatal() already called */ ++ goto err; ++ } ++ ++ ret = 1; ++ err: ++ OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); ++ EVP_PKEY_CTX_free(pctx); ++ return ret; ++} ++ ++static int tlcp_process_cke_sm2dhe(SSL *s, PACKET *pkt) ++{ ++ int ret = 0; ++ const unsigned char *ecparams; ++ PACKET pt_encoded; ++ EVP_PKEY *skey; ++ EVP_PKEY *ckey = NULL; ++ ++ if ((skey = s->s3->tmp.pkey) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ if (!PACKET_get_bytes(pkt, &ecparams, 3)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ SSL_R_LENGTH_TOO_SHORT); ++ goto end; ++ } ++ ++ if (!PACKET_get_length_prefixed_1(pkt, &pt_encoded)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ SSL_R_LENGTH_TOO_SHORT); ++ goto end; ++ } ++ ++ if (PACKET_remaining(pkt) != 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ SSL_R_LENGTH_TOO_LONG); ++ goto end; ++ } ++ ++ if ((ckey = EVP_PKEY_new()) == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ ERR_R_MALLOC_FAILURE); ++ goto end; ++ } ++ ++ if (EVP_PKEY_copy_parameters(ckey, skey) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ if (EVP_PKEY_set1_tls_encodedpoint(ckey, ++ PACKET_data(&pt_encoded), PACKET_remaining(&pt_encoded)) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ ERR_R_EC_LIB); ++ goto end; ++ } ++ ++ if (!tlcp_derive(s, skey, ckey)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_PROCESS_CKE_SM2DHE, ++ ERR_R_INTERNAL_ERROR); ++ goto end; ++ } ++ ++ ret = 1; ++ ++end: ++ EVP_PKEY_free(ckey); ++ EVP_PKEY_free(skey); ++ s->s3->tmp.pkey = NULL; ++ ++ return ret; ++} ++ ++static MSG_PROCESS_RETURN tlcp_process_client_key_exchange(SSL *s, PACKET *pkt) ++{ ++ unsigned long alg_k; ++ ++ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; ++ ++ if (alg_k & SSL_kSM2ECC) { ++ if (!tlcp_process_cke_sm2ecc(s, pkt)) { ++ goto err; ++ } ++ } else if (alg_k & SSL_kSM2DHE) { ++ if (!tlcp_process_cke_sm2dhe(s, pkt)) { ++ goto err; ++ } ++ } else { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ++ SSL_F_TLCP_PROCESS_CLIENT_KEY_EXCHANGE, ++ SSL_R_UNKNOWN_CIPHER_TYPE); ++ goto err; ++ } ++ ++ return MSG_PROCESS_CONTINUE_PROCESSING; ++err: ++ return MSG_PROCESS_ERROR; ++} ++#endif ++ + MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) + { ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) ++ return tlcp_process_client_key_exchange(s, pkt); ++#endif + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; +diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c +index c85c0b0..e86a663 100644 +--- a/ssl/t1_enc.c ++++ b/ssl/t1_enc.c +@@ -676,3 +676,87 @@ int tls1_alert_code(int code) + return -1; + } + } ++ ++#ifndef OPENSSL_NO_TLCP ++int tlcp_alert_code(int code) ++{ ++ switch (code) { ++ case SSL_AD_CLOSE_NOTIFY: ++ return (SSL3_AD_CLOSE_NOTIFY); ++ case SSL_AD_UNEXPECTED_MESSAGE: ++ return (SSL3_AD_UNEXPECTED_MESSAGE); ++ case SSL_AD_BAD_RECORD_MAC: ++ return (SSL3_AD_BAD_RECORD_MAC); ++ case SSL_AD_DECRYPTION_FAILED: ++ return (TLS1_AD_DECRYPTION_FAILED); ++ case SSL_AD_RECORD_OVERFLOW: ++ return (TLS1_AD_RECORD_OVERFLOW); ++ case SSL_AD_DECOMPRESSION_FAILURE: ++ return (SSL3_AD_DECOMPRESSION_FAILURE); ++ case SSL_AD_HANDSHAKE_FAILURE: ++ return (SSL3_AD_HANDSHAKE_FAILURE); ++ case SSL_AD_BAD_CERTIFICATE: ++ return (SSL3_AD_BAD_CERTIFICATE); ++ case SSL_AD_UNSUPPORTED_CERTIFICATE: ++ return (SSL3_AD_UNSUPPORTED_CERTIFICATE); ++ case SSL_AD_CERTIFICATE_REVOKED: ++ return (SSL3_AD_CERTIFICATE_REVOKED); ++ case SSL_AD_CERTIFICATE_EXPIRED: ++ return (SSL3_AD_CERTIFICATE_EXPIRED); ++ case SSL_AD_CERTIFICATE_UNKNOWN: ++ return (SSL3_AD_CERTIFICATE_UNKNOWN); ++ case SSL_AD_ILLEGAL_PARAMETER: ++ return (SSL3_AD_ILLEGAL_PARAMETER); ++ case SSL_AD_UNKNOWN_CA: ++ return (TLS1_AD_UNKNOWN_CA); ++ case SSL_AD_ACCESS_DENIED: ++ return (TLS1_AD_ACCESS_DENIED); ++ case SSL_AD_DECODE_ERROR: ++ return (TLS1_AD_DECODE_ERROR); ++ case SSL_AD_DECRYPT_ERROR: ++ return (TLS1_AD_DECRYPT_ERROR); ++ case SSL_AD_EXPORT_RESTRICTION: ++ return (TLS1_AD_EXPORT_RESTRICTION); ++ case SSL_AD_PROTOCOL_VERSION: ++ return (TLS1_AD_PROTOCOL_VERSION); ++ case SSL_AD_INSUFFICIENT_SECURITY: ++ return (TLS1_AD_INSUFFICIENT_SECURITY); ++ case SSL_AD_INTERNAL_ERROR: ++ return (TLS1_AD_INTERNAL_ERROR); ++ case SSL_AD_USER_CANCELLED: ++ return (TLS1_AD_USER_CANCELLED); ++ case SSL_AD_NO_RENEGOTIATION: ++ return (TLS1_AD_NO_RENEGOTIATION); ++ case SSL_AD_UNSUPPORTED_EXTENSION: ++ return (TLS1_AD_UNSUPPORTED_EXTENSION); ++ case SSL_AD_CERTIFICATE_UNOBTAINABLE: ++ return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); ++ case SSL_AD_UNRECOGNIZED_NAME: ++ return (TLS1_AD_UNRECOGNIZED_NAME); ++ case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: ++ return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); ++ case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: ++ return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); ++ case SSL_AD_INAPPROPRIATE_FALLBACK: ++ return (TLS1_AD_INAPPROPRIATE_FALLBACK); ++ case SSL_AD_NO_APPLICATION_PROTOCOL: ++ return (TLS1_AD_NO_APPLICATION_PROTOCOL); ++ case SSL_AD_CERTIFICATE_REQUIRED: ++ return (SSL_AD_HANDSHAKE_FAILURE); ++ case SSL_AD_UNSUPPORTED_SITE2SITE: ++ return (TLCP_AD_UNSUPPORTED_SITE2SITE); ++ case SSL_AD_NO_AREA: ++ return (TLCP_AD_NO_AREA); ++ case SSL_AD_UNSUPPORTED_AREATYPE: ++ return (TLCP_AD_UNSUPPORTED_AREATYPE); ++ case SSL_AD_BAD_IBCPARAM: ++ return (TLCP_AD_BAD_IBCPARAM); ++ case SSL_AD_UNSUPPORTED_IBCPARAM: ++ return (TLCP_AD_UNSUPPORTED_IBCPARAM); ++ case SSL_AD_IDENTITY_NEED: ++ return (TLCP_AD_IDENTITY_NEED); ++ default: ++ return (-1); ++ } ++} ++#endif +\ No newline at end of file +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index 841feec..8b4a61b 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -93,6 +93,25 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = { + ssl3_handshake_write + }; + ++#ifndef OPENSSL_NO_TLCP ++SSL3_ENC_METHOD const TLCP_enc_data = { ++ tls1_enc, ++ tls1_mac, ++ tls1_setup_key_block, ++ tls1_generate_master_secret, ++ tls1_change_cipher_state, ++ tls1_final_finish_mac, ++ TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, ++ TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, ++ tlcp_alert_code, ++ tls1_export_keying_material, ++ SSL_ENC_FLAG_EXPLICIT_IV, ++ ssl3_set_handshake_header, ++ tls_close_construct_packet, ++ ssl3_handshake_write ++}; ++#endif ++ + long tls1_default_timeout(void) + { + /* +@@ -169,6 +188,9 @@ static const TLS_GROUP_INFO nid_list[] = { + {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ + {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ + {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ ++#ifndef OPENSSL_NO_TLCP ++ [40] = {EVP_PKEY_SM2, 128, TLS_CURVE_PRIME} /* sm2 (41) */ ++#endif + }; + + static const unsigned char ecformats_default[] = { +@@ -184,6 +206,9 @@ static const uint16_t eccurves_default[] = { + 30, /* X448 (30) */ + 25, /* secp521r1 (25) */ + 24, /* secp384r1 (24) */ ++#ifndef OPENSSL_NO_TLCP ++ 41, /* sm2 (41) */ ++#endif + }; + + static const uint16_t suiteb_curves[] = { +@@ -260,6 +285,12 @@ int tls_curve_allowed(SSL *s, uint16_t curve, int op) + # endif + if (FIPS_mode() && !(cinfo->flags & TLS_CURVE_FIPS)) + return 0; ++#ifndef OPENSSL_NO_TLCP ++ // SM2 is only allowed in TLCP ++ if (s->version != TLCP_VERSION && cinfo->nid == NID_sm2) { ++ return 0; ++ } ++#endif + ctmp[0] = curve >> 8; + ctmp[1] = curve & 0xff; + return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); +@@ -547,6 +578,10 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, + /* For Suite B we don't support char2 fields */ + if (tls1_suiteb(s)) + *num_formats = sizeof(ecformats_default) - 1; ++#ifndef OPENSSL_NO_TLCP ++ else if (SSL_IS_TLCP(s)) // TLCP version only support uncompressed ++ *num_formats = sizeof(ecformats_default) - 2; ++#endif + else + *num_formats = sizeof(ecformats_default); + } +@@ -639,6 +674,9 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) + /* Default sigalg schemes */ + static const uint16_t tls12_sigalgs[] = { + #ifndef OPENSSL_NO_EC ++#ifndef OPENSSL_NO_TLCP ++ TLSEXT_SIGALG_sm2dsa_sm3, ++#endif + TLSEXT_SIGALG_ecdsa_secp256r1_sha256, + TLSEXT_SIGALG_ecdsa_secp384r1_sha384, + TLSEXT_SIGALG_ecdsa_secp521r1_sha512, +@@ -687,6 +725,11 @@ static const uint16_t suiteb_sigalgs[] = { + + static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { + #ifndef OPENSSL_NO_EC ++#ifndef OPENSSL_NO_TLCP ++ {"sm2dsa_sm3", TLSEXT_SIGALG_sm2dsa_sm3, ++ NID_sm3, SSL_MD_SM3_IDX, EVP_PKEY_SM2, SSL_PKEY_SM2_SIGN, ++ NID_SM2_with_SM3, NID_sm2}, ++#endif + {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256, + NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA256, NID_X9_62_prime256v1}, +@@ -796,6 +839,10 @@ static const uint16_t tls_default_sigalg[] = { + TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, /* SSL_PKEY_GOST12_512 */ + 0, /* SSL_PKEY_ED25519 */ + 0, /* SSL_PKEY_ED448 */ ++#ifndef OPENSSL_NO_TLCP ++ TLSEXT_SIGALG_sm2dsa_sm3, /* SSL_PKEY_SM2_SIGN */ ++ 0, /* SSL_PKEY_SM2_ENC */ ++#endif + }; + + /* Lookup TLS signature algorithm */ +@@ -983,7 +1030,7 @@ int tls_check_sigalg_curve(const SSL *s, int curve) + + if (lu == NULL) + continue; +- if (lu->sig == EVP_PKEY_EC ++ if ((lu->sig == EVP_PKEY_EC || lu->sig == EVP_PKEY_SM2) + && lu->curve != NID_undef + && curve == lu->curve) + return 1; +@@ -1055,6 +1102,9 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) + if (lu == NULL + || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) + || (pkeyid != lu->sig ++#ifndef OPENSSL_NO_TCLP ++ && (lu->sig != EVP_PKEY_SM2) ++#endif + && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); +@@ -1199,6 +1249,13 @@ int ssl_set_client_disabled(SSL *s) + s->s3->tmp.mask_a |= SSL_aSRP; + s->s3->tmp.mask_k |= SSL_kSRP; + } ++#endif ++#ifndef OPENSSL_NO_TLCP ++ /* TLCP ciphersuites will be disabled while using other protocols */ ++ if (s->version != TLCP_VERSION) { ++ s->s3->tmp.mask_a |= SSL_aSM2; ++ s->s3->tmp.mask_k |= SSL_kSM2ECC | SSL_kSM2DHE; ++ } + #endif + return 1; + } +@@ -1319,7 +1376,11 @@ SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, + * (e.g. TLSv1.3) behave as if no ticket present to permit stateful + * resumption. + */ ++#ifndef OPENSSL_NO_TLCP ++ if ((s->version <= SSL3_VERSION && s->version != TLCP_VERSION) || !tls_use_ticket(s)) ++#else + if (s->version <= SSL3_VERSION || !tls_use_ticket(s)) ++#endif + return SSL_TICKET_NONE; + + ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket]; +@@ -1597,6 +1658,13 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) + unsigned char sigalgstr[2]; + int secbits; + ++#ifndef OPENSSL_NO_TLCP ++ // SM2 is only allowed in TLCP ++ if (s->version != TLCP_VERSION && lu != NULL && lu->sig == EVP_PKEY_SM2) { ++ return 0; ++ } ++#endif ++ + /* See if sigalgs is recognised and if hash is enabled */ + if (!tls1_lookup_md(lu, NULL)) + return 0; +@@ -2430,6 +2498,10 @@ void tls1_set_cert_validity(SSL *s) + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED25519); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED448); ++#ifndef OPENSSL_NO_TLCP ++ tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_SM2_ENC); ++ tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_SM2_SIGN); ++#endif + } + + /* User level utility function to check a chain is suitable */ +@@ -2734,6 +2806,55 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) + return lu; + } + ++#ifndef OPENSSL_NO_TLCP ++int tlcp_choose_sigalg(SSL *s, int fatalerrs) ++{ ++ int sig_idx; ++ const SIGALG_LOOKUP *lu = NULL; ++ ++ // sever must used sm2dsa cert for signature ++ if (s->server) { ++ s->cert->key = &(s->cert->pkeys[SSL_PKEY_SM2_SIGN]); ++ } ++ ++ sig_idx = s->cert->key - s->cert->pkeys; ++ ++ // check cert is existed ++ if (!ssl_has_cert(s, sig_idx)) { ++ if (!fatalerrs) ++ return 1; ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CHOOSE_SIGALG, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ // only support sm2dsa cert now ++ switch(sig_idx) { ++ case SSL_PKEY_ECC: ++ if (!EVP_PKEY_is_sm2(s->cert->key->privatekey)) ++ break; ++ case SSL_PKEY_SM2_SIGN: ++ lu = tls1_lookup_sigalg(TLSEXT_SIGALG_sm2dsa_sm3); ++ break; ++ default: ++ lu = NULL; ++ } ++ ++ if (lu == NULL) { ++ if (!fatalerrs) ++ return 1; ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLCP_CHOOSE_SIGALG, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ s->s3->tmp.cert = &s->cert->pkeys[sig_idx]; ++ s->cert->key = s->s3->tmp.cert; ++ s->s3->tmp.sigalg = lu; ++ return 1; ++} ++#endif ++ + /* + * Choose an appropriate signature algorithm based on available certificates + * Sets chosen certificate and signature algorithm. +@@ -2753,6 +2874,12 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) + s->s3->tmp.cert = NULL; + s->s3->tmp.sigalg = NULL; + ++#ifndef OPENSSL_NO_TLCP ++ if (SSL_IS_TLCP(s)) { ++ return tlcp_choose_sigalg(s, fatalerrs); ++ } ++#endif ++ + if (SSL_IS_TLS13(s)) { + lu = find_sig_alg(s, NULL, NULL); + if (lu == NULL) { +@@ -2766,6 +2893,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) + /* If ciphersuite doesn't require a cert nothing to do */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT)) + return 1; ++ + if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys)) + return 1; + +diff --git a/test/build.info b/test/build.info +index 726bd22..db16a1f 100644 +--- a/test/build.info ++++ b/test/build.info +@@ -51,7 +51,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN + recordlentest drbgtest drbg_cavs_test sslbuffertest \ + time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ + servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ +- sysdefaulttest errtest ssl_ctx_test gosttest ++ sysdefaulttest errtest ssl_ctx_test gosttest tlcptest + + SOURCE[versions]=versions.c + INCLUDE[versions]=../include +@@ -320,6 +320,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN + INCLUDE[dtlstest]=../include + DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a + ++ SOURCE[tlcptest]=tlcptest.c ssltestlib.c ++ INCLUDE[tlcptest]=.. ../include ++ DEPEND[tlcptest]=../libcrypto ../libssl libtestutil.a ++ + SOURCE[sslcorrupttest]=sslcorrupttest.c ssltestlib.c + INCLUDE[sslcorrupttest]=../include + DEPEND[sslcorrupttest]=../libcrypto ../libssl libtestutil.a +diff --git a/test/ciphername_test.c b/test/ciphername_test.c +index 303e28f..5c9edf4 100644 +--- a/test/ciphername_test.c ++++ b/test/ciphername_test.c +@@ -434,6 +434,9 @@ static int test_cipher_name(void) + if ((id == 0xFF85) || (id == 0xFF87)) + /* skip GOST2012-GOST8912-GOST891 and GOST2012-NULL-GOST12 */ + continue; ++ if ((id == 0xE011) || (id == 0xE013)) ++ /* skip ECDHE_SM2_WITH_SM4_CBC_SM3 and ECC_SM2_WITH_SM4_CBC_SM3 */ ++ continue; + p = SSL_CIPHER_standard_name(c); + q = get_std_name_by_id(id); + if (!TEST_ptr(p)) { +diff --git a/test/recipes/85-test_tlcp.t b/test/recipes/85-test_tlcp.t +new file mode 100644 +index 0000000..eb87123 +--- /dev/null ++++ b/test/recipes/85-test_tlcp.t +@@ -0,0 +1,34 @@ ++#! /usr/bin/env perl ++# Copyright 2022 Huawei Technologies Co., Ltd. All Rights Reserved. ++# ++# Licensed under the OpenSSL license (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++use OpenSSL::Test::Utils; ++use OpenSSL::Test qw/:DEFAULT data_file/; ++ ++setup("test_tlcp"); ++ ++plan skip_all => "TLCP is not supported by this OpenSSL build" ++ if disabled("tlcp"); ++ ++plan tests => 1; ++ ++ok(run(test(["tlcptest", ++ data_file("sm2-root-cert.pem"), # 0 ++ data_file("sm2-server-sig-cert.pem"), # 1 ++ data_file("sm2-server-sig-key.pem"), # 2 ++ data_file("sm2-server-enc-cert.pem"), # 3 ++ data_file("sm2-server-enc-key.pem"), # 4 ++ data_file("sm2-client-sig-cert.pem"), # 5 ++ data_file("sm2-client-sig-key.pem"), # 6 ++ data_file("sm2-client-enc-cert.pem"), # 7 ++ data_file("sm2-client-enc-key.pem"), # 8 ++ data_file("ecdsa-root-cert.pem"), # 9 ++ data_file("ecdsa-server-cert.pem"), # 10 ++ data_file("ecdsa-server-key.pem"), # 11 ++ data_file("ecdsa-client-cert.pem"), # 12 ++ data_file("ecdsa-client-key.pem") # 13 ++ ]))); +\ No newline at end of file +diff --git a/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem +new file mode 100644 +index 0000000..4f41232 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/ecdsa-client-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB2zCCAYGgAwIBAgIUIxUR+f5s2IPkP5kd86umC0jtOy0wCgYIKoZIzj0EAwIw ++YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB ++KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMF8xCzAJBgNVBAYTAkNO ++MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL ++DAdUZXN0IE9VMRcwFQYDVQQDDA5jbGllbnQgKEVDRFNBKTBZMBMGByqGSM49AgEG ++CCqGSM49AwEHA0IABJg2jl8qqQkLHwcqKC+gu8SWpDNHl8x2xSlsNkS8hm2edlsJ ++5QHfMPw7b138CmEE2FEtMqCtpRtsQnb5JRcxfTajGjAYMAkGA1UdEwQCMAAwCwYD ++VR0PBAQDAgbAMAoGCCqGSM49BAMCA0gAMEUCICBPe4rSKQdIWdB3u8EZ9+AR6Slu ++wsqdPm8p2mE409x4AiEAx513RsVDYohfejrvJmEL9ELIHmqTHjX+WjTjfMR/qrY= ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem b/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem +new file mode 100644 +index 0000000..8a356ba +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/ecdsa-client-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgj/hA8kscmW1VDMMn ++jWDNu/JrGrZ5Xr1kH0Q61zpRhIShRANCAASYNo5fKqkJCx8HKigvoLvElqQzR5fM ++dsUpbDZEvIZtnnZbCeUB3zD8O29d/AphBNhRLTKgraUbbEJ2+SUXMX02 ++-----END PRIVATE KEY----- +diff --git a/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem +new file mode 100644 +index 0000000..80d8c06 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/ecdsa-root-cert.pem +@@ -0,0 +1,14 @@ ++-----BEGIN CERTIFICATE----- ++MIICHzCCAcWgAwIBAgIUcxkoWsrQfKvdPzNFeZt9sUACCv8wCgYIKoZIzj0EAwIw ++YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB ++KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMGAxCzAJBgNVBAYTAkNO ++MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL ++DAdUZXN0IE9VMRgwFgYDVQQDDA9UZXN0IENBIChFQ0RTQSkwWTATBgcqhkjOPQIB ++BggqhkjOPQMBBwNCAAQb8M+p/ywfaaLb6y5jP/6essKMw+HBYIzluA8JpAyuSEag ++hiiIegi/fJA9tONUKGGQrE92gFIjsyrGvwPnYqF1o10wWzAdBgNVHQ4EFgQU+BnE ++9UFgm03egYusuG7wtBeF12kwHwYDVR0jBBgwFoAU+BnE9UFgm03egYusuG7wtBeF ++12kwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIh ++AO3LVs9OBinihB4W22ju3zoqfXTtHGdF0d9nbHbZEYqdAiAum1ZhMbtyWo/3YLDR ++2DqMuw5al5FbOlCIwrMbqcL+qQ== ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem b/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem +new file mode 100644 +index 0000000..7e0d8d7 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/ecdsa-server-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB2zCCAYGgAwIBAgIUIxUR+f5s2IPkP5kd86umC0jtOywwCgYIKoZIzj0EAwIw ++YDELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxGDAWBgNVBAMMD1Rlc3QgQ0EgKEVDRFNB ++KTAeFw0yMjA1MTkwOTI3MTVaFw0yNjA2MjcwOTI3MTVaMF8xCzAJBgNVBAYTAkNO ++MRIwEAYDVQQIDAlHdWFuZ2RvbmcxETAPBgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQL ++DAdUZXN0IE9VMRcwFQYDVQQDDA5zZXJ2ZXIgKEVDRFNBKTBZMBMGByqGSM49AgEG ++CCqGSM49AwEHA0IABAAmT2rADtfh1M/AW6n3cgLm2kEq/StWWcFDQ/AmTz54nFMp ++9AHt7xAqnizKl2UcdzUcDbhyBeNwjZ+80Eavvx2jGjAYMAkGA1UdEwQCMAAwCwYD ++VR0PBAQDAgbAMAoGCCqGSM49BAMCA0gAMEUCIQC70m1KUdKAsLI8zq78azjV2r/Z ++Oc6vwXfAqLKgF7EhtQIgYvh0XrMU9ETKKbfHORqJK+BD9DmFnAkxNpc9KVmN/D8= ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem b/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem +new file mode 100644 +index 0000000..9d9af8d +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/ecdsa-server-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqMLQcziYtVwg+30u ++MvCIb3bYAfxAazvxQ8I69Jtml9uhRANCAAQAJk9qwA7X4dTPwFup93IC5tpBKv0r ++VlnBQ0PwJk8+eJxTKfQB7e8QKp4sypdlHHc1HA24cgXjcI2fvNBGr78d ++-----END PRIVATE KEY----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem b/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem +new file mode 100644 +index 0000000..4a3e3f0 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-client-enc-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB2DCCAYCgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WQwCgYIKoEcz1UBg3Uw ++XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw ++HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBgMQswCQYDVQQGEwJDTjES ++MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH ++VGVzdCBPVTEYMBYGA1UEAwwPY2xpZW50IGVuYyhTTTIpMFkwEwYHKoZIzj0CAQYI ++KoEcz1UBgi0DQgAEsjxuZnSYi2M2iL4vUqHFdegJqxALkFxq+XiA/C8vQSMOCDaz ++8ZH1XrCwU3kMShiQyNM8AkjufKgCOGSB3B58qKMaMBgwCQYDVR0TBAIwADALBgNV ++HQ8EBAMCAzgwCgYIKoEcz1UBg3UDRgAwQwIgcwaVeJ3pa/WUuR28r9+tGRg2EIEO ++IOlzRUlo6mwqcDACHxugAc0CFsB1dUWLOJuwJtpYsEmNpNHwLzxa16cfW3w= ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem b/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem +new file mode 100644 +index 0000000..7a03991 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-client-enc-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg5xwdNhYtjBcZ5YEd ++VNu5609rYpePHUZUlQvlAJIqMB2hRANCAASyPG5mdJiLYzaIvi9SocV16AmrEAuQ ++XGr5eID8Ly9BIw4INrPxkfVesLBTeQxKGJDI0zwCSO58qAI4ZIHcHnyo ++-----END PRIVATE KEY----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem b/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem +new file mode 100644 +index 0000000..ce539a6 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-client-sig-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB3DCCAYKgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WMwCgYIKoEcz1UBg3Uw ++XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw ++HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBiMQswCQYDVQQGEwJDTjES ++MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH ++VGVzdCBPVTEaMBgGA1UEAwwRY2xpZW50IHNpZ24gKFNNMikwWTATBgcqhkjOPQIB ++BggqgRzPVQGCLQNCAAQDr0xTp4anFz8UHoMWyAWq/yYpiXdysF1dvciTvgET7CAA ++PydlOnKQw2K1NguwiecT4/XCpZMmbvhthMcCsyywoxowGDAJBgNVHRMEAjAAMAsG ++A1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEA1pxw3tMJ6epz6r/wonHMWBE/ ++3MBbRIsOq9xxhOhqhyECIBR0V+O51j3gsuDwSqSU81rYLXPaE0RGuhbdWOHi4bII ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem b/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem +new file mode 100644 +index 0000000..d2c537d +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-client-sig-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg0x2USJzgAonYJeiQ ++VkBw/u6/uo6B9M88YVL3A1OmorKhRANCAAQDr0xTp4anFz8UHoMWyAWq/yYpiXdy ++sF1dvciTvgET7CAAPydlOnKQw2K1NguwiecT4/XCpZMmbvhthMcCsyyw ++-----END PRIVATE KEY----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-root-cert.pem b/test/recipes/85-test_tlcp_data/sm2-root-cert.pem +new file mode 100644 +index 0000000..a20df8c +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-root-cert.pem +@@ -0,0 +1,14 @@ ++-----BEGIN CERTIFICATE----- ++MIICGjCCAcGgAwIBAgIUV3TWPlV09Vqm5/FpSqR7ryeGrfEwCgYIKoEcz1UBg3Uw ++XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw ++HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBeMQswCQYDVQQGEwJDTjES ++MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH ++VGVzdCBPVTEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTBZMBMGByqGSM49AgEGCCqB ++HM9VAYItA0IABHsTJfkk1NiaYrPidOIQHCGWBs77fKEhXoG1uONGTfHEDhhhA3EX ++QZBL9cVO//farVmKF9ipYR9GA4pk0wHtGEKjXTBbMB0GA1UdDgQWBBQ9YT+D7/Cv ++3KqG4b9YxuWOSbMRRzAfBgNVHSMEGDAWgBQ9YT+D7/Cv3KqG4b9YxuWOSbMRRzAM ++BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNHADBEAiAOJ4al ++v3c1AHBohqZQkAAZsY9+LSH/3/e3C4Q4jQsDUQIgUDJFXbXSUrsMoKFmkvHONmz+ ++9zGXND9ctJ1Dineo9dI= ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem b/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem +new file mode 100644 +index 0000000..c7a5ef2 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-server-enc-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB2jCCAYGgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WIwCgYIKoEcz1UBg3Uw ++XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw ++HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBhMQswCQYDVQQGEwJDTjES ++MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH ++VGVzdCBPVTEZMBcGA1UEAwwQc2VydmVyIGVuYyAoU00yKTBZMBMGByqGSM49AgEG ++CCqBHM9VAYItA0IABCWsJ/Vs/68DYkqIgoTdE8zoOA86UMHLASZriw+AF0lbmiOD ++dngO7RvDd55OOAmFK6sY7d+vzsIeMNQus4YLkc2jGjAYMAkGA1UdEwQCMAAwCwYD ++VR0PBAQDAgM4MAoGCCqBHM9VAYN1A0cAMEQCICZgP6OiaVyAbYTX5yJpiwusEvDU ++bMB/+hpnNA0ors3zAiB4EkZEBWZkd0su+umAXpO44IYaDvUumPSaGZLBbg7m1w== ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem b/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem +new file mode 100644 +index 0000000..ae509ec +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-server-enc-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgE32DrOaCm3ai/cPZ ++/9nnxJoCH171qVL7ignjIrMBGdGhRANCAAQlrCf1bP+vA2JKiIKE3RPM6DgPOlDB ++ywEma4sPgBdJW5ojg3Z4Du0bw3eeTjgJhSurGO3fr87CHjDULrOGC5HN ++-----END PRIVATE KEY----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem b/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem +new file mode 100644 +index 0000000..8238bad +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-server-sig-cert.pem +@@ -0,0 +1,12 @@ ++-----BEGIN CERTIFICATE----- ++MIIB2zCCAYKgAwIBAgIUMsQnTMiHshN4IOMc/ydgCOWB3WEwCgYIKoEcz1UBg3Uw ++XjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UECgwIVGVz ++dCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFjAUBgNVBAMMDVRlc3QgQ0EgKFNNMikw ++HhcNMjIwNTE5MDkyNzEwWhcNMjYwNjI3MDkyNzEwWjBiMQswCQYDVQQGEwJDTjES ++MBAGA1UECAwJR3Vhbmdkb25nMREwDwYDVQQKDAhUZXN0IE9yZzEQMA4GA1UECwwH ++VGVzdCBPVTEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNNMikwWTATBgcqhkjOPQIB ++BggqgRzPVQGCLQNCAAQgP2f+HnNb6BWCGscITDpf53BwVvpj3gxrlHz05Po3i2IA ++qyL5yL2VE+bqTrxCFpQOHupjW3f5Bkihv7IUW/zMoxowGDAJBgNVHRMEAjAAMAsG ++A1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiA63GVhHaDzcVJ9DMLK/53wQZvg ++HR+tj4MCBtb6F9hL9QIgbojf0R49GnO6VYHHUx0fe+4+2DfAcMdVIutOmbpRc60= ++-----END CERTIFICATE----- +diff --git a/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem b/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem +new file mode 100644 +index 0000000..f7fa712 +--- /dev/null ++++ b/test/recipes/85-test_tlcp_data/sm2-server-sig-key.pem +@@ -0,0 +1,5 @@ ++-----BEGIN PRIVATE KEY----- ++MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgr9nuyaNIE7aSQw/I ++sc7JhizpuCPUNKBF9zZy1on8BHShRANCAAQgP2f+HnNb6BWCGscITDpf53BwVvpj ++3gxrlHz05Po3i2IAqyL5yL2VE+bqTrxCFpQOHupjW3f5Bkihv7IUW/zM ++-----END PRIVATE KEY----- +diff --git a/test/sm2_internal_test.c b/test/sm2_internal_test.c +index 4951cd3..0ab84b2 100644 +--- a/test/sm2_internal_test.c ++++ b/test/sm2_internal_test.c +@@ -7,6 +7,7 @@ + * https://www.openssl.org/source/license.html + */ + ++#include + #include + #include + #include +@@ -17,6 +18,7 @@ + #include + #include + #include ++#include + #include "testutil.h" + + #ifndef OPENSSL_NO_SM2 +@@ -404,6 +406,114 @@ static int sm2_sig_test(void) + return testresult; + } + ++static EC_KEY* create_EC_key(EC_GROUP *group, const char *prv_hex, const char *x_hex, const char *y_hex) ++{ ++ BIGNUM *prv = NULL; ++ BIGNUM *x = NULL; ++ BIGNUM *y = NULL; ++ EC_KEY *key = NULL; ++ ++ if (!TEST_true(BN_hex2bn(&prv, prv_hex)) ++ || !TEST_true(BN_hex2bn(&x, x_hex)) ++ || !TEST_true(BN_hex2bn(&y, y_hex))) ++ goto err; ++ ++ if (!TEST_ptr(key = EC_KEY_new()) ++ || !TEST_true(EC_KEY_set_group(key, group)) ++ || !TEST_true(EC_KEY_set_private_key(key, prv)) ++ || !TEST_true(EC_KEY_set_public_key_affine_coordinates(key, x, y))) { ++ EC_KEY_free(key); ++ key = NULL; ++ } ++ ++err: ++ BN_free(prv); ++ BN_free(x); ++ BN_free(y); ++ ++ return key; ++} ++ ++static int sm2_key_exchange_test(void) ++{ ++ const char *userA = "ALICE123@YAHOO.COM"; ++ const char *userB = "BILL456@YAHOO.COM"; ++ const char *privA_hex = "6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE"; ++ const char *pubA_x_hex = "3099093BF3C137D8FCBBCDF4A2AE50F3B0F216C3122D79425FE03A45DBFE1655"; ++ const char *pubA_y_hex = "3DF79E8DAC1CF0ECBAA2F2B49D51A4B387F2EFAF482339086A27A8E05BAED98B"; ++ const char *privB_hex = "5E35D7D3F3C54DBAC72E61819E730B019A84208CA3A35E4C2E353DFCCB2A3B53"; ++ const char *pubB_x_hex = "245493D446C38D8CC0F118374690E7DF633A8A4BFB3329B5ECE604B2B4F37F43"; ++ const char *pubB_y_hex = "53C0869F4B9E17773DE68FEC45E14904E0DEA45BF6CECF9918C85EA047C60A4C"; ++ const char *ra = "83A2C9C8B96E5AF70BD480B472409A9A327257F1EBB73F5B073354B248668563"; ++ const char *x1 = "6CB5633816F4DD560B1DEC458310CBCC6856C09505324A6D23150C408F162BF0"; ++ const char *y1 = "0D6FCF62F1036C0A1B6DACCF57399223A65F7D7BF2D9637E5BBBEB857961BF1A"; ++ const char *rb = "33FE21940342161C55619C4A0C060293D543C80AF19748CE176D83477DE71C80"; ++ const char *x2 = "1799B2A2C778295300D9A2325C686129B8F2B5337B3DCF4514E8BBC19D900EE5"; ++ const char *y2 = "54C9288C82733EFDF7808AE7F27D0E732F7C73A7D9AC98B7D8740A91D0DB3CF4"; ++ ++ EC_KEY *keyA = NULL; ++ EC_KEY *keyB = NULL; ++ EC_KEY *keyRa = NULL; ++ EC_KEY *keyRb = NULL; ++ ++ unsigned char Ka[16]; ++ unsigned char Kb[16]; ++ unsigned char K[] = {0x55, 0xB0, 0xAC, 0x62, 0xA6, 0xB9, 0x27, 0xBA, 0x23, 0x70, 0x38, 0x32, 0xC8, 0x53, 0xDE, 0xD4}; ++ ++ int ret = 0; ++ ++ EC_GROUP *test_group = ++ create_EC_group ++ ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", ++ "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", ++ "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", ++ "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", ++ "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", ++ "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", ++ "1"); ++ ++ if (!TEST_ptr(keyA = create_EC_key(test_group, privA_hex, pubA_x_hex, pubA_y_hex)) ++ || !TEST_ptr(keyB = create_EC_key(test_group, privB_hex, pubB_x_hex, pubB_y_hex))) ++ goto done; ++ ++ if (!TEST_ptr(keyRa = create_EC_key(test_group, ra, x1, y1)) ++ || !TEST_ptr(keyRb = create_EC_key(test_group, rb, x2, y2))) ++ goto done; ++ ++ ret = SM2_compute_key(Ka, sizeof(Ka), 1, ++ userB, strlen(userB), userA, strlen(userA), ++ keyRb, keyRa, ++ keyB, keyA, ++ EVP_sm3()); ++ if (!TEST_int_eq(ret, sizeof(Ka))) { ++ ret = 0; ++ goto done; ++ } ++ ++ ret = SM2_compute_key(Kb, sizeof(Kb), 0, ++ userA, strlen(userA), userB, strlen(userB), ++ keyRa, keyRb, ++ keyA, keyB, ++ EVP_sm3()); ++ if (!TEST_int_eq(ret, sizeof(Kb))) { ++ ret = 0; ++ goto done; ++ } ++ ++ if (!TEST_mem_eq(Ka, sizeof(Ka), K, sizeof(K)) ++ || !TEST_mem_eq(Kb, sizeof(Kb), K, sizeof(K))) ++ ret = 0; ++ ++done: ++ EC_KEY_free(keyA); ++ EC_KEY_free(keyB); ++ EC_KEY_free(keyRa); ++ EC_KEY_free(keyRb); ++ EC_GROUP_free(test_group); ++ ++ return ret; ++} ++ + #endif + + int setup_tests(void) +@@ -413,6 +523,7 @@ int setup_tests(void) + #else + ADD_TEST(sm2_crypt_test); + ADD_TEST(sm2_sig_test); ++ ADD_TEST(sm2_key_exchange_test); + #endif + return 1; + } +diff --git a/test/tlcptest.c b/test/tlcptest.c +new file mode 100644 +index 0000000..7ebf1a2 +--- /dev/null ++++ b/test/tlcptest.c +@@ -0,0 +1,746 @@ ++/* ++ * Copyright 2022 Huawei Technologies Co., Ltd. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "internal/nelem.h" ++#include "ssltestlib.h" ++#include "testutil.h" ++ ++#ifndef OPENSSL_NO_TLCP ++ ++typedef enum { ++ IDX_SM2_ROOT_CERT = 0, ++ IDX_SM2_SERVER_SIG_CERT, ++ IDX_SM2_SERVER_SIG_KEY, ++ IDX_SM2_SERVER_ENC_CERT, ++ IDX_SM2_SERVER_ENC_KEY, ++ IDX_SM2_CLIENT_SIG_CERT, ++ IDX_SM2_CLIENT_SIG_KEY, ++ IDX_SM2_CLIENT_ENC_CERT, ++ IDX_SM2_CLIENT_ENC_KEY, ++ IDX_ECDSA_ROOT_CERT, ++ IDX_ECDSA_SERVER_CERT, ++ IDX_ECDSA_SERVER_KEY, ++ IDX_ECDSA_CLIENT_CERT, ++ IDX_ECDSA_CLIENT_KEY, ++ IDX_MAX ++} TEST_FILES_IDX; ++ ++#define OPTION_IS_CA 0x00000001U ++#define OPTION_IS_CERT 0x00000002U ++#define OPTION_IS_KEY 0x00000004U ++#define OPTION_USE_NEWAPI 0x00000008U ++#define OPTION_USE_EXTRA 0x00000010U ++#define OPTION_IS_SIG 0x00000020U ++#define OPTION_IS_ENC 0x00000040U ++ ++typedef struct { ++ TEST_FILES_IDX idx; ++ int flag; ++} LOAD_OPTION; ++ ++typedef struct { ++ const char *method_name; ++ const char *sid_ctx; ++ int verify_mode; ++ int ssl_options; ++ int set_version; ++ LOAD_OPTION load_options[IDX_MAX]; ++} SSL_CTX_OPTION; ++typedef struct { ++ const char *case_name; ++ SSL_CTX_OPTION server; ++ SSL_CTX_OPTION client; ++ const char *ciphersuite; ++ const char *expected_version; ++ const char *expected_cipher; ++ int regenotiate; ++ int reuse_session; ++} TLCP_TEST_CASE; ++ ++static const TLCP_TEST_CASE tlcp_test_cases[] = { ++ { "test_ecc_and_cert_position", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_extra_cert", ++ { ++ "TLS_server", NULL, SSL_VERIFY_NONE, 0, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA | OPTION_USE_EXTRA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_NONE, 0, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA | OPTION_USE_EXTRA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_ssl_op_no", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TLSv1_3 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLS_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TLSv1_3 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_set_version_bound", ++ { ++ "TLCP_server", NULL, SSL_VERIFY_PEER, 0, TLCP_VERSION, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLS_client", NULL, SSL_VERIFY_PEER, 0, TLCP_VERSION, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ NULL, ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_use_old_api_and_other_certs", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, 0, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_IS_ENC | OPTION_IS_KEY }, ++ {IDX_ECDSA_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_ECDSA_SERVER_CERT, OPTION_IS_CERT}, ++ {IDX_ECDSA_SERVER_KEY, OPTION_IS_KEY} ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, 0, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_IS_ENC | OPTION_IS_KEY }, ++ {IDX_ECDSA_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_ECDSA_CLIENT_CERT, OPTION_IS_CERT}, ++ {IDX_ECDSA_CLIENT_KEY, OPTION_IS_KEY} ++ } ++ }, ++ NULL, ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_sm2dhe_and_cert_position", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECDHE-SM4-CBC-SM3", ++ "TLCP", ++ "ECDHE-SM4-CBC-SM3", ++ 0, 0 ++ }, ++ { "test_ecc_regenotiate", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 1, 0 ++ }, ++ { "test_sm2dhe_regenotiate", ++ { ++ "TLS_server", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECDHE-SM4-CBC-SM3", ++ "TLCP", ++ "ECDHE-SM4-CBC-SM3", ++ 1, 0 ++ }, ++ { "test_ecc_reused_sessionid", ++ { ++ "TLS_server", "TEST", SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 1 ++ }, ++ { "test_sm2dhe_reused_sessionid", ++ { ++ "TLS_server", "TEST", SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_PEER, SSL_OP_NO_TICKET | SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECDHE-SM4-CBC-SM3", ++ "TLCP", ++ "ECDHE-SM4-CBC-SM3", ++ 0, 1 ++ }, ++ { "test_ecc_reused_ticket", ++ { ++ "TLS_server", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECC-SM4-CBC-SM3", ++ "TLCP", ++ "ECC-SM4-CBC-SM3", ++ 0, 1 ++ }, ++ { "test_sm2dhe_reused_ticket", ++ { ++ "TLS_server", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_SERVER_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_SERVER_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_SERVER_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ { ++ "TLCP_client", NULL, SSL_VERIFY_NONE, SSL_OP_ENCCERT_SECOND_POSITION, 0, ++ { ++ {IDX_SM2_ROOT_CERT, OPTION_IS_CA}, ++ {IDX_SM2_CLIENT_SIG_CERT, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_SIG_KEY, OPTION_USE_NEWAPI | OPTION_IS_SIG | OPTION_IS_KEY }, ++ {IDX_SM2_CLIENT_ENC_CERT, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_CERT }, ++ {IDX_SM2_CLIENT_ENC_KEY, OPTION_USE_NEWAPI | OPTION_IS_ENC | OPTION_IS_KEY } ++ } ++ }, ++ "ECDHE-SM4-CBC-SM3", ++ "TLCP", ++ "ECDHE-SM4-CBC-SM3", ++ 0, 1 ++ }, ++}; ++ ++static const char *test_files[IDX_MAX]; ++ ++static X509 *PEM_file_to_X509(const char *file) ++{ ++ BIO *in; ++ X509 *x = NULL; ++ ++ in = BIO_new(BIO_s_file()); ++ if (in == NULL || BIO_read_filename(in, file) <= 0) ++ goto err; ++ ++ x = PEM_read_bio_X509(in, NULL, NULL, NULL); ++err: ++ BIO_free(in); ++ return x; ++} ++ ++static EVP_PKEY *PEM_file_to_PrivateKey(const char *file) ++{ ++ BIO *in; ++ EVP_PKEY *pkey = NULL; ++ ++ in = BIO_new(BIO_s_file()); ++ if (in == NULL || BIO_read_filename(in, file) <= 0) ++ goto err; ++ ++ pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); ++err: ++ BIO_free(in); ++ return pkey; ++} ++ ++static int use_extra_cert_file(SSL_CTX *ctx, const char *file) ++{ ++ X509 *x; ++ ++ x = PEM_file_to_X509(file); ++ ++ if (x == NULL) ++ return 0; ++ ++ if (!SSL_CTX_add_extra_chain_cert(ctx, x)) { ++ X509_free(x); ++ return 0; ++ } ++ return 1; ++} ++ ++static int load_test_file_by_option(SSL_CTX *ctx, LOAD_OPTION opt) ++{ ++ int usage = -1; ++ if (opt.idx >= IDX_MAX) ++ return 0; ++ ++ if (opt.flag & OPTION_IS_CA) { ++ return (opt.flag & OPTION_USE_EXTRA) ++ ? use_extra_cert_file(ctx, test_files[opt.idx]) ++ : SSL_CTX_load_verify_locations(ctx, test_files[opt.idx], NULL); ++ } ++ ++ if (opt.flag & OPTION_IS_SIG) { ++ usage = SSL_USAGE_SIG; ++ } else if (opt.flag & OPTION_IS_ENC) { ++ usage = SSL_USAGE_ENC; ++ } ++ ++ if (opt.flag & OPTION_IS_CERT) { ++ return (opt.flag & OPTION_USE_NEWAPI) ++ ? SSL_CTX_use_gm_certificate_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM, usage) ++ : SSL_CTX_use_certificate_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM); ++ } else if (opt.flag & OPTION_IS_KEY){ ++ return (opt.flag & OPTION_USE_NEWAPI) ++ ? SSL_CTX_use_gm_PrivateKey_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM, usage) ++ : SSL_CTX_use_PrivateKey_file(ctx, test_files[opt.idx], SSL_FILETYPE_PEM); ++ } ++ return 1; ++} ++ ++static int load_test_files(SSL_CTX *ctx, LOAD_OPTION *opt, size_t optlen) ++{ ++ int i; ++ for (i = 0; i < optlen; ++i) { ++ if (!load_test_file_by_option(ctx, opt[i])) { ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++static SSL_CTX *SSL_CTX_create_by_option(const SSL_CTX_OPTION *opt) ++{ ++ SSL_CTX *ctx = NULL; ++ if (opt == NULL) ++ return NULL; ++ ++ if (strcmp(opt->method_name, "TLS_server") == 0) { ++ ctx = SSL_CTX_new(TLS_server_method()); ++ } else if (strcmp(opt->method_name, "TLS_client") == 0) { ++ ctx = SSL_CTX_new(TLS_client_method()); ++ } else if (strcmp(opt->method_name, "TLCP_server") == 0) { ++ ctx = SSL_CTX_new(TLCP_server_method()); ++ } else if (strcmp(opt->method_name, "TLCP_client") == 0) { ++ ctx = SSL_CTX_new(TLCP_client_method()); ++ } ++ if (ctx == NULL) ++ return NULL; ++ ++ SSL_CTX_set_verify(ctx, opt->verify_mode, NULL); ++ SSL_CTX_set_options(ctx, opt->ssl_options); ++ SSL_CTX_set_min_proto_version(ctx, opt->set_version); ++ SSL_CTX_set_max_proto_version(ctx, opt->set_version); ++ ++ if (opt->sid_ctx ++ && SSL_CTX_set_session_id_context(ctx, (unsigned char*)opt->sid_ctx, strlen(opt->sid_ctx)) != 1) { ++ SSL_CTX_free(ctx); ++ return NULL; ++ } ++ ++ if (!load_test_files(ctx, (LOAD_OPTION *)opt->load_options, OSSL_NELEM(opt->load_options))) { ++ SSL_CTX_free(ctx); ++ return NULL; ++ } ++ return ctx; ++} ++ ++static int test_tlcp_regenotiate(SSL *server_ssl, SSL *client_ssl) ++{ ++ SSL_SESSION *sess_pre; ++ SSL_SESSION *sess_post; ++ ++ if (!TEST_ptr(sess_pre = SSL_get0_session(server_ssl))) ++ return 0; ++ ++ if (!TEST_int_eq(SSL_renegotiate(client_ssl), 1) ++ || !TEST_int_eq(SSL_renegotiate_pending(client_ssl), 1)) ++ return 0; ++ ++ for (int i = 0; i < 3; i++) { ++ unsigned char buf; ++ size_t readbytes; ++ int ret = SSL_read_ex(client_ssl, &buf, sizeof(buf), &readbytes); ++ if ((ret > 0 && !TEST_ulong_eq(readbytes, 0)) ++ || (ret <= 0 && !TEST_int_eq(SSL_get_error(client_ssl, 0), SSL_ERROR_WANT_READ))) { ++ return 0; ++ } ++ ++ ret = SSL_read_ex(server_ssl, &buf, sizeof(buf), &readbytes); ++ if ((ret > 0 && !TEST_ulong_eq(readbytes, 0)) ++ || (ret <= 0 && SSL_get_error(server_ssl, 0) != SSL_ERROR_WANT_READ)) { ++ if (!strcmp("ECDHE-SM4-CBC-SM3", SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)))) ++ return 1; ++ return 0; ++ } ++ } ++ ++ if (!TEST_false(SSL_renegotiate_pending(client_ssl)) ++ || !TEST_int_eq(SSL_session_reused(client_ssl), 0) ++ || !TEST_int_eq(SSL_session_reused(server_ssl), 0) ++ || !TEST_ptr(sess_post = SSL_get0_session(server_ssl)) ++ || !TEST_ptr_ne(sess_pre, sess_post)) ++ return 0; ++ ++ return 1; ++} ++ ++static int test_tlcp_reuse_session(SSL **p_server_ssl, SSL **p_client_ssl) ++{ ++ int ret = 0; ++ SSL *server_ssl = *p_server_ssl; ++ SSL *client_ssl = *p_client_ssl; ++ SSL_CTX *server_ctx; ++ SSL_CTX *client_ctx; ++ SSL_SESSION *sess_pre; ++ SSL_SESSION *sess_post; ++ SSL_SESSION *sess; ++ const unsigned char *sess_pre_id; ++ unsigned int sess_pre_id_len; ++ const unsigned char *sess_post_id; ++ unsigned int sess_post_id_len; ++ const char *ciph_name = SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)); ++ ++ if (!TEST_ptr(server_ctx = SSL_get_SSL_CTX(server_ssl)) ++ || !TEST_ptr(client_ctx = SSL_get_SSL_CTX(client_ssl))) ++ return 0; ++ ++ if (!TEST_ptr(sess_pre = SSL_get0_session(server_ssl))) ++ return 0; ++ ++ if (!TEST_ptr(sess = SSL_get1_session(client_ssl))) ++ return 0; ++ ++ shutdown_ssl_connection(server_ssl, client_ssl); ++ *p_server_ssl = NULL; ++ *p_client_ssl = NULL; ++ ++ if (!TEST_int_eq(create_ssl_objects(server_ctx, client_ctx, p_server_ssl, p_client_ssl, NULL, NULL), 1)) ++ goto out; ++ ++ server_ssl = *p_server_ssl; ++ client_ssl = *p_client_ssl; ++ ++ if (!TEST_int_eq(SSL_set_session(client_ssl, sess), 1)) ++ goto out; ++ ++ if (!TEST_int_eq(create_ssl_connection(server_ssl, client_ssl, SSL_ERROR_NONE), 1)) ++ goto out; ++ ++ if (!TEST_int_eq(SSL_session_reused(client_ssl), 1) ++ || !TEST_int_eq(SSL_session_reused(server_ssl), 1)) ++ goto out; ++ ++ if (!TEST_ptr(sess_post = SSL_get0_session(server_ssl)) ++ || !TEST_str_eq(ciph_name, SSL_CIPHER_get_name(SSL_get_current_cipher(client_ssl)))) ++ goto out; ++ ++ if ((SSL_get_options(client_ssl) & SSL_OP_NO_TICKET) && (SSL_get_options(server_ssl) & SSL_OP_NO_TICKET) ++ && !TEST_ptr_eq(sess_pre, sess_post)) ++ goto out; ++ ++ sess_post_id = SSL_SESSION_get_id(sess_post, &sess_post_id_len); ++ sess_pre_id = SSL_SESSION_get_id(sess, &sess_pre_id_len); ++ ++ if (!TEST_mem_eq(sess_pre_id, sess_pre_id_len, sess_post_id, sess_post_id_len)) ++ goto out; ++ ++ ret = 1; ++ ++out: ++ SSL_SESSION_free(sess); ++ ++ return ret; ++} ++ ++static int test_tlcp_ciphersuites(int idx) ++{ ++ int result = 0; ++ SSL_CTX *server_ctx = NULL; ++ SSL_CTX *client_ctx = NULL; ++ SSL *server_ssl = NULL; ++ SSL *client_ssl = NULL; ++ const TLCP_TEST_CASE *case_ptr; ++ ++ case_ptr = &tlcp_test_cases[idx]; ++ if (!TEST_ptr(server_ctx = SSL_CTX_create_by_option(&case_ptr->server)) ++ || !TEST_ptr(client_ctx = SSL_CTX_create_by_option(&case_ptr->client))) ++ goto err; ++ ++ if (case_ptr->ciphersuite != NULL && ++ !TEST_int_eq(SSL_CTX_set_cipher_list(client_ctx, case_ptr->ciphersuite), 1)) ++ goto err; ++ ++ if (!TEST_int_eq(create_ssl_objects(server_ctx, client_ctx ++ , &server_ssl, &client_ssl, NULL, NULL), 1)) ++ goto err; ++ ++ if (!TEST_int_eq(create_ssl_connection(server_ssl, client_ssl, SSL_ERROR_NONE), 1)) ++ goto err; ++ ++ if (case_ptr->expected_version != NULL && ++ !TEST_str_eq(SSL_get_version(client_ssl), case_ptr->expected_version)) ++ goto err; ++ ++ if (case_ptr->expected_cipher && ++ !TEST_str_eq(SSL_get_cipher(client_ssl), case_ptr->expected_cipher)) ++ goto err; ++ ++ if (case_ptr->regenotiate ++ && !TEST_int_eq(test_tlcp_regenotiate(server_ssl, client_ssl), 1)) ++ goto err; ++ ++ if (case_ptr->reuse_session ++ && !TEST_int_eq(test_tlcp_reuse_session(&server_ssl, &client_ssl), 1)) ++ goto err; ++ ++ result = 1; ++err: ++ if (server_ssl != NULL) ++ SSL_shutdown(server_ssl); ++ if (client_ssl != NULL) ++ SSL_shutdown(client_ssl); ++ SSL_free(server_ssl); ++ SSL_free(client_ssl); ++ SSL_CTX_free(server_ctx); ++ SSL_CTX_free(client_ctx); ++ return result; ++} ++ ++static int test_use_certs_and_keys(void) ++{ ++ SSL_CTX *ctx = NULL; ++ SSL *ssl = NULL; ++ X509 *x = NULL; ++ EVP_PKEY *pkey = NULL; ++ int result = 0; ++ ++ ctx = SSL_CTX_new(TLCP_method()); ++ if (ctx == NULL) ++ goto err; ++ ++ ssl = SSL_new(ctx); ++ if (ssl == NULL) ++ goto err; ++ ++ if (!TEST_int_ne(SSL_use_gm_certificate_file(ssl, test_files[IDX_ECDSA_SERVER_CERT], ++ SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1) ++ || !TEST_int_ne(SSL_use_gm_PrivateKey_file(ssl, test_files[IDX_ECDSA_CLIENT_KEY], ++ SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1)) { ++ goto err; ++ } ++ ++ if (!TEST_int_eq(SSL_use_certificate_file(ssl, test_files[IDX_SM2_SERVER_SIG_CERT], ++ SSL_FILETYPE_PEM), 1) ++ || !TEST_int_eq(SSL_use_gm_PrivateKey_file(ssl, test_files[IDX_SM2_SERVER_SIG_KEY], ++ SSL_FILETYPE_PEM, SSL_USAGE_SIG), 1) ++ || !TEST_int_eq(SSL_use_gm_certificate_file(ssl, test_files[IDX_SM2_SERVER_ENC_CERT], ++ SSL_FILETYPE_PEM, SSL_USAGE_ENC), 1) ++ || !TEST_int_eq(SSL_use_PrivateKey_file(ssl, test_files[IDX_SM2_SERVER_ENC_KEY], ++ SSL_FILETYPE_PEM), 1)){ ++ goto err; ++ } ++ ++ if (!TEST_ptr(x = PEM_file_to_X509(test_files[IDX_SM2_CLIENT_SIG_CERT])) ++ || !TEST_ptr(pkey = PEM_file_to_PrivateKey(test_files[IDX_SM2_CLIENT_SIG_KEY])) ++ || !TEST_int_eq(SSL_use_gm_cert_and_key(ssl, x, pkey, NULL, 1, SSL_USAGE_SIG), 1)) { ++ goto err; ++ } ++ result = 1; ++err: ++ X509_free(x); ++ ++ EVP_PKEY_free(pkey); ++ SSL_free(ssl); ++ SSL_CTX_free(ctx); ++ return result; ++} ++ ++#endif ++ ++int setup_tests(void) ++{ ++#ifndef OPENSSL_NO_TLCP ++ int argc; ++ ++ for (argc = 0; argc < IDX_MAX; ++argc) { ++ if (!TEST_ptr(test_files[argc] = test_get_argument(argc))) { ++ return 0; ++ } ++ } ++ ++ ADD_ALL_TESTS(test_tlcp_ciphersuites, OSSL_NELEM(tlcp_test_cases)); ++ ADD_TEST(test_use_certs_and_keys); ++#endif ++ return 1; ++} +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 81a6388..95bccf9 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4630,3 +4630,5 @@ X509_set0_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2 + X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2 + X509_REQ_get0_sm2_id 6385 1_1_1m EXIST::FUNCTION:SM2 + X509_REQ_set0_sm2_id 6386 1_1_1m EXIST::FUNCTION:SM2 ++EVP_PKEY_is_sm2 6387 1_1_1m EXIST::FUNCTION:SM2 ++SM2_compute_key 6388 1_1_1m EXIST::FUNCTION: +diff --git a/util/libssl.num b/util/libssl.num +index 297522c..f120bed 100644 +--- a/util/libssl.num ++++ b/util/libssl.num +@@ -498,3 +498,20 @@ SSL_CTX_get_recv_max_early_data 498 1_1_1 EXIST::FUNCTION: + SSL_CTX_set_recv_max_early_data 499 1_1_1 EXIST::FUNCTION: + SSL_CTX_set_post_handshake_auth 500 1_1_1 EXIST::FUNCTION: + SSL_get_signature_type_nid 501 1_1_1a EXIST::FUNCTION: ++SSL_use_gm_PrivateKey 502 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_certificate_file 503 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_certificate 504 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_certificate_file 505 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_certificate_ASN1 506 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_PrivateKey_file 507 1_1_1m EXIST::FUNCTION:TLCP ++TLCP_method 508 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_PrivateKey_file 509 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_PrivateKey_ASN1 510 1_1_1m EXIST::FUNCTION:TLCP ++TLCP_client_method 511 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_cert_and_key 512 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_PrivateKey 513 1_1_1m EXIST::FUNCTION:TLCP ++TLCP_server_method 514 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_cert_and_key 515 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_certificate 516 1_1_1m EXIST::FUNCTION:TLCP ++SSL_use_gm_certificate_ASN1 517 1_1_1m EXIST::FUNCTION:TLCP ++SSL_CTX_use_gm_PrivateKey_ASN1 518 1_1_1m EXIST::FUNCTION:TLCP +-- +2.20.1 (Apple Git-117) + diff --git a/Feature-X509-command-supports-SM2-certificate-signing-with-default-sm2id.patch b/Feature-X509-command-supports-SM2-certificate-signing-with-default-sm2id.patch new file mode 100644 index 0000000000000000000000000000000000000000..99610bc9fa174112d79a2a44fd6e137d79ae86e2 --- /dev/null +++ b/Feature-X509-command-supports-SM2-certificate-signing-with-default-sm2id.patch @@ -0,0 +1,87 @@ +From d3e1106ea296a2ec94d27dd34692c34ad543ad04 Mon Sep 17 00:00:00 2001 +From: s_c_c +Date: Wed, 29 Jun 2022 17:54:50 +0800 +Subject: [PATCH] X509 command supports SM2 certificate signing with default + sm2id + +--- + apps/x509.c | 4 ++++ + include/openssl/sm2.h | 9 +++++++++ + test/recipes/25-test_req.t | 13 ++++++++++--- + 3 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/apps/x509.c b/apps/x509.c +index 1043eba..2669894 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -1078,6 +1078,10 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, + if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) + goto err; + } ++#ifndef OPENSSL_NO_SM2 ++ if (EVP_PKEY_is_sm2(pkey) && !EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) ++ goto err; ++#endif + if (!X509_sign(x, pkey, digest)) + goto err; + return 1; +diff --git a/include/openssl/sm2.h b/include/openssl/sm2.h +index 505ebfc..cc517bc 100644 +--- a/include/openssl/sm2.h ++++ b/include/openssl/sm2.h +@@ -1,3 +1,12 @@ ++/* ++ * Copyright 2022 Huawei Technologies Co., Ltd. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ + #ifndef HEADER_SM2_H + # define HEADER_SM2_H + +diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t +index d53e577..2b0c08c 100644 +--- a/test/recipes/25-test_req.t ++++ b/test/recipes/25-test_req.t +@@ -182,10 +182,10 @@ subtest "generating certificate requests" => sub { + }; + + subtest "generating SM2 certificate requests" => sub { +- plan tests => 4; ++ plan tests => 5; + + SKIP: { +- skip "SM2 is not supported by this OpenSSL build", 4 ++ skip "SM2 is not supported by this OpenSSL build", 5 + if disabled("sm2"); + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-new", "-key", srctop_file("test", "certs", "sm2.key"), +@@ -198,6 +198,13 @@ subtest "generating SM2 certificate requests" => sub { + "-sm2-id", "1234567812345678", "-sm3"])), + "Verifying signature on SM2 certificate request"); + ++ # Use default sm2 id ++ ok(run(app(["openssl", "x509", "-req", "-extfile", srctop_file("test", "CAss.cnf"), ++ "-extensions", "v3_ca", "-sm3", "-days", "365", ++ "-in", "testreq.pem", "-signkey", srctop_file("test", "certs", "sm2.key"), ++ "-out", "testsign.pem"])), ++ "Signing SM2 certificate request"); ++ + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-new", "-key", srctop_file("test", "certs", "sm2.key"), + "-sigopt", "sm2_hex_id:DEADBEEF", +@@ -218,7 +225,7 @@ run_conversion('req conversions', + run_conversion('req conversions -- testreq2', + srctop_file("test", "testreq2.pem")); + +-unlink "testkey.pem", "testreq.pem", "testreq_withattrs_pem.pem", "testreq_withattrs_der.pem"; ++unlink "testkey.pem", "testreq.pem", "testreq_withattrs_pem.pem", "testreq_withattrs_der.pem", "testsign.pem"; + + sub run_conversion { + my $title = shift; +-- +2.20.1 (Apple Git-117) + diff --git a/Feature-add-ARMv8-implementations-of-SM4-in-ECB-and-XTS.patch b/Feature-add-ARMv8-implementations-of-SM4-in-ECB-and-XTS.patch new file mode 100644 index 0000000000000000000000000000000000000000..1deb0abab8b714390966fc5c9bf2c95c2e990067 --- /dev/null +++ b/Feature-add-ARMv8-implementations-of-SM4-in-ECB-and-XTS.patch @@ -0,0 +1,2225 @@ +From df56c1da16d705fb6f471651feb77a69171af9e3 Mon Sep 17 00:00:00 2001 +From: Xu Yizhou +Date: Wed, 19 Oct 2022 13:28:58 +0800 +Subject: [PATCH] add ARMv8 implementations of SM4 in ECB and XTS + +--- + Configurations/00-base-templates.conf | 1 + + Configure | 4 + + crypto/evp/c_allc.c | 1 + + crypto/evp/e_sm4.c | 352 ++++++- + crypto/modes/build.info | 2 +- + crypto/modes/xts128gb.c | 204 ++++ + crypto/objects/obj_dat.h | 15 +- + crypto/objects/obj_mac.num | 1 + + crypto/objects/objects.txt | 1 + + crypto/sm4/asm/vpsm4_ex-armv8.pl | 1173 +++++++++++++++++++++ + crypto/sm4/build.info | 5 +- + doc/man3/EVP_sm4_xts.pod | 67 ++ + fuzz/oids.txt | 1 + + include/openssl/evp.h | 4 + + include/openssl/modes.h | 9 + + include/openssl/obj_mac.h | 5 + + test/evp_test.c | 17 +- + test/recipes/30-test_evp_data/evpciph.txt | 22 + + util/libcrypto.num | 2 + + 19 files changed, 1832 insertions(+), 54 deletions(-) + create mode 100644 crypto/modes/xts128gb.c + create mode 100644 crypto/sm4/asm/vpsm4_ex-armv8.pl + create mode 100644 doc/man3/EVP_sm4_xts.pod + +diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf +index e01dc63..1d35012 100644 +--- a/Configurations/00-base-templates.conf ++++ b/Configurations/00-base-templates.conf +@@ -321,6 +321,7 @@ my %targets=( + chacha_asm_src => "chacha-armv8.S", + poly1305_asm_src=> "poly1305-armv8.S", + keccak1600_asm_src => "keccak1600-armv8.S", ++ sm4_asm_src => "vpsm4_ex-armv8.S", + }, + parisc11_asm => { + template => 1, +diff --git a/Configure b/Configure +index a41c897..3bfe360 100755 +--- a/Configure ++++ b/Configure +@@ -1420,6 +1420,9 @@ unless ($disabled{asm}) { + if ($target{poly1305_asm_src} ne "") { + push @{$config{lib_defines}}, "POLY1305_ASM"; + } ++ if ($target{sm4_asm_src} ne "") { ++ push @{$config{lib_defines}}, "VPSM4_EX_ASM"; ++ } + } + + my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); +@@ -3375,6 +3378,7 @@ sub print_table_entry + "mtoutflag", + "multilib", + "build_scheme", ++ "sm4_asm_src", + ); + + if ($type eq "TABLE") { +diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c +index 22fdcc4..01b0d1f 100644 +--- a/crypto/evp/c_allc.c ++++ b/crypto/evp/c_allc.c +@@ -85,6 +85,7 @@ void openssl_add_all_ciphers_int(void) + EVP_add_cipher(EVP_sm4_cfb()); + EVP_add_cipher(EVP_sm4_ofb()); + EVP_add_cipher(EVP_sm4_ctr()); ++ EVP_add_cipher(EVP_sm4_xts()); + EVP_add_cipher_alias(SN_sm4_cbc, "SM4"); + EVP_add_cipher_alias(SN_sm4_cbc, "sm4"); + #endif +diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c +index fce3279..169d6c7 100644 +--- a/crypto/evp/e_sm4.c ++++ b/crypto/evp/e_sm4.c +@@ -15,86 +15,346 @@ + # include + # include "crypto/sm4.h" + # include "crypto/evp.h" ++# include "evp_local.h" ++# include "modes_local.h" ++ ++#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) ++# include "arm_arch.h" ++# if __ARM_MAX_ARCH__>=7 ++# if defined(VPSM4_EX_ASM) ++# define VPSM4_EX_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) ++# endif ++# endif ++#endif + + typedef struct { +- SM4_KEY ks; ++ union { ++ double align; ++ SM4_KEY ks; ++ } ks; ++ block128_f block; ++ union { ++ ecb128_f ecb; ++ } stream; + } EVP_SM4_KEY; + ++#ifdef VPSM4_EX_CAPABLE ++void vpsm4_ex_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); ++void vpsm4_ex_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); ++#define vpsm4_ex_encrypt SM4_encrypt ++#define vpsm4_ex_decrypt SM4_encrypt ++void vpsm4_ex_ecb_encrypt( ++ const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key, const int enc); ++/* xts mode in GB/T 17964-2021 */ ++void vpsm4_ex_xts_encrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void vpsm4_ex_xts_decrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++/* xts mode in IEEE Std 1619-2007 */ ++void vpsm4_ex_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++void vpsm4_ex_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, ++ const SM4_KEY *key2, const uint8_t iv[16]); ++#endif ++ ++# define BLOCK_CIPHER_generic(nid,blocksize,ivlen,nmode,mode,MODE,flags) \ ++static const EVP_CIPHER sm4_##mode = { \ ++ nid##_##nmode,blocksize,128/8,ivlen, \ ++ flags|EVP_CIPH_##MODE##_MODE, \ ++ sm4_init_key, \ ++ sm4_##mode##_cipher, \ ++ NULL, \ ++ sizeof(EVP_SM4_KEY), \ ++ NULL,NULL,NULL,NULL }; \ ++const EVP_CIPHER *EVP_sm4_##mode(void) \ ++{ return &sm4_##mode; } ++ ++#define BLOCK_CIPHER_generic_pack(nid,flags) \ ++ BLOCK_CIPHER_generic(nid,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ ++ BLOCK_CIPHER_generic(nid,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ ++ BLOCK_CIPHER_generic(nid,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ ++ BLOCK_CIPHER_generic(nid,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ ++ BLOCK_CIPHER_generic(nid,1,16,ctr,ctr,CTR,flags) ++ + static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { +- SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); ++ int mode; ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx); ++ ++ mode = EVP_CIPHER_CTX_mode(ctx); ++ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { ++#ifdef VPSM4_EX_CAPABLE ++ if (VPSM4_EX_CAPABLE) { ++ vpsm4_ex_set_decrypt_key(key, &dat->ks.ks); ++ dat->block = (block128_f) vpsm4_ex_decrypt; ++ if (mode == EVP_CIPH_ECB_MODE) ++ dat->stream.ecb = (ecb128_f) vpsm4_ex_ecb_encrypt; ++ } else ++#endif ++ { ++ dat->block = (block128_f)SM4_decrypt; ++ SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); ++ } ++ } else { ++#ifdef VPSM4_EX_CAPABLE ++ if (VPSM4_EX_CAPABLE) { ++ vpsm4_ex_set_encrypt_key(key, &dat->ks.ks); ++ dat->block = (block128_f) vpsm4_ex_encrypt; ++ if (mode == EVP_CIPH_ECB_MODE) ++ dat->stream.ecb = (ecb128_f) vpsm4_ex_ecb_encrypt; ++ } else ++#endif ++ { ++ dat->block = (block128_f)SM4_encrypt; ++ SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); ++ } ++ } + return 1; + } + +-static void sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, +- size_t len, const SM4_KEY *key, +- unsigned char *ivec, const int enc) ++static int sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) + { +- if (enc) +- CRYPTO_cbc128_encrypt(in, out, len, key, ivec, +- (block128_f)SM4_encrypt); ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); ++ ++ if (EVP_CIPHER_CTX_encrypting(ctx)) ++ CRYPTO_cbc128_encrypt(in, out, len, &dat->ks.ks, ++ EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + else +- CRYPTO_cbc128_decrypt(in, out, len, key, ivec, +- (block128_f)SM4_decrypt); ++ CRYPTO_cbc128_decrypt(in, out, len, &dat->ks.ks, ++ EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); ++ return 1; + } + +-static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, +- size_t length, const SM4_KEY *key, +- unsigned char *ivec, int *num, const int enc) ++static int sm4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) + { +- CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, +- (block128_f)SM4_encrypt); ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); ++ int num = EVP_CIPHER_CTX_num(ctx); ++ ++ CRYPTO_cfb128_encrypt(in, out, len, &dat->ks.ks, ++ ctx->iv, &num, ++ EVP_CIPHER_CTX_encrypting(ctx), dat->block); ++ EVP_CIPHER_CTX_set_num(ctx, num); ++ ++ return 1; + } + +-static void sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, +- const SM4_KEY *key, const int enc) ++static int sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) + { +- if (enc) +- SM4_encrypt(in, out, key); ++ size_t bl = EVP_CIPHER_CTX_block_size(ctx); ++ size_t i; ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); ++ ++ if (len < bl){ ++ return 1; ++ } ++ if (dat->stream.ecb != NULL) ++ (*dat->stream.ecb) (in, out, len, &dat->ks.ks, ++ EVP_CIPHER_CTX_encrypting(ctx)); + else +- SM4_decrypt(in, out, key); ++ for (i = 0, len -= bl; i <= len; i += bl) ++ (*dat->block) (in + i, out + i, &dat->ks.ks); ++ return 1; + } + +-static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, +- size_t length, const SM4_KEY *key, +- unsigned char *ivec, int *num) ++static int sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) + { +- CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, +- (block128_f)SM4_encrypt); +-} ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); ++ int num = EVP_CIPHER_CTX_num(ctx); + +-IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4, +- 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1, +- sm4_init_key, 0, 0, 0, 0) ++ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks.ks, ++ ctx->iv, &num, dat->block); ++ EVP_CIPHER_CTX_set_num(ctx, num); ++ return 1; ++} + + static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) + { +- unsigned int num = EVP_CIPHER_CTX_num(ctx); +- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx); ++ int n = EVP_CIPHER_CTX_num(ctx); ++ unsigned int num; ++ EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx); ++ ++ if (n < 0) ++ return 0; ++ num = (unsigned int)n; + +- CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, +- EVP_CIPHER_CTX_iv_noconst(ctx), +- EVP_CIPHER_CTX_buf_noconst(ctx), &num, +- (block128_f)SM4_encrypt); ++ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks.ks, ++ ctx->iv, ++ EVP_CIPHER_CTX_buf_noconst(ctx), &num, ++ dat->block); + EVP_CIPHER_CTX_set_num(ctx, num); + return 1; + } + +-static const EVP_CIPHER sm4_ctr_mode = { +- NID_sm4_ctr, 1, 16, 16, +- EVP_CIPH_CTR_MODE, +- sm4_init_key, +- sm4_ctr_cipher, +- NULL, +- sizeof(EVP_SM4_KEY), +- NULL, NULL, NULL, NULL +-}; ++BLOCK_CIPHER_generic_pack(NID_sm4, 0) + +-const EVP_CIPHER *EVP_sm4_ctr(void) ++typedef struct { ++ union { ++ double align; ++ SM4_KEY ks; ++ } ks1, ks2; /* sm4 key schedules to use */ ++ XTS128_CONTEXT xts; ++ int std; /* 0 for xts mode in GB/T 17964-2021 */ ++ /* 1 for xts mode in IEEE Std 1619-2007 */ ++ void (*stream_gb) (const unsigned char *in, ++ unsigned char *out, size_t length, ++ const SM4_KEY *key1, const SM4_KEY *key2, ++ const unsigned char iv[16]); /* stream for xts mode in GB/T 17964-2021 */ ++ void (*stream) (const unsigned char *in, ++ unsigned char *out, size_t length, ++ const SM4_KEY *key1, const SM4_KEY *key2, ++ const unsigned char iv[16]); /* stream for xts mode in IEEE Std 1619-2007 */ ++} EVP_SM4_XTS_CTX; ++ ++static int sm4_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) ++{ ++ EVP_SM4_XTS_CTX *xctx = EVP_C_DATA(EVP_SM4_XTS_CTX, c); ++ ++ if (type == EVP_CTRL_COPY) { ++ EVP_CIPHER_CTX *out = ptr; ++ EVP_SM4_XTS_CTX *xctx_out = EVP_C_DATA(EVP_SM4_XTS_CTX,out); ++ ++ if (xctx->xts.key1) { ++ if (xctx->xts.key1 != &xctx->ks1) ++ return 0; ++ xctx_out->xts.key1 = &xctx_out->ks1; ++ } ++ if (xctx->xts.key2) { ++ if (xctx->xts.key2 != &xctx->ks2) ++ return 0; ++ xctx_out->xts.key2 = &xctx_out->ks2; ++ } ++ return 1; ++ } else if (type == EVP_CTRL_XTS_STANDARD) { ++ if ((arg < 0) || (arg > 1)) ++ return 0; ++ xctx->std = arg; ++ return 1; ++ } else if (type != EVP_CTRL_INIT) ++ return -1; ++ /* key1 and key2 are used as an indicator both key and IV are set */ ++ xctx->xts.key1 = NULL; ++ xctx->xts.key2 = NULL; ++ return 1; ++} ++ ++static int sm4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc) ++{ ++ EVP_SM4_XTS_CTX *xctx = EVP_C_DATA(EVP_SM4_XTS_CTX,ctx); ++ ++ if (!iv && !key) ++ return 1; ++ ++ if (key) ++ do { ++ /* The key is two half length keys in reality */ ++ const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; ++ xctx->stream_gb = NULL; ++ xctx->stream = NULL; ++#ifdef VPSM4_EX_CAPABLE ++ if (VPSM4_EX_CAPABLE) { ++ if (enc) { ++ vpsm4_ex_set_encrypt_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) vpsm4_ex_encrypt; ++ xctx->stream_gb = vpsm4_ex_xts_encrypt_gb; ++ xctx->stream = vpsm4_ex_xts_encrypt; ++ } else { ++ vpsm4_ex_set_decrypt_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) vpsm4_ex_decrypt; ++ xctx->stream_gb = vpsm4_ex_xts_decrypt_gb; ++ xctx->stream = vpsm4_ex_xts_decrypt; ++ } ++ vpsm4_ex_set_encrypt_key(key + bytes, &xctx->ks2.ks); ++ xctx->xts.block2 = (block128_f) vpsm4_ex_encrypt; ++ ++ xctx->xts.key1 = &xctx->ks1; ++ break; ++ } else ++#endif ++ (void)0; /* terminate potentially open 'else' */ ++ ++ if (enc) { ++ SM4_set_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) SM4_encrypt; ++ } else { ++ SM4_set_key(key, &xctx->ks1.ks); ++ xctx->xts.block1 = (block128_f) SM4_decrypt; ++ } ++ ++ SM4_set_key(key + bytes, &xctx->ks2.ks); ++ xctx->xts.block2 = (block128_f) SM4_encrypt; ++ ++ xctx->xts.key1 = &xctx->ks1; ++ } while (0); ++ ++ if (iv) { ++ xctx->xts.key2 = &xctx->ks2; ++ memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); ++ } ++ ++ return 1; ++} ++ ++static int sm4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ EVP_SM4_XTS_CTX *xctx = EVP_C_DATA(EVP_SM4_XTS_CTX,ctx); ++ if (!xctx->xts.key1 || !xctx->xts.key2) ++ return 0; ++ if (!out || !in || len < SM4_BLOCK_SIZE) ++ return 0; ++ if (xctx->std) { ++ if (xctx->stream) ++ (*xctx->stream) (in, out, len, ++ xctx->xts.key1, xctx->xts.key2, ++ EVP_CIPHER_CTX_iv_noconst(ctx)); ++ else if (CRYPTO_xts128_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx), ++ in, out, len, ++ EVP_CIPHER_CTX_encrypting(ctx))) ++ return 0; ++ } else { ++ if (xctx->stream_gb) ++ (*xctx->stream_gb) (in, out, len, ++ xctx->xts.key1, xctx->xts.key2, ++ EVP_CIPHER_CTX_iv_noconst(ctx)); ++ else if (CRYPTO_xts128gb_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx), ++ in, out, len, ++ EVP_CIPHER_CTX_encrypting(ctx))) ++ return 0; ++ } ++ return 1; ++} ++ ++#define SM4_XTS_BLOCK_SIZE 1 ++#define SM4_XTS_IV_LENGTH 16 ++#define SM4_XTS_KEY_LENGTH 32 ++ ++#define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ ++ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ ++ | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_XTS_MODE) ++ ++static const EVP_CIPHER sm4_xts_mode = { ++ NID_sm4_xts, ++ SM4_XTS_BLOCK_SIZE, ++ SM4_XTS_KEY_LENGTH, ++ SM4_XTS_IV_LENGTH, ++ XTS_FLAGS, ++ sm4_xts_init_key, ++ sm4_xts_cipher, ++ NULL, ++ sizeof(EVP_SM4_XTS_CTX), ++ NULL, NULL, sm4_xts_ctrl, NULL ++}; ++ ++const EVP_CIPHER *EVP_sm4_xts(void) + { +- return &sm4_ctr_mode; ++ return &sm4_xts_mode; + } + + #endif +diff --git a/crypto/modes/build.info b/crypto/modes/build.info +index 821340e..f974b04 100644 +--- a/crypto/modes/build.info ++++ b/crypto/modes/build.info +@@ -1,7 +1,7 @@ + LIBS=../../libcrypto + SOURCE[../../libcrypto]=\ + cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \ +- ccm128.c xts128.c wrap128.c ocb128.c \ ++ ccm128.c xts128.c xts128gb.c wrap128.c ocb128.c \ + {- $target{modes_asm_src} -} + + INCLUDE[gcm128.o]=.. +diff --git a/crypto/modes/xts128gb.c b/crypto/modes/xts128gb.c +new file mode 100644 +index 0000000..8f57cc5 +--- /dev/null ++++ b/crypto/modes/xts128gb.c +@@ -0,0 +1,204 @@ ++/* ++ * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++// This is the xts mode in GB/T 17964-2021 ++#include ++#include "modes_local.h" ++#include ++ ++#ifndef STRICT_ALIGNMENT ++# ifdef __GNUC__ ++typedef u64 u64_a1 __attribute((__aligned__(1))); ++# else ++typedef u64 u64_a1; ++# endif ++#endif ++ ++int CRYPTO_xts128gb_encrypt(const XTS128_CONTEXT *ctx, ++ const unsigned char iv[16], ++ const unsigned char *inp, unsigned char *out, ++ size_t len, int enc) ++{ ++ const union { ++ long one; ++ char little; ++ } is_endian = { ++ 1 ++ }; ++ union { ++ u64 u[2]; ++ u32 d[4]; ++ u8 c[16]; ++ } tweak, scratch; ++ unsigned int i; ++ ++ if (len < 16) ++ return -1; ++ ++ memcpy(tweak.c, iv, 16); ++ ++ (*ctx->block2) (tweak.c, tweak.c, ctx->key2); ++ ++ if (!enc && (len % 16)) ++ len -= 16; ++ ++ while (len >= 16) { ++#if defined(STRICT_ALIGNMENT) ++ memcpy(scratch.c, inp, 16); ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++#else ++ scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak.u[0]; ++ scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak.u[1]; ++#endif ++ (*ctx->block1) (scratch.c, scratch.c, ctx->key1); ++#if defined(STRICT_ALIGNMENT) ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++ memcpy(out, scratch.c, 16); ++#else ++ ((u64_a1 *)out)[0] = scratch.u[0] ^= tweak.u[0]; ++ ((u64_a1 *)out)[1] = scratch.u[1] ^= tweak.u[1]; ++#endif ++ inp += 16; ++ out += 16; ++ len -= 16; ++ ++ if (len == 0) ++ return 0; ++ ++ if (is_endian.little) { ++ u8 res; ++ u64 hi, lo; ++#ifdef BSWAP8 ++ hi = BSWAP8(tweak.u[0]); ++ lo = BSWAP8(tweak.u[1]); ++#else ++ u8 *p = tweak.c; ++ ++ hi = (u64)GETU32(p) << 32 | GETU32(p + 4); ++ lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); ++#endif ++ res = (u8)lo & 1; ++ tweak.u[0] = (lo >> 1) | (hi << 63); ++ tweak.u[1] = hi >> 1; ++ if (res) ++ tweak.c[15] ^= 0xe1; ++#ifdef BSWAP8 ++ hi = BSWAP8(tweak.u[0]); ++ lo = BSWAP8(tweak.u[1]); ++#else ++ p = tweak.c; ++ ++ hi = (u64)GETU32(p) << 32 | GETU32(p + 4); ++ lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); ++#endif ++ tweak.u[0] = lo; ++ tweak.u[1] = hi; ++ } else { ++ u8 Cin, Cout; ++ Cin = 0; ++ for (i = 0; i < 16; ++i) { ++ Cout = (tweak.c[i] << 7) & 0x80; ++ tweak.c[i] = ((tweak.c[i] >> 1) + Cin) & 0xff; ++ Cin = Cout; ++ } ++ if (Cout) ++ tweak.c[0] ^= 0xe1; ++ } ++ } ++ if (enc) { ++ for (i = 0; i < len; ++i) { ++ u8 c = inp[i]; ++ out[i] = scratch.c[i]; ++ scratch.c[i] = c; ++ } ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++ (*ctx->block1) (scratch.c, scratch.c, ctx->key1); ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++ memcpy(out - 16, scratch.c, 16); ++ } else { ++ union { ++ u64 u[2]; ++ u8 c[16]; ++ } tweak1; ++ ++ if (is_endian.little) { ++ u8 res; ++ u64 hi, lo; ++#ifdef BSWAP8 ++ hi = BSWAP8(tweak.u[0]); ++ lo = BSWAP8(tweak.u[1]); ++#else ++ u8 *p = tweak.c; ++ ++ hi = (u64)GETU32(p) << 32 | GETU32(p + 4); ++ lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); ++#endif ++ res = (u8)lo & 1; ++ tweak1.u[0] = (lo >> 1) | (hi << 63); ++ tweak1.u[1] = hi >> 1; ++ if (res) ++ tweak1.c[15] ^= 0xe1; ++#ifdef BSWAP8 ++ hi = BSWAP8(tweak1.u[0]); ++ lo = BSWAP8(tweak1.u[1]); ++#else ++ p = tweak1.c; ++ ++ hi = (u64)GETU32(p) << 32 | GETU32(p + 4); ++ lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); ++#endif ++ tweak1.u[0] = lo; ++ tweak1.u[1] = hi; ++ } else { ++ u8 Cin, Cout; ++ Cin = 0; ++ for ( i = 0; i < 16; ++i ) { ++ Cout = (tweak.c[i] << 7) & 0x80; ++ tweak1.c[i] = ((tweak.c[i] >> 1) + Cin) & 0xff; ++ Cin = Cout; ++ } ++ if (Cout) ++ tweak1.c[0] ^= 0xe1; ++ } ++#if defined(STRICT_ALIGNMENT) ++ memcpy(scratch.c, inp, 16); ++ scratch.u[0] ^= tweak1.u[0]; ++ scratch.u[1] ^= tweak1.u[1]; ++#else ++ scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak1.u[0]; ++ scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak1.u[1]; ++#endif ++ (*ctx->block1) (scratch.c, scratch.c, ctx->key1); ++ scratch.u[0] ^= tweak1.u[0]; ++ scratch.u[1] ^= tweak1.u[1]; ++ ++ for (i = 0; i < len; ++i) { ++ u8 c = inp[16 + i]; ++ out[16 + i] = scratch.c[i]; ++ scratch.c[i] = c; ++ } ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++ (*ctx->block1) (scratch.c, scratch.c, ctx->key1); ++#if defined(STRICT_ALIGNMENT) ++ scratch.u[0] ^= tweak.u[0]; ++ scratch.u[1] ^= tweak.u[1]; ++ memcpy(out, scratch.c, 16); ++#else ++ ((u64_a1 *)out)[0] = scratch.u[0] ^ tweak.u[0]; ++ ((u64_a1 *)out)[1] = scratch.u[1] ^ tweak.u[1]; ++#endif ++ } ++ ++ return 0; ++} +diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h +index eb4cce4..6d60f87 100644 +--- a/crypto/objects/obj_dat.h ++++ b/crypto/objects/obj_dat.h +@@ -10,7 +10,7 @@ + */ + + /* Serialized OID's */ +-static const unsigned char so[7770] = { ++static const unsigned char so[7778] = { + 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +@@ -1077,9 +1077,10 @@ static const unsigned char so[7770] = { + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7761] OBJ_SM2_with_SM3 */ ++ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x0A, /* [ 7769] OBJ_sm4_xts */ + }; + +-#define NUM_NID 1196 ++#define NUM_NID 1197 + static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"UNDEF", "undefined", NID_undef}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, +@@ -2277,9 +2278,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]}, + {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]}, + {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7761]}, ++ {"SM4-XTS", "sm4-xts", NID_sm4_xts, 8, &so[7769]}, + }; + +-#define NUM_SN 1187 ++#define NUM_SN 1188 + static const unsigned int sn_objs[NUM_SN] = { + 364, /* "AD_DVCS" */ + 419, /* "AES-128-CBC" */ +@@ -2554,6 +2556,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1139, /* "SM4-CTR" */ + 1133, /* "SM4-ECB" */ + 1135, /* "SM4-OFB" */ ++ 1196, /* "SM4-XTS" */ + 188, /* "SMIME" */ + 167, /* "SMIME-CAPS" */ + 100, /* "SN" */ +@@ -3470,7 +3473,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1093, /* "x509ExtAdmission" */ + }; + +-#define NUM_LN 1187 ++#define NUM_LN 1188 + static const unsigned int ln_objs[NUM_LN] = { + 363, /* "AD Time Stamping" */ + 405, /* "ANSI X9.62" */ +@@ -4613,6 +4616,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 1139, /* "sm4-ctr" */ + 1133, /* "sm4-ecb" */ + 1135, /* "sm4-ofb" */ ++ 1196, /* "sm4-xts" */ + 16, /* "stateOrProvinceName" */ + 660, /* "streetAddress" */ + 498, /* "subtreeMaximumQuality" */ +@@ -4661,7 +4665,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 125, /* "zlib compression" */ + }; + +-#define NUM_OBJ 1072 ++#define NUM_OBJ 1073 + static const unsigned int obj_objs[NUM_OBJ] = { + 0, /* OBJ_undef 0 */ + 181, /* OBJ_iso 1 */ +@@ -5128,6 +5132,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { + 1136, /* OBJ_sm4_cfb1 1 2 156 10197 1 104 5 */ + 1138, /* OBJ_sm4_cfb8 1 2 156 10197 1 104 6 */ + 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ ++ 1196, /* OBJ_sm4_xts 1 2 156 10197 1 104 10 */ + 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ + 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ + 1195, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ +diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num +index 8b797b0..77ad385 100644 +--- a/crypto/objects/obj_mac.num ++++ b/crypto/objects/obj_mac.num +@@ -1193,3 +1193,4 @@ magma_mac 1192 + hmacWithSHA512_224 1193 + hmacWithSHA512_256 1194 + SM2_with_SM3 1195 ++sm4_xts 1196 +diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt +index be9da47..5713fae 100644 +--- a/crypto/objects/objects.txt ++++ b/crypto/objects/objects.txt +@@ -1520,6 +1520,7 @@ sm-scheme 104 4 : SM4-CFB : sm4-cfb + sm-scheme 104 5 : SM4-CFB1 : sm4-cfb1 + sm-scheme 104 6 : SM4-CFB8 : sm4-cfb8 + sm-scheme 104 7 : SM4-CTR : sm4-ctr ++sm-scheme 104 10 : SM4-XTS : sm4-xts + + # There is no OID that just denotes "HMAC" oddly enough... + +diff --git a/crypto/sm4/asm/vpsm4_ex-armv8.pl b/crypto/sm4/asm/vpsm4_ex-armv8.pl +new file mode 100644 +index 0000000..86a6f89 +--- /dev/null ++++ b/crypto/sm4/asm/vpsm4_ex-armv8.pl +@@ -0,0 +1,1173 @@ ++#! /usr/bin/env perl ++# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++# ++# This module implements SM4 with ASIMD and AESE on AARCH64 ++# ++# Feb 2022 ++# ++ ++# $output is the last argument if it looks like a file (it has an extension) ++# $flavour is the first argument if it doesn't look like a file ++$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; ++$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or ++die "can't locate arm-xlate.pl"; ++ ++open OUT,"| \"$^X\" $xlate $flavour \"$output\"" ++ or die "can't call $xlate: $!"; ++*STDOUT=*OUT; ++ ++$prefix="vpsm4_ex"; ++my ($inp,$outp,$rks1,$rks2,$ivp,$enc)=("x0","x1","x3","x4","x5","x6"); ++my ($blocks,$len)=("x2","x2"); ++my $remain=("x7"); ++my ($ptr,$counter)=("x12","w13"); ++my ($wtmp0,$wtmp1,$wtmp2,$wtmp3)=("w8","w9","w10","w11"); ++my ($xtmp0,$xtmp1,$xtmp2,$xtmp3)=("x8","x9","x10","x11"); ++my ($word0,$word1,$word2,$word3)=("w14","w15","w16","w17"); ++my @twx=map("x$_",(14..29)); ++my $lastBlk=("x26"); ++ ++my @tweak=map("v$_",(0..7)); ++my @qtmp=map("q$_",(8..11)); ++my @vtmp=map("v$_",(8..11)); ++my ($rk0,$rk1)=("v12","v13"); ++my ($rka,$rkb)=("v14","v15"); ++my @data=map("v$_",(16..19)); ++my @datax=map("v$_",(20..23)); ++my ($vtmp4,$vtmp5)=("v24","v25"); ++my $lastTweak=("v25"); ++my ($MaskV,$TAHMatV,$TALMatV,$ATAHMatV,$ATALMatV,$ANDMaskV)=("v26","v27","v28","v29","v30","v31"); ++my ($MaskQ,$TAHMatQ,$TALMatQ,$ATAHMatQ,$ATALMatQ,$ANDMaskQ)=("q26","q27","q28","q29","q30","q31"); ++ ++sub rev32() { ++ my $dst = shift; ++ my $src = shift; ++ ++ if ($src and ("$src" ne "$dst")) { ++$code.=<<___; ++#ifndef __ARMEB__ ++ rev32 $dst.16b,$src.16b ++#else ++ mov $dst.16b,$src.16b ++#endif ++___ ++ } else { ++$code.=<<___; ++#ifndef __ARMEB__ ++ rev32 $dst.16b,$dst.16b ++#endif ++___ ++ } ++} ++ ++sub rev32_armeb() { ++ my $dst = shift; ++ my $src = shift; ++ ++ if ($src and ("$src" ne "$dst")) { ++$code.=<<___; ++#ifdef __ARMEB__ ++ rev32 $dst.16b,$src.16b ++#else ++ mov $dst.16b,$src.16b ++#endif ++___ ++ } else { ++$code.=<<___; ++#ifdef __ARMEB__ ++ rev32 $dst.16b,$dst.16b ++#endif ++___ ++ } ++} ++ ++sub transpose() { ++ my ($dat0,$dat1,$dat2,$dat3,$vt0,$vt1,$vt2,$vt3) = @_; ++ ++$code.=<<___; ++ zip1 $vt0.4s,$dat0.4s,$dat1.4s ++ zip2 $vt1.4s,$dat0.4s,$dat1.4s ++ zip1 $vt2.4s,$dat2.4s,$dat3.4s ++ zip2 $vt3.4s,$dat2.4s,$dat3.4s ++ zip1 $dat0.2d,$vt0.2d,$vt2.2d ++ zip2 $dat1.2d,$vt0.2d,$vt2.2d ++ zip1 $dat2.2d,$vt1.2d,$vt3.2d ++ zip2 $dat3.2d,$vt1.2d,$vt3.2d ++___ ++} ++ ++sub load_sbox_matrix () { ++$code.=<<___; ++ ldr $MaskQ, =0x0306090c0f0205080b0e0104070a0d00 ++ ldr $TAHMatQ, =0x22581a6002783a4062185a2042387a00 ++ ldr $TALMatQ, =0xc10bb67c4a803df715df62a89e54e923 ++ ldr $ATAHMatQ, =0x1407c6d56c7fbeadb9aa6b78c1d21300 ++ ldr $ATALMatQ, =0xe383c1a1fe9edcbc6404462679195b3b ++ ldr $ANDMaskQ, =0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f ++___ ++} ++# matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) ++sub mul_matrix() { ++ my $x = shift; ++ my $higherMat = shift; ++ my $lowerMat = shift; ++ my $tmp = shift; ++$code.=<<___; ++ ushr $tmp.16b, $x.16b, 4 ++ and $x.16b, $x.16b, $ANDMaskV.16b ++ tbl $x.16b, {$lowerMat.16b}, $x.16b ++ tbl $tmp.16b, {$higherMat.16b}, $tmp.16b ++ eor $x.16b, $x.16b, $tmp.16b ++___ ++} ++ ++# sbox operation for one single word ++sub sbox_1word () { ++ my $word = shift; ++ ++$code.=<<___; ++ mov @vtmp[3].s[0],$word ++ // optimize sbox using AESE instruction ++ tbl @vtmp[0].16b, {@vtmp[3].16b}, $MaskV.16b ++___ ++ &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, @vtmp[2]); ++$code.=<<___; ++ eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b ++ aese @vtmp[0].16b,@vtmp[1].16b ++___ ++ &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, @vtmp[2]); ++$code.=<<___; ++ ++ mov $wtmp0,@vtmp[0].s[0] ++ eor $word,$wtmp0,$wtmp0,ror #32-2 ++ eor $word,$word,$wtmp0,ror #32-10 ++ eor $word,$word,$wtmp0,ror #32-18 ++ eor $word,$word,$wtmp0,ror #32-24 ++___ ++} ++ ++# sbox operation for 4-lane of words ++sub sbox() { ++ my $dat = shift; ++ ++$code.=<<___; ++ // optimize sbox using AESE instruction ++ tbl @vtmp[0].16b, {$dat.16b}, $MaskV.16b ++___ ++ &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, $vtmp4); ++$code.=<<___; ++ eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b ++ aese @vtmp[0].16b,@vtmp[1].16b ++___ ++ &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, $vtmp4); ++$code.=<<___; ++ mov $dat.16b,@vtmp[0].16b ++ ++ // linear transformation ++ ushr @vtmp[0].4s,$dat.4s,32-2 ++ ushr @vtmp[1].4s,$dat.4s,32-10 ++ ushr @vtmp[2].4s,$dat.4s,32-18 ++ ushr @vtmp[3].4s,$dat.4s,32-24 ++ sli @vtmp[0].4s,$dat.4s,2 ++ sli @vtmp[1].4s,$dat.4s,10 ++ sli @vtmp[2].4s,$dat.4s,18 ++ sli @vtmp[3].4s,$dat.4s,24 ++ eor $vtmp4.16b,@vtmp[0].16b,$dat.16b ++ eor $vtmp4.16b,$vtmp4.16b,$vtmp[1].16b ++ eor $dat.16b,@vtmp[2].16b,@vtmp[3].16b ++ eor $dat.16b,$dat.16b,$vtmp4.16b ++___ ++} ++ ++# sbox operation for 8-lane of words ++sub sbox_double() { ++ my $dat = shift; ++ my $datx = shift; ++ ++$code.=<<___; ++ // optimize sbox using AESE instruction ++ tbl @vtmp[0].16b, {$dat.16b}, $MaskV.16b ++ tbl @vtmp[1].16b, {$datx.16b}, $MaskV.16b ++___ ++ &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, $vtmp4); ++ &mul_matrix(@vtmp[1], $TAHMatV, $TALMatV, $vtmp4); ++$code.=<<___; ++ eor $vtmp5.16b, $vtmp5.16b, $vtmp5.16b ++ aese @vtmp[0].16b,$vtmp5.16b ++ aese @vtmp[1].16b,$vtmp5.16b ++___ ++ &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV,$vtmp4); ++ &mul_matrix(@vtmp[1], $ATAHMatV, $ATALMatV,$vtmp4); ++$code.=<<___; ++ mov $dat.16b,@vtmp[0].16b ++ mov $datx.16b,@vtmp[1].16b ++ ++ // linear transformation ++ ushr @vtmp[0].4s,$dat.4s,32-2 ++ ushr $vtmp5.4s,$datx.4s,32-2 ++ ushr @vtmp[1].4s,$dat.4s,32-10 ++ ushr @vtmp[2].4s,$dat.4s,32-18 ++ ushr @vtmp[3].4s,$dat.4s,32-24 ++ sli @vtmp[0].4s,$dat.4s,2 ++ sli $vtmp5.4s,$datx.4s,2 ++ sli @vtmp[1].4s,$dat.4s,10 ++ sli @vtmp[2].4s,$dat.4s,18 ++ sli @vtmp[3].4s,$dat.4s,24 ++ eor $vtmp4.16b,@vtmp[0].16b,$dat.16b ++ eor $vtmp4.16b,$vtmp4.16b,@vtmp[1].16b ++ eor $dat.16b,@vtmp[2].16b,@vtmp[3].16b ++ eor $dat.16b,$dat.16b,$vtmp4.16b ++ ushr @vtmp[1].4s,$datx.4s,32-10 ++ ushr @vtmp[2].4s,$datx.4s,32-18 ++ ushr @vtmp[3].4s,$datx.4s,32-24 ++ sli @vtmp[1].4s,$datx.4s,10 ++ sli @vtmp[2].4s,$datx.4s,18 ++ sli @vtmp[3].4s,$datx.4s,24 ++ eor $vtmp4.16b,$vtmp5.16b,$datx.16b ++ eor $vtmp4.16b,$vtmp4.16b,@vtmp[1].16b ++ eor $datx.16b,@vtmp[2].16b,@vtmp[3].16b ++ eor $datx.16b,$datx.16b,$vtmp4.16b ++___ ++} ++ ++# sm4 for one block of data, in scalar registers word0/word1/word2/word3 ++sub sm4_1blk () { ++ my $kptr = shift; ++ ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ++ eor $wtmp3,$word2,$word3 ++ eor $wtmp2,$wtmp0,$word1 ++ eor $wtmp3,$wtmp3,$wtmp2 ++___ ++ &sbox_1word($wtmp3); ++$code.=<<___; ++ eor $word0,$word0,$wtmp3 ++ /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ++ eor $wtmp3,$word2,$word3 ++ eor $wtmp2,$word0,$wtmp1 ++ eor $wtmp3,$wtmp3,$wtmp2 ++___ ++ &sbox_1word($wtmp3); ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ eor $word1,$word1,$wtmp3 ++ /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ++ eor $wtmp3,$word0,$word1 ++ eor $wtmp2,$wtmp0,$word3 ++ eor $wtmp3,$wtmp3,$wtmp2 ++___ ++ &sbox_1word($wtmp3); ++$code.=<<___; ++ eor $word2,$word2,$wtmp3 ++ /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ++ eor $wtmp3,$word0,$word1 ++ eor $wtmp2,$word2,$wtmp1 ++ eor $wtmp3,$wtmp3,$wtmp2 ++___ ++ &sbox_1word($wtmp3); ++$code.=<<___; ++ eor $word3,$word3,$wtmp3 ++___ ++} ++ ++# sm4 for 4-lanes of data, in neon registers data0/data1/data2/data3 ++sub sm4_4blks () { ++ my $kptr = shift; ++ ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ dup $rk0.4s,$wtmp0 ++ dup $rk1.4s,$wtmp1 ++ ++ /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ++ eor $rka.16b,@data[2].16b,@data[3].16b ++ eor $rk0.16b,@data[1].16b,$rk0.16b ++ eor $rk0.16b,$rka.16b,$rk0.16b ++___ ++ &sbox($rk0); ++$code.=<<___; ++ eor @data[0].16b,@data[0].16b,$rk0.16b ++ ++ /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ++ eor $rka.16b,$rka.16b,@data[0].16b ++ eor $rk1.16b,$rka.16b,$rk1.16b ++___ ++ &sbox($rk1); ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ eor @data[1].16b,@data[1].16b,$rk1.16b ++ ++ dup $rk0.4s,$wtmp0 ++ dup $rk1.4s,$wtmp1 ++ ++ /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ++ eor $rka.16b,@data[0].16b,@data[1].16b ++ eor $rk0.16b,@data[3].16b,$rk0.16b ++ eor $rk0.16b,$rka.16b,$rk0.16b ++___ ++ &sbox($rk0); ++$code.=<<___; ++ eor @data[2].16b,@data[2].16b,$rk0.16b ++ ++ /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ++ eor $rka.16b,$rka.16b,@data[2].16b ++ eor $rk1.16b,$rka.16b,$rk1.16b ++___ ++ &sbox($rk1); ++$code.=<<___; ++ eor @data[3].16b,@data[3].16b,$rk1.16b ++___ ++} ++ ++# sm4 for 8 lanes of data, in neon registers ++# data0/data1/data2/data3 datax0/datax1/datax2/datax3 ++sub sm4_8blks () { ++ my $kptr = shift; ++ ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ++ dup $rk0.4s,$wtmp0 ++ eor $rka.16b,@data[2].16b,@data[3].16b ++ eor $rkb.16b,@datax[2].16b,@datax[3].16b ++ eor @vtmp[0].16b,@data[1].16b,$rk0.16b ++ eor @vtmp[1].16b,@datax[1].16b,$rk0.16b ++ eor $rk0.16b,$rka.16b,@vtmp[0].16b ++ eor $rk1.16b,$rkb.16b,@vtmp[1].16b ++___ ++ &sbox_double($rk0,$rk1); ++$code.=<<___; ++ eor @data[0].16b,@data[0].16b,$rk0.16b ++ eor @datax[0].16b,@datax[0].16b,$rk1.16b ++ ++ /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ++ dup $rk1.4s,$wtmp1 ++ eor $rka.16b,$rka.16b,@data[0].16b ++ eor $rkb.16b,$rkb.16b,@datax[0].16b ++ eor $rk0.16b,$rka.16b,$rk1.16b ++ eor $rk1.16b,$rkb.16b,$rk1.16b ++___ ++ &sbox_double($rk0,$rk1); ++$code.=<<___; ++ ldp $wtmp0,$wtmp1,[$kptr],8 ++ eor @data[1].16b,@data[1].16b,$rk0.16b ++ eor @datax[1].16b,@datax[1].16b,$rk1.16b ++ ++ /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ++ dup $rk0.4s,$wtmp0 ++ eor $rka.16b,@data[0].16b,@data[1].16b ++ eor $rkb.16b,@datax[0].16b,@datax[1].16b ++ eor @vtmp[0].16b,@data[3].16b,$rk0.16b ++ eor @vtmp[1].16b,@datax[3].16b,$rk0.16b ++ eor $rk0.16b,$rka.16b,@vtmp[0].16b ++ eor $rk1.16b,$rkb.16b,@vtmp[1].16b ++___ ++ &sbox_double($rk0,$rk1); ++$code.=<<___; ++ eor @data[2].16b,@data[2].16b,$rk0.16b ++ eor @datax[2].16b,@datax[2].16b,$rk1.16b ++ ++ /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ++ dup $rk1.4s,$wtmp1 ++ eor $rka.16b,$rka.16b,@data[2].16b ++ eor $rkb.16b,$rkb.16b,@datax[2].16b ++ eor $rk0.16b,$rka.16b,$rk1.16b ++ eor $rk1.16b,$rkb.16b,$rk1.16b ++___ ++ &sbox_double($rk0,$rk1); ++$code.=<<___; ++ eor @data[3].16b,@data[3].16b,$rk0.16b ++ eor @datax[3].16b,@datax[3].16b,$rk1.16b ++___ ++} ++ ++sub encrypt_1blk_norev() { ++ my $dat = shift; ++ my $rks = shift; ++$code.=<<___; ++ mov $ptr,$rks ++ mov $counter,#8 ++ mov $word0,$dat.s[0] ++ mov $word1,$dat.s[1] ++ mov $word2,$dat.s[2] ++ mov $word3,$dat.s[3] ++10: ++___ ++ &sm4_1blk($ptr); ++$code.=<<___; ++ subs $counter,$counter,#1 ++ b.ne 10b ++ mov $dat.s[0],$word3 ++ mov $dat.s[1],$word2 ++ mov $dat.s[2],$word1 ++ mov $dat.s[3],$word0 ++___ ++} ++ ++sub encrypt_1blk() { ++ my $dat = shift; ++ my $rks = shift; ++ ++ &encrypt_1blk_norev($dat,$rks); ++ &rev32($dat,$dat); ++} ++ ++sub encrypt_4blks() { ++$code.=<<___; ++ mov $ptr,$rks1 ++ mov $counter,#8 ++10: ++___ ++ &sm4_4blks($ptr); ++$code.=<<___; ++ subs $counter,$counter,#1 ++ b.ne 10b ++___ ++ &rev32(@vtmp[3],@data[0]); ++ &rev32(@vtmp[2],@data[1]); ++ &rev32(@vtmp[1],@data[2]); ++ &rev32(@vtmp[0],@data[3]); ++} ++ ++sub encrypt_8blks() { ++ my $rks = shift; ++$code.=<<___; ++ mov $ptr,$rks ++ mov $counter,#8 ++10: ++___ ++ &sm4_8blks($ptr); ++$code.=<<___; ++ subs $counter,$counter,#1 ++ b.ne 10b ++___ ++ &rev32(@vtmp[3],@data[0]); ++ &rev32(@vtmp[2],@data[1]); ++ &rev32(@vtmp[1],@data[2]); ++ &rev32(@vtmp[0],@data[3]); ++ &rev32(@data[3],@datax[0]); ++ &rev32(@data[2],@datax[1]); ++ &rev32(@data[1],@datax[2]); ++ &rev32(@data[0],@datax[3]); ++} ++ ++sub mov_reg_to_vec() { ++ my $src0 = shift; ++ my $src1 = shift; ++ my $desv = shift; ++$code.=<<___; ++ mov $desv.d[0],$src0 ++ mov $desv.d[1],$src1 ++#ifdef __ARMEB__ ++ rev32 $desv.16b,$desv.16b ++#endif ++___ ++} ++ ++sub mov_vec_to_reg() { ++ my $srcv = shift; ++ my $des0 = shift; ++ my $des1 = shift; ++$code.=<<___; ++ mov $des0,$srcv.d[0] ++ mov $des1,$srcv.d[1] ++___ ++} ++ ++sub compute_tweak() { ++ my $src0 = shift; ++ my $src1 = shift; ++ my $des0 = shift; ++ my $des1 = shift; ++$code.=<<___; ++ mov $wtmp0,0x87 ++ extr $xtmp2,$src1,$src1,#32 ++ extr $des1,$src1,$src0,#63 ++ and $wtmp1,$wtmp0,$wtmp2,asr#31 ++ eor $des0,$xtmp1,$src0,lsl#1 ++___ ++} ++ ++sub compute_tweak_vec() { ++ my $src = shift; ++ my $des = shift; ++ &rbit(@vtmp[2],$src); ++$code.=<<___; ++ ldr @qtmp[0], =0x01010101010101010101010101010187 ++ shl $des.16b, @vtmp[2].16b, #1 ++ ext @vtmp[1].16b, @vtmp[2].16b, @vtmp[2].16b,#15 ++ ushr @vtmp[1].16b, @vtmp[1].16b, #7 ++ mul @vtmp[1].16b, @vtmp[1].16b, @vtmp[0].16b ++ eor $des.16b, $des.16b, @vtmp[1].16b ++___ ++ &rbit($des,$des); ++} ++ ++sub mov_en_to_enc(){ ++ my $en = shift; ++ if ($en eq "en") { ++$code.=<<___; ++ mov $enc,1 ++___ ++ } else { ++$code.=<<___; ++ mov $enc,0 ++___ ++ } ++} ++ ++sub rbit() { ++ my $dst = shift; ++ my $src = shift; ++ ++ if ($src and ("$src" ne "$dst")) { ++ if ($standard eq "_gb") { ++$code.=<<___; ++ rbit $dst.16b,$src.16b ++___ ++ } else { ++$code.=<<___; ++ mov $dst.16b,$src.16b ++___ ++ } ++ } else { ++ if ($standard eq "_gb") { ++$code.=<<___; ++ rbit $dst.16b,$src.16b ++___ ++ } ++ } ++} ++ ++$code=<<___; ++#include "arm_arch.h" ++.arch armv8-a+crypto ++.text ++ ++.type ${prefix}_consts,%object ++.align 7 ++${prefix}_consts: ++.Lck: ++ .long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 ++ .long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 ++ .long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 ++ .long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 ++ .long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 ++ .long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 ++ .long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 ++ .long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 ++.Lfk: ++ .long 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc ++.Lshuffles: ++ .long 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x03020100 ++ ++.size ${prefix}_consts,.-${prefix}_consts ++___ ++ ++{{{ ++my ($userKey,$roundKey,$enc)=("x0","x1","w2"); ++my ($pointer,$schedules,$wtmp,$roundkey)=("x5","x6","w7","w8"); ++my ($vkey,$vfk,$vmap)=("v5","v6","v7"); ++$code.=<<___; ++.type ${prefix}_set_key,%function ++.align 4 ++${prefix}_set_key: ++ ld1 {$vkey.4s},[$userKey] ++___ ++ &load_sbox_matrix(); ++ &rev32($vkey,$vkey); ++$code.=<<___; ++ adr $pointer,.Lshuffles ++ ld1 {$vmap.4s},[$pointer] ++ adr $pointer,.Lfk ++ ld1 {$vfk.4s},[$pointer] ++ eor $vkey.16b,$vkey.16b,$vfk.16b ++ mov $schedules,#32 ++ adr $pointer,.Lck ++ movi @vtmp[0].16b,#64 ++ cbnz $enc,1f ++ add $roundKey,$roundKey,124 ++1: ++ mov $wtmp,$vkey.s[1] ++ ldr $roundkey,[$pointer],#4 ++ eor $roundkey,$roundkey,$wtmp ++ mov $wtmp,$vkey.s[2] ++ eor $roundkey,$roundkey,$wtmp ++ mov $wtmp,$vkey.s[3] ++ eor $roundkey,$roundkey,$wtmp ++ ++ // optimize sbox using AESE instruction ++ mov @data[0].s[0],$roundkey ++ tbl @vtmp[0].16b, {@data[0].16b}, $MaskV.16b ++___ ++ &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, @vtmp[2]); ++$code.=<<___; ++ eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b ++ aese @vtmp[0].16b,@vtmp[1].16b ++___ ++ &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, @vtmp[2]); ++$code.=<<___; ++ mov $wtmp,@vtmp[0].s[0] ++ ++ // linear transformation ++ eor $roundkey,$wtmp,$wtmp,ror #19 ++ eor $roundkey,$roundkey,$wtmp,ror #9 ++ mov $wtmp,$vkey.s[0] ++ eor $roundkey,$roundkey,$wtmp ++ mov $vkey.s[0],$roundkey ++ cbz $enc,2f ++ str $roundkey,[$roundKey],#4 ++ b 3f ++2: ++ str $roundkey,[$roundKey],#-4 ++3: ++ tbl $vkey.16b,{$vkey.16b},$vmap.16b ++ subs $schedules,$schedules,#1 ++ b.ne 1b ++ ret ++.size ${prefix}_set_key,.-${prefix}_set_key ++___ ++}}} ++ ++ ++{{{ ++$code.=<<___; ++.type ${prefix}_enc_4blks,%function ++.align 4 ++${prefix}_enc_4blks: ++___ ++ &encrypt_4blks(); ++$code.=<<___; ++ ret ++.size ${prefix}_enc_4blks,.-${prefix}_enc_4blks ++___ ++}}} ++ ++{{{ ++$code.=<<___; ++.type ${prefix}_enc_8blks,%function ++.align 4 ++${prefix}_enc_8blks: ++___ ++ &encrypt_8blks($rks1); ++$code.=<<___; ++ ret ++.size ${prefix}_enc_8blks,.-${prefix}_enc_8blks ++___ ++}}} ++ ++{{{ ++my ($key,$keys)=("x0","x1"); ++$code.=<<___; ++.globl ${prefix}_set_encrypt_key ++.type ${prefix}_set_encrypt_key,%function ++.align 5 ++${prefix}_set_encrypt_key: ++ stp x29,x30,[sp,#-16]! ++ mov w2,1 ++ bl ${prefix}_set_key ++ ldp x29,x30,[sp],#16 ++ ret ++.size ${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key ++___ ++}}} ++ ++{{{ ++my ($key,$keys)=("x0","x1"); ++$code.=<<___; ++.globl ${prefix}_set_decrypt_key ++.type ${prefix}_set_decrypt_key,%function ++.align 5 ++${prefix}_set_decrypt_key: ++ stp x29,x30,[sp,#-16]! ++ mov w2,0 ++ bl ${prefix}_set_key ++ ldp x29,x30,[sp],#16 ++ ret ++.size ${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key ++___ ++}}} ++ ++ ++{{{ ++ ++$code.=<<___; ++.globl ${prefix}_ecb_encrypt ++.type ${prefix}_ecb_encrypt,%function ++.align 5 ++${prefix}_ecb_encrypt: ++ stp d8,d9,[sp,#-0x10]! ++ stp d10,d11,[sp,#-0x10]! ++ stp d12,d13,[sp,#-0x10]! ++ stp d14,d15,[sp,#-0x10]! ++ stp x16,x17,[sp,#-0x10]! ++ stp x29,x30,[sp,#-0x10]! ++___ ++ &load_sbox_matrix(); ++$code.=<<___; ++ // convert length into blocks ++ lsr x2,x2,4 ++.Lecb_8_blocks_process: ++ cmp $blocks,#8 ++ b.lt .Lecb_4_blocks_process ++ ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 ++ ld4 {@datax[0].4s,$datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++ &rev32(@datax[0],@datax[0]); ++ &rev32(@datax[1],@datax[1]); ++ &rev32(@datax[2],@datax[2]); ++ &rev32(@datax[3],@datax[3]); ++$code.=<<___; ++ bl ${prefix}_enc_8blks ++ st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 ++ st4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 ++ subs $blocks,$blocks,#8 ++ b.gt .Lecb_8_blocks_process ++ b 100f ++.Lecb_4_blocks_process: ++ cmp $blocks,#4 ++ b.lt 1f ++ ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++ st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 ++ sub $blocks,$blocks,#4 ++1: ++ // process last block ++ cmp $blocks,#1 ++ b.lt 100f ++ b.gt 1f ++ ld1 {@data[0].4s},[$inp] ++___ ++ &rev32(@data[0],@data[0]); ++ &encrypt_1blk(@data[0],$rks1); ++$code.=<<___; ++ st1 {@data[0].4s},[$outp] ++ b 100f ++1: // process last 2 blocks ++ ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[0],[$inp],#16 ++ ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[1],[$inp],#16 ++ cmp $blocks,#2 ++ b.gt 1f ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++ st4 {@vtmp[0].s-@vtmp[3].s}[0],[$outp],#16 ++ st4 {@vtmp[0].s-@vtmp[3].s}[1],[$outp] ++ b 100f ++1: // process last 3 blocks ++ ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[2],[$inp],#16 ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++ st4 {@vtmp[0].s-@vtmp[3].s}[0],[$outp],#16 ++ st4 {@vtmp[0].s-@vtmp[3].s}[1],[$outp],#16 ++ st4 {@vtmp[0].s-@vtmp[3].s}[2],[$outp] ++100: ++ ldp x29,x30,[sp],#0x10 ++ ldp x16,x17,[sp],#0x10 ++ ldp d14,d15,[sp],#0x10 ++ ldp d12,d13,[sp],#0x10 ++ ldp d10,d11,[sp],#0x10 ++ ldp d8,d9,[sp],#0x10 ++ ret ++.size ${prefix}_ecb_encrypt,.-${prefix}_ecb_encrypt ++___ ++}}} ++ ++{{{ ++sub gen_xts_do_cipher() { ++$code.=<<___; ++.globl ${prefix}_xts_do_cipher${standard} ++.type ${prefix}_xts_do_cipher${standard},%function ++.align 5 ++${prefix}_xts_do_cipher${standard}: ++ stp x29,x30,[sp,#-16]! ++ ld1 {@tweak[0].4s}, [$ivp] ++___ ++ &load_sbox_matrix(); ++ &rev32(@tweak[0],@tweak[0]); ++ &encrypt_1blk(@tweak[0],$rks2); ++$code.=<<___; ++ and $remain,$len,#0x0F ++ // convert length into blocks ++ lsr $blocks,$len,4 ++ cmp $blocks,#1 ++ b.lt .return${standard} ++ ++ cmp $remain,0 ++ // If the encryption/decryption Length is N times of 16, ++ // the all blocks are encrypted/decrypted in .xts_encrypt_blocks${standard} ++ b.eq .xts_encrypt_blocks${standard} ++ ++ // If the encryption/decryption length is not N times of 16, ++ // the last two blocks are encrypted/decrypted in .last_2blks_tweak${standard} or .only_2blks_tweak${standard} ++ // the other blocks are encrypted/decrypted in .xts_encrypt_blocks${standard} ++ subs $blocks,$blocks,#1 ++ b.eq .only_2blks_tweak${standard} ++.xts_encrypt_blocks${standard}: ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rev32_armeb(@tweak[0],@tweak[0]); ++ &mov_vec_to_reg(@tweak[0],@twx[0],@twx[1]); ++ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); ++ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); ++ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); ++ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); ++ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); ++ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); ++ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); ++$code.=<<___; ++.Lxts_8_blocks_process${standard}: ++ cmp $blocks,#8 ++___ ++ &mov_reg_to_vec(@twx[0],@twx[1],@tweak[0]); ++ &compute_tweak(@twx[14],@twx[15],@twx[0],@twx[1]); ++ &mov_reg_to_vec(@twx[2],@twx[3],@tweak[1]); ++ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); ++ &mov_reg_to_vec(@twx[4],@twx[5],@tweak[2]); ++ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); ++ &mov_reg_to_vec(@twx[6],@twx[7],@tweak[3]); ++ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); ++ &mov_reg_to_vec(@twx[8],@twx[9],@tweak[4]); ++ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); ++ &mov_reg_to_vec(@twx[10],@twx[11],@tweak[5]); ++ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); ++ &mov_reg_to_vec(@twx[12],@twx[13],@tweak[6]); ++ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); ++ &mov_reg_to_vec(@twx[14],@twx[15],@tweak[7]); ++ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); ++$code.=<<___; ++ b.lt .Lxts_4_blocks_process${standard} ++ ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++ &rbit(@tweak[3],@tweak[3]); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++ eor @data[1].16b, @data[1].16b, @tweak[1].16b ++ eor @data[2].16b, @data[2].16b, @tweak[2].16b ++ eor @data[3].16b, @data[3].16b, @tweak[3].16b ++ ld1 {@datax[0].4s,$datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 ++___ ++ &rbit(@tweak[4],@tweak[4]); ++ &rbit(@tweak[5],@tweak[5]); ++ &rbit(@tweak[6],@tweak[6]); ++ &rbit(@tweak[7],@tweak[7]); ++$code.=<<___; ++ eor @datax[0].16b, @datax[0].16b, @tweak[4].16b ++ eor @datax[1].16b, @datax[1].16b, @tweak[5].16b ++ eor @datax[2].16b, @datax[2].16b, @tweak[6].16b ++ eor @datax[3].16b, @datax[3].16b, @tweak[7].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++ &rev32(@datax[0],@datax[0]); ++ &rev32(@datax[1],@datax[1]); ++ &rev32(@datax[2],@datax[2]); ++ &rev32(@datax[3],@datax[3]); ++ &transpose(@data,@vtmp); ++ &transpose(@datax,@vtmp); ++$code.=<<___; ++ bl ${prefix}_enc_8blks ++___ ++ &transpose(@vtmp,@datax); ++ &transpose(@data,@datax); ++$code.=<<___; ++ eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b ++ eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b ++ eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b ++ eor @vtmp[3].16b, @vtmp[3].16b, @tweak[3].16b ++ eor @data[0].16b, @data[0].16b, @tweak[4].16b ++ eor @data[1].16b, @data[1].16b, @tweak[5].16b ++ eor @data[2].16b, @data[2].16b, @tweak[6].16b ++ eor @data[3].16b, @data[3].16b, @tweak[7].16b ++ ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[7].16b ++ st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 ++ st1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 ++ subs $blocks,$blocks,#8 ++ b.gt .Lxts_8_blocks_process${standard} ++ b 100f ++.Lxts_4_blocks_process${standard}: ++ cmp $blocks,#4 ++ b.lt 1f ++ ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++ &rbit(@tweak[3],@tweak[3]); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++ eor @data[1].16b, @data[1].16b, @tweak[1].16b ++ eor @data[2].16b, @data[2].16b, @tweak[2].16b ++ eor @data[3].16b, @data[3].16b, @tweak[3].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &rev32(@data[3],@data[3]); ++ &transpose(@data,@vtmp); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++___ ++ &transpose(@vtmp,@data); ++$code.=<<___; ++ eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b ++ eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b ++ eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b ++ eor @vtmp[3].16b, @vtmp[3].16b, @tweak[3].16b ++ st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 ++ sub $blocks,$blocks,#4 ++ mov @tweak[0].16b,@tweak[4].16b ++ mov @tweak[1].16b,@tweak[5].16b ++ mov @tweak[2].16b,@tweak[6].16b ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[3].16b ++1: ++ // process last block ++ cmp $blocks,#1 ++ b.lt 100f ++ b.gt 1f ++ ld1 {@data[0].4s},[$inp],#16 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &encrypt_1blk(@data[0],$rks1); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++ st1 {@data[0].4s},[$outp],#16 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[0].16b ++ b 100f ++1: // process last 2 blocks ++ cmp $blocks,#2 ++ b.gt 1f ++ ld1 {@data[0].4s,@data[1].4s},[$inp],#32 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++ eor @data[1].16b, @data[1].16b, @tweak[1].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &transpose(@data,@vtmp); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++___ ++ &transpose(@vtmp,@data); ++$code.=<<___; ++ eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b ++ eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b ++ st1 {@vtmp[0].4s,@vtmp[1].4s},[$outp],#32 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[1].16b ++ b 100f ++1: // process last 3 blocks ++ ld1 {@data[0].4s,@data[1].4s,@data[2].4s},[$inp],#48 ++___ ++ &rbit(@tweak[0],@tweak[0]); ++ &rbit(@tweak[1],@tweak[1]); ++ &rbit(@tweak[2],@tweak[2]); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[0].16b ++ eor @data[1].16b, @data[1].16b, @tweak[1].16b ++ eor @data[2].16b, @data[2].16b, @tweak[2].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &rev32(@data[1],@data[1]); ++ &rev32(@data[2],@data[2]); ++ &transpose(@data,@vtmp); ++$code.=<<___; ++ bl ${prefix}_enc_4blks ++___ ++ &transpose(@vtmp,@data); ++$code.=<<___; ++ eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b ++ eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b ++ eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b ++ st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s},[$outp],#48 ++ // save the last tweak ++ mov $lastTweak.16b,@tweak[2].16b ++100: ++ cmp $remain,0 ++ b.eq .return${standard} ++ ++// This brance calculates the last two tweaks, ++// while the encryption/decryption length is larger than 32 ++.last_2blks_tweak${standard}: ++___ ++ &rev32_armeb($lastTweak,$lastTweak); ++ &compute_tweak_vec($lastTweak,@tweak[1]); ++ &compute_tweak_vec(@tweak[1],@tweak[2]); ++$code.=<<___; ++ b .check_dec${standard} ++ ++ ++// This brance calculates the last two tweaks, ++// while the encryption/decryption length is equal to 32, who only need two tweaks ++.only_2blks_tweak${standard}: ++ mov @tweak[1].16b,@tweak[0].16b ++___ ++ &rev32_armeb(@tweak[1],@tweak[1]); ++ &compute_tweak_vec(@tweak[1],@tweak[2]); ++$code.=<<___; ++ b .check_dec${standard} ++ ++ ++// Determine whether encryption or decryption is required. ++// The last two tweaks need to be swapped for decryption. ++.check_dec${standard}: ++ // encryption:1 decryption:0 ++ cmp $enc,1 ++ b.eq .prcess_last_2blks${standard} ++ mov @vtmp[0].16B,@tweak[1].16b ++ mov @tweak[1].16B,@tweak[2].16b ++ mov @tweak[2].16B,@vtmp[0].16b ++ ++.prcess_last_2blks${standard}: ++___ ++ &rev32_armeb(@tweak[1],@tweak[1]); ++ &rev32_armeb(@tweak[2],@tweak[2]); ++$code.=<<___; ++ ld1 {@data[0].4s},[$inp],#16 ++ eor @data[0].16b, @data[0].16b, @tweak[1].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &encrypt_1blk(@data[0],$rks1); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[1].16b ++ st1 {@data[0].4s},[$outp],#16 ++ ++ sub $lastBlk,$outp,16 ++ .loop${standard}: ++ subs $remain,$remain,1 ++ ldrb $wtmp0,[$lastBlk,$remain] ++ ldrb $wtmp1,[$inp,$remain] ++ strb $wtmp1,[$lastBlk,$remain] ++ strb $wtmp0,[$outp,$remain] ++ b.gt .loop${standard} ++ ld1 {@data[0].4s}, [$lastBlk] ++ eor @data[0].16b, @data[0].16b, @tweak[2].16b ++___ ++ &rev32(@data[0],@data[0]); ++ &encrypt_1blk(@data[0],$rks1); ++$code.=<<___; ++ eor @data[0].16b, @data[0].16b, @tweak[2].16b ++ st1 {@data[0].4s}, [$lastBlk] ++.return${standard}: ++ ldp x29,x30,[sp],#16 ++ ret ++.size ${prefix}_xts_do_cipher${standard},.-${prefix}_xts_do_cipher${standard} ++___ ++} #end of gen_xts_do_cipher ++ ++}}} ++ ++{{{ ++sub gen_xts_cipher() { ++ my $en = shift; ++ ++$code.=<<___; ++.globl ${prefix}_xts_${en}crypt${standard} ++.type ${prefix}_xts_${en}crypt${standard},%function ++.align 5 ++${prefix}_xts_${en}crypt${standard}: ++ stp x15, x16, [sp, #-0x10]! ++ stp x17, x18, [sp, #-0x10]! ++ stp x19, x20, [sp, #-0x10]! ++ stp x21, x22, [sp, #-0x10]! ++ stp x23, x24, [sp, #-0x10]! ++ stp x25, x26, [sp, #-0x10]! ++ stp x27, x28, [sp, #-0x10]! ++ stp x29, x30, [sp, #-0x10]! ++ stp d8, d9, [sp, #-0x10]! ++ stp d10, d11, [sp, #-0x10]! ++ stp d12, d13, [sp, #-0x10]! ++ stp d14, d15, [sp, #-0x10]! ++___ ++ &mov_en_to_enc($en); ++$code.=<<___; ++ bl ${prefix}_xts_do_cipher${standard} ++ ldp d14, d15, [sp], #0x10 ++ ldp d12, d13, [sp], #0x10 ++ ldp d10, d11, [sp], #0x10 ++ ldp d8, d9, [sp], #0x10 ++ ldp x29, x30, [sp], #0x10 ++ ldp x27, x28, [sp], #0x10 ++ ldp x25, x26, [sp], #0x10 ++ ldp x23, x24, [sp], #0x10 ++ ldp x21, x22, [sp], #0x10 ++ ldp x19, x20, [sp], #0x10 ++ ldp x17, x18, [sp], #0x10 ++ ldp x15, x16, [sp], #0x10 ++ ret ++.size ${prefix}_xts_${en}crypt${standard},.-${prefix}_xts_${en}crypt${standard} ++___ ++ ++} # end of gen_xts_cipher ++$standard="_gb"; ++&gen_xts_do_cipher(); ++&gen_xts_cipher("en"); ++&gen_xts_cipher("de"); ++$standard=""; ++&gen_xts_do_cipher(); ++&gen_xts_cipher("en"); ++&gen_xts_cipher("de"); ++}}} ++ ++######################################## ++open SELF,$0; ++while() { ++ next if (/^#!/); ++ last if (!s/^#/\/\// and !/^$/); ++ print; ++} ++close SELF; ++ ++foreach(split("\n",$code)) { ++ s/\`([^\`]*)\`/eval($1)/ge; ++ print $_,"\n"; ++} ++ ++close STDOUT or die "error closing STDOUT: $!"; +diff --git a/crypto/sm4/build.info b/crypto/sm4/build.info +index b65a7d1..bb042c5 100644 +--- a/crypto/sm4/build.info ++++ b/crypto/sm4/build.info +@@ -1,4 +1,7 @@ + LIBS=../../libcrypto + SOURCE[../../libcrypto]=\ +- sm4.c ++ sm4.c {- $target{sm4_asm_src} -} + ++ ++GENERATE[vpsm4_ex-armv8.S]=asm/vpsm4_ex-armv8.pl $(PERLASM_SCHEME) ++INCLUDE[vpsm4_ex-armv8.o]=.. +\ No newline at end of file +diff --git a/doc/man3/EVP_sm4_xts.pod b/doc/man3/EVP_sm4_xts.pod +new file mode 100644 +index 0000000..09ca3fb +--- /dev/null ++++ b/doc/man3/EVP_sm4_xts.pod +@@ -0,0 +1,67 @@ ++=pod ++ ++=head1 NAME ++ ++EVP_sm4_xts, ++- EVP SM4 cipher ++ ++=head1 SYNOPSIS ++ ++ #include ++ ++ const EVP_CIPHER *EVP_sm4_xts(void); ++ ++=head1 DESCRIPTION ++ ++The XTS mode of operation (GB/T 17964-2021) for SM4 block cipher. ++ ++=over 4 ++ ++=item EVP_sm4_xts(), ++ ++The SM4 blockcipher with a 256-bit key in XTS mode. This mode use a key length of 256 bits and acts on blocks of 128 bits. ++ ++The B parameter to L or L is the XTS first "tweak" value. XTS mode has two implementations to calculate the following tweak values, one is standardized in IEEE Std. 1619-2007 and has been widely used (e.g., XTS AES), the other is proposed recently (GB/T 17964-2021 implemented in May 2022) and is currently only used in SM4. ++ ++Assume that the input data (B, B, and B) are consistent, the following tweak values are inconsistent due to different standards. As a result, the first ciphertext block are consistent, but the subsequent ciphertext blocks (if any) are different. ++ ++By default, EVP_sm4_xts is standardized in GB/T 17964-2021, and can be changed by EVP_CIPHER_CTX_ctrl. The following Is is supported in XTS mode for SM4. ++ ++=over 4 ++ ++=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_XTS_STANDARD, std, NULL) ++ ++Sets the standard of EVP_sm4_xts to B. This must be one of 0 or 1, 0 for XTS mode in GB/T 17964-2021, 1 for XTS mode in IEEE Std 1619-2007. ++ ++=back ++ ++The XTS implementation in OpenSSL does not support streaming. That is there must ++only be one L call per L call (and ++similarly with the "Decrypt" functions). ++ ++=back ++ ++=head1 RETURN VALUES ++ ++These functions return a B structure that contains the ++implementation of the symmetric cipher. See L for ++details of the B structure. ++ ++=head1 SEE ALSO ++ ++L, ++L, ++L ++ ++=head1 COPYRIGHT ++ ++Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. ++Copyright 2022 Ribose Inc. All Rights Reserved. ++ ++Licensed under the OpenSSL license (the "License"). You may not use ++this file except in compliance with the License. You can obtain a copy ++in the file LICENSE in the source distribution or at ++L. ++ ++=cut ++ +diff --git a/fuzz/oids.txt b/fuzz/oids.txt +index 8dfdea9..d1f98a8 100644 +--- a/fuzz/oids.txt ++++ b/fuzz/oids.txt +@@ -1064,3 +1064,4 @@ OBJ_id_tc26_gost_3410_2012_256_paramSetD="\x2A\x85\x03\x07\x01\x02\x01\x01\x04" + OBJ_hmacWithSHA512_224="\x2A\x86\x48\x86\xF7\x0D\x02\x0C" + OBJ_hmacWithSHA512_256="\x2A\x86\x48\x86\xF7\x0D\x02\x0D" + OBJ_SM2_with_SM3="\x2A\x81\x1C\xCF\x55\x01\x83\x75" ++OBJ_sm4_xts="\x2A\x81\x1C\xCF\x55\x01\x68\x0A" +diff --git a/include/openssl/evp.h b/include/openssl/evp.h +index 3116c1b..69326bc 100644 +--- a/include/openssl/evp.h ++++ b/include/openssl/evp.h +@@ -353,6 +353,9 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + + # define EVP_CTRL_GET_IVLEN 0x25 + ++/* Set the XTS mode standard, SM4 only */ ++# define EVP_CTRL_XTS_STANDARD 0x26 ++ + /* Padding modes */ + #define EVP_PADDING_PKCS7 1 + #define EVP_PADDING_ISO7816_4 2 +@@ -937,6 +940,7 @@ const EVP_CIPHER *EVP_sm4_cfb128(void); + # define EVP_sm4_cfb EVP_sm4_cfb128 + const EVP_CIPHER *EVP_sm4_ofb(void); + const EVP_CIPHER *EVP_sm4_ctr(void); ++const EVP_CIPHER *EVP_sm4_xts(void); + # endif + + # if OPENSSL_API_COMPAT < 0x10100000L +diff --git a/include/openssl/modes.h b/include/openssl/modes.h +index d544f98..dea324f 100644 +--- a/include/openssl/modes.h ++++ b/include/openssl/modes.h +@@ -22,6 +22,10 @@ typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + ++typedef void (*ecb128_f) (const unsigned char *in, unsigned char *out, ++ size_t len, const void *key, ++ int enc); ++ + typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); +@@ -153,6 +157,11 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + ++int CRYPTO_xts128gb_encrypt(const XTS128_CONTEXT *ctx, ++ const unsigned char iv[16], ++ const unsigned char *inp, unsigned char *out, ++ size_t len, int enc); ++ + size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, +diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h +index 9b125c1..edfc87d 100644 +--- a/include/openssl/obj_mac.h ++++ b/include/openssl/obj_mac.h +@@ -4772,6 +4772,11 @@ + #define NID_sm4_ctr 1139 + #define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L + ++#define SN_sm4_xts "SM4-XTS" ++#define LN_sm4_xts "sm4-xts" ++#define NID_sm4_xts 1196 ++#define OBJ_sm4_xts OBJ_sm_scheme,104L,10L ++ + #define SN_hmac "HMAC" + #define LN_hmac "hmac" + #define NID_hmac 855 +diff --git a/test/evp_test.c b/test/evp_test.c +index 62f20ec..3c65ce9 100644 +--- a/test/evp_test.c ++++ b/test/evp_test.c +@@ -485,6 +485,8 @@ typedef struct cipher_data_st { + unsigned char *tag; + size_t tag_len; + int tag_late; ++ /* SM4 XTS only */ ++ int std; + } CIPHER_DATA; + + static int cipher_test_init(EVP_TEST *t, const char *alg) +@@ -568,6 +570,15 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword, + return -1; + return 1; + } ++ if (strcmp(keyword, "Standard") == 0) { ++ if (strcmp(value, "GB") == 0) ++ cdat->std = 0; ++ else if (strcmp(value, "IEEE") == 0) ++ cdat->std = 1; ++ else ++ return -1; ++ return 1; ++ } + return 0; + } + +@@ -707,7 +718,11 @@ static int cipher_test_enc(EVP_TEST *t, int enc, + goto err; + } + } +- ++ if (expected->std) { ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_XTS_STANDARD, expected->std, NULL)) { ++ goto err; ++ }; ++ } + EVP_CIPHER_CTX_set_padding(ctx, 0); + t->err = "CIPHERUPDATE_ERROR"; + tmplen = 0; +diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt +index 76c839b..a3687bc 100644 +--- a/test/recipes/30-test_evp_data/evpciph.txt ++++ b/test/recipes/30-test_evp_data/evpciph.txt +@@ -2132,6 +2132,28 @@ IV = 0123456789ABCDEFFEDCBA9876543210 + Plaintext = AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA + Ciphertext = C2B4759E78AC3CF43D0852F4E8D5F9FD7256E8A5FCB65A350EE00630912E44492A0B17E1B85B060D0FBA612D8A95831638B361FD5FFACD942F081485A83CA35D + ++Title = SM4 XTS test vectors, the XTS mode is standardized in GB/T 17964-2021 by default ++Cipher = SM4-XTS ++Key = 2B7E151628AED2A6ABF7158809CF4F3C000102030405060708090A0B0C0D0E0F ++IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF ++Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17 ++Ciphertext = E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB0BA42F63499279213D318D2C11F6886E903BE7F93A1B3479 ++ ++Title = SM4 test vectors for XTS mode in GB/T 17964-2021 and IEEE Std 1619-2007 ++Cipher = SM4-XTS ++Key = 2B7E151628AED2A6ABF7158809CF4F3C000102030405060708090A0B0C0D0E0F ++IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF ++Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17 ++Ciphertext = E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB0BA42F63499279213D318D2C11F6886E903BE7F93A1B3479 ++Standard = GB ++ ++Cipher = SM4-XTS ++Key = 2B7E151628AED2A6ABF7158809CF4F3C000102030405060708090A0B0C0D0E0F ++IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF ++Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17 ++Ciphertext = E9538251C71D7B80BBE4483FEF497BD1B3DB1A3E60408C575D63FF7DB39F83260869F9E2585FEC9F0B863BF8FD784B8627D16C0DB6D2CFC7 ++Standard = IEEE ++ + Title = ARIA test vectors from RFC5794 (and others) + + Cipher = ARIA-128-ECB +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 95bccf9..62e2ea2 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4632,3 +4632,5 @@ X509_REQ_get0_sm2_id 6385 1_1_1m EXIST::FUNCTION:SM2 + X509_REQ_set0_sm2_id 6386 1_1_1m EXIST::FUNCTION:SM2 + EVP_PKEY_is_sm2 6387 1_1_1m EXIST::FUNCTION:SM2 + SM2_compute_key 6388 1_1_1m EXIST::FUNCTION: ++EVP_sm4_xts 6389 1_1_1m EXIST::FUNCTION:SM4 ++CRYPTO_xts128gb_encrypt 6390 1_1_1m EXIST::FUNCTION: +\ No newline at end of file +-- +2.36.1 + diff --git a/Fix-reported-performance-degradation-on-aarch64.patch b/Fix-reported-performance-degradation-on-aarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..34445aa7e40b7f4ebea47ac07f84e6c9a070b6a7 --- /dev/null +++ b/Fix-reported-performance-degradation-on-aarch64.patch @@ -0,0 +1,146 @@ +From a8f6d73fda64d514171e99a50d1483c0c0b8d968 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Sun, 12 Jun 2022 09:37:26 +0200 +Subject: [PATCH] Fix reported performance degradation on aarch64 + +This restores the implementation prior to +commit 2621751 ("aes/asm/aesv8-armx.pl: avoid 32-bit lane assignment in CTR mode") +for 64bit targets only, since it is reportedly 2-17% slower, +and the silicon errata only affects 32bit targets. +Only for 32bit targets the new algorithm is used. + +Fixes #18445 + +Reviewed-by: Tomas Mraz +Reviewed-by: Paul Dale +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18539) +--- + crypto/aes/asm/aesv8-armx.pl | 62 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl +index 2b0e982..1856d99 100755 +--- a/crypto/aes/asm/aesv8-armx.pl ++++ b/crypto/aes/asm/aesv8-armx.pl +@@ -740,6 +740,21 @@ $code.=<<___; + #ifndef __ARMEB__ + rev $ctr, $ctr + #endif ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ vorr $dat1,$dat0,$dat0 ++ add $tctr1, $ctr, #1 ++ vorr $dat2,$dat0,$dat0 ++ add $ctr, $ctr, #2 ++ vorr $ivec,$dat0,$dat0 ++ rev $tctr1, $tctr1 ++ vmov.32 ${dat1}[3],$tctr1 ++ b.ls .Lctr32_tail ++ rev $tctr2, $ctr ++ sub $len,$len,#3 // bias ++ vmov.32 ${dat2}[3],$tctr2 ++___ ++$code.=<<___ if ($flavour !~ /64/); + add $tctr1, $ctr, #1 + vorr $ivec,$dat0,$dat0 + rev $tctr1, $tctr1 +@@ -751,6 +766,8 @@ $code.=<<___; + vmov.32 ${ivec}[3],$tctr2 + sub $len,$len,#3 // bias + vorr $dat2,$ivec,$ivec ++___ ++$code.=<<___; + b .Loop3x_ctr32 + + .align 4 +@@ -777,11 +794,25 @@ $code.=<<___; + aese $dat1,q8 + aesmc $tmp1,$dat1 + vld1.8 {$in0},[$inp],#16 ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ vorr $dat0,$ivec,$ivec ++___ ++$code.=<<___ if ($flavour !~ /64/); + add $tctr0,$ctr,#1 ++___ ++$code.=<<___; + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ vorr $dat1,$ivec,$ivec ++___ ++$code.=<<___ if ($flavour !~ /64/); + rev $tctr0,$tctr0 ++___ ++$code.=<<___; + aese $tmp0,q9 + aesmc $tmp0,$tmp0 + aese $tmp1,q9 +@@ -790,6 +821,12 @@ $code.=<<___; + mov $key_,$key + aese $dat2,q9 + aesmc $tmp2,$dat2 ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ vorr $dat2,$ivec,$ivec ++ add $tctr0,$ctr,#1 ++___ ++$code.=<<___; + aese $tmp0,q12 + aesmc $tmp0,$tmp0 + aese $tmp1,q12 +@@ -805,22 +842,47 @@ $code.=<<___; + aese $tmp1,q13 + aesmc $tmp1,$tmp1 + veor $in2,$in2,$rndlast ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ rev $tctr0,$tctr0 ++ aese $tmp2,q13 ++ aesmc $tmp2,$tmp2 ++ vmov.32 ${dat0}[3], $tctr0 ++___ ++$code.=<<___ if ($flavour !~ /64/); + vmov.32 ${ivec}[3], $tctr0 + aese $tmp2,q13 + aesmc $tmp2,$tmp2 + vorr $dat0,$ivec,$ivec ++___ ++$code.=<<___; + rev $tctr1,$tctr1 + aese $tmp0,q14 + aesmc $tmp0,$tmp0 ++___ ++$code.=<<___ if ($flavour !~ /64/); + vmov.32 ${ivec}[3], $tctr1 + rev $tctr2,$ctr ++___ ++$code.=<<___; + aese $tmp1,q14 + aesmc $tmp1,$tmp1 ++___ ++$code.=<<___ if ($flavour =~ /64/); ++ vmov.32 ${dat1}[3], $tctr1 ++ rev $tctr2,$ctr ++ aese $tmp2,q14 ++ aesmc $tmp2,$tmp2 ++ vmov.32 ${dat2}[3], $tctr2 ++___ ++$code.=<<___ if ($flavour !~ /64/); + vorr $dat1,$ivec,$ivec + vmov.32 ${ivec}[3], $tctr2 + aese $tmp2,q14 + aesmc $tmp2,$tmp2 + vorr $dat2,$ivec,$ivec ++___ ++$code.=<<___; + subs $len,$len,#3 + aese $tmp0,q15 + aese $tmp1,q15 +-- +1.8.3.1 + diff --git a/Makefile.certificate b/Makefile.certificate new file mode 100644 index 0000000000000000000000000000000000000000..cc88c52ea92720c52479a97fa0320f0e00febdfd --- /dev/null +++ b/Makefile.certificate @@ -0,0 +1,82 @@ +UTF8 := $(shell locale -c LC_CTYPE -k | grep -q charmap.*UTF-8 && echo -utf8) +DAYS=365 +KEYLEN=2048 +TYPE=rsa:$(KEYLEN) +EXTRA_FLAGS= +ifdef SERIAL + EXTRA_FLAGS+=-set_serial $(SERIAL) +endif + +.PHONY: usage +.SUFFIXES: .key .csr .crt .pem +.PRECIOUS: %.key %.csr %.crt %.pem + +usage: + @echo "This makefile allows you to create:" + @echo " o public/private key pairs" + @echo " o SSL certificate signing requests (CSRs)" + @echo " o self-signed SSL test certificates" + @echo + @echo "To create a key pair, run \"make SOMETHING.key\"." + @echo "To create a CSR, run \"make SOMETHING.csr\"." + @echo "To create a test certificate, run \"make SOMETHING.crt\"." + @echo "To create a key and a test certificate in one file, run \"make SOMETHING.pem\"." + @echo + @echo "To create a key for use with Apache, run \"make genkey\"." + @echo "To create a CSR for use with Apache, run \"make certreq\"." + @echo "To create a test certificate for use with Apache, run \"make testcert\"." + @echo + @echo "To create a test certificate with serial number other than random, add SERIAL=num" + @echo "You can also specify key length with KEYLEN=n and expiration in days with DAYS=n" + @echo "Any additional options can be passed to openssl req via EXTRA_FLAGS" + @echo + @echo Examples: + @echo " make server.key" + @echo " make server.csr" + @echo " make server.crt" + @echo " make stunnel.pem" + @echo " make genkey" + @echo " make certreq" + @echo " make testcert" + @echo " make server.crt SERIAL=1" + @echo " make stunnel.pem EXTRA_FLAGS=-sha384" + @echo " make testcert DAYS=600" + +%.pem: + umask 77 ; \ + PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ + PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ + /usr/bin/openssl req $(UTF8) -newkey $(TYPE) -keyout $$PEM1 -nodes -x509 -days $(DAYS) -out $$PEM2 $(EXTRA_FLAGS) ; \ + cat $$PEM1 > $@ ; \ + echo "" >> $@ ; \ + cat $$PEM2 >> $@ ; \ + $(RM) $$PEM1 $$PEM2 + +%.key: + umask 77 ; \ + /usr/bin/openssl genrsa -aes128 $(KEYLEN) > $@ + +%.csr: %.key + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $^ -out $@ + +%.crt: %.key + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $^ -x509 -days $(DAYS) -out $@ $(EXTRA_FLAGS) + +TLSROOT=/etc/pki/tls +KEY=$(TLSROOT)/private/localhost.key +CSR=$(TLSROOT)/certs/localhost.csr +CRT=$(TLSROOT)/certs/localhost.crt + +genkey: $(KEY) +certreq: $(CSR) +testcert: $(CRT) + +$(CSR): $(KEY) + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $(KEY) -out $(CSR) + +$(CRT): $(KEY) + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $(KEY) -x509 -days $(DAYS) -out $(CRT) $(EXTRA_FLAGS) diff --git a/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch b/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch new file mode 100644 index 0000000000000000000000000000000000000000..63c03f236119a85a9925a328f2f25c9931e850bb --- /dev/null +++ b/backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch @@ -0,0 +1,187 @@ +From 55eafed6fbefbc1e725bf7b17b2bbca083a457fc Mon Sep 17 00:00:00 2001 +From: "Dr. David von Oheimb" +Date: Mon, 30 May 2022 16:53:05 +0200 +Subject: [PATCH] APPS/x509: With -CA but both -CAserial and -CAcreateserial + not given, use random serial. + +Also improve openssl-x509.pod.in and error handling of load_serial() in apps.c. +Backported from https://github.com/openssl/openssl/pull/18373 + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +Reviewed-by: David von Oheimb +(Merged from https://github.com/openssl/openssl/pull/18803) +--- + apps/apps.c | 15 +++++++++++++-- + apps/apps.h | 9 ++++++--- + apps/ca.c | 6 ++++-- + apps/x509.c | 12 ++++++++---- + doc/man1/x509.pod | 12 +++++++----- + 5 files changed, 38 insertions(+), 16 deletions(-) + +diff --git a/apps/apps.c b/apps/apps.c +index db5b48e4cf..f2447fb0be 100644 +--- a/apps/apps.c ++++ b/apps/apps.c +@@ -1376,7 +1376,8 @@ static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) + static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) + #undef BSIZE + #define BSIZE 256 +-BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) ++BIGNUM *load_serial(const char *serialfile, int *exists, int create, ++ ASN1_INTEGER **retai) + { + BIO *in = NULL; + BIGNUM *ret = NULL; +@@ -1388,6 +1389,8 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + goto err; + + in = BIO_new_file(serialfile, "r"); ++ if (exists != NULL) ++ *exists = in != NULL; + if (in == NULL) { + if (!create) { + perror(serialfile); +@@ -1395,8 +1398,14 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + } + ERR_clear_error(); + ret = BN_new(); +- if (ret == NULL || !rand_serial(ret, ai)) ++ if (ret == NULL) { + BIO_printf(bio_err, "Out of memory\n"); ++ } else if (!rand_serial(ret, ai)) { ++ BIO_printf(bio_err, "Error creating random number to store in %s\n", ++ serialfile); ++ BN_free(ret); ++ ret = NULL; ++ } + } else { + if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { + BIO_printf(bio_err, "unable to load number from %s\n", +@@ -1416,6 +1425,8 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) + ai = NULL; + } + err: ++ if (ret == NULL) ++ ERR_print_errors(bio_err); + BIO_free(in); + ASN1_INTEGER_free(ai); + return ret; +diff --git a/apps/apps.h b/apps/apps.h +index 34c3fd8633..775342b4f3 100644 +--- a/apps/apps.h ++++ b/apps/apps.h +@@ -527,9 +527,12 @@ typedef struct ca_db_st { + } CA_DB; + + void* app_malloc(int sz, const char *what); +-BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai); +-int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, +- ASN1_INTEGER **retai); ++ ++/* load_serial, save_serial, and rotate_serial are also used for CRL numbers */ ++BIGNUM *load_serial(const char *serialfile, int *exists, int create, ++ ASN1_INTEGER **retai); ++int save_serial(const char *serialfile, const char *suffix, ++ const BIGNUM *serial, ASN1_INTEGER **retai); + int rotate_serial(const char *serialfile, const char *new_suffix, + const char *old_suffix); + int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); +diff --git a/apps/ca.c b/apps/ca.c +index 390ac37493..ad01bba55a 100755 +--- a/apps/ca.c ++++ b/apps/ca.c +@@ -842,7 +842,8 @@ end_of_options: + goto end; + } + } else { +- if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) { ++ serial = load_serial(serialfile, NULL, create_ser, NULL); ++ if (serial == NULL) { + BIO_printf(bio_err, "error while loading serial number\n"); + goto end; + } +@@ -1078,7 +1079,8 @@ end_of_options: + + if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER)) + != NULL) +- if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) { ++ if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL)) ++ == NULL) { + BIO_printf(bio_err, "error while loading CRL number\n"); + goto end; + } +diff --git a/apps/x509.c b/apps/x509.c +index 1f53504209..67a70e7fea 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -400,7 +400,7 @@ int x509_main(int argc, char **argv) + aliasout = ++num; + break; + case OPT_CACREATESERIAL: +- CA_createserial = ++num; ++ CA_createserial = 1; + break; + case OPT_CLREXT: + clrext = 1; +@@ -916,6 +916,7 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + char *buf = NULL; + ASN1_INTEGER *bs = NULL; + BIGNUM *serial = NULL; ++ int defaultfile = 0, file_exists; + + if (serialfile == NULL) { + const char *p = strrchr(CAfile, '.'); +@@ -925,9 +926,10 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + memcpy(buf, CAfile, len); + memcpy(buf + len, POSTFIX, sizeof(POSTFIX)); + serialfile = buf; ++ defaultfile = 1; + } + +- serial = load_serial(serialfile, create, NULL); ++ serial = load_serial(serialfile, &file_exists, create || defaultfile, NULL); + if (serial == NULL) + goto end; + +@@ -936,8 +938,10 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, + goto end; + } + +- if (!save_serial(serialfile, NULL, serial, &bs)) +- goto end; ++ if (file_exists || create) ++ save_serial(serialfile, NULL, serial, &bs); ++ else ++ bs = BN_to_ASN1_INTEGER(serial, NULL); + + end: + OPENSSL_free(buf); +diff --git a/doc/man1/x509.pod b/doc/man1/x509.pod +index 3c9b2f2263..67d131389a 100644 +--- a/doc/man1/x509.pod ++++ b/doc/man1/x509.pod +@@ -443,13 +443,15 @@ The default filename consists of the CA certificate file base name with + ".srl" appended. For example if the CA certificate file is called + "mycacert.pem" it expects to find a serial number file called "mycacert.srl". + ++If the B<-CA> option is specified and both the <-CAserial> and <-CAcreateserial> ++options are not given and the default serial number file does not exist, ++a random number is generated; this is the recommended practice. ++ + =item B<-CAcreateserial> + +-With this option the CA serial number file is created if it does not exist: +-it will contain the serial number "02" and the certificate being signed will +-have the 1 as its serial number. If the B<-CA> option is specified +-and the serial number file does not exist a random number is generated; +-this is the recommended practice. ++With this option the CA serial number file is created if it does not exist. ++A random number is generated, used for the certificate, and saved into the ++serial number file in that case. + + =item B<-extfile filename> + +-- +2.17.1 + diff --git a/backport-Add-an-extra-reduction-step-to-RSAZ-mod_exp-implemen.patch b/backport-Add-an-extra-reduction-step-to-RSAZ-mod_exp-implemen.patch new file mode 100644 index 0000000000000000000000000000000000000000..463429d4f1399a796bdc814dc4015d48bea4b647 --- /dev/null +++ b/backport-Add-an-extra-reduction-step-to-RSAZ-mod_exp-implemen.patch @@ -0,0 +1,123 @@ +From 8438d3a7b7309cbea521d3628fddeda7bd6d6e20 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Thu, 9 Jun 2022 16:20:05 +0200 +Subject: [PATCH] Add an extra reduction step to RSAZ mod_exp implementations + +Inspired by BoringSSL fix by David Benjamin. + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18511) +--- + crypto/bn/rsaz_exp.c | 8 ++++++++ + crypto/bn/rsaz_exp.h | 23 +++++++++++++++++++++++ + test/recipes/10-test_bn_data/bnmod.txt | 10 ++++------ + 3 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/crypto/bn/rsaz_exp.c b/crypto/bn/rsaz_exp.c +index 22455b8a63..5c5cd4c282 100644 +--- a/crypto/bn/rsaz_exp.c ++++ b/crypto/bn/rsaz_exp.c +@@ -66,6 +66,7 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], + unsigned char *R2 = table_s; /* borrow */ + int index; + int wvalue; ++ BN_ULONG tmp[16]; + + if ((((size_t)p_str & 4095) + 320) >> 12) { + result = p_str; +@@ -237,7 +238,10 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], + + rsaz_1024_red2norm_avx2(result_norm, result); + ++ bn_reduce_once_in_place(result_norm, /*carry=*/0, m_norm, tmp, 16); ++ + OPENSSL_cleanse(storage, sizeof(storage)); ++ OPENSSL_cleanse(tmp, sizeof(tmp)); + } + + /* +@@ -266,6 +270,7 @@ void RSAZ_512_mod_exp(BN_ULONG result[8], + unsigned char *p_str = (unsigned char *)exponent; + int index; + unsigned int wvalue; ++ BN_ULONG tmp[8]; + + /* table[0] = 1_inv */ + temp[0] = 0 - m[0]; +@@ -309,7 +314,10 @@ void RSAZ_512_mod_exp(BN_ULONG result[8], + /* from Montgomery */ + rsaz_512_mul_by_one(result, temp, m, k0); + ++ bn_reduce_once_in_place(result, /*carry=*/0, m, tmp, 8); ++ + OPENSSL_cleanse(storage, sizeof(storage)); ++ OPENSSL_cleanse(tmp, sizeof(tmp)); + } + + #endif +diff --git a/crypto/bn/rsaz_exp.h b/crypto/bn/rsaz_exp.h +index 88f65a4bae..606496d45a 100644 +--- a/crypto/bn/rsaz_exp.h ++++ b/crypto/bn/rsaz_exp.h +@@ -22,6 +22,8 @@ + # define RSAZ_ENABLED + + # include ++# include "internal/constant_time.h" ++# include "bn_local.h" + + void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], + const BN_ULONG base_norm[16], +@@ -35,6 +37,27 @@ void RSAZ_512_mod_exp(BN_ULONG result[8], + const BN_ULONG m_norm[8], BN_ULONG k0, + const BN_ULONG RR[8]); + ++static ossl_inline void bn_select_words(BN_ULONG *r, BN_ULONG mask, ++ const BN_ULONG *a, ++ const BN_ULONG *b, size_t num) ++{ ++ size_t i; ++ ++ for (i = 0; i < num; i++) { ++ r[i] = constant_time_select_64(mask, a[i], b[i]); ++ } ++} ++ ++static ossl_inline BN_ULONG bn_reduce_once_in_place(BN_ULONG *r, ++ BN_ULONG carry, ++ const BN_ULONG *m, ++ BN_ULONG *tmp, size_t num) ++{ ++ carry -= bn_sub_words(tmp, r, m, num); ++ bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); ++ return carry; ++} ++ + # endif + + #endif +diff --git a/test/recipes/10-test_bn_data/bnmod.txt b/test/recipes/10-test_bn_data/bnmod.txt +index 69f8af43d5..edde03bd62 100644 +--- a/test/recipes/10-test_bn_data/bnmod.txt ++++ b/test/recipes/10-test_bn_data/bnmod.txt +@@ -2493,12 +2493,10 @@ E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + M = 8f42c9e9e351ba9b32ab0cf69da43f4acf7028d19cff6e5059ea0e3fcc97c97f36a31470044737d4c0c933ac441ecb29e32c81401523afdac7de9c3fd8493c97 + + # 1024-bit +-# TODO(davidben): This test breaks the RSAZ implementation. Fix it and enable +-# this test. +-# ModExp = 00 +-# A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f +-# E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +-# M = 9da8dc26fdf4d2e49833b240ee552beb7a6e251caa91bfb5d6cafaf8ed9461877fda8f6ac299036d35806bc1ae7872e54eaac1ec6bee6d02c6621a9cf8883b3abc33c49b3e601203e0e86ef8f0562412cc689ee2670704583909ca6d7774c9f9f9f4d77d37fedef9cb51d207cb629ec02fa03b526fd6594bfa8f2da71238a0b7 ++ModExp = 00 ++A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 9da8dc26fdf4d2e49833b240ee552beb7a6e251caa91bfb5d6cafaf8ed9461877fda8f6ac299036d35806bc1ae7872e54eaac1ec6bee6d02c6621a9cf8883b3abc33c49b3e601203e0e86ef8f0562412cc689ee2670704583909ca6d7774c9f9f9f4d77d37fedef9cb51d207cb629ec02fa03b526fd6594bfa8f2da71238a0b7 + + # 1025-bit + ModExp = 00 +-- +2.17.1 + diff --git a/backport-Add-missing-header-for-memcmp.patch b/backport-Add-missing-header-for-memcmp.patch new file mode 100644 index 0000000000000000000000000000000000000000..50ed322cc51be41a7ca9bfbda121a2f473574080 --- /dev/null +++ b/backport-Add-missing-header-for-memcmp.patch @@ -0,0 +1,33 @@ +From 60f011f584d80447e86cae1d1bd3ae24bc13235b Mon Sep 17 00:00:00 2001 +From: Gregor Jasny +Date: Tue, 5 Jul 2022 12:57:06 +0200 +Subject: [PATCH] Add missing header for memcmp + +CLA: trivial + +Reviewed-by: Paul Dale +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Todd Short +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/18719) + +(cherry picked from commit f9e578e720bb35228948564192adbe3bc503d5fb) +--- + test/v3ext.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/test/v3ext.c b/test/v3ext.c +index 386135fed8..7a240cd706 100644 +--- a/test/v3ext.c ++++ b/test/v3ext.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + #include +-- +2.17.1 + diff --git a/backport-Add-test-for-EC_KEY_set_private_key.patch b/backport-Add-test-for-EC_KEY_set_private_key.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6def396daa5f57737545f83b8c63be4a601d8de --- /dev/null +++ b/backport-Add-test-for-EC_KEY_set_private_key.patch @@ -0,0 +1,71 @@ +From 1c2f52bed3ebee6222cf078278074c72717df4ec Mon Sep 17 00:00:00 2001 +From: Roberto Hueso Gomez +Date: Mon, 1 Aug 2022 02:08:47 +0200 +Subject: [PATCH] Add test for EC_KEY_set_private_key() + +This tests the behavior and API of the EC_KEY_set_private_key function. +It tests compliance with legacy features related to NULL private keys +too. + +Reviewed-by: Nicola Tuveri +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18874) +--- + test/ec_internal_test.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/test/ec_internal_test.c b/test/ec_internal_test.c +index 45a36ab94a..4da842a8a7 100644 +--- a/test/ec_internal_test.c ++++ b/test/ec_internal_test.c +@@ -183,6 +183,39 @@ static int field_tests_default(int n) + return ret; + } + ++/* ++ * Tests behavior of the EC_KEY_set_private_key ++ */ ++static int set_private_key(void) ++{ ++ EC_KEY *key = NULL, *aux_key = NULL; ++ int testresult = 0; ++ ++ key = EC_KEY_new_by_curve_name(NID_secp224r1); ++ aux_key = EC_KEY_new_by_curve_name(NID_secp224r1); ++ if (!TEST_ptr(key) ++ || !TEST_ptr(aux_key) ++ || !TEST_int_eq(EC_KEY_generate_key(key), 1) ++ || !TEST_int_eq(EC_KEY_generate_key(aux_key), 1)) ++ goto err; ++ ++ /* Test setting a valid private key */ ++ if (!TEST_int_eq(EC_KEY_set_private_key(key, aux_key->priv_key), 1)) ++ goto err; ++ ++ /* Test compliance with legacy behavior for NULL private keys */ ++ if (!TEST_int_eq(EC_KEY_set_private_key(key, NULL), 0) ++ || !TEST_ptr_null(key->priv_key)) ++ goto err; ++ ++ testresult = 1; ++ ++ err: ++ EC_KEY_free(key); ++ EC_KEY_free(aux_key); ++ return testresult; ++} ++ + /* + * Tests behavior of the decoded_from_explicit_params flag and API + */ +@@ -337,6 +370,7 @@ int setup_tests(void) + ADD_TEST(field_tests_ec2_simple); + #endif + ADD_ALL_TESTS(field_tests_default, crv_len); ++ ADD_TEST(set_private_key); + ADD_TEST(decoded_flag_test); + ADD_ALL_TESTS(ecpkparams_i2d2i_test, crv_len); + +-- +2.17.1 + diff --git a/backport-Add-test-for-empty-supported-groups-extension.patch b/backport-Add-test-for-empty-supported-groups-extension.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e118780cc0579a34b3f7abb23edc01aba9fb9d7 --- /dev/null +++ b/backport-Add-test-for-empty-supported-groups-extension.patch @@ -0,0 +1,157 @@ +From c7d6c08290b67cbeef2b4f636f04788ea405520a Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Fri, 29 Apr 2022 17:02:19 +0200 +Subject: [PATCH] Add test for empty supported-groups extension + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18213) +--- + test/recipes/80-test_ssl_new.t | 4 +- + test/ssl-tests/16-certstatus.conf | 0 + test/ssl-tests/30-supported-groups.conf | 54 ++++++++++++++++++++++ + test/ssl-tests/30-supported-groups.conf.in | 45 ++++++++++++++++++ + 4 files changed, 102 insertions(+), 1 deletion(-) + delete mode 100644 test/ssl-tests/16-certstatus.conf + create mode 100644 test/ssl-tests/30-supported-groups.conf + create mode 100644 test/ssl-tests/30-supported-groups.conf.in + +diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t +index 81d8f59a70..fa62b30850 100644 +--- a/test/recipes/80-test_ssl_new.t ++++ b/test/recipes/80-test_ssl_new.t +@@ -28,7 +28,7 @@ map { s/\^// } @conf_files if $^O eq "VMS"; + + # We hard-code the number of tests to double-check that the globbing above + # finds all files as expected. +-plan tests => 29; # = scalar @conf_srcs ++plan tests => 30; # = scalar @conf_srcs + + # Some test results depend on the configuration of enabled protocols. We only + # verify generated sources in the default configuration. +@@ -70,6 +70,8 @@ my %conf_dependent_tests = ( + "25-cipher.conf" => disabled("poly1305") || disabled("chacha"), + "27-ticket-appdata.conf" => !$is_default_tls, + "28-seclevel.conf" => disabled("tls1_2") || $no_ec, ++ "30-supported-groups.conf" => disabled("tls1_2") || disabled("tls1_3") ++ || $no_ec || $no_ec2m + ); + + # Add your test here if it should be skipped for some compile-time +diff --git a/test/ssl-tests/16-certstatus.conf b/test/ssl-tests/16-certstatus.conf +deleted file mode 100644 +index e69de29bb2..0000000000 +diff --git a/test/ssl-tests/30-supported-groups.conf b/test/ssl-tests/30-supported-groups.conf +new file mode 100644 +index 0000000000..4280db7114 +--- /dev/null ++++ b/test/ssl-tests/30-supported-groups.conf +@@ -0,0 +1,54 @@ ++# Generated with generate_ssl_tests.pl ++ ++num_tests = 2 ++ ++test-0 = 0-Just a sanity test case ++test-1 = 1-Pass with empty groups with TLS1.2 ++# =========================================================== ++ ++[0-Just a sanity test case] ++ssl_conf = 0-Just a sanity test case-ssl ++ ++[0-Just a sanity test case-ssl] ++server = 0-Just a sanity test case-server ++client = 0-Just a sanity test case-client ++ ++[0-Just a sanity test case-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[0-Just a sanity test case-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-0] ++ExpectedResult = Success ++ ++ ++# =========================================================== ++ ++[1-Pass with empty groups with TLS1.2] ++ssl_conf = 1-Pass with empty groups with TLS1.2-ssl ++ ++[1-Pass with empty groups with TLS1.2-ssl] ++server = 1-Pass with empty groups with TLS1.2-server ++client = 1-Pass with empty groups with TLS1.2-client ++ ++[1-Pass with empty groups with TLS1.2-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[1-Pass with empty groups with TLS1.2-client] ++CipherString = DEFAULT ++Groups = sect163k1 ++MaxProtocol = TLSv1.2 ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-1] ++ExpectedResult = Success ++ ++ +diff --git a/test/ssl-tests/30-supported-groups.conf.in b/test/ssl-tests/30-supported-groups.conf.in +new file mode 100644 +index 0000000000..438a07a11f +--- /dev/null ++++ b/test/ssl-tests/30-supported-groups.conf.in +@@ -0,0 +1,45 @@ ++# -*- mode: perl; -*- ++# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the OpenSSL license (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++ ++## SSL test configurations ++ ++package ssltests; ++use OpenSSL::Test::Utils; ++ ++our @tests = ( ++ { ++ name => "Just a sanity test case", ++ server => { }, ++ client => { }, ++ test => { "ExpectedResult" => "Success" }, ++ }, ++); ++ ++our @tests_tls1_3 = ( ++ { ++ name => "Fail empty groups with TLS1.3", ++ server => { }, ++ client => { "Groups" => "sect163k1" }, ++ test => { "ExpectedResult" => "ClientFail" }, ++ }, ++); ++ ++our @tests_tls1_2 = ( ++ { ++ name => "Pass with empty groups with TLS1.2", ++ server => { }, ++ client => { "Groups" => "sect163k1", ++ "MaxProtocol" => "TLSv1.2" }, ++ test => { "ExpectedResult" => "Success" }, ++ }, ++); ++ ++push @tests, @tests_tls1_3 unless disabled("tls1_3") ++ || !disabled("ec2m") || disabled("ec"); ++push @tests, @tests_tls1_2 unless disabled("tls1_2") || disabled("ec"); +-- +2.17.1 + diff --git a/backport-Always-end-BN_mod_exp_mont_consttime-with-normal-Mon.patch b/backport-Always-end-BN_mod_exp_mont_consttime-with-normal-Mon.patch new file mode 100644 index 0000000000000000000000000000000000000000..6084d8cb1712780dd05b0c05b2bf8e7f179ce2df --- /dev/null +++ b/backport-Always-end-BN_mod_exp_mont_consttime-with-normal-Mon.patch @@ -0,0 +1,406 @@ +From 0ed27fb7a8d85685cb671bf0a1e41bcdfc2624dc Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Thu, 9 Jun 2022 12:34:55 +0200 +Subject: [PATCH] Always end BN_mod_exp_mont_consttime with normal Montgomery + reduction. + +This partially fixes a bug where, on x86_64, BN_mod_exp_mont_consttime +would sometimes return m, the modulus, when it should have returned +zero. Thanks to Guido Vranken for reporting it. It is only a partial fix +because the same bug also exists in the "rsaz" codepath. + +The bug only affects zero outputs (with non-zero inputs), so we believe +it has no security impact on our cryptographic functions. + +The fx is to delete lowercase bn_from_montgomery altogether, and have the +mont5 path use the same BN_from_montgomery ending as the non-mont5 path. +This only impacts the final step of the whole exponentiation and has no +measurable perf impact. + +See the original BoringSSL commit +https://boringssl.googlesource.com/boringssl/+/13c9d5c69d04485a7a8840c12185c832026c8315 +for further analysis. + +Original-author: David Benjamin + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18511) +--- + crypto/bn/asm/x86_64-mont5.pl | 196 ------------------------- + crypto/bn/bn_exp.c | 44 +++--- + test/recipes/10-test_bn_data/bnmod.txt | 67 +++++++++ + 3 files changed, 93 insertions(+), 214 deletions(-) + +diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl +index 8c37d132e4..cc7b610145 100755 +--- a/crypto/bn/asm/x86_64-mont5.pl ++++ b/crypto/bn/asm/x86_64-mont5.pl +@@ -2101,193 +2101,6 @@ __bn_post4x_internal: + .size __bn_post4x_internal,.-__bn_post4x_internal + ___ + } +-{ +-$code.=<<___; +-.globl bn_from_montgomery +-.type bn_from_montgomery,\@abi-omnipotent +-.align 32 +-bn_from_montgomery: +-.cfi_startproc +- testl \$7,`($win64?"48(%rsp)":"%r9d")` +- jz bn_from_mont8x +- xor %eax,%eax +- ret +-.cfi_endproc +-.size bn_from_montgomery,.-bn_from_montgomery +- +-.type bn_from_mont8x,\@function,6 +-.align 32 +-bn_from_mont8x: +-.cfi_startproc +- .byte 0x67 +- mov %rsp,%rax +-.cfi_def_cfa_register %rax +- push %rbx +-.cfi_push %rbx +- push %rbp +-.cfi_push %rbp +- push %r12 +-.cfi_push %r12 +- push %r13 +-.cfi_push %r13 +- push %r14 +-.cfi_push %r14 +- push %r15 +-.cfi_push %r15 +-.Lfrom_prologue: +- +- shl \$3,${num}d # convert $num to bytes +- lea ($num,$num,2),%r10 # 3*$num in bytes +- neg $num +- mov ($n0),$n0 # *n0 +- +- ############################################################## +- # Ensure that stack frame doesn't alias with $rptr+3*$num +- # modulo 4096, which covers ret[num], am[num] and n[num] +- # (see bn_exp.c). The stack is allocated to aligned with +- # bn_power5's frame, and as bn_from_montgomery happens to be +- # last operation, we use the opportunity to cleanse it. +- # +- lea -320(%rsp,$num,2),%r11 +- mov %rsp,%rbp +- sub $rptr,%r11 +- and \$4095,%r11 +- cmp %r11,%r10 +- jb .Lfrom_sp_alt +- sub %r11,%rbp # align with $aptr +- lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) +- jmp .Lfrom_sp_done +- +-.align 32 +-.Lfrom_sp_alt: +- lea 4096-320(,$num,2),%r10 +- lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) +- sub %r10,%r11 +- mov \$0,%r10 +- cmovc %r10,%r11 +- sub %r11,%rbp +-.Lfrom_sp_done: +- and \$-64,%rbp +- mov %rsp,%r11 +- sub %rbp,%r11 +- and \$-4096,%r11 +- lea (%rbp,%r11),%rsp +- mov (%rsp),%r10 +- cmp %rbp,%rsp +- ja .Lfrom_page_walk +- jmp .Lfrom_page_walk_done +- +-.Lfrom_page_walk: +- lea -4096(%rsp),%rsp +- mov (%rsp),%r10 +- cmp %rbp,%rsp +- ja .Lfrom_page_walk +-.Lfrom_page_walk_done: +- +- mov $num,%r10 +- neg $num +- +- ############################################################## +- # Stack layout +- # +- # +0 saved $num, used in reduction section +- # +8 &t[2*$num], used in reduction section +- # +32 saved *n0 +- # +40 saved %rsp +- # +48 t[2*$num] +- # +- mov $n0, 32(%rsp) +- mov %rax, 40(%rsp) # save original %rsp +-.cfi_cfa_expression %rsp+40,deref,+8 +-.Lfrom_body: +- mov $num,%r11 +- lea 48(%rsp),%rax +- pxor %xmm0,%xmm0 +- jmp .Lmul_by_1 +- +-.align 32 +-.Lmul_by_1: +- movdqu ($aptr),%xmm1 +- movdqu 16($aptr),%xmm2 +- movdqu 32($aptr),%xmm3 +- movdqa %xmm0,(%rax,$num) +- movdqu 48($aptr),%xmm4 +- movdqa %xmm0,16(%rax,$num) +- .byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 # lea 64($aptr),$aptr +- movdqa %xmm1,(%rax) +- movdqa %xmm0,32(%rax,$num) +- movdqa %xmm2,16(%rax) +- movdqa %xmm0,48(%rax,$num) +- movdqa %xmm3,32(%rax) +- movdqa %xmm4,48(%rax) +- lea 64(%rax),%rax +- sub \$64,%r11 +- jnz .Lmul_by_1 +- +- movq $rptr,%xmm1 +- movq $nptr,%xmm2 +- .byte 0x67 +- mov $nptr,%rbp +- movq %r10, %xmm3 # -num +-___ +-$code.=<<___ if ($addx); +- mov OPENSSL_ia32cap_P+8(%rip),%r11d +- and \$0x80108,%r11d +- cmp \$0x80108,%r11d # check for AD*X+BMI2+BMI1 +- jne .Lfrom_mont_nox +- +- lea (%rax,$num),$rptr +- call __bn_sqrx8x_reduction +- call __bn_postx4x_internal +- +- pxor %xmm0,%xmm0 +- lea 48(%rsp),%rax +- jmp .Lfrom_mont_zero +- +-.align 32 +-.Lfrom_mont_nox: +-___ +-$code.=<<___; +- call __bn_sqr8x_reduction +- call __bn_post4x_internal +- +- pxor %xmm0,%xmm0 +- lea 48(%rsp),%rax +- jmp .Lfrom_mont_zero +- +-.align 32 +-.Lfrom_mont_zero: +- mov 40(%rsp),%rsi # restore %rsp +-.cfi_def_cfa %rsi,8 +- movdqa %xmm0,16*0(%rax) +- movdqa %xmm0,16*1(%rax) +- movdqa %xmm0,16*2(%rax) +- movdqa %xmm0,16*3(%rax) +- lea 16*4(%rax),%rax +- sub \$32,$num +- jnz .Lfrom_mont_zero +- +- mov \$1,%rax +- mov -48(%rsi),%r15 +-.cfi_restore %r15 +- mov -40(%rsi),%r14 +-.cfi_restore %r14 +- mov -32(%rsi),%r13 +-.cfi_restore %r13 +- mov -24(%rsi),%r12 +-.cfi_restore %r12 +- mov -16(%rsi),%rbp +-.cfi_restore %rbp +- mov -8(%rsi),%rbx +-.cfi_restore %rbx +- lea (%rsi),%rsp +-.cfi_def_cfa_register %rsp +-.Lfrom_epilogue: +- ret +-.cfi_endproc +-.size bn_from_mont8x,.-bn_from_mont8x +-___ +-} + }}} + + if ($addx) {{{ +@@ -3894,10 +3707,6 @@ mul_handler: + .rva .LSEH_begin_bn_power5 + .rva .LSEH_end_bn_power5 + .rva .LSEH_info_bn_power5 +- +- .rva .LSEH_begin_bn_from_mont8x +- .rva .LSEH_end_bn_from_mont8x +- .rva .LSEH_info_bn_from_mont8x + ___ + $code.=<<___ if ($addx); + .rva .LSEH_begin_bn_mulx4x_mont_gather5 +@@ -3929,11 +3738,6 @@ $code.=<<___; + .byte 9,0,0,0 + .rva mul_handler + .rva .Lpower5_prologue,.Lpower5_body,.Lpower5_epilogue # HandlerData[] +-.align 8 +-.LSEH_info_bn_from_mont8x: +- .byte 9,0,0,0 +- .rva mul_handler +- .rva .Lfrom_prologue,.Lfrom_body,.Lfrom_epilogue # HandlerData[] + ___ + $code.=<<___ if ($addx); + .align 8 +diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c +index 8c54ab005c..e21dcff027 100644 +--- a/crypto/bn/bn_exp.c ++++ b/crypto/bn/bn_exp.c +@@ -900,14 +900,21 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + #if defined(OPENSSL_BN_ASM_MONT5) + if (window == 5 && top > 1) { + /* +- * This optimization uses ideas from http://eprint.iacr.org/2011/239, +- * specifically optimization of cache-timing attack countermeasures +- * and pre-computation optimization. +- */ +- +- /* +- * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as +- * 512-bit RSA is hardly relevant, we omit it to spare size... ++ * This optimization uses ideas from https://eprint.iacr.org/2011/239, ++ * specifically optimization of cache-timing attack countermeasures, ++ * pre-computation optimization, and Almost Montgomery Multiplication. ++ * ++ * The paper discusses a 4-bit window to optimize 512-bit modular ++ * exponentiation, used in RSA-1024 with CRT, but RSA-1024 is no longer ++ * important. ++ * ++ * |bn_mul_mont_gather5| and |bn_power5| implement the "almost" ++ * reduction variant, so the values here may not be fully reduced. ++ * They are bounded by R (i.e. they fit in |top| words), not |m|. ++ * Additionally, we pass these "almost" reduced inputs into ++ * |bn_mul_mont|, which implements the normal reduction variant. ++ * Given those inputs, |bn_mul_mont| may not give reduced ++ * output, but it will still produce "almost" reduced output. + */ + void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, +@@ -919,9 +926,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + int bn_get_bits5(const BN_ULONG *ap, int off); +- int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, +- const BN_ULONG *not_used, const BN_ULONG *np, +- const BN_ULONG *n0, int num); + + BN_ULONG *n0 = mont->n0, *np; + +@@ -1010,14 +1014,18 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + } + } + +- ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); + tmp.top = top; +- bn_correct_top(&tmp); +- if (ret) { +- if (!BN_copy(rr, &tmp)) +- ret = 0; +- goto err; /* non-zero ret means it's not error */ +- } ++ /* ++ * The result is now in |tmp| in Montgomery form, but it may not be ++ * fully reduced. This is within bounds for |BN_from_montgomery| ++ * (tmp < R <= m*R) so it will, when converting from Montgomery form, ++ * produce a fully reduced result. ++ * ++ * This differs from Figure 2 of the paper, which uses AMM(h, 1) to ++ * convert from Montgomery form with unreduced output, followed by an ++ * extra reduction step. In the paper's terminology, we replace ++ * steps 9 and 10 with MM(h, 1). ++ */ + } else + #endif + { +diff --git a/test/recipes/10-test_bn_data/bnmod.txt b/test/recipes/10-test_bn_data/bnmod.txt +index 6c94a0f025..69f8af43d5 100644 +--- a/test/recipes/10-test_bn_data/bnmod.txt ++++ b/test/recipes/10-test_bn_data/bnmod.txt +@@ -2474,6 +2474,73 @@ A = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9c + E = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0 + M = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7 + ++# The following inputs trigger an edge case between Montgomery reduction and the ++# "almost" reduction variant from https://eprint.iacr.org/2011/239 ++ModExp = 00 ++A = 19c7bc9b97c6083cd7b8d1cd001452c9b67983247169c6532047eb7fc8933014dbf69fee7a358769f1429802c8ea89d4f9ca6ba6f368fbdb1fa5717b4a00 ++E = bbc7e09147408571050e8d0c634682c5863b7e8a573626648902cff12e590c74f5a23ecce39732266bc15b8afbd6c48a48c83fbdc33947515cc0b6e4fb98ae2cd730e58f951fec8be7e2e3c74f4506c7fd7e29bdb28675fe8a59789ab1148e931a2ebd2d36f78bc241682a3d8083d8ff538858cd240c5a693936e5a391dc9d77118062a3f868c058440a4192267faaaba91112f45eee5842060febbf9353a6d3e7f7996573209136a5506062ea23d74067f08c613f3ff74bade25f8c3368e6dba84eae672eac11be1137fc514924fcab8c82e46d092bd047dcbadaa48c67a096ec1a04f392a8511e6acbad9954949b703e71ff837337b594055ae6f3c0fc154447a687c9ac8a2cdfd64a2e680c6ff21254735af7f5eb6b43f0bce86bda55a04143a991711081435ed4f4a89b23fc3a588022b7a8543db4bf5c8ac93603367c750ff2191f59a716340fab49bb7544759c8d846465eec1438e76395f73e7b5e945f31f1b87fefa854a0d208846eaab5fa27144fd039911608bab0eaee80f1d3553dfa2d9ba95268479b97a059613660df5ad79796e0b272244aca90ccc13449ec15c206eeed7b60405a4c5cfdf5da5d136c27fa9385d810ad198dfe794ffce9955e10520efea1e2eb794e379401b9affd863b9566ce941c4726755574a1b1946acf0090bfb93f37dd55f524485bbba7fa84b53addfde01ae1de9c57fe50d4b708dd0fa45d02af398b3d05c6d17f84c11e9aacdbe0b146cad6ddbd877731e26a17f3ebed459560d12ed7a6abc2ea6fe922e69d2622ef11b6b245b9ba8f0940faaa671a4beb727be5393a94dafaeff7221b29183e7418f4c5bb95a6a586c93dbc8ce0236d9dbe26c40513611b4141fed66599adbfb20fc30e09a4815e4159f65a6708f34584a7a77b3843941cd61a6917dcc3d07a3dfb5a2cb108bacea7e782f2111b4d22ecaaeff469ecd0da371df1ac5e9bf6df6ccba2d3a9f393d597499eaca2c206bfb81c3426c5fe45bcf16e38aecd246a319a1f37041c638b75a4839517e43a6d01bee7d85eaeedbce13cd15699d3ee42c7414cfed576590e4fb6ddb6edd3e1957efaf039bfe8b9dc75869b1f93abff15cae8b234161070fa3542303c2ed35ca66083d0ac299b81182317a2a3985269602b1fa1e822fcbda48e686d80b273f06b0a702ca7f42cbbbd2fc2b3601422c8bff6302eda3c61b293049636002649b16f3c1f0be2b6599d66493a4497cd795b10a2ab8220fafad24fa90e1bfcf39ecce337e705695c7a224bf9f445a287d6aab221341659ca4be7861f6ac4c9d33dac811e6 ++M = 519b6e57781d40d897ec0c1b648d195526726b295438c9a70928ac25979563d72db91c8c42298a33b572edecdf40904c68a23337aa5341b56e92b0da5041 ++ ++# To fully exercise BN_mod_exp_mont_consttime codepaths, we generate inputs at ++# different bitwidths. rsaz-avx2.pl only runs at 1024-bit moduli, and ++# x86_64-mont5.pl unrolls 8 64-bit words at a time, so we want to capture both ++# multiples of 512- and non-multiples. Also include moduli that are not quite a ++# full word. ++# 512-bit ++ModExp = 00 ++A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 8f42c9e9e351ba9b32ab0cf69da43f4acf7028d19cff6e5059ea0e3fcc97c97f36a31470044737d4c0c933ac441ecb29e32c81401523afdac7de9c3fd8493c97 ++ ++# 1024-bit ++# TODO(davidben): This test breaks the RSAZ implementation. Fix it and enable ++# this test. ++# ModExp = 00 ++# A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f ++# E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++# M = 9da8dc26fdf4d2e49833b240ee552beb7a6e251caa91bfb5d6cafaf8ed9461877fda8f6ac299036d35806bc1ae7872e54eaac1ec6bee6d02c6621a9cf8883b3abc33c49b3e601203e0e86ef8f0562412cc689ee2670704583909ca6d7774c9f9f9f4d77d37fedef9cb51d207cb629ec02fa03b526fd6594bfa8f2da71238a0b7 ++ ++# 1025-bit ++ModExp = 00 ++A = 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 010223abfdda02e84e11cec8ee7fc784fa135733935f7b9054bb70f1f06d234d76dcf3beed55c7f39e955dc1fef2b65009240fd02f7a1b27a78fc2867144bf666efb929856db9f671c356c4c67a068a70fe83c52eebda03668872fd270d0794f0771d217fb6b93b12529a944f7f0496a9158757c55b8ee14f803f1d2d887e2f561 ++ ++# 1088-bit ++ModExp = 00 ++A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = e91f6d748773cb212a23aa348125615123b1800c9ea222c9374c757702ae4140fa333790ed8f6bf60a1d7dda65c2767cc5f33e32e333d19fbfb5a2b85795757c9ca070268763a618e9d33873d28a89bf88acd209efbb15b80cd33b92a6b3a682e1c91782fc24fb86ddff4f809219c977b54b99359094bbcc51dfe17b992ab24b74a17950ad754281 ++ ++# 1472-bit ++ModExp = 00 ++A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = a8770362f4bfe4fc1ab0e52705c11a9b6ba235d5a5f22197c2d68e27ed18426ede3316af706aa79bcf943dbd51459eb15ae1f9386216b3f3a847f94440a65b97659bc5ba2adb67173714ecaa886c0b926d7a64ea45576f9d2171784ce7e801724d5b0abfd93357d538ea7ad3ad89a74f4660bdb66dfb5f684dcf00402e3cdf0ab58afd867c943c8f47b80268a789456aa7c50a619dd2f9f5e3f74b5d810f0f8dadbf4ad5b917cdcb156c4c132611c8b3b035118a9e03551f ++ ++# 1536-bit ++ModExp = 00 ++A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 878cd000778f927b2f1a4b8bac86efd282079a7ac0d25e09ffd2f72fbc282e65e233929d2457c7b1d63c56fb706cdfa04fb87e654c578c98d7cf59c2293dc5641086b68db4867105981daaf147a0ee91f6932ef064deae4142c19e58d50c0686f0eaf778be72450f89a98b4680bbc5ffab942195e44dd20616150fd1deca058068ca31ab2f861e99082588f17a2025bf5e536150142fca3187a259c791fc721430f24d7e338f8dc02e693a7e694d42775e80f7f7c03600b6ae86b4aba2b0e991 ++ ++# 2048-bit ++ModExp = 00 ++A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 9f40a7535c561208ecb38e17c9336d9bc8484d335901b2cd42759cf03689227f6992f10cb6b586d767fbcdf30e9d82a0eda60d2694ccd0194fa96b50b56e0cdeec1951ea9e58b07e334a7f108841a0ab28256917fecea561388807ed124a17386a7a7b501f9cbf3404247a76948d0561e48137d3f9669e36f175731796aeaf78851f7d866917f661422186a4814aa35c066b5a90b9cfc918af769a9f0bb30c12581027df64ac328a0f07dbd20adb704479f6d0f233a131828c71bab19c3c34795ea4fb68aa632c6f688e5b3b84413c9031d8dc251003a590dec0dd09bfa6109ed4570701439b6f265b84ac2170c317357b5fbe5535e2bbdd93c1aacfdaa28c85 ++ ++# 3072-bit ++ModExp = 00 ++A = 80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = c23dfd244a58a668d514498a705c8f8f548311b24f0f98b023d2d33632534c2ae948d6641d41fd7a29fbbd594bfc7fdd6e8162cbb3056af3075347b6fc8876458d33a9d0ffdbcdf482de0c73d1310fd8fa8f9f92dd0dbb0e2034e98a30f6c11b482f7476c5b593f673a322b1130daa4314e9074270dce1076436f0d56cf196afcbb235a9a7b3ac85b9062e85fc0e63a12c468c787019f6805f9faab64fc6a0babc80785d88740243f11366bffb40ccbe8b2bb7a99a2c8238a6f656bb0117d7b2602aa400f4d77de5f93c673f13264ca70de949454e3e3f261993c1aa427e8ef4f507af744f71f3b4aaf3c981d44cc1bfb1eb1151168762b242b740573df698e500d99612e17dc760f7b3bf7c235e39e81ad7edbe6c07dbb8b139745bb394d61cb799bcafec5de074932b0b2d74797e779ac8d81f63a2b2e9baa229dfaa7f90f34ffade1d2ad022a3407d35eb2d7477c6ae8ad100f6e95c05b4f947c1fabfb11a17add384e6b4cd3a02fd9b43f46805c6c74e366b74aa3b766be7a5fbbd67fa81 ++ ++# 4096-bit ++ModExp = 00 ++A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 ++E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++M = 8030411ecbddcb0fe4e76fd6b5bf542e8b015d1610cf96130ded12ba2cda0641bd9692080f218ea8b0d751845b519d95b843542ec8d2a07f1f93afe3189b69a4f35c983011c7f7928c3df458cc3eae85c36e6934a4b1bc0a67c8a521de336642c49e10a7ffa8d0af911aacc19e3900449161940f139220e099a150dcaf0ff96ffff6e726c1ac139969103cf6a828ac3adf0301506aa02787b4f570d5dde53a34acab8fec6fa94760abf16ee99954371ad65a6e899daab87b95811d069404991de9abe064ebbddf886e970f10d260c899dda940191a82d4c8bd36651363aff5493f4f59e700007dcadf37ebea7fcfd7600d16617ffea0d9ae659446d851d93c564e50e558f734c894d735fa273770703dab62844d9f01badf632f3d14a00f739c022c9be95f54e9cea46ec6da7cb11f4602e06962951c48204726b7f120ddbd0eb3566dc8d1e6f195a9196e96db33322d088b43aecffe9b4df182dd016aca0bd14f1c56cd1a18b89165c027029862b09ffd78e92ab614349c4fd67f49cb12cd33d0728930d0538bda57acef1365a73cc8fbac7d463b9e3c3bae0bb6224b080cdb8b5cd47d546d53111fdc22b7ff679bcfe27192920ee163b2be337d8cccc93b4de7d2d31934b9c0e97af291dcc1135b4a473bd37114eec3ba75c411887b57799d3188e7353f33a4d31735ebfc9fcfc044985148dd96da3876a5ab7ea7a404b411 + + # These test vectors satisfy (ModSqrt * ModSqrt) mod P = A mod P with P a prime. + # ModSqrt is in [0, (P-1)/2]. +-- +2.17.1 + diff --git a/backport-Avoid-potential-memory-leak.patch b/backport-Avoid-potential-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..761057aded22dfe3e8b39ee47c1f475e93eafd84 --- /dev/null +++ b/backport-Avoid-potential-memory-leak.patch @@ -0,0 +1,36 @@ +From c02fff5aecd4d002143a0e901f3dde3d14934a18 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Mon, 7 Mar 2022 17:05:57 +0100 +Subject: [PATCH] Avoid potential memory leak + +Resolves #17827 + +Reviewed-by: Tomas Mraz +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/17828) + +(cherry picked from commit 175355923046921a689b500f7a72455f7095708f) +--- + crypto/x509v3/v3_utl.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c +index 40d8f31554..83a4bc8a06 100644 +--- a/crypto/x509v3/v3_utl.c ++++ b/crypto/x509v3/v3_utl.c +@@ -538,8 +538,11 @@ static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email + return 0; + + emtmp = OPENSSL_strndup((char *)email->data, email->length); +- if (emtmp == NULL) ++ if (emtmp == NULL) { ++ X509_email_free(*sk); ++ *sk = NULL; + return 0; ++ } + + /* Don't add duplicates */ + if (sk_OPENSSL_STRING_find(*sk, emtmp) != -1) { +-- +2.17.1 + diff --git a/backport-Check-password-length-only-when-verify-is-enabled.patch b/backport-Check-password-length-only-when-verify-is-enabled.patch new file mode 100644 index 0000000000000000000000000000000000000000..4196ef1e84f868a10e7514f1098138e1d8a4f6ab --- /dev/null +++ b/backport-Check-password-length-only-when-verify-is-enabled.patch @@ -0,0 +1,30 @@ +From 0a9bb445893b4a98ad1588aef2d14c29e6c4c5e3 Mon Sep 17 00:00:00 2001 +From: Daniel Fiala +Date: Wed, 16 Mar 2022 07:42:55 +0100 +Subject: [PATCH] Check password length only when verify is enabled. + +Fixes #16231. + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17899) +--- + apps/apps.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/apps/apps.c b/apps/apps.c +index 1a92271595..db5b48e4cf 100644 +--- a/apps/apps.c ++++ b/apps/apps.c +@@ -307,6 +307,8 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) + if (cb_data != NULL && cb_data->password != NULL + && *(const char*)cb_data->password != '\0') + pw_min_len = 1; ++ else if (!verify) ++ pw_min_len = 0; + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (!prompt) { + BIO_printf(bio_err, "Out of memory\n"); +-- +2.17.1 + diff --git a/backport-Convert-serverinfo-in-SSL_CTX_use_serverinfo-to-v2.patch b/backport-Convert-serverinfo-in-SSL_CTX_use_serverinfo-to-v2.patch new file mode 100644 index 0000000000000000000000000000000000000000..8fd098c0e5094eeffef7ce82a6dcd090dee4d5dc --- /dev/null +++ b/backport-Convert-serverinfo-in-SSL_CTX_use_serverinfo-to-v2.patch @@ -0,0 +1,376 @@ +From 6e6aad333f26694ff39aba1e59b358e3f25a9a1d Mon Sep 17 00:00:00 2001 +From: Daniel Fiala +Date: Sun, 28 Aug 2022 11:53:32 +0200 +Subject: [PATCH] Convert serverinfo in SSL_CTX_use_serverinfo() to v2. + +Fixes #18183. + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/19081) +--- + ssl/ssl_rsa.c | 81 ++++++++++++++++------ + test/sslapitest.c | 171 +++++++++++++++++++++++++++++++--------------- + 2 files changed, 177 insertions(+), 75 deletions(-) + +diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c +index 6457c0c0ef..3535c95354 100644 +--- a/ssl/ssl_rsa.c ++++ b/ssl/ssl_rsa.c +@@ -727,6 +727,34 @@ static int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type, + return 1; + } + ++static size_t extension_contextoff(unsigned int version) ++{ ++ return version == SSL_SERVERINFOV1 ? 4 : 0; ++} ++ ++static size_t extension_append_length(unsigned int version, size_t extension_length) ++{ ++ return extension_length + extension_contextoff(version); ++} ++ ++static void extension_append(unsigned int version, ++ const unsigned char *extension, ++ const size_t extension_length, ++ unsigned char *serverinfo) ++{ ++ const size_t contextoff = extension_contextoff(version); ++ ++ if (contextoff > 0) { ++ /* We know this only uses the last 2 bytes */ ++ serverinfo[0] = 0; ++ serverinfo[1] = 0; ++ serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; ++ serverinfo[3] = SYNTHV1CONTEXT & 0xff; ++ } ++ ++ memcpy(serverinfo + contextoff, extension, extension_length); ++} ++ + static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, void *arg) +@@ -842,12 +870,36 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, + const unsigned char *serverinfo, + size_t serverinfo_length) + { +- unsigned char *new_serverinfo; ++ unsigned char *new_serverinfo = NULL; + + if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } ++ if (version == SSL_SERVERINFOV1) { ++ /* ++ * Convert serverinfo version v1 to v2 and call yourself recursively ++ * over the converted serverinfo. ++ */ ++ const size_t sinfo_length = extension_append_length(SSL_SERVERINFOV1, ++ serverinfo_length); ++ unsigned char *sinfo; ++ int ret; ++ ++ sinfo = OPENSSL_malloc(sinfo_length); ++ if (sinfo == NULL) { ++ SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo); ++ ++ ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, sinfo, ++ sinfo_length); ++ ++ OPENSSL_free(sinfo); ++ return ret; ++ } + if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, + NULL)) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); +@@ -899,7 +951,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) + char namePrefix2[] = "SERVERINFOV2 FOR "; + int ret = 0; + BIO *bin = NULL; +- size_t num_extensions = 0, contextoff = 0; ++ size_t num_extensions = 0; + + if (ctx == NULL || file == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER); +@@ -918,6 +970,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) + + for (num_extensions = 0;; num_extensions++) { + unsigned int version; ++ size_t append_length; + + if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) + == 0) { +@@ -962,11 +1015,6 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); + goto end; + } +- /* +- * File does not have a context value so we must take account of +- * this later. +- */ +- contextoff = 4; + } else { + /* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */ + if (extension_length < 8 +@@ -977,25 +1025,16 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) + } + } + /* Append the decoded extension to the serverinfo buffer */ +- tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length +- + contextoff); ++ append_length = extension_append_length(version, extension_length); ++ tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length); + if (tmp == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); + goto end; + } + serverinfo = tmp; +- if (contextoff > 0) { +- unsigned char *sinfo = serverinfo + serverinfo_length; +- +- /* We know this only uses the last 2 bytes */ +- sinfo[0] = 0; +- sinfo[1] = 0; +- sinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; +- sinfo[3] = SYNTHV1CONTEXT & 0xff; +- } +- memcpy(serverinfo + serverinfo_length + contextoff, +- extension, extension_length); +- serverinfo_length += extension_length + contextoff; ++ extension_append(version, extension, extension_length, ++ serverinfo + serverinfo_length); ++ serverinfo_length += append_length; + + OPENSSL_free(name); + name = NULL; +diff --git a/test/sslapitest.c b/test/sslapitest.c +index 7197e15cac..685c28d934 100644 +--- a/test/sslapitest.c ++++ b/test/sslapitest.c +@@ -85,20 +85,6 @@ struct sslapitest_log_counts { + }; + + +-static unsigned char serverinfov1[] = { +- 0xff, 0xff, /* Dummy extension type */ +- 0x00, 0x01, /* Extension length is 1 byte */ +- 0xff /* Dummy extension data */ +-}; +- +-static unsigned char serverinfov2[] = { +- 0x00, 0x00, 0x00, +- (unsigned char)(SSL_EXT_CLIENT_HELLO & 0xff), /* Dummy context - 4 bytes */ +- 0xff, 0xff, /* Dummy extension type */ +- 0x00, 0x01, /* Extension length is 1 byte */ +- 0xff /* Dummy extension data */ +-}; +- + static int hostname_cb(SSL *s, int *al, void *arg) + { + const char *hostname = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); +@@ -4349,62 +4335,137 @@ end: + return testresult; + } + +-/* +- * Test loading of serverinfo data in various formats. test_sslmessages actually +- * tests to make sure the extensions appear in the handshake +- */ +-static int test_serverinfo(int tst) ++#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_3) ++ ++#define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ ++ | SSL_EXT_CLIENT_HELLO \ ++ | SSL_EXT_TLS1_2_SERVER_HELLO \ ++ | SSL_EXT_IGNORE_ON_RESUMPTION) ++ ++#define TLS13CONTEXT (SSL_EXT_TLS1_3_CERTIFICATE \ ++ | SSL_EXT_TLS1_2_SERVER_HELLO \ ++ | SSL_EXT_CLIENT_HELLO) ++ ++#define SERVERINFO_CUSTOM \ ++ 0x00, (char)TLSEXT_TYPE_signed_certificate_timestamp, \ ++ 0x00, 0x03, \ ++ 0x04, 0x05, 0x06 \ ++ ++static const unsigned char serverinfo_custom_tls13[] = { ++ 0x00, 0x00, (TLS13CONTEXT >> 8) & 0xff, TLS13CONTEXT & 0xff, ++ SERVERINFO_CUSTOM ++}; ++static const unsigned char serverinfo_custom_v2[] = { ++ 0x00, 0x00, (SYNTHV1CONTEXT >> 8) & 0xff, SYNTHV1CONTEXT & 0xff, ++ SERVERINFO_CUSTOM ++}; ++static const unsigned char serverinfo_custom_v1[] = { ++ SERVERINFO_CUSTOM ++}; ++static const size_t serverinfo_custom_tls13_len = sizeof(serverinfo_custom_tls13); ++static const size_t serverinfo_custom_v2_len = sizeof(serverinfo_custom_v2); ++static const size_t serverinfo_custom_v1_len = sizeof(serverinfo_custom_v1); ++ ++static int serverinfo_custom_parse_cb(SSL *s, unsigned int ext_type, ++ unsigned int context, ++ const unsigned char *in, ++ size_t inlen, X509 *x, ++ size_t chainidx, int *al, ++ void *parse_arg) + { +- unsigned int version; +- unsigned char *sibuf; +- size_t sibuflen; +- int ret, expected, testresult = 0; +- SSL_CTX *ctx; ++ const size_t len = serverinfo_custom_v1_len; ++ const unsigned char *si = &serverinfo_custom_v1[len - 3]; ++ int *p_cb_result = (int*)parse_arg; ++ *p_cb_result = TEST_mem_eq(in, inlen, si, 3); ++ return 1; ++} + +- ctx = SSL_CTX_new(TLS_method()); +- if (!TEST_ptr(ctx)) +- goto end; ++static int test_serverinfo_custom(const int idx) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *clientssl = NULL, *serverssl = NULL; ++ int testresult = 0; ++ int cb_result = 0; + +- if ((tst & 0x01) == 0x01) +- version = SSL_SERVERINFOV2; +- else +- version = SSL_SERVERINFOV1; ++ /* ++ * Following variables are set in the switch statement ++ * according to the test iteration. ++ * Default values do not make much sense: test would fail with them. ++ */ ++ int serverinfo_version = 0; ++ int protocol_version = 0; ++ unsigned int extension_context = 0; ++ const unsigned char *si = NULL; ++ size_t si_len = 0; + +- if ((tst & 0x02) == 0x02) { +- sibuf = serverinfov2; +- sibuflen = sizeof(serverinfov2); +- expected = (version == SSL_SERVERINFOV2); +- } else { +- sibuf = serverinfov1; +- sibuflen = sizeof(serverinfov1); +- expected = (version == SSL_SERVERINFOV1); ++ const int call_use_serverinfo_ex = idx > 0; ++ switch (idx) { ++ case 0: /* FALLTHROUGH */ ++ case 1: ++ serverinfo_version = SSL_SERVERINFOV1; ++ protocol_version = TLS1_2_VERSION; ++ extension_context = SYNTHV1CONTEXT; ++ si = serverinfo_custom_v1; ++ si_len = serverinfo_custom_v1_len; ++ break; ++ case 2: ++ serverinfo_version = SSL_SERVERINFOV2; ++ protocol_version = TLS1_2_VERSION; ++ extension_context = SYNTHV1CONTEXT; ++ si = serverinfo_custom_v2; ++ si_len = serverinfo_custom_v2_len; ++ break; ++ case 3: ++ serverinfo_version = SSL_SERVERINFOV2; ++ protocol_version = TLS1_3_VERSION; ++ extension_context = TLS13CONTEXT; ++ si = serverinfo_custom_tls13; ++ si_len = serverinfo_custom_tls13_len; ++ break; + } + +- if ((tst & 0x04) == 0x04) { +- ret = SSL_CTX_use_serverinfo_ex(ctx, version, sibuf, sibuflen); +- } else { +- ret = SSL_CTX_use_serverinfo(ctx, sibuf, sibuflen); ++ if (!TEST_true(create_ssl_ctx_pair(TLS_method(), ++ TLS_method(), ++ protocol_version, ++ protocol_version, ++ &sctx, &cctx, cert, privkey))) ++ goto end; + +- /* +- * The version variable is irrelevant in this case - it's what is in the +- * buffer that matters +- */ +- if ((tst & 0x02) == 0x02) +- expected = 0; +- else +- expected = 1; ++ if (call_use_serverinfo_ex) { ++ if (!TEST_true(SSL_CTX_use_serverinfo_ex(sctx, serverinfo_version, ++ si, si_len))) ++ goto end; ++ } else { ++ if (!TEST_true(SSL_CTX_use_serverinfo(sctx, si, si_len))) ++ goto end; + } + +- if (!TEST_true(ret == expected)) ++ if (!TEST_true(SSL_CTX_add_custom_ext(cctx, TLSEXT_TYPE_signed_certificate_timestamp, ++ extension_context, ++ NULL, NULL, NULL, ++ serverinfo_custom_parse_cb, ++ &cb_result)) ++ || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, ++ NULL, NULL)) ++ || !TEST_true(create_ssl_connection(serverssl, clientssl, ++ SSL_ERROR_NONE)) ++ || !TEST_int_eq(SSL_do_handshake(clientssl), 1)) ++ goto end; ++ ++ if (!TEST_true(cb_result)) + goto end; + + testresult = 1; + + end: +- SSL_CTX_free(ctx); ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); + + return testresult; + } ++#endif + + /* + * Test that SSL_export_keying_material() produces expected results. There are +@@ -7175,7 +7236,6 @@ int setup_tests(void) + #else + ADD_ALL_TESTS(test_custom_exts, 3); + #endif +- ADD_ALL_TESTS(test_serverinfo, 8); + ADD_ALL_TESTS(test_export_key_mat, 6); + #ifndef OPENSSL_NO_TLS1_3 + ADD_ALL_TESTS(test_export_key_mat_early, 3); +@@ -7207,6 +7267,9 @@ int setup_tests(void) + #endif + ADD_TEST(test_set_alpn); + ADD_TEST(test_inherit_verify_param); ++#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_3) ++ ADD_ALL_TESTS(test_serverinfo_custom, 4); ++#endif + return 1; + } + +-- +2.17.1 + diff --git a/backport-Coverity-1508534-1508540-misuses-of-time_t.patch b/backport-Coverity-1508534-1508540-misuses-of-time_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..22cd21f8621455fb772134f0f8306e5186a73efb --- /dev/null +++ b/backport-Coverity-1508534-1508540-misuses-of-time_t.patch @@ -0,0 +1,67 @@ +From 552603edfed18f30466277d29b70939390fea65b Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Tue, 16 Aug 2022 11:05:02 +1000 +Subject: [PATCH] Coverity 1508534 & 1508540: misuses of time_t + +Avoid problems when the lower 32 bits of time_t roll over by delaying +the cast to integer until after the time delta has been computed. + +Reviewed-by: Ben Kaduk +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/19004) + +(cherry picked from commit a6cadcbdc3b4f3fbd0fd228e41177f0661b68264) +--- + ssl/statem/extensions_clnt.c | 5 ++--- + ssl/statem/extensions_srvr.c | 5 ++--- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c +index b6f72d685c..1cbaefa9f1 100644 +--- a/ssl/statem/extensions_clnt.c ++++ b/ssl/statem/extensions_clnt.c +@@ -1002,7 +1002,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) + { + #ifndef OPENSSL_NO_TLS1_3 +- uint32_t now, agesec, agems = 0; ++ uint32_t agesec, agems = 0; + size_t reshashsize = 0, pskhashsize = 0, binderoffset, msglen; + unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL; + const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL; +@@ -1059,8 +1059,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, + * this in multiple places in the code, so portability shouldn't be an + * issue. + */ +- now = (uint32_t)time(NULL); +- agesec = now - (uint32_t)s->session->time; ++ agesec = (uint32_t)(time(NULL) - s->session->time); + /* + * We calculate the age in seconds but the server may work in ms. Due to + * rounding errors we could overestimate the age by up to 1s. It is +diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c +index 04f64f8106..f110053273 100644 +--- a/ssl/statem/extensions_srvr.c ++++ b/ssl/statem/extensions_srvr.c +@@ -1167,7 +1167,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + s->ext.early_data_ok = 1; + s->ext.ticket_expected = 1; + } else { +- uint32_t ticket_age = 0, now, agesec, agems; ++ uint32_t ticket_age = 0, agesec, agems; + int ret; + + /* +@@ -1209,8 +1209,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + } + + ticket_age = (uint32_t)ticket_agel; +- now = (uint32_t)time(NULL); +- agesec = now - (uint32_t)sess->time; ++ agesec = (uint32_t)(time(NULL) - sess->time); + agems = agesec * (uint32_t)1000; + ticket_age -= sess->ext.tick_age_add; + +-- +2.17.1 + diff --git a/backport-Do-not-send-an-empty-supported-groups-extension.patch b/backport-Do-not-send-an-empty-supported-groups-extension.patch new file mode 100644 index 0000000000000000000000000000000000000000..527ffab6fe26c19ea53502600f4e9c96e95814ea --- /dev/null +++ b/backport-Do-not-send-an-empty-supported-groups-extension.patch @@ -0,0 +1,54 @@ +From bd164884f258d99ca876f6cdcdf9bd0dcceee6ad Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Fri, 29 Apr 2022 16:36:36 +0200 +Subject: [PATCH] Do not send an empty supported groups extension + +This allows handshake to proceed if the maximum TLS version enabled is <1.3 + +Fixes #13583 + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18213) +--- + CHANGES | 24 ++++++++++++++---------- + ssl/statem/extensions_clnt.c | 16 +++++++++++++++- + 2 files changed, 29 insertions(+), 11 deletions(-) + +diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c +index 9d38ac23b5..036a9b3c48 100644 +--- a/ssl/statem/extensions_clnt.c ++++ b/ssl/statem/extensions_clnt.c +@@ -118,6 +118,8 @@ static int use_ecc(SSL *s) + int i, end, ret = 0; + unsigned long alg_k, alg_a; + STACK_OF(SSL_CIPHER) *cipher_stack = NULL; ++ const uint16_t *pgroups = NULL; ++ size_t num_groups, j; + + /* See if we support any ECC ciphersuites */ + if (s->version == SSL3_VERSION) +@@ -139,7 +141,19 @@ static int use_ecc(SSL *s) + } + + sk_SSL_CIPHER_free(cipher_stack); +- return ret; ++ if (!ret) ++ return 0; ++ ++ /* Check we have at least one EC supported group */ ++ tls1_get_supported_groups(s, &pgroups, &num_groups); ++ for (j = 0; j < num_groups; j++) { ++ uint16_t ctmp = pgroups[j]; ++ ++ if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) ++ return 1; ++ } ++ ++ return 0; + } + + EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, +-- +2.17.1 + diff --git a/backport-Fix-Coverity-1201763-uninitialised-pointer-read.patch b/backport-Fix-Coverity-1201763-uninitialised-pointer-read.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa1406f0adabb7f1af40a7a474505b8cee013693 --- /dev/null +++ b/backport-Fix-Coverity-1201763-uninitialised-pointer-read.patch @@ -0,0 +1,37 @@ +From ad24941228eafe59fe3807d1659585c4d98eac97 Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 16 Mar 2022 13:48:27 +1100 +Subject: [PATCH] Fix Coverity 1201763 uninitialised pointer read + +Reviewed-by: Shane Lontis +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17890) + +(cherry picked from commit a0238b7ed87998c48b1c92bad7fa82dcbba507f9) +--- + crypto/bn/bn_exp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c +index 9531acfc3c..451e88ac3c 100644 +--- a/crypto/bn/bn_exp.c ++++ b/crypto/bn/bn_exp.c +@@ -188,13 +188,14 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + return ret; + } + ++ BN_RECP_CTX_init(&recp); ++ + BN_CTX_start(ctx); + aa = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (val[0] == NULL) + goto err; + +- BN_RECP_CTX_init(&recp); + if (m->neg) { + /* ignore sign of 'm' */ + if (!BN_copy(aa, m)) +-- +2.17.1 + diff --git a/backport-Fix-Coverity-1498611-1498608-uninitialised-read.patch b/backport-Fix-Coverity-1498611-1498608-uninitialised-read.patch new file mode 100644 index 0000000000000000000000000000000000000000..865ffa3b78b30f55f8ec29639b914610f7de35fb --- /dev/null +++ b/backport-Fix-Coverity-1498611-1498608-uninitialised-read.patch @@ -0,0 +1,37 @@ +From cd2471cd797ae5a6355814bb14a176af6a7d883f Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 16 Mar 2022 14:21:01 +1100 +Subject: [PATCH] Fix Coverity 1498611 & 1498608: uninitialised read + +Reviewed-by: Shane Lontis +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17893) + +(cherry picked from commit 09134f183f76539aa1294adfef10fcc694e90267) +--- + ssl/ssl_lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 9c411a3293..7383badce3 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -2084,6 +2084,7 @@ int SSL_shutdown(SSL *s) + if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + struct ssl_async_args args; + ++ memset(&args, 0, sizeof(args)); + args.s = s; + args.type = OTHERFUNC; + args.f.func_other = s->method->ssl_shutdown; +@@ -3709,6 +3710,7 @@ int SSL_do_handshake(SSL *s) + if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + struct ssl_async_args args; + ++ memset(&args, 0, sizeof(args)); + args.s = s; + + ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern); +-- +2.17.1 + diff --git a/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch b/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0354a90fb6fd4fbfd4094c9bf329805098263f0 --- /dev/null +++ b/backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch @@ -0,0 +1,42 @@ +From 143d7d4c791df8b9051356be51d9f77bc241fe4c Mon Sep 17 00:00:00 2001 +From: Roberto Hueso Gomez +Date: Tue, 26 Jul 2022 20:41:02 +0200 +Subject: [PATCH] Fix EC_KEY_set_private_key() priv_key regression + +This allows to set EC_KEY's private key to NULL and fixes regression +issue following OTC guideline in +https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696 + +Fixes #18744. + +Reviewed-by: Nicola Tuveri +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18874) +--- + crypto/ec/ec_key.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c +index 3017f0936c..63799002bc 100644 +--- a/crypto/ec/ec_key.c ++++ b/crypto/ec/ec_key.c +@@ -443,6 +443,16 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) + && key->meth->set_private(key, priv_key) == 0) + return 0; + ++ /* ++ * Return `0` to comply with legacy behavior for this function, see ++ * https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696 ++ */ ++ if (priv_key == NULL) { ++ BN_clear_free(key->priv_key); ++ key->priv_key = NULL; ++ return 0; /* intentional for legacy compatibility */ ++ } ++ + /* + * We should never leak the bit length of the secret scalar in the key, + * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM` +-- +2.17.1 + diff --git a/backport-Fix-NULL-pointer-dereference-for-BN_mod_exp2_mont.patch b/backport-Fix-NULL-pointer-dereference-for-BN_mod_exp2_mont.patch new file mode 100644 index 0000000000000000000000000000000000000000..1a02df857c758432e198de155d3d42eedeacd64d --- /dev/null +++ b/backport-Fix-NULL-pointer-dereference-for-BN_mod_exp2_mont.patch @@ -0,0 +1,98 @@ +From 8845aeb3ed528491b9eccba365182f90540e5b95 Mon Sep 17 00:00:00 2001 +From: Hugo Landau +Date: Tue, 1 Mar 2022 14:08:12 +0000 +Subject: [PATCH] Fix NULL pointer dereference for BN_mod_exp2_mont + +This fixes a bug whereby BN_mod_exp2_mont can dereference a NULL pointer +if BIGNUM argument m represents zero. + +Regression test added. Fixes #17648. Backport from master to 1.1. + +Reviewed-by: Matt Caswell +Reviewed-by: Todd Short +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17787) +--- + crypto/bn/bn_exp2.c | 2 +- + test/bntest.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/crypto/bn/bn_exp2.c b/crypto/bn/bn_exp2.c +index e542abe46f..de3e249d78 100644 +--- a/crypto/bn/bn_exp2.c ++++ b/crypto/bn/bn_exp2.c +@@ -32,7 +32,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, + bn_check_top(p2); + bn_check_top(m); + +- if (!(m->d[0] & 1)) { ++ if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } +diff --git a/test/bntest.c b/test/bntest.c +index bab34ba54b..390dd80073 100644 +--- a/test/bntest.c ++++ b/test/bntest.c +@@ -2798,6 +2798,50 @@ static int test_mod_exp_consttime(int i) + return res; + } + ++/* ++ * Regression test to ensure BN_mod_exp2_mont fails safely if argument m is ++ * zero. ++ */ ++static int test_mod_exp2_mont(void) ++{ ++ int res = 0; ++ BIGNUM *exp_result = NULL; ++ BIGNUM *exp_a1 = NULL, *exp_p1 = NULL, *exp_a2 = NULL, *exp_p2 = NULL, ++ *exp_m = NULL; ++ ++ if (!TEST_ptr(exp_result = BN_new()) ++ || !TEST_ptr(exp_a1 = BN_new()) ++ || !TEST_ptr(exp_p1 = BN_new()) ++ || !TEST_ptr(exp_a2 = BN_new()) ++ || !TEST_ptr(exp_p2 = BN_new()) ++ || !TEST_ptr(exp_m = BN_new())) ++ goto err; ++ ++ if (!TEST_true(BN_one(exp_a1)) ++ || !TEST_true(BN_one(exp_p1)) ++ || !TEST_true(BN_one(exp_a2)) ++ || !TEST_true(BN_one(exp_p2))) ++ goto err; ++ ++ BN_zero(exp_m); ++ ++ /* input of 0 is even, so must fail */ ++ if (!TEST_int_eq(BN_mod_exp2_mont(exp_result, exp_a1, exp_p1, exp_a2, ++ exp_p2, exp_m, ctx, NULL), 0)) ++ goto err; ++ ++ res = 1; ++ ++err: ++ BN_free(exp_result); ++ BN_free(exp_a1); ++ BN_free(exp_p1); ++ BN_free(exp_a2); ++ BN_free(exp_p2); ++ BN_free(exp_m); ++ return res; ++} ++ + static int file_test_run(STANZA *s) + { + static const FILETEST filetests[] = { +@@ -2906,6 +2950,7 @@ int setup_tests(void) + ADD_TEST(test_gcd_prime); + ADD_ALL_TESTS(test_mod_exp, (int)OSSL_NELEM(ModExpTests)); + ADD_ALL_TESTS(test_mod_exp_consttime, (int)OSSL_NELEM(ModExpTests)); ++ ADD_TEST(test_mod_exp2_mont); + } else { + ADD_ALL_TESTS(run_file_tests, n); + } +-- +2.17.1 + diff --git a/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch b/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch new file mode 100644 index 0000000000000000000000000000000000000000..c39270400fd0eb71b21be3d15055893109838fac --- /dev/null +++ b/backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch @@ -0,0 +1,89 @@ +From 01fc812cb0aafc3cfc271303b6646d1c0a86b020 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Mon, 25 Jul 2022 15:59:38 +0100 +Subject: [PATCH] Fix SSL_pending() and SSL_has_pending() with DTLS + +If app data is received before a Finished message in DTLS then we buffer +it to return later. The function SSL_pending() is supposed to tell you +how much processed app data we have already buffered, and SSL_has_pending() +is supposed to tell you if we have any data buffered (whether processed or +not, and whether app data or not). + +Neither SSL_pending() or SSL_has_pending() were taking account of this +DTLS specific app data buffer. + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18976) +--- + ssl/record/rec_layer_s3.c | 14 +++++++++++++- + ssl/ssl_lib.c | 24 +++++++++++++++++++----- + 2 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c +index 8249b4ace9..23cd4219e9 100644 +--- a/ssl/record/rec_layer_s3.c ++++ b/ssl/record/rec_layer_s3.c +@@ -115,10 +115,22 @@ size_t ssl3_pending(const SSL *s) + if (s->rlayer.rstate == SSL_ST_READ_BODY) + return 0; + ++ /* Take into account DTLS buffered app data */ ++ if (SSL_IS_DTLS(s)) { ++ DTLS1_RECORD_DATA *rdata; ++ pitem *item, *iter; ++ ++ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); ++ while ((item = pqueue_next(&iter)) != NULL) { ++ rdata = item->data; ++ num += rdata->rrec.length; ++ } ++ } ++ + for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) { + if (SSL3_RECORD_get_type(&s->rlayer.rrec[i]) + != SSL3_RT_APPLICATION_DATA) +- return 0; ++ return num; + num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]); + } + +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 25a1a44785..47adc3211c 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -1510,12 +1510,26 @@ int SSL_has_pending(const SSL *s) + { + /* + * Similar to SSL_pending() but returns a 1 to indicate that we have +- * unprocessed data available or 0 otherwise (as opposed to the number of +- * bytes available). Unlike SSL_pending() this will take into account +- * read_ahead data. A 1 return simply indicates that we have unprocessed +- * data. That data may not result in any application data, or we may fail +- * to parse the records for some reason. ++ * processed or unprocessed data available or 0 otherwise (as opposed to the ++ * number of bytes available). Unlike SSL_pending() this will take into ++ * account read_ahead data. A 1 return simply indicates that we have data. ++ * That data may not result in any application data, or we may fail to parse ++ * the records for some reason. + */ ++ ++ /* Check buffered app data if any first */ ++ if (SSL_IS_DTLS(s)) { ++ DTLS1_RECORD_DATA *rdata; ++ pitem *item, *iter; ++ ++ iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); ++ while ((item = pqueue_next(&iter)) != NULL) { ++ rdata = item->data; ++ if (rdata->rrec.length > 0) ++ return 1; ++ } ++ } ++ + if (RECORD_LAYER_processed_read_pending(&s->rlayer)) + return 1; + +-- +2.17.1 + diff --git a/backport-Fix-a-DTLS-server-hangup-due-to-TLS13_AD_MISSING_EXT.patch b/backport-Fix-a-DTLS-server-hangup-due-to-TLS13_AD_MISSING_EXT.patch new file mode 100644 index 0000000000000000000000000000000000000000..1229cba6123a6acf9e6c13e338641bfd95d352a8 --- /dev/null +++ b/backport-Fix-a-DTLS-server-hangup-due-to-TLS13_AD_MISSING_EXT.patch @@ -0,0 +1,440 @@ +From 6e73a0a0bd608daecb8e2c1e46de9d1014194c84 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Tue, 12 Apr 2022 08:27:21 +0200 +Subject: [PATCH] Fix a DTLS server hangup due to TLS13_AD_MISSING_EXTENSION + +This causes the DTLS server to enter an error state: + +./openssl s_server -dtls +./openssl s_client -dtls -maxfraglen 512 -sess_out s1.txt +[...] +Q +./openssl s_client -dtls -sess_in s1.txt +CONNECTED(00000003) +^C +./openssl s_client -dtls +CONNECTED(00000003) +140335537067840:error:14102410:SSL routines:dtls1_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_d1.c:614:SSL alert number 40 + +At this point the dtls server needs to be restarted, +because verify_cookie_callback always fails, because +the previous cookie is checked against the current one. +The reason for this is not fully understood. + +In wireshark we see the following each time: +c->s Client Hello (without cookie) +s->c Hello Verify Request (with new cookie) +s->c Alert (Level: Fatal, Description: Handshake Failure) +c->s Client Hello (echoes new cookie) + +The client gives up when the Alert arrives. +The Alert is triggered because the server calls +verify_cookie_callback with the previous cookie, +although it just sent the current cookie in the +Hello Verify Request. + +However this does only happen because no Alert message +is sent when the client re-connects the session with +the missing -maxfraglen option. + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18094) +--- + ssl/s3_enc.c | 2 + + ssl/t1_enc.c | 2 + + test/ssl-tests/10-resumption.conf | 121 +++++++++++++++++++++++- + test/ssl-tests/11-dtls_resumption.conf | 124 ++++++++++++++++++++++++- + test/ssl-tests/protocol_version.pm | 63 +++++++++++++ + 5 files changed, 310 insertions(+), 2 deletions(-) + +diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c +index 8a89f512fe..eb1f36ac7e 100644 +--- a/ssl/s3_enc.c ++++ b/ssl/s3_enc.c +@@ -589,6 +589,8 @@ int ssl3_alert_code(int code) + return TLS1_AD_NO_APPLICATION_PROTOCOL; + case SSL_AD_CERTIFICATE_REQUIRED: + return SSL_AD_HANDSHAKE_FAILURE; ++ case SSL_AD_MISSING_EXTENSION: ++ return SSL_AD_HANDSHAKE_FAILURE; + default: + return -1; + } +diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c +index c85c0b0310..2087b274d1 100644 +--- a/ssl/t1_enc.c ++++ b/ssl/t1_enc.c +@@ -672,6 +672,8 @@ int tls1_alert_code(int code) + return TLS1_AD_NO_APPLICATION_PROTOCOL; + case SSL_AD_CERTIFICATE_REQUIRED: + return SSL_AD_HANDSHAKE_FAILURE; ++ case SSL_AD_MISSING_EXTENSION: ++ return SSL_AD_HANDSHAKE_FAILURE; + default: + return -1; + } +diff --git a/test/ssl-tests/10-resumption.conf b/test/ssl-tests/10-resumption.conf +index 73de974ab0..a33a1d80e4 100644 +--- a/test/ssl-tests/10-resumption.conf ++++ b/test/ssl-tests/10-resumption.conf +@@ -1,6 +1,6 @@ + # Generated with generate_ssl_tests.pl + +-num_tests = 65 ++num_tests = 68 + + test-0 = 0-resumption + test-1 = 1-resumption +@@ -67,6 +67,9 @@ test-61 = 61-resumption + test-62 = 62-resumption + test-63 = 63-resumption + test-64 = 64-resumption-with-hrr ++test-65 = 65-resumption-when-mfl-ext-is-missing ++test-66 = 66-resumption-when-mfl-ext-is-different ++test-67 = 67-resumption-when-mfl-ext-is-correct + # =========================================================== + + [0-resumption] +@@ -2437,3 +2440,119 @@ Method = TLS + ResumptionExpected = Yes + + ++# =========================================================== ++ ++[65-resumption-when-mfl-ext-is-missing] ++ssl_conf = 65-resumption-when-mfl-ext-is-missing-ssl ++ ++[65-resumption-when-mfl-ext-is-missing-ssl] ++server = 65-resumption-when-mfl-ext-is-missing-server ++client = 65-resumption-when-mfl-ext-is-missing-client ++resume-server = 65-resumption-when-mfl-ext-is-missing-server ++resume-client = 65-resumption-when-mfl-ext-is-missing-resume-client ++ ++[65-resumption-when-mfl-ext-is-missing-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[65-resumption-when-mfl-ext-is-missing-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[65-resumption-when-mfl-ext-is-missing-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-65] ++ExpectedResult = ServerFail ++HandshakeMode = Resume ++ResumptionExpected = No ++client = 65-resumption-when-mfl-ext-is-missing-client-extra ++ ++[65-resumption-when-mfl-ext-is-missing-client-extra] ++MaxFragmentLenExt = 512 ++ ++ ++# =========================================================== ++ ++[66-resumption-when-mfl-ext-is-different] ++ssl_conf = 66-resumption-when-mfl-ext-is-different-ssl ++ ++[66-resumption-when-mfl-ext-is-different-ssl] ++server = 66-resumption-when-mfl-ext-is-different-server ++client = 66-resumption-when-mfl-ext-is-different-client ++resume-server = 66-resumption-when-mfl-ext-is-different-server ++resume-client = 66-resumption-when-mfl-ext-is-different-resume-client ++ ++[66-resumption-when-mfl-ext-is-different-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[66-resumption-when-mfl-ext-is-different-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[66-resumption-when-mfl-ext-is-different-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-66] ++ExpectedResult = ServerFail ++HandshakeMode = Resume ++ResumptionExpected = No ++client = 66-resumption-when-mfl-ext-is-different-client-extra ++resume-client = 66-resumption-when-mfl-ext-is-different-resume-client-extra ++ ++[66-resumption-when-mfl-ext-is-different-client-extra] ++MaxFragmentLenExt = 512 ++ ++[66-resumption-when-mfl-ext-is-different-resume-client-extra] ++MaxFragmentLenExt = 1024 ++ ++ ++# =========================================================== ++ ++[67-resumption-when-mfl-ext-is-correct] ++ssl_conf = 67-resumption-when-mfl-ext-is-correct-ssl ++ ++[67-resumption-when-mfl-ext-is-correct-ssl] ++server = 67-resumption-when-mfl-ext-is-correct-server ++client = 67-resumption-when-mfl-ext-is-correct-client ++resume-server = 67-resumption-when-mfl-ext-is-correct-server ++resume-client = 67-resumption-when-mfl-ext-is-correct-resume-client ++ ++[67-resumption-when-mfl-ext-is-correct-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[67-resumption-when-mfl-ext-is-correct-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[67-resumption-when-mfl-ext-is-correct-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-67] ++ExpectedResult = Success ++HandshakeMode = Resume ++ResumptionExpected = Yes ++client = 67-resumption-when-mfl-ext-is-correct-client-extra ++resume-client = 67-resumption-when-mfl-ext-is-correct-resume-client-extra ++ ++[67-resumption-when-mfl-ext-is-correct-client-extra] ++MaxFragmentLenExt = 512 ++ ++[67-resumption-when-mfl-ext-is-correct-resume-client-extra] ++MaxFragmentLenExt = 512 ++ ++ +diff --git a/test/ssl-tests/11-dtls_resumption.conf b/test/ssl-tests/11-dtls_resumption.conf +index a981fa51df..635279a30f 100644 +--- a/test/ssl-tests/11-dtls_resumption.conf ++++ b/test/ssl-tests/11-dtls_resumption.conf +@@ -1,6 +1,6 @@ + # Generated with generate_ssl_tests.pl + +-num_tests = 16 ++num_tests = 19 + + test-0 = 0-resumption + test-1 = 1-resumption +@@ -18,6 +18,9 @@ test-12 = 12-resumption + test-13 = 13-resumption + test-14 = 14-resumption + test-15 = 15-resumption ++test-16 = 16-resumption-when-mfl-ext-is-missing ++test-17 = 17-resumption-when-mfl-ext-is-different ++test-18 = 18-resumption-when-mfl-ext-is-correct + # =========================================================== + + [0-resumption] +@@ -618,3 +621,122 @@ Method = DTLS + ResumptionExpected = Yes + + ++# =========================================================== ++ ++[16-resumption-when-mfl-ext-is-missing] ++ssl_conf = 16-resumption-when-mfl-ext-is-missing-ssl ++ ++[16-resumption-when-mfl-ext-is-missing-ssl] ++server = 16-resumption-when-mfl-ext-is-missing-server ++client = 16-resumption-when-mfl-ext-is-missing-client ++resume-server = 16-resumption-when-mfl-ext-is-missing-server ++resume-client = 16-resumption-when-mfl-ext-is-missing-resume-client ++ ++[16-resumption-when-mfl-ext-is-missing-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[16-resumption-when-mfl-ext-is-missing-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[16-resumption-when-mfl-ext-is-missing-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-16] ++ExpectedResult = ServerFail ++HandshakeMode = Resume ++Method = DTLS ++ResumptionExpected = No ++client = 16-resumption-when-mfl-ext-is-missing-client-extra ++ ++[16-resumption-when-mfl-ext-is-missing-client-extra] ++MaxFragmentLenExt = 512 ++ ++ ++# =========================================================== ++ ++[17-resumption-when-mfl-ext-is-different] ++ssl_conf = 17-resumption-when-mfl-ext-is-different-ssl ++ ++[17-resumption-when-mfl-ext-is-different-ssl] ++server = 17-resumption-when-mfl-ext-is-different-server ++client = 17-resumption-when-mfl-ext-is-different-client ++resume-server = 17-resumption-when-mfl-ext-is-different-server ++resume-client = 17-resumption-when-mfl-ext-is-different-resume-client ++ ++[17-resumption-when-mfl-ext-is-different-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[17-resumption-when-mfl-ext-is-different-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[17-resumption-when-mfl-ext-is-different-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-17] ++ExpectedResult = ServerFail ++HandshakeMode = Resume ++Method = DTLS ++ResumptionExpected = No ++client = 17-resumption-when-mfl-ext-is-different-client-extra ++resume-client = 17-resumption-when-mfl-ext-is-different-resume-client-extra ++ ++[17-resumption-when-mfl-ext-is-different-client-extra] ++MaxFragmentLenExt = 512 ++ ++[17-resumption-when-mfl-ext-is-different-resume-client-extra] ++MaxFragmentLenExt = 1024 ++ ++ ++# =========================================================== ++ ++[18-resumption-when-mfl-ext-is-correct] ++ssl_conf = 18-resumption-when-mfl-ext-is-correct-ssl ++ ++[18-resumption-when-mfl-ext-is-correct-ssl] ++server = 18-resumption-when-mfl-ext-is-correct-server ++client = 18-resumption-when-mfl-ext-is-correct-client ++resume-server = 18-resumption-when-mfl-ext-is-correct-server ++resume-client = 18-resumption-when-mfl-ext-is-correct-resume-client ++ ++[18-resumption-when-mfl-ext-is-correct-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[18-resumption-when-mfl-ext-is-correct-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[18-resumption-when-mfl-ext-is-correct-resume-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-18] ++ExpectedResult = Success ++HandshakeMode = Resume ++Method = DTLS ++ResumptionExpected = Yes ++client = 18-resumption-when-mfl-ext-is-correct-client-extra ++resume-client = 18-resumption-when-mfl-ext-is-correct-resume-client-extra ++ ++[18-resumption-when-mfl-ext-is-correct-client-extra] ++MaxFragmentLenExt = 512 ++ ++[18-resumption-when-mfl-ext-is-correct-resume-client-extra] ++MaxFragmentLenExt = 512 ++ ++ +diff --git a/test/ssl-tests/protocol_version.pm b/test/ssl-tests/protocol_version.pm +index 943719e84a..039d782b73 100644 +--- a/test/ssl-tests/protocol_version.pm ++++ b/test/ssl-tests/protocol_version.pm +@@ -265,6 +265,69 @@ sub generate_resumption_tests { + }; + } + ++ push @client_tests, { ++ "name" => "resumption-when-mfl-ext-is-missing", ++ "server" => { ++ }, ++ "client" => { ++ "extra" => { ++ "MaxFragmentLenExt" => 512, ++ }, ++ }, ++ "resume_client" => { ++ }, ++ "test" => { ++ "Method" => $method, ++ "HandshakeMode" => "Resume", ++ "ResumptionExpected" => "No", ++ "ExpectedResult" => "ServerFail", ++ } ++ }; ++ ++ push @client_tests, { ++ "name" => "resumption-when-mfl-ext-is-different", ++ "server" => { ++ }, ++ "client" => { ++ "extra" => { ++ "MaxFragmentLenExt" => 512, ++ }, ++ }, ++ "resume_client" => { ++ "extra" => { ++ "MaxFragmentLenExt" => 1024, ++ }, ++ }, ++ "test" => { ++ "Method" => $method, ++ "HandshakeMode" => "Resume", ++ "ResumptionExpected" => "No", ++ "ExpectedResult" => "ServerFail", ++ } ++ }; ++ ++ push @client_tests, { ++ "name" => "resumption-when-mfl-ext-is-correct", ++ "server" => { ++ }, ++ "client" => { ++ "extra" => { ++ "MaxFragmentLenExt" => 512, ++ }, ++ }, ++ "resume_client" => { ++ "extra" => { ++ "MaxFragmentLenExt" => 512, ++ }, ++ }, ++ "test" => { ++ "Method" => $method, ++ "HandshakeMode" => "Resume", ++ "ResumptionExpected" => "Yes", ++ "ExpectedResult" => "Success", ++ } ++ }; ++ + return (@server_tests, @client_tests); + } + +-- +2.17.1 + diff --git a/backport-Fix-a-crash-in-X509v3_asid_subset.patch b/backport-Fix-a-crash-in-X509v3_asid_subset.patch new file mode 100644 index 0000000000000000000000000000000000000000..3aaa529bf1533962adf2d2e1fed5b986f336a6af --- /dev/null +++ b/backport-Fix-a-crash-in-X509v3_asid_subset.patch @@ -0,0 +1,161 @@ +From 8f078819556da83c15751678c39558a59bc746fc Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 9 Jun 2022 16:57:30 +0100 +Subject: [PATCH] Fix a crash in X509v3_asid_subset() + +If the asnum or rdi fields are NULL and the ASIdentifiers are otherwise +subsets then this will result in a crash. Of note is that rdi will usually +be NULL. + +Reported by Theo Buehler (@botovq) + +Reviewed-by: Tomas Mraz +Reviewed-by: Paul Yang +Reviewed-by: Todd Short +(Merged from https://github.com/openssl/openssl/pull/18514) + +(cherry picked from commit 01fc9b6bce82f0534d6673659a0e59a71f57ee82) +--- + crypto/x509v3/v3_asid.c | 31 +++++++++++----- + test/v3ext.c | 78 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 100 insertions(+), 9 deletions(-) + +diff --git a/crypto/x509v3/v3_asid.c b/crypto/x509v3/v3_asid.c +index ac68572672..9bdc682978 100644 +--- a/crypto/x509v3/v3_asid.c ++++ b/crypto/x509v3/v3_asid.c +@@ -700,15 +700,28 @@ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) + */ + int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) + { +- return (a == NULL || +- a == b || +- (b != NULL && +- !X509v3_asid_inherits(a) && +- !X509v3_asid_inherits(b) && +- asid_contains(b->asnum->u.asIdsOrRanges, +- a->asnum->u.asIdsOrRanges) && +- asid_contains(b->rdi->u.asIdsOrRanges, +- a->rdi->u.asIdsOrRanges))); ++ int subset; ++ ++ if (a == NULL || a == b) ++ return 1; ++ ++ if (b == NULL) ++ return 0; ++ ++ if (X509v3_asid_inherits(a) || X509v3_asid_inherits(b)) ++ return 0; ++ ++ subset = a->asnum == NULL ++ || (b->asnum != NULL ++ && asid_contains(b->asnum->u.asIdsOrRanges, ++ a->asnum->u.asIdsOrRanges)); ++ if (!subset) ++ return 0; ++ ++ return a->rdi == NULL ++ || (b->rdi != NULL ++ && asid_contains(b->rdi->u.asIdsOrRanges, ++ a->rdi->u.asIdsOrRanges)); + } + + /* +diff --git a/test/v3ext.c b/test/v3ext.c +index 14ae49969d..1575e923da 100644 +--- a/test/v3ext.c ++++ b/test/v3ext.c +@@ -37,11 +37,89 @@ end: + return ret; + } + ++static int test_asid(void) ++{ ++ ASN1_INTEGER *val1 = NULL, *val2 = NULL; ++ ASIdentifiers *asid1 = ASIdentifiers_new(), *asid2 = ASIdentifiers_new(), ++ *asid3 = ASIdentifiers_new(), *asid4 = ASIdentifiers_new(); ++ int testresult = 0; ++ ++ if (!TEST_ptr(asid1) ++ || !TEST_ptr(asid2) ++ || !TEST_ptr(asid3)) ++ goto err; ++ ++ if (!TEST_ptr(val1 = ASN1_INTEGER_new()) ++ || !TEST_true(ASN1_INTEGER_set_int64(val1, 64496))) ++ goto err; ++ ++ if (!TEST_true(X509v3_asid_add_id_or_range(asid1, V3_ASID_ASNUM, val1, NULL))) ++ goto err; ++ ++ val1 = NULL; ++ if (!TEST_ptr(val2 = ASN1_INTEGER_new()) ++ || !TEST_true(ASN1_INTEGER_set_int64(val2, 64497))) ++ goto err; ++ ++ if (!TEST_true(X509v3_asid_add_id_or_range(asid2, V3_ASID_ASNUM, val2, NULL))) ++ goto err; ++ ++ val2 = NULL; ++ if (!TEST_ptr(val1 = ASN1_INTEGER_new()) ++ || !TEST_true(ASN1_INTEGER_set_int64(val1, 64496)) ++ || !TEST_ptr(val2 = ASN1_INTEGER_new()) ++ || !TEST_true(ASN1_INTEGER_set_int64(val2, 64497))) ++ goto err; ++ ++ /* ++ * Just tests V3_ASID_ASNUM for now. Could be extended at some point to also ++ * test V3_ASID_RDI if we think it is worth it. ++ */ ++ if (!TEST_true(X509v3_asid_add_id_or_range(asid3, V3_ASID_ASNUM, val1, val2))) ++ goto err; ++ val1 = val2 = NULL; ++ ++ /* Actual subsets */ ++ if (!TEST_true(X509v3_asid_subset(NULL, NULL)) ++ || !TEST_true(X509v3_asid_subset(NULL, asid1)) ++ || !TEST_true(X509v3_asid_subset(asid1, asid1)) ++ || !TEST_true(X509v3_asid_subset(asid2, asid2)) ++ || !TEST_true(X509v3_asid_subset(asid1, asid3)) ++ || !TEST_true(X509v3_asid_subset(asid2, asid3)) ++ || !TEST_true(X509v3_asid_subset(asid3, asid3)) ++ || !TEST_true(X509v3_asid_subset(asid4, asid1)) ++ || !TEST_true(X509v3_asid_subset(asid4, asid2)) ++ || !TEST_true(X509v3_asid_subset(asid4, asid3))) ++ goto err; ++ ++ /* Not subsets */ ++ if (!TEST_false(X509v3_asid_subset(asid1, NULL)) ++ || !TEST_false(X509v3_asid_subset(asid1, asid2)) ++ || !TEST_false(X509v3_asid_subset(asid2, asid1)) ++ || !TEST_false(X509v3_asid_subset(asid3, asid1)) ++ || !TEST_false(X509v3_asid_subset(asid3, asid2)) ++ || !TEST_false(X509v3_asid_subset(asid1, asid4)) ++ || !TEST_false(X509v3_asid_subset(asid2, asid4)) ++ || !TEST_false(X509v3_asid_subset(asid3, asid4))) ++ goto err; ++ ++ testresult = 1; ++ err: ++ ASN1_INTEGER_free(val1); ++ ASN1_INTEGER_free(val2); ++ ASIdentifiers_free(asid1); ++ ASIdentifiers_free(asid2); ++ ASIdentifiers_free(asid3); ++ ASIdentifiers_free(asid4); ++ return testresult; ++} ++ + int setup_tests(void) + { + if (!TEST_ptr(infile = test_get_argument(0))) + return 0; + + ADD_TEST(test_pathlen); ++ ADD_TEST(test_asid); + return 1; + } +-- +2.17.1 + diff --git a/backport-Fix-a-crash-in-asn1_item_embed_new.patch b/backport-Fix-a-crash-in-asn1_item_embed_new.patch new file mode 100644 index 0000000000000000000000000000000000000000..45a35827b7529de23514e726993f3ba36f545f8b --- /dev/null +++ b/backport-Fix-a-crash-in-asn1_item_embed_new.patch @@ -0,0 +1,93 @@ +From 8e60f41d064786f95440e4c56660ffe9777783d7 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Fri, 20 May 2022 08:02:47 +0200 +Subject: [PATCH] Fix a crash in asn1_item_embed_new + +This happens usually if an template object is created +and there is an out of memory error before the ASN1_OP_NEW_POST +method is called, but asn1_item_embed_free calls now the +ASN1_OP_FREE_POST which may crash because the object is not +properly initialized. Apparently that is only an issue with +the ASN1_OP_FREE_POST handling of crypot/x509/x_crl.c, which +ought to be tolerant to incomplete initialized objects. + +The error can be reproduced with the reproducible error injection patch: + +$ ERROR_INJECT=1652890550 ../util/shlib_wrap.sh ./asn1-test ./corpora/asn1/0ff17293911f54d1538b9896563a4048d67d9ee4 + #0 0x7faae9dbeeba in __sanitizer_print_stack_trace ../../../../gcc-trunk/libsanitizer/asan/asan_stack.cpp:87 + #1 0x408dc4 in my_malloc fuzz/test-corpus.c:114 + #2 0x7faae99f2430 in CRYPTO_zalloc crypto/mem.c:230 + #3 0x7faae97f09e5 in ASN1_STRING_type_new crypto/asn1/asn1_lib.c:341 + #4 0x7faae98118f7 in asn1_primitive_new crypto/asn1/tasn_new.c:318 + #5 0x7faae9812401 in asn1_item_embed_new crypto/asn1/tasn_new.c:78 + #6 0x7faae9812401 in asn1_template_new crypto/asn1/tasn_new.c:240 + #7 0x7faae9812315 in asn1_item_embed_new crypto/asn1/tasn_new.c:137 + #8 0x7faae9812315 in asn1_template_new crypto/asn1/tasn_new.c:240 + #9 0x7faae9812a54 in asn1_item_embed_new crypto/asn1/tasn_new.c:137 + #10 0x7faae9812a54 in ASN1_item_ex_new crypto/asn1/tasn_new.c:39 + #11 0x7faae980be51 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:325 + #12 0x7faae980c813 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:611 + #13 0x7faae980d288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #14 0x7faae980b9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #15 0x7faae980caf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #16 0x7faae980d7d3 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:494 + #17 0x7faae980b9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #18 0x7faae980dd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #19 0x7faae980de35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #20 0x40712c in FuzzerTestOneInput fuzz/asn1.c:301 + #21 0x40893b in testfile fuzz/test-corpus.c:182 + #22 0x406b86 in main fuzz/test-corpus.c:226 + #23 0x7faae8eb1f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +AddressSanitizer:DEADLYSIGNAL +================================================================= +==1194==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x7faae9b0625f bp 0x7fffffe41a00 sp 0x7fffffe41920 T0) +==1194==The signal is caused by a READ memory access. +==1194==Hint: address points to the zero page. + #0 0x7faae9b0625f in crl_cb crypto/x509/x_crl.c:258 + #1 0x7faae9811255 in asn1_item_embed_free crypto/asn1/tasn_fre.c:113 + #2 0x7faae9812a65 in asn1_item_embed_new crypto/asn1/tasn_new.c:150 + #3 0x7faae9812a65 in ASN1_item_ex_new crypto/asn1/tasn_new.c:39 + #4 0x7faae980be51 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:325 + #5 0x7faae980c813 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:611 + #6 0x7faae980d288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #7 0x7faae980b9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #8 0x7faae980caf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #9 0x7faae980d7d3 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:494 + #10 0x7faae980b9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #11 0x7faae980dd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #12 0x7faae980de35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #13 0x40712c in FuzzerTestOneInput fuzz/asn1.c:301 + #14 0x40893b in testfile fuzz/test-corpus.c:182 + #15 0x406b86 in main fuzz/test-corpus.c:226 + #16 0x7faae8eb1f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +AddressSanitizer can not provide additional info. +SUMMARY: AddressSanitizer: SEGV crypto/x509/x_crl.c:258 in crl_cb +==1194==ABORTING + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18360) + +(cherry picked from commit 557825acd622f98fc21423aba092e374db84f483) +--- + crypto/x509/x_crl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c +index c9762f9e23..9af39a45fc 100644 +--- a/crypto/x509/x_crl.c ++++ b/crypto/x509/x_crl.c +@@ -255,7 +255,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + break; + + case ASN1_OP_FREE_POST: +- if (crl->meth->crl_free) { ++ if (crl->meth != NULL && crl->meth->crl_free != NULL) { + if (!crl->meth->crl_free(crl)) + return 0; + } +-- +2.17.1 + diff --git a/backport-Fix-a-crash-in-ssl_security_cert_chain.patch b/backport-Fix-a-crash-in-ssl_security_cert_chain.patch new file mode 100644 index 0000000000000000000000000000000000000000..234a78330d3dd28c922c9130f97dc8686a2974e5 --- /dev/null +++ b/backport-Fix-a-crash-in-ssl_security_cert_chain.patch @@ -0,0 +1,88 @@ +From 4a28f8451fbc1848fd2d1b99203a7c75876123f6 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Sun, 22 May 2022 20:12:56 +0200 +Subject: [PATCH] Fix a crash in ssl_security_cert_chain + +Prior to the crash there is an out of memory error +in X509_verify_cert which makes the chain NULL or +empty. The error is ignored by ssl_add_cert_chain, +and ssl_security_cert_chain crashes due to the +unchecked null pointer. + +This is reproducible with my error injection patch. + +The test vector has been validated on the 1.1.1 branch +but the issue is of course identical in all branches. + +$ ERROR_INJECT=1652848273 ../util/shlib_wrap.sh ./server-test ./corpora/server/47c8e933c4ec66fa3c309422283dfe0f31aafae8# ./corpora/server/47c8e933c4ec66fa3c309422283dfe0f31aafae8 + #0 0x7f3a8f766eba in __sanitizer_print_stack_trace ../../../../gcc-trunk/libsanitizer/asan/asan_stack.cpp:87 + #1 0x403ba4 in my_malloc fuzz/test-corpus.c:114 + #2 0x7f3a8f39a430 in CRYPTO_zalloc crypto/mem.c:230 + #3 0x7f3a8f46bd3b in sk_reserve crypto/stack/stack.c:180 + #4 0x7f3a8f46bd3b in OPENSSL_sk_insert crypto/stack/stack.c:242 + #5 0x7f3a8f4a4fd8 in sk_X509_push include/openssl/x509.h:99 + #6 0x7f3a8f4a4fd8 in X509_verify_cert crypto/x509/x509_vfy.c:286 + #7 0x7f3a8fed726e in ssl_add_cert_chain ssl/statem/statem_lib.c:959 + #8 0x7f3a8fed726e in ssl3_output_cert_chain ssl/statem/statem_lib.c:1015 + #9 0x7f3a8fee1c50 in tls_construct_server_certificate ssl/statem/statem_srvr.c:3812 + #10 0x7f3a8feb8b0a in write_state_machine ssl/statem/statem.c:843 + #11 0x7f3a8feb8b0a in state_machine ssl/statem/statem.c:443 + #12 0x7f3a8fe84b3f in SSL_do_handshake ssl/ssl_lib.c:3718 + #13 0x403202 in FuzzerTestOneInput fuzz/server.c:740 + #14 0x40371b in testfile fuzz/test-corpus.c:182 + #15 0x402856 in main fuzz/test-corpus.c:226 + #16 0x7f3a8e859f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + #17 0x402936 (/home/ed/OPC/openssl/fuzz/server-test+0x402936) + +AddressSanitizer:DEADLYSIGNAL +================================================================= +==8400==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000158 (pc 0x7f3a8f4d822f bp 0x7ffc39b76190 sp 0x7ffc39b760a0 T0) +==8400==The signal is caused by a READ memory access. +==8400==Hint: address points to the zero page. + #0 0x7f3a8f4d822f in x509v3_cache_extensions crypto/x509v3/v3_purp.c:386 + #1 0x7f3a8f4d9d3a in X509_check_purpose crypto/x509v3/v3_purp.c:84 + #2 0x7f3a8f4da02a in X509_get_extension_flags crypto/x509v3/v3_purp.c:921 + #3 0x7f3a8feff7d2 in ssl_security_cert_sig ssl/t1_lib.c:2518 + #4 0x7f3a8feff7d2 in ssl_security_cert ssl/t1_lib.c:2542 + #5 0x7f3a8feffa03 in ssl_security_cert_chain ssl/t1_lib.c:2562 + #6 0x7f3a8fed728d in ssl_add_cert_chain ssl/statem/statem_lib.c:963 + #7 0x7f3a8fed728d in ssl3_output_cert_chain ssl/statem/statem_lib.c:1015 + #8 0x7f3a8fee1c50 in tls_construct_server_certificate ssl/statem/statem_srvr.c:3812 + #9 0x7f3a8feb8b0a in write_state_machine ssl/statem/statem.c:843 + #10 0x7f3a8feb8b0a in state_machine ssl/statem/statem.c:443 + #11 0x7f3a8fe84b3f in SSL_do_handshake ssl/ssl_lib.c:3718 + #12 0x403202 in FuzzerTestOneInput fuzz/server.c:740 + #13 0x40371b in testfile fuzz/test-corpus.c:182 + #14 0x402856 in main fuzz/test-corpus.c:226 + #15 0x7f3a8e859f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + #16 0x402936 (/home/ed/OPC/openssl/fuzz/server-test+0x402936) + +AddressSanitizer can not provide additional info. +SUMMARY: AddressSanitizer: SEGV crypto/x509v3/v3_purp.c:386 in x509v3_cache_extensions +==8400==ABORTING + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18376) + +(cherry picked from commit dc0ef292f7df4ce0c49c64b47726a6768f9ac044) +--- + ssl/t1_lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index b1d3add187..4de4623a49 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -2555,6 +2555,8 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) + int rv, start_idx, i; + if (x == NULL) { + x = sk_X509_value(sk, 0); ++ if (x == NULL) ++ return ERR_R_INTERNAL_ERROR; + start_idx = 1; + } else + start_idx = 0; +-- +2.17.1 + diff --git a/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch b/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch new file mode 100644 index 0000000000000000000000000000000000000000..90f12eab47c49320053c9befe1a38fa1793b09fb --- /dev/null +++ b/backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch @@ -0,0 +1,76 @@ +From 264a3f453c418dc01f4b74928ed2a76a08a65513 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 10 Jun 2022 12:33:45 +0100 +Subject: [PATCH] Fix a crash in v2i_IPAddrBlocks() + +If an IP address prefix value is supplied that is too large then a crash +can result. v2i_IPAddrBlocks() should sanity check the prefix value, as +should X509v3_addr_add_prefix(). + +Reported by Theo Buehler (@botovq) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + crypto/x509v3/v3_addr.c | 17 ++++--- + test/v3ext.c | 99 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 111 insertions(+), 5 deletions(-) + +diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c +index ccce34ef2e..f9c368bea4 100644 +--- a/crypto/x509v3/v3_addr.c ++++ b/crypto/x509v3/v3_addr.c +@@ -392,12 +392,14 @@ static int range_should_be_prefix(const unsigned char *min, + /* + * Construct a prefix. + */ +-static int make_addressPrefix(IPAddressOrRange **result, +- unsigned char *addr, const int prefixlen) ++static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, ++ const int prefixlen, const int afilen) + { + int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; + IPAddressOrRange *aor = IPAddressOrRange_new(); + ++ if (prefixlen < 0 || prefixlen > (afilen * 8)) ++ return 0; + if (aor == NULL) + return 0; + aor->type = IPAddressOrRange_addressPrefix; +@@ -437,7 +439,7 @@ static int make_addressRange(IPAddressOrRange **result, + return 0; + + if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) +- return make_addressPrefix(result, min, prefixlen); ++ return make_addressPrefix(result, min, prefixlen, length); + + if ((aor = IPAddressOrRange_new()) == NULL) + return 0; +@@ -599,7 +601,9 @@ int X509v3_addr_add_prefix(IPAddrBlocks *addr, + { + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; +- if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) ++ ++ if (aors == NULL ++ || !make_addressPrefix(&aor, a, prefixlen, length_from_afi(afi))) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; +@@ -996,7 +1000,10 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, + switch (delim) { + case '/': + prefixlen = (int)strtoul(s + i2, &t, 10); +- if (t == s + i2 || *t != '\0') { ++ if (t == s + i2 ++ || *t != '\0' ++ || prefixlen > (length * 8) ++ || prefixlen < 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); +-- +2.17.1 + diff --git a/backport-Fix-a-memory-leak-in-EC_GROUP_new_from_ecparameters.patch b/backport-Fix-a-memory-leak-in-EC_GROUP_new_from_ecparameters.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0b7d2e3c83cd6bd2bf48e8326cd2af0122b28a6 --- /dev/null +++ b/backport-Fix-a-memory-leak-in-EC_GROUP_new_from_ecparameters.patch @@ -0,0 +1,134 @@ +From 6c8879c8bf6030666c851623f93fff03c1266715 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Wed, 22 Jun 2022 17:05:55 +0200 +Subject: [PATCH] Fix a memory leak in EC_GROUP_new_from_ecparameters + +This can be reproduced with my error injection patch. + +The test vector has been validated on the 1.1.1 branch +but the issue is of course identical in all branches. + +$ ERROR_INJECT=1656112173 ../util/shlib_wrap.sh ./x509-test ./corpora/x509/fe543a8d7e09109a9a08114323eefec802ad79e2 + #0 0x7fb61945eeba in __sanitizer_print_stack_trace ../../../../gcc-trunk/libsanitizer/asan/asan_stack.cpp:87 + #1 0x402f84 in my_malloc fuzz/test-corpus.c:114 + #2 0x7fb619092430 in CRYPTO_zalloc crypto/mem.c:230 + #3 0x7fb618ef7561 in bn_expand_internal crypto/bn/bn_lib.c:280 + #4 0x7fb618ef7561 in bn_expand2 crypto/bn/bn_lib.c:304 + #5 0x7fb618ef819d in BN_bin2bn crypto/bn/bn_lib.c:454 + #6 0x7fb618e7aa13 in asn1_string_to_bn crypto/asn1/a_int.c:503 + #7 0x7fb618e7aa13 in ASN1_INTEGER_to_BN crypto/asn1/a_int.c:559 + #8 0x7fb618fd8e79 in EC_GROUP_new_from_ecparameters crypto/ec/ec_asn1.c:814 + #9 0x7fb618fd98e8 in EC_GROUP_new_from_ecpkparameters crypto/ec/ec_asn1.c:935 + #10 0x7fb618fd9aec in d2i_ECPKParameters crypto/ec/ec_asn1.c:966 + #11 0x7fb618fdace9 in d2i_ECParameters crypto/ec/ec_asn1.c:1184 + #12 0x7fb618fd1fc7 in eckey_type2param crypto/ec/ec_ameth.c:119 + #13 0x7fb618fd57b4 in eckey_pub_decode crypto/ec/ec_ameth.c:165 + #14 0x7fb6191a9c62 in x509_pubkey_decode crypto/x509/x_pubkey.c:124 + #15 0x7fb6191a9e42 in pubkey_cb crypto/x509/x_pubkey.c:46 + #16 0x7fb618eac032 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:432 + #17 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #18 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #19 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #20 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #21 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #22 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #23 0x7fb618eadd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #24 0x7fb618eade35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #25 0x40310c in FuzzerTestOneInput fuzz/x509.c:33 + #26 0x402afb in testfile fuzz/test-corpus.c:182 + #27 0x402656 in main fuzz/test-corpus.c:226 + #28 0x7fb618551f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + #29 0x402756 (/home/ed/OPC/openssl/fuzz/x509-test+0x402756) + +================================================================= +==12221==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 24 byte(s) in 1 object(s) allocated from: + #0 0x7fb61945309f in __interceptor_malloc ../../../../gcc-trunk/libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 0x7fb619092430 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fb618ef5f11 in BN_new crypto/bn/bn_lib.c:246 + #3 0x7fb618ef82f4 in BN_bin2bn crypto/bn/bn_lib.c:440 + #4 0x7fb618fd8933 in EC_GROUP_new_from_ecparameters crypto/ec/ec_asn1.c:618 + #5 0x7fb618fd98e8 in EC_GROUP_new_from_ecpkparameters crypto/ec/ec_asn1.c:935 + #6 0x7fb618fd9aec in d2i_ECPKParameters crypto/ec/ec_asn1.c:966 + #7 0x7fb618fdace9 in d2i_ECParameters crypto/ec/ec_asn1.c:1184 + #8 0x7fb618fd1fc7 in eckey_type2param crypto/ec/ec_ameth.c:119 + #9 0x7fb618fd57b4 in eckey_pub_decode crypto/ec/ec_ameth.c:165 + #10 0x7fb6191a9c62 in x509_pubkey_decode crypto/x509/x_pubkey.c:124 + #11 0x7fb6191a9e42 in pubkey_cb crypto/x509/x_pubkey.c:46 + #12 0x7fb618eac032 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:432 + #13 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #14 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #15 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #16 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #17 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #18 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #19 0x7fb618eadd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #20 0x7fb618eade35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #21 0x40310c in FuzzerTestOneInput fuzz/x509.c:33 + #22 0x402afb in testfile fuzz/test-corpus.c:182 + #23 0x402656 in main fuzz/test-corpus.c:226 + #24 0x7fb618551f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +Indirect leak of 56 byte(s) in 1 object(s) allocated from: + #0 0x7fb61945309f in __interceptor_malloc ../../../../gcc-trunk/libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 0x7fb619092430 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fb618ef7561 in bn_expand_internal crypto/bn/bn_lib.c:280 + #3 0x7fb618ef7561 in bn_expand2 crypto/bn/bn_lib.c:304 + #4 0x7fb618ef819d in BN_bin2bn crypto/bn/bn_lib.c:454 + #5 0x7fb618fd8933 in EC_GROUP_new_from_ecparameters crypto/ec/ec_asn1.c:618 + #6 0x7fb618fd98e8 in EC_GROUP_new_from_ecpkparameters crypto/ec/ec_asn1.c:935 + #7 0x7fb618fd9aec in d2i_ECPKParameters crypto/ec/ec_asn1.c:966 + #8 0x7fb618fdace9 in d2i_ECParameters crypto/ec/ec_asn1.c:1184 + #9 0x7fb618fd1fc7 in eckey_type2param crypto/ec/ec_ameth.c:119 + #10 0x7fb618fd57b4 in eckey_pub_decode crypto/ec/ec_ameth.c:165 + #11 0x7fb6191a9c62 in x509_pubkey_decode crypto/x509/x_pubkey.c:124 + #12 0x7fb6191a9e42 in pubkey_cb crypto/x509/x_pubkey.c:46 + #13 0x7fb618eac032 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:432 + #14 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #15 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #16 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #17 0x7fb618eacaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #18 0x7fb618ead288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #19 0x7fb618eab9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #20 0x7fb618eadd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #21 0x7fb618eade35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #22 0x40310c in FuzzerTestOneInput fuzz/x509.c:33 + #23 0x402afb in testfile fuzz/test-corpus.c:182 + #24 0x402656 in main fuzz/test-corpus.c:226 + #25 0x7fb618551f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +SUMMARY: AddressSanitizer: 80 byte(s) leaked in 2 allocation(s). + +Reviewed-by: Tomas Mraz +Reviewed-by: Kurt Roeckx +(Merged from https://github.com/openssl/openssl/pull/18632) +--- + crypto/ec/ec_asn1.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c +index 34de7b2aab..1acbbde3d3 100644 +--- a/crypto/ec/ec_asn1.c ++++ b/crypto/ec/ec_asn1.c +@@ -794,7 +794,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) + } + + /* extract the order */ +- if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { ++ if (ASN1_INTEGER_to_BN(params->order, a) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB); + goto err; + } +@@ -811,7 +811,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) + if (params->cofactor == NULL) { + BN_free(b); + b = NULL; +- } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { ++ } else if (ASN1_INTEGER_to_BN(params->cofactor, b) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB); + goto err; + } +-- +2.17.1 + diff --git a/backport-Fix-a-memory-leak-in-X509_issuer_and_serial_hash.patch b/backport-Fix-a-memory-leak-in-X509_issuer_and_serial_hash.patch new file mode 100644 index 0000000000000000000000000000000000000000..397b8c6c440569c98312efb5c2a6a33f198e3679 --- /dev/null +++ b/backport-Fix-a-memory-leak-in-X509_issuer_and_serial_hash.patch @@ -0,0 +1,74 @@ +From 59b8eca400d9ea7b77dc98fe08a91bbfe35d025a Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Sat, 21 May 2022 15:41:46 +0200 +Subject: [PATCH] Fix a memory leak in X509_issuer_and_serial_hash + +This is reproducible with my error injection patch: + +$ ERROR_INJECT=1653267699 ../util/shlib_wrap.sh ./x509-test ./corpora/x509/5f4034ae85d6587dcad4da3e812e80f3d312894d +ERROR_INJECT=1653267699 + #0 0x7fd485a6ad4f in __sanitizer_print_stack_trace ../../../../src/libsanitizer/asan/asan_stack.cc:36 + #1 0x55c12d268724 in my_malloc fuzz/test-corpus.c:114 + #2 0x7fd484f51a75 in CRYPTO_zalloc crypto/mem.c:230 + #3 0x7fd484ed778d in EVP_DigestInit_ex crypto/evp/digest.c:139 + #4 0x7fd4850a9849 in X509_issuer_and_serial_hash crypto/x509/x509_cmp.c:44 + #5 0x55c12d268951 in FuzzerTestOneInput fuzz/x509.c:44 + #6 0x55c12d268239 in testfile fuzz/test-corpus.c:182 + #7 0x55c12d267c7f in main fuzz/test-corpus.c:226 + #8 0x7fd483a42082 in __libc_start_main ../csu/libc-start.c:308 + #9 0x55c12d267e5d in _start (/home/ed/OPCToolboxV5/Source/Core/OpenSSL/openssl/fuzz/x509-test+0x3e5d) + +================================================================= +==1058475==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 268 byte(s) in 1 object(s) allocated from: + #0 0x7fd485a5dc3e in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:163 + #1 0x7fd484d2eb9b in BUF_MEM_grow crypto/buffer/buffer.c:97 + #2 0x7fd4850b2913 in X509_NAME_oneline crypto/x509/x509_obj.c:43 + #3 0x7fd4850a982f in X509_issuer_and_serial_hash crypto/x509/x509_cmp.c:41 + #4 0x55c12d268951 in FuzzerTestOneInput fuzz/x509.c:44 + #5 0x55c12d268239 in testfile fuzz/test-corpus.c:182 + #6 0x55c12d267c7f in main fuzz/test-corpus.c:226 + #7 0x7fd483a42082 in __libc_start_main ../csu/libc-start.c:308 + +SUMMARY: AddressSanitizer: 268 byte(s) leaked in 1 allocation(s). + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18370) +--- + crypto/x509/x509_cmp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c +index 1d8d2d7b28..1661cac634 100644 +--- a/crypto/x509/x509_cmp.c ++++ b/crypto/x509/x509_cmp.c +@@ -34,7 +34,7 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) + unsigned long ret = 0; + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + unsigned char md[16]; +- char *f; ++ char *f = NULL; + + if (ctx == NULL) + goto err; +@@ -45,7 +45,6 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) + goto err; + if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f))) + goto err; +- OPENSSL_free(f); + if (!EVP_DigestUpdate + (ctx, (unsigned char *)a->cert_info.serialNumber.data, + (unsigned long)a->cert_info.serialNumber.length)) +@@ -56,6 +55,7 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + err: ++ OPENSSL_free(f); + EVP_MD_CTX_free(ctx); + return ret; + } +-- +2.17.1 + diff --git a/backport-Fix-a-memory-leak-in-crl_set_issuers.patch b/backport-Fix-a-memory-leak-in-crl_set_issuers.patch new file mode 100644 index 0000000000000000000000000000000000000000..803b7276e2721e86265010e2bca30be3e40dd014 --- /dev/null +++ b/backport-Fix-a-memory-leak-in-crl_set_issuers.patch @@ -0,0 +1,118 @@ +From 8754fa5f60ac4fdb5127f2eded9c7bbe0651c880 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Sat, 21 May 2022 07:50:46 +0200 +Subject: [PATCH] Fix a memory leak in crl_set_issuers + +This can be reproduced with my error injection patch. + +The test vector has been validated on the 1.1.1 branch +but the issue is of course identical in all branches. + +$ ERROR_INJECT=1653520461 ../util/shlib_wrap.sh ./cms-test ./corpora/cms/3eff1d2f1232bd66d5635db2c3f9e7f23830dfd1 +log file: cms-3eff1d2f1232bd66d5635db2c3f9e7f23830dfd1-32454-test.out +ERROR_INJECT=1653520461 + #0 0x7fd5d8b8eeba in __sanitizer_print_stack_trace ../../../../gcc-trunk/libsanitizer/asan/asan_stack.cpp:87 + #1 0x402fc4 in my_realloc fuzz/test-corpus.c:129 + #2 0x7fd5d8893c49 in sk_reserve crypto/stack/stack.c:198 + #3 0x7fd5d8893c49 in OPENSSL_sk_insert crypto/stack/stack.c:242 + #4 0x7fd5d88d6d7f in sk_GENERAL_NAMES_push include/openssl/x509v3.h:168 + #5 0x7fd5d88d6d7f in crl_set_issuers crypto/x509/x_crl.c:111 + #6 0x7fd5d88d6d7f in crl_cb crypto/x509/x_crl.c:246 + #7 0x7fd5d85dc032 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:432 + #8 0x7fd5d85dcaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #9 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #10 0x7fd5d85db2b5 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:259 + #11 0x7fd5d85dc813 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:611 + #12 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #13 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #14 0x7fd5d85dca28 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:633 + #15 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #16 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #17 0x7fd5d85dcaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #18 0x7fd5d85dd7d3 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:494 + #19 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #20 0x7fd5d85ddd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #21 0x7fd5d85dde35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #22 0x7fd5d85a77e0 in ASN1_item_d2i_bio crypto/asn1/a_d2i_fp.c:69 + #23 0x402845 in FuzzerTestOneInput fuzz/cms.c:43 + #24 0x402bbb in testfile fuzz/test-corpus.c:182 + #25 0x402626 in main fuzz/test-corpus.c:226 + #26 0x7fd5d7c81f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + #27 0x402706 (/home/ed/OPC/openssl/fuzz/cms-test+0x402706) + +================================================================= +==29625==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 32 byte(s) in 1 object(s) allocated from: + #0 0x7fd5d8b8309f in __interceptor_malloc ../../../../gcc-trunk/libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 0x7fd5d87c2430 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fd5d889501f in OPENSSL_sk_new_reserve crypto/stack/stack.c:209 + #3 0x7fd5d85dcbc3 in sk_ASN1_VALUE_new_null include/openssl/asn1t.h:928 + #4 0x7fd5d85dcbc3 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:577 + #5 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #6 0x7fd5d85db104 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:178 + #7 0x7fd5d85ddd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #8 0x7fd5d85dde35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #9 0x7fd5d88f86d9 in X509V3_EXT_d2i crypto/x509v3/v3_lib.c:142 + #10 0x7fd5d88d6d3c in crl_set_issuers crypto/x509/x_crl.c:97 + #11 0x7fd5d88d6d3c in crl_cb crypto/x509/x_crl.c:246 + #12 0x7fd5d85dc032 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:432 + #13 0x7fd5d85dcaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #14 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #15 0x7fd5d85db2b5 in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:259 + #16 0x7fd5d85dc813 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:611 + #17 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #18 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #19 0x7fd5d85dca28 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:633 + #20 0x7fd5d85dd288 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:518 + #21 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #22 0x7fd5d85dcaf5 in asn1_template_noexp_d2i crypto/asn1/tasn_dec.c:643 + #23 0x7fd5d85dd7d3 in asn1_template_ex_d2i crypto/asn1/tasn_dec.c:494 + #24 0x7fd5d85db9ce in asn1_item_embed_d2i crypto/asn1/tasn_dec.c:382 + #25 0x7fd5d85ddd1f in ASN1_item_ex_d2i crypto/asn1/tasn_dec.c:124 + #26 0x7fd5d85dde35 in ASN1_item_d2i crypto/asn1/tasn_dec.c:114 + #27 0x7fd5d85a77e0 in ASN1_item_d2i_bio crypto/asn1/a_d2i_fp.c:69 + #28 0x402845 in FuzzerTestOneInput fuzz/cms.c:43 + #29 0x402bbb in testfile fuzz/test-corpus.c:182 + #30 0x402626 in main fuzz/test-corpus.c:226 + #31 0x7fd5d7c81f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +SUMMARY: AddressSanitizer: 32 byte(s) leaked in 1 allocation(s). + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18391) + +(cherry picked from commit e9007e09792e3735d4973743634ff55d354fc7d8) +--- + crypto/x509/x_crl.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c +index 9af39a45fc..a4e4a415de 100644 +--- a/crypto/x509/x_crl.c ++++ b/crypto/x509/x_crl.c +@@ -103,13 +103,17 @@ static int crl_set_issuers(X509_CRL *crl) + + if (gtmp) { + gens = gtmp; +- if (!crl->issuers) { ++ if (crl->issuers == NULL) { + crl->issuers = sk_GENERAL_NAMES_new_null(); +- if (!crl->issuers) ++ if (crl->issuers == NULL) { ++ GENERAL_NAMES_free(gtmp); + return 0; ++ } + } +- if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) ++ if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) { ++ GENERAL_NAMES_free(gtmp); + return 0; ++ } + } + rev->issuer = gens; + +-- +2.17.1 + diff --git a/backport-Fix-a-memory-leak-in-ec_key_simple_oct2priv.patch b/backport-Fix-a-memory-leak-in-ec_key_simple_oct2priv.patch new file mode 100644 index 0000000000000000000000000000000000000000..a209f0ed376c3007240f638d31b77b3709f906cf --- /dev/null +++ b/backport-Fix-a-memory-leak-in-ec_key_simple_oct2priv.patch @@ -0,0 +1,61 @@ +From 8e1ece20cdb4a584be5311370256c4e813c09826 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Fri, 20 May 2022 16:15:44 +0200 +Subject: [PATCH] Fix a memory leak in ec_key_simple_oct2priv + +This is reproducible with my error injection patch: + +$ ERROR_INJECT=1652710284 ../util/shlib_wrap.sh ./server-test ./corpora/server/4e48da8aecce6b9b58e8e4dbbf0523e6d2dd56dc +140587884632000:error:03078041:bignum routines:bn_expand_internal:malloc failure:crypto/bn/bn_lib.c:282: +140587884632000:error:10103003:elliptic curve routines:ec_key_simple_oct2priv:BN lib:crypto/ec/ec_key.c:662: +140587884632000:error:100DE08E:elliptic curve routines:old_ec_priv_decode:decode error:crypto/ec/ec_ameth.c:464: +140587884632000:error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag:crypto/asn1/tasn_dec.c:1149: +140587884632000:error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:309:Type=X509_ALGOR +140587884632000:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=pkeyalg, Type=PKCS8_PRIV_KEY_INFO +140587884632000:error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib:crypto/pem/pem_pkey.c:88: + +================================================================= +==19676==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 24 byte(s) in 1 object(s) allocated from: + #0 0x7fdd2a6bb09f in __interceptor_malloc ../../../../gcc-trunk/libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 0x7fdd2a2fa430 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fdd2a15df11 in BN_new crypto/bn/bn_lib.c:246 + #3 0x7fdd2a15df88 in BN_secure_new crypto/bn/bn_lib.c:257 + #4 0x7fdd2a247390 in ec_key_simple_oct2priv crypto/ec/ec_key.c:655 + #5 0x7fdd2a241fc5 in d2i_ECPrivateKey crypto/ec/ec_asn1.c:1030 + #6 0x7fdd2a23dac5 in old_ec_priv_decode crypto/ec/ec_ameth.c:463 + #7 0x7fdd2a109db7 in d2i_PrivateKey crypto/asn1/d2i_pr.c:46 + #8 0x7fdd2a33ab16 in PEM_read_bio_PrivateKey crypto/pem/pem_pkey.c:84 + #9 0x7fdd2a3330b6 in PEM_read_bio_ECPrivateKey crypto/pem/pem_all.c:151 + #10 0x402dba in FuzzerTestOneInput fuzz/server.c:592 + #11 0x40370b in testfile fuzz/test-corpus.c:182 + #12 0x402846 in main fuzz/test-corpus.c:226 + #13 0x7fdd297b9f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) + +SUMMARY: AddressSanitizer: 24 byte(s) leaked in 1 allocation(s). + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18361) +--- + crypto/ec/ec_key.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c +index 23efbd015c..27d5a43b5f 100644 +--- a/crypto/ec/ec_key.c ++++ b/crypto/ec/ec_key.c +@@ -657,8 +657,7 @@ int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) + ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE); + return 0; + } +- eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key); +- if (eckey->priv_key == NULL) { ++ if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) { + ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB); + return 0; + } +-- +2.17.1 + diff --git a/backport-Fix-a-memory-leak-in-tls13_generate_secret.patch b/backport-Fix-a-memory-leak-in-tls13_generate_secret.patch new file mode 100644 index 0000000000000000000000000000000000000000..2789d555957e90095661031afbaf3d131a292f8f --- /dev/null +++ b/backport-Fix-a-memory-leak-in-tls13_generate_secret.patch @@ -0,0 +1,117 @@ +From a937806043bda5775091844050e8c632a41922ac Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Tue, 5 Jul 2022 20:39:06 +0200 +Subject: [PATCH] Fix a memory leak in tls13_generate_secret + +This was found by my Reproducible Error Injection patch (#18356) + +Due to the exact location of the injected memory +error the sha256 digest is missing, and this causes much later +the memory leak (and a failed assertion) in tls13_generate_secret. + +But the reproduction is a bit challenging, as it requires AESNI +and RDRAND capability. + +OPENSSL_ia32cap=0x4200000000000000 ERROR_INJECT=1657070330 ../util/shlib_wrap.sh ./client-test ./corpora/client/791afc153e17db072175eeef85385a38d7f6d194 + #0 0x7fceaffb7d4f in __sanitizer_print_stack_trace ../../../../src/libsanitizer/asan/asan_stack.cc:36 + #1 0x55fb9117f934 in my_malloc fuzz/test-corpus.c:114 + #2 0x7fceafa147f3 in OPENSSL_LH_insert crypto/lhash/lhash.c:109 + #3 0x7fceafa42639 in lh_OBJ_NAME_insert crypto/objects/obj_local.h:12 + #4 0x7fceafa42639 in OBJ_NAME_add crypto/objects/o_names.c:236 + #5 0x7fceaf9f7baa in EVP_add_digest crypto/evp/names.c:39 + #6 0x7fceaf9c6b97 in openssl_add_all_digests_int crypto/evp/c_alld.c:39 + #7 0x7fceafa0f8ec in ossl_init_add_all_digests crypto/init.c:275 + #8 0x7fceafa0f8ec in ossl_init_add_all_digests_ossl_ crypto/init.c:264 + #9 0x7fceaf69b4de in __pthread_once_slow /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_once.c:116 + #10 0x7fceafafb27c in CRYPTO_THREAD_run_once crypto/threads_pthread.c:118 + #11 0x7fceafa1000e in OPENSSL_init_crypto crypto/init.c:677 + #12 0x7fceafa1000e in OPENSSL_init_crypto crypto/init.c:611 + #13 0x7fceafdad3e8 in OPENSSL_init_ssl ssl/ssl_init.c:190 + #14 0x55fb9117ee0f in FuzzerInitialize fuzz/client.c:46 + #15 0x55fb9117e939 in main fuzz/test-corpus.c:194 + #16 0x7fceaf4bc082 in __libc_start_main ../csu/libc-start.c:308 + #17 0x55fb9117ec7d in _start (.../openssl/fuzz/client-test+0x2c7d) + + #0 0x7fceaffb7d4f in __sanitizer_print_stack_trace ../../../../src/libsanitizer/asan/asan_stack.cc:36 + #1 0x55fb9117f934 in my_malloc fuzz/test-corpus.c:114 + #2 0x7fceafa147f3 in OPENSSL_LH_insert crypto/lhash/lhash.c:109 + #3 0x7fceafa42639 in lh_OBJ_NAME_insert crypto/objects/obj_local.h:12 + #4 0x7fceafa42639 in OBJ_NAME_add crypto/objects/o_names.c:236 + #5 0x7fceaf9f7baa in EVP_add_digest crypto/evp/names.c:39 + #6 0x7fceafdad328 in ossl_init_ssl_base ssl/ssl_init.c:87 + #7 0x7fceafdad328 in ossl_init_ssl_base_ossl_ ssl/ssl_init.c:24 + #8 0x7fceaf69b4de in __pthread_once_slow /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_once.c:116 + #9 0x7fceafafb27c in CRYPTO_THREAD_run_once crypto/threads_pthread.c:118 + #10 0x7fceafdad412 in OPENSSL_init_ssl ssl/ssl_init.c:193 + #11 0x55fb9117ee0f in FuzzerInitialize fuzz/client.c:46 + #12 0x55fb9117e939 in main fuzz/test-corpus.c:194 + #13 0x7fceaf4bc082 in __libc_start_main ../csu/libc-start.c:308 + #14 0x55fb9117ec7d in _start (.../openssl/fuzz/client-test+0x2c7d) + +================================================================= +==1320996==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 80 byte(s) in 1 object(s) allocated from: + #0 0x7fceaffaa808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144 + #1 0x7fceafa19425 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fceafa03a85 in int_ctx_new crypto/evp/pmeth_lib.c:144 + #3 0x7fceafa03a85 in EVP_PKEY_CTX_new_id crypto/evp/pmeth_lib.c:250 + #4 0x7fceafe38de5 in tls13_generate_secret ssl/tls13_enc.c:174 + #5 0x7fceafd9537f in ssl_derive ssl/s3_lib.c:4833 + #6 0x7fceafdde91c in tls_parse_stoc_key_share ssl/statem/extensions_clnt.c:1902 + #7 0x7fceafdd4ac1 in tls_parse_all_extensions ssl/statem/extensions.c:752 + #8 0x7fceafdf8079 in tls_process_server_hello ssl/statem/statem_clnt.c:1698 + #9 0x7fceafe01f87 in ossl_statem_client_process_message ssl/statem/statem_clnt.c:1034 + #10 0x7fceafdeec0d in read_state_machine ssl/statem/statem.c:636 + #11 0x7fceafdeec0d in state_machine ssl/statem/statem.c:434 + #12 0x7fceafdb88d7 in SSL_do_handshake ssl/ssl_lib.c:3718 + #13 0x55fb9117f07c in FuzzerTestOneInput fuzz/client.c:98 + #14 0x55fb9117f463 in testfile fuzz/test-corpus.c:182 + #15 0x55fb9117eb92 in main fuzz/test-corpus.c:226 + #16 0x7fceaf4bc082 in __libc_start_main ../csu/libc-start.c:308 + +Indirect leak of 1080 byte(s) in 1 object(s) allocated from: + #0 0x7fceaffaa808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144 + #1 0x7fceafa19425 in CRYPTO_zalloc crypto/mem.c:230 + #2 0x7fceafa11555 in pkey_hkdf_init crypto/kdf/hkdf.c:51 + #3 0x7fceafa03b36 in int_ctx_new crypto/evp/pmeth_lib.c:160 + #4 0x7fceafa03b36 in EVP_PKEY_CTX_new_id crypto/evp/pmeth_lib.c:250 + #5 0x7fceafe38de5 in tls13_generate_secret ssl/tls13_enc.c:174 + #6 0x7fceafd9537f in ssl_derive ssl/s3_lib.c:4833 + #7 0x7fceafdde91c in tls_parse_stoc_key_share ssl/statem/extensions_clnt.c:1902 + #8 0x7fceafdd4ac1 in tls_parse_all_extensions ssl/statem/extensions.c:752 + #9 0x7fceafdf8079 in tls_process_server_hello ssl/statem/statem_clnt.c:1698 + #10 0x7fceafe01f87 in ossl_statem_client_process_message ssl/statem/statem_clnt.c:1034 + #11 0x7fceafdeec0d in read_state_machine ssl/statem/statem.c:636 + #12 0x7fceafdeec0d in state_machine ssl/statem/statem.c:434 + #13 0x7fceafdb88d7 in SSL_do_handshake ssl/ssl_lib.c:3718 + #14 0x55fb9117f07c in FuzzerTestOneInput fuzz/client.c:98 + #15 0x55fb9117f463 in testfile fuzz/test-corpus.c:182 + #16 0x55fb9117eb92 in main fuzz/test-corpus.c:226 + #17 0x7fceaf4bc082 in __libc_start_main ../csu/libc-start.c:308 + +SUMMARY: AddressSanitizer: 1160 byte(s) leaked in 2 allocation(s). + +Reviewed-by: Todd Short +Reviewed-by: Shane Lontis +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18725) +--- + ssl/tls13_enc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c +index b8fb07f210..51ca1050a4 100644 +--- a/ssl/tls13_enc.c ++++ b/ssl/tls13_enc.c +@@ -190,6 +190,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, + if (!ossl_assert(mdleni >= 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, + ERR_R_INTERNAL_ERROR); ++ EVP_PKEY_CTX_free(pctx); + return 0; + } + mdlen = (size_t)mdleni; +-- +2.17.1 + diff --git a/backport-Fix-an-assertion-in-the-DTLS-server-code.patch b/backport-Fix-an-assertion-in-the-DTLS-server-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..0f75a9f665c7a80eaca02839970b4af27288a389 --- /dev/null +++ b/backport-Fix-an-assertion-in-the-DTLS-server-code.patch @@ -0,0 +1,145 @@ +From 564a8d442cbd8ce68d452ff2e8a58c0aea6b0632 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Mon, 11 Apr 2022 10:12:48 +0200 +Subject: [PATCH] Fix an assertion in the DTLS server code + +This fixes an internal error alert from the server and +an unexpected connection failure in the release version, +but a failed assertion and a server crash in the +debug version. + +Reproduce this issue with a DTLS server/client like that: + +./openssl s_server -dtls -mtu 1500 +./openssl s_client -dtls -maxfraglen 512 + +In the debug version a crash happens in the Server now: + +./openssl s_server -dtls -mtu 1500 +Using default temp DH parameters +ACCEPT +ssl/statem/statem_dtls.c:269: OpenSSL internal error: Assertion failed: len == written +Aborted (core dumped) + +While in the release version the handshake exceeds the +negotiated max fragment size, and fails because of this: + +$ ./openssl s_server -dtls -mtu 1500 +Using default temp DH parameters +ACCEPT +ERROR +4057152ADA7F0000:error:0A0000C2:SSL routines:do_dtls1_write:exceeds max fragment size:ssl/record/rec_layer_d1.c:826: +shutting down SSL +CONNECTION CLOSED + +From the client's point of view the connection fails +with an Internal Error Alert: + +$ ./openssl s_client -dtls -maxfraglen 512 +Connecting to ::1 +CONNECTED(00000003) +40B76343377F0000:error:0A000438:SSL routines:dtls1_read_bytes:tlsv1 alert internal error:ssl/record/rec_layer_d1.c:613:SSL alert number 80 + +and now the connection attempt fails unexpectedly. + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18093) + +(cherry picked from commit e915c3f5381cd38ebdc1824c3ba9896ea7160103) +--- + ssl/statem/statem_dtls.c | 6 ++--- + test/dtls_mtu_test.c | 48 +++++++++++++++++++++++++++++++++++++++- + 2 files changed, 50 insertions(+), 4 deletions(-) + +diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c +index 8e3fb686ee..620367ace4 100644 +--- a/ssl/statem/statem_dtls.c ++++ b/ssl/statem/statem_dtls.c +@@ -218,8 +218,8 @@ int dtls1_do_write(SSL *s, int type) + else + len = s->init_num; + +- if (len > s->max_send_fragment) +- len = s->max_send_fragment; ++ if (len > ssl_get_max_send_fragment(s)) ++ len = ssl_get_max_send_fragment(s); + + /* + * XDTLS: this function is too long. split out the CCS part +@@ -241,7 +241,7 @@ int dtls1_do_write(SSL *s, int type) + + ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len, + &written); +- if (ret < 0) { ++ if (ret <= 0) { + /* + * might need to update MTU here, but we don't know which + * previous packet caused the failure -- so can't really +diff --git a/test/dtls_mtu_test.c b/test/dtls_mtu_test.c +index f20edf02d2..9b69e80a62 100644 +--- a/test/dtls_mtu_test.c ++++ b/test/dtls_mtu_test.c +@@ -185,12 +185,58 @@ static int run_mtu_tests(void) + + end: + SSL_CTX_free(ctx); +- bio_s_mempacket_test_free(); + return ret; + } + ++static int test_server_mtu_larger_than_max_fragment_length(void) ++{ ++ SSL_CTX *ctx = NULL; ++ SSL *srvr_ssl = NULL, *clnt_ssl = NULL; ++ int rv = 0; ++ ++ if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_method()))) ++ goto end; ++ ++ SSL_CTX_set_psk_server_callback(ctx, srvr_psk_callback); ++ SSL_CTX_set_psk_client_callback(ctx, clnt_psk_callback); ++ ++#ifndef OPENSSL_NO_DH ++ if (!TEST_true(SSL_CTX_set_dh_auto(ctx, 1))) ++ goto end; ++#endif ++ ++ if (!TEST_true(create_ssl_objects(ctx, ctx, &srvr_ssl, &clnt_ssl, ++ NULL, NULL))) ++ goto end; ++ ++ SSL_set_options(srvr_ssl, SSL_OP_NO_QUERY_MTU); ++ if (!TEST_true(DTLS_set_link_mtu(srvr_ssl, 1500))) ++ goto end; ++ ++ SSL_set_tlsext_max_fragment_length(clnt_ssl, ++ TLSEXT_max_fragment_length_512); ++ ++ if (!TEST_true(create_ssl_connection(srvr_ssl, clnt_ssl, ++ SSL_ERROR_NONE))) ++ goto end; ++ ++ rv = 1; ++ ++ end: ++ SSL_free(clnt_ssl); ++ SSL_free(srvr_ssl); ++ SSL_CTX_free(ctx); ++ return rv; ++} ++ + int setup_tests(void) + { + ADD_TEST(run_mtu_tests); ++ ADD_TEST(test_server_mtu_larger_than_max_fragment_length); + return 1; + } ++ ++void cleanup_tests(void) ++{ ++ bio_s_mempacket_test_free(); ++} +-- +2.17.1 + diff --git a/backport-Fix-bn_gcd-code-to-check-return-value-when-calling-B.patch b/backport-Fix-bn_gcd-code-to-check-return-value-when-calling-B.patch new file mode 100644 index 0000000000000000000000000000000000000000..04a597b8d4d1205f21236595755fe5d68a03bb5f --- /dev/null +++ b/backport-Fix-bn_gcd-code-to-check-return-value-when-calling-B.patch @@ -0,0 +1,47 @@ +From 6495cab1c876ad80ce983d848ccaa1dc286a63e1 Mon Sep 17 00:00:00 2001 +From: slontis +Date: Fri, 1 Jul 2022 13:47:11 +1000 +Subject: [PATCH] Fix bn_gcd code to check return value when calling BN_one() + +BN_one() uses the expand function which calls malloc which may fail. +All other places that reference BN_one() check the return value. + +The issue is triggered by a memory allocation failure. +Detected by PR #18355 + +Reviewed-by: Tomas Mraz +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18697) + +(cherry picked from commit 7fe7cc57af3db1e497877f0329ba17609b2efc8b) +--- + crypto/bn/bn_gcd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c +index 0941f7b97f..c4b7854e1a 100644 +--- a/crypto/bn/bn_gcd.c ++++ b/crypto/bn/bn_gcd.c +@@ -47,7 +47,8 @@ BIGNUM *bn_mod_inverse_no_branch(BIGNUM *in, + if (R == NULL) + goto err; + +- BN_one(X); ++ if (!BN_one(X)) ++ goto err; + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; +@@ -235,7 +236,8 @@ BIGNUM *int_bn_mod_inverse(BIGNUM *in, + if (R == NULL) + goto err; + +- BN_one(X); ++ if (!BN_one(X)) ++ goto err; + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; +-- +2.17.1 + diff --git a/backport-Fix-coverity-1498607-uninitialised-value.patch b/backport-Fix-coverity-1498607-uninitialised-value.patch new file mode 100644 index 0000000000000000000000000000000000000000..7fa05993941be68dede01c1f74350a51406bb9fc --- /dev/null +++ b/backport-Fix-coverity-1498607-uninitialised-value.patch @@ -0,0 +1,29 @@ +From 2f1c42553dbaac97d38657cd1ac1209ef4c11e78 Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 16 Mar 2022 14:45:44 +1100 +Subject: [PATCH] Fix coverity 1498607: uninitialised value + +Reviewed-by: Tim Hudson +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17897) + +(cherry picked from commit 70cd9a51911e9a4e2f24e29ddd84fa9fcb778b63) +--- + crypto/ec/ecp_nistz256.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c +index 5005249b05..43eab75fa7 100644 +--- a/crypto/ec/ecp_nistz256.c ++++ b/crypto/ec/ecp_nistz256.c +@@ -973,6 +973,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, + return 0; + } + ++ memset(&p, 0, sizeof(p)); + BN_CTX_start(ctx); + + if (scalar) { +-- +2.17.1 + diff --git a/backport-Fix-failure-to-check-result-of-bn_rshift_fixed_top.patch b/backport-Fix-failure-to-check-result-of-bn_rshift_fixed_top.patch new file mode 100644 index 0000000000000000000000000000000000000000..61e4595fac1062dad37110dba333a65c20236032 --- /dev/null +++ b/backport-Fix-failure-to-check-result-of-bn_rshift_fixed_top.patch @@ -0,0 +1,36 @@ +From 93ac3b8dd1cc49b27c402278cbe73a1c4ac91f9b Mon Sep 17 00:00:00 2001 +From: Hugo Landau +Date: Mon, 4 Apr 2022 12:25:16 +0100 +Subject: [PATCH] Fix failure to check result of bn_rshift_fixed_top + +Fixes #18010. + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18034) + +(cherry picked from commit bc6bac8561ead83d6135f376ffcbbb0b657e64fe) +--- + crypto/bn/bn_div.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c +index 0da9f39b31..e2821fb6cd 100644 +--- a/crypto/bn/bn_div.c ++++ b/crypto/bn/bn_div.c +@@ -446,8 +446,10 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, + snum->neg = num_neg; + snum->top = div_n; + snum->flags |= BN_FLG_FIXED_TOP; +- if (rm != NULL) +- bn_rshift_fixed_top(rm, snum, norm_shift); ++ ++ if (rm != NULL && bn_rshift_fixed_top(rm, snum, norm_shift) == 0) ++ goto err; ++ + BN_CTX_end(ctx); + return 1; + err: +-- +2.17.1 + diff --git a/backport-Fix-integer-overflow-in-evp_EncryptDecryptUpdate.patch b/backport-Fix-integer-overflow-in-evp_EncryptDecryptUpdate.patch new file mode 100644 index 0000000000000000000000000000000000000000..71df3f04f0dfcbc7f758477c2bc3e9b115a88e79 --- /dev/null +++ b/backport-Fix-integer-overflow-in-evp_EncryptDecryptUpdate.patch @@ -0,0 +1,62 @@ +From eed53b9addd097a5d39f896b05aa857d6f29b245 Mon Sep 17 00:00:00 2001 +From: Hugo Landau +Date: Fri, 11 Mar 2022 08:36:11 +0000 +Subject: [PATCH] Fix integer overflow in evp_EncryptDecryptUpdate + +Fixes #17871. + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17872) +--- + crypto/evp/evp_enc.c | 8 +++++--- + crypto/evp/evp_local.h | 2 +- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c +index d835968f25..b8b9d90d36 100644 +--- a/crypto/evp/evp_enc.c ++++ b/crypto/evp/evp_enc.c +@@ -281,7 +281,7 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + # define PTRDIFF_T size_t + #endif + +-int is_partially_overlapping(const void *ptr1, const void *ptr2, int len) ++int is_partially_overlapping(const void *ptr1, const void *ptr2, size_t len) + { + PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2; + /* +@@ -299,7 +299,8 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl) + { +- int i, j, bl, cmpl = inl; ++ int i, j, bl; ++ size_t cmpl = (size_t)inl; + + if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) + cmpl = (cmpl + 7) / 8; +@@ -464,8 +465,9 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) + int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) + { +- int fix_len, cmpl = inl; ++ int fix_len; + unsigned int b; ++ size_t cmpl = (size_t)inl; + + /* Prevent accidental use of encryption context when decrypting */ + if (ctx->encrypt) { +diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h +index f1589d6828..cd3c1cf148 100644 +--- a/crypto/evp/evp_local.h ++++ b/crypto/evp/evp_local.h +@@ -65,4 +65,4 @@ struct evp_Encode_Ctx_st { + typedef struct evp_pbe_st EVP_PBE_CTL; + DEFINE_STACK_OF(EVP_PBE_CTL) + +-int is_partially_overlapping(const void *ptr1, const void *ptr2, int len); ++int is_partially_overlapping(const void *ptr1, const void *ptr2, size_t len); +-- +2.17.1 + diff --git a/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch b/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch new file mode 100644 index 0000000000000000000000000000000000000000..fec39592c817a115ad5b1996e11d18f076d9137a --- /dev/null +++ b/backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch @@ -0,0 +1,45 @@ +From 65e30e7d56f01008d29e65c9ae7a42ce074def2f Mon Sep 17 00:00:00 2001 +From: Amir Mohammadi +Date: Wed, 4 Aug 2021 09:43:49 +0430 +Subject: [PATCH] Fix ipv4_from_asc behavior on invalid Ip addresses + +sscanf() call in ipv4_from_asc does not check that +the string is terminated immediately after the last digit. + +(cherry picked from commit 8b9a13b43ba3d71e441fca47a52e800ce79b3d2b) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + crypto/x509v3/v3_utl.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c +index a7ff4b4fb4..eac78259fc 100644 +--- a/crypto/x509v3/v3_utl.c ++++ b/crypto/x509v3/v3_utl.c +@@ -1087,12 +1087,17 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc) + + static int ipv4_from_asc(unsigned char *v4, const char *in) + { +- int a0, a1, a2, a3; +- if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) ++ const char *p; ++ int a0, a1, a2, a3, n; ++ ++ if (sscanf(in, "%d.%d.%d.%d%n", &a0, &a1, &a2, &a3, &n) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) + || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; ++ p = in + n; ++ if (!(*p == '\0' || ossl_isspace(*p))) ++ return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; +-- +2.17.1 + diff --git a/backport-Fix-issue-where-OBJ_nid2obj-doesn-t-always-raise-an-.patch b/backport-Fix-issue-where-OBJ_nid2obj-doesn-t-always-raise-an-.patch new file mode 100644 index 0000000000000000000000000000000000000000..681863a8c82e74b1fef5c9ccbd4b636a3335f006 --- /dev/null +++ b/backport-Fix-issue-where-OBJ_nid2obj-doesn-t-always-raise-an-.patch @@ -0,0 +1,80 @@ +From add8c29badb315cb8137655893826562ff12a581 Mon Sep 17 00:00:00 2001 +From: Hugo Landau +Date: Thu, 3 Mar 2022 17:27:23 +0000 +Subject: [PATCH] Fix issue where OBJ_nid2obj doesn't always raise an error + +This was previously fixed in 3.0 but not 1.1. + +Fixes #13008. + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +Reviewed-by: Todd Short +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/17808) +--- + crypto/objects/obj_dat.c | 5 +++-- + test/asn1_internal_test.c | 27 +++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 2 deletions(-) + +diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c +index 46006fe6cf..a501ca104b 100644 +--- a/crypto/objects/obj_dat.c ++++ b/crypto/objects/obj_dat.c +@@ -228,9 +228,10 @@ ASN1_OBJECT *OBJ_nid2obj(int n) + return NULL; + } + return (ASN1_OBJECT *)&(nid_objs[n]); +- } else if (added == NULL) ++ } else if (added == NULL) { ++ OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return NULL; +- else { ++ } else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; +diff --git a/test/asn1_internal_test.c b/test/asn1_internal_test.c +index 865e058421..caca0cb15e 100644 +--- a/test/asn1_internal_test.c ++++ b/test/asn1_internal_test.c +@@ -107,9 +107,36 @@ static int test_standard_methods(void) + return 0; + } + ++/********************************************************************** ++ * ++ * Regression test for issue where OBJ_nid2obj does not raise ++ * an error when a NID is not registered. ++ * ++ ***/ ++static int test_nid2obj_nonexist(void) ++{ ++ ASN1_OBJECT *obj; ++ unsigned long err; ++ ++ obj = OBJ_nid2obj(INT_MAX); ++ if (!TEST_true(obj == NULL)) ++ return 0; ++ ++ err = ERR_get_error(); ++ ++ if (!TEST_int_eq(ERR_GET_FUNC(err), OBJ_F_OBJ_NID2OBJ)) ++ return 0; ++ ++ if (!TEST_int_eq(ERR_GET_REASON(err), OBJ_R_UNKNOWN_NID)) ++ return 0; ++ ++ return 1; ++} ++ + int setup_tests(void) + { + ADD_TEST(test_tbl_standard); + ADD_TEST(test_standard_methods); ++ ADD_TEST(test_nid2obj_nonexist); + return 1; + } +-- +2.17.1 + diff --git a/backport-Fix-leakage-when-the-cacheline-is-32-bytes-in-CBC_MA.patch b/backport-Fix-leakage-when-the-cacheline-is-32-bytes-in-CBC_MA.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6319831712820a6f46bdd8c8ec21ee65e3a29e5 --- /dev/null +++ b/backport-Fix-leakage-when-the-cacheline-is-32-bytes-in-CBC_MA.patch @@ -0,0 +1,61 @@ +From 6ef91d8153e04a2302bff11b29caf7e888b62fe8 Mon Sep 17 00:00:00 2001 +From: basavesh +Date: Tue, 5 Apr 2022 17:49:09 +0200 +Subject: [PATCH] Fix leakage when the cacheline is 32-bytes in + CBC_MAC_ROTATE_IN_PLACE + +rotated_mac is a 64-byte aligned buffer of size 64 and rotate_offset is secret. +Consider a weaker leakage model(CL) where only cacheline base address is leaked, +i.e address/32 for 32-byte cacheline(CL32). + +Previous code used to perform two loads + 1. rotated_mac[rotate_offset ^ 32] and + 2. rotated_mac[rotate_offset++] +which would leak 2q + 1, 2q for 0 <= rotate_offset < 32 +and 2q, 2q + 1 for 32 <= rotate_offset < 64 + +The proposed fix performs load operations which will always leak 2q, 2q + 1 and +selects the appropriate value in constant-time. + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18050) +--- + ssl/record/ssl3_record.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c +index f158544789..69f1a64cb3 100644 +--- a/ssl/record/ssl3_record.c ++++ b/ssl/record/ssl3_record.c +@@ -1532,6 +1532,7 @@ int ssl3_cbc_copy_mac(unsigned char *out, + #if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; ++ char aux1, aux2, aux3, mask; + #else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; + #endif +@@ -1581,9 +1582,16 @@ int ssl3_cbc_copy_mac(unsigned char *out, + #if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) { +- /* in case cache-line is 32 bytes, touch second line */ +- ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; +- out[j++] = rotated_mac[rotate_offset++]; ++ /* ++ * in case cache-line is 32 bytes, ++ * load from both lines and select appropriately ++ */ ++ aux1 = rotated_mac[rotate_offset & ~32]; ++ aux2 = rotated_mac[rotate_offset | 32]; ++ mask = constant_time_eq_8(rotate_offset & ~32, rotate_offset); ++ aux3 = constant_time_select_8(mask, aux1, aux2); ++ out[j++] = aux3; ++ rotate_offset++; + rotate_offset &= constant_time_lt_s(rotate_offset, md_size); + } + #else +-- +2.17.1 + diff --git a/backport-Fix-memory-leak-in-X509V3_add1_i2d-when-flag-is-X509.patch b/backport-Fix-memory-leak-in-X509V3_add1_i2d-when-flag-is-X509.patch new file mode 100644 index 0000000000000000000000000000000000000000..a8b4d7e3b1c6bf9bdc8f3e2f59a51fec62df41c8 --- /dev/null +++ b/backport-Fix-memory-leak-in-X509V3_add1_i2d-when-flag-is-X509.patch @@ -0,0 +1,36 @@ +From c3efe5c96128d699f0884128ce905906bc28ed34 Mon Sep 17 00:00:00 2001 +From: Allan +Date: Thu, 7 Jul 2022 16:04:09 -0700 +Subject: [PATCH] Fix memory leak in X509V3_add1_i2d when flag is + X509V3_ADD_DELETE + +Fixes #18677 + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18698) + +(cherry picked from commit 4798e0680b112993815098ca21d7d68ff31ebc6e) +--- + crypto/x509v3/v3_lib.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c +index 97c1cbc20f..d7e7c9a5cb 100644 +--- a/crypto/x509v3/v3_lib.c ++++ b/crypto/x509v3/v3_lib.c +@@ -242,8 +242,10 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { +- if (!sk_X509_EXTENSION_delete(*x, extidx)) ++ extmp = sk_X509_EXTENSION_delete(*x, extidx); ++ if (extmp == NULL) + return -1; ++ X509_EXTENSION_free(extmp); + return 1; + } + } else { +-- +2.17.1 + diff --git a/backport-Fix-password_callback-to-handle-short-passwords.patch b/backport-Fix-password_callback-to-handle-short-passwords.patch new file mode 100644 index 0000000000000000000000000000000000000000..5eb5758b0c180805d8ec98442445a21718a4dc96 --- /dev/null +++ b/backport-Fix-password_callback-to-handle-short-passwords.patch @@ -0,0 +1,72 @@ +From f4942134815f95845706993c15ca7e4fd6e44627 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Fri, 7 Jan 2022 10:18:58 +0100 +Subject: [PATCH] Fix password_callback to handle short passwords + +Fixes #17426 + +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/17439) +--- + apps/apps.c | 8 ++++++-- + test/recipes/15-test_genrsa.t | 7 ++++++- + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/apps/apps.c b/apps/apps.c +index c06241abb9..531fbec551 100644 +--- a/apps/apps.c ++++ b/apps/apps.c +@@ -300,9 +300,13 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) + int ui_flags = 0; + const char *prompt_info = NULL; + char *prompt; ++ int pw_min_len = PW_MIN_LENGTH; + + if (cb_data != NULL && cb_data->prompt_info != NULL) + prompt_info = cb_data->prompt_info; ++ if (cb_data != NULL && cb_data->password != NULL ++ && *(const char*)cb_data->password != '\0') ++ pw_min_len = 1; + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (!prompt) { + BIO_printf(bio_err, "Out of memory\n"); +@@ -317,12 +321,12 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) + (void)UI_add_user_data(ui, cb_data); + + ok = UI_add_input_string(ui, prompt, ui_flags, buf, +- PW_MIN_LENGTH, bufsiz - 1); ++ pw_min_len, bufsiz - 1); + + if (ok >= 0 && verify) { + buff = app_malloc(bufsiz, "password buffer"); + ok = UI_add_verify_string(ui, prompt, ui_flags, buff, +- PW_MIN_LENGTH, bufsiz - 1, buf); ++ pw_min_len, bufsiz - 1, buf); + } + if (ok >= 0) + do { +diff --git a/test/recipes/15-test_genrsa.t b/test/recipes/15-test_genrsa.t +index e16a9a4042..c9bc6bdc8a 100644 +--- a/test/recipes/15-test_genrsa.t ++++ b/test/recipes/15-test_genrsa.t +@@ -16,7 +16,7 @@ use OpenSSL::Test::Utils; + + setup("test_genrsa"); + +-plan tests => 5; ++plan tests => 7; + + # We want to know that an absurdly small number of bits isn't support + is(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', '8'])), 0, "genrsa -3 8"); +@@ -52,3 +52,8 @@ ok(run(app([ 'openssl', 'genrsa', '-f4', '-out', 'genrsatest.pem', $good ])), + "genrsa -f4 $good"); + ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), + "rsa -check"); ++ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest.pem', '-out', 'genrsatest-enc.pem', ++ '-aes256', '-passout', 'pass:x' ])), ++ "rsa encrypt"); ++ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest-enc.pem', '-passin', 'pass:x' ])), ++ "rsa decrypt"); +-- +2.17.1 + diff --git a/backport-Fix-range_should_be_prefix-to-actually-return-the-co.patch b/backport-Fix-range_should_be_prefix-to-actually-return-the-co.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1235f4baf519ff184d4b09529d7bef4fae7896c --- /dev/null +++ b/backport-Fix-range_should_be_prefix-to-actually-return-the-co.patch @@ -0,0 +1,71 @@ +From a1d80edcf830739131e0567dc03b1e80b7988b1e Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 10 Jun 2022 15:58:58 +0100 +Subject: [PATCH] Fix range_should_be_prefix() to actually return the correct + result + +range_should_be_prefix() was misidentifying whether an IP address range +should in fact be represented as a prefix. This was due to a bug introduced +in commit 42d7d7dd which made this incorrect change: + +- OPENSSL_assert(memcmp(min, max, length) <= 0); ++ if (memcmp(min, max, length) <= 0) ++ return -1; + +This error leads to incorrect DER being encoded/accepted. + +Reported by Theo Buehler (@botovq) + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18524) + +(cherry picked from commit 30532e59f475e0066c030693e4d614311a9e0cae) +(cherry picked from commit 2c6550c6db9b1b69dc24f968b4ceb534edcf4841) +--- + crypto/x509v3/v3_addr.c | 14 ++++- + test/v3ext.c | 111 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 123 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c +index 4258dbc40c..32f77a2679 100644 +--- a/crypto/x509v3/v3_addr.c ++++ b/crypto/x509v3/v3_addr.c +@@ -13,6 +13,8 @@ + + #include + #include ++#include ++#include + + #include "internal/cryptlib.h" + #include +@@ -342,8 +344,13 @@ static int range_should_be_prefix(const unsigned char *min, + unsigned char mask; + int i, j; + +- if (memcmp(min, max, length) <= 0) +- return -1; ++ /* ++ * It is the responsibility of the caller to confirm min <= max. We don't ++ * use ossl_assert() here since we have no way of signalling an error from ++ * this function - so we just use a plain assert instead. ++ */ ++ assert(memcmp(min, max, length) <= 0); ++ + for (i = 0; i < length && min[i] == max[i]; i++) ; + for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; + if (i < j) +@@ -426,6 +433,9 @@ static int make_addressRange(IPAddressOrRange **result, + IPAddressOrRange *aor; + int i, prefixlen; + ++ if (memcmp(min, max, length) > 0) ++ return 0; ++ + if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) + return make_addressPrefix(result, min, prefixlen); + +-- +2.17.1 + diff --git a/backport-Fix-re-signing-certificates-with-different-key-sizes.patch b/backport-Fix-re-signing-certificates-with-different-key-sizes.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc15494d3b25a7ee28514f3b74387460aaa2aafe --- /dev/null +++ b/backport-Fix-re-signing-certificates-with-different-key-sizes.patch @@ -0,0 +1,131 @@ +From 952fab01bebb15a8408c6ac27b59c28c979f7d49 Mon Sep 17 00:00:00 2001 +From: Todd Short +Date: Wed, 20 Jul 2022 16:42:50 -0400 +Subject: [PATCH] Fix re-signing certificates with different key sizes + +PR #18129 broke the scenario of signing a certificate (not CSR) with +different-sized key. This works in 3.0, so port the fix from 3.0 +(which is to only update the issuer for a request). + +Partially undo #18129, but keep setting the issuer only for a CSR + +Create two certs (a and ca) then sign a with c (into b): +``` +openssl req -x509 -newkey rsa:2048 -keyout a-key.pem -out a-cert.pem -days 365 -nodes -subj /CN=a.example.com +openssl req -x509 -newkey rsa:4096 -keyout ${HERE}/ca-key.pem -out ${HERE}/ca-cert.pem -days 3650 -nodes -subj /CN=ca.example.com +openssl x509 -in a-cert.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial '1234567890' -preserve_dates -sha256 -out b-cert.pem +``` +The above succeeds in 1.1.1n and 3.0, fails in 1.1.1o (which includes #18129) +The issue in #16080 is also fixed. + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +Reviewed-by: Ben Kaduk +(Merged from https://github.com/openssl/openssl/pull/18836) +--- + apps/x509.c | 4 ++- + test/recipes/25-test_x509.t | 61 ++++++++++++++++++++++++++++++++++++- + 2 files changed, 63 insertions(+), 2 deletions(-) + +diff --git a/apps/x509.c b/apps/x509.c +index 67a70e7fea..8d4bf71a03 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -590,7 +590,7 @@ int x509_main(int argc, char **argv) + xca = load_cert(CAfile, CAformat, "CA Certificate"); + if (xca == NULL) + goto end; +- if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) ++ if (reqfile && !X509_set_issuer_name(x, X509_get_subject_name(xca))) + goto end; + } + +@@ -993,6 +993,8 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges + goto end; + } + ++ if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) ++ goto end; + if (!X509_set_serialNumber(x, bs)) + goto end; + +diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t +index f5ef0f9963..73548145c8 100644 +--- a/test/recipes/25-test_x509.t ++++ b/test/recipes/25-test_x509.t +@@ -15,7 +15,11 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; + + setup("test_x509"); + +-plan tests => 9; ++plan tests => 16; ++ ++# Prevent MSys2 filename munging for arguments that look like file paths but ++# aren't ++$ENV{MSYS2_ARG_CONV_EXCL} = "/CN="; + + require_ok(srctop_file('test','recipes','tconversion.pl')); + +@@ -46,4 +50,59 @@ subtest 'x509 -- second x.509 v3 certificate' => sub { + + subtest 'x509 -- pathlen' => sub { + ok(run(test(["v3ext", srctop_file("test/certs", "pathlen.pem")]))); ++}; ++ ++# extracts issuer from a -text formatted-output ++sub get_issuer { ++ my $f = shift(@_); ++ my $issuer = ""; ++ open my $fh, $f or die; ++ while (my $line = <$fh>) { ++ if ($line =~ /Issuer:/) { ++ $issuer = $line; ++ } ++ } ++ close $fh; ++ return $issuer; + } ++ ++# Tests for signing certs (broken in 1.1.1o) ++my $a_key = "a-key.pem"; ++my $a_cert = "a-cert.pem"; ++my $a2_cert = "a2-cert.pem"; ++my $ca_key = "ca-key.pem"; ++my $ca_cert = "ca-cert.pem"; ++my $cnf = srctop_file('apps', 'openssl.cnf'); ++ ++# Create cert A ++ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:2048", ++ "-config", $cnf, ++ "-keyout", $a_key, "-out", $a_cert, "-days", "365", ++ "-nodes", "-subj", "/CN=test.example.com"]))); ++# Create cert CA - note key size ++ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:4096", ++ "-config", $cnf, ++ "-keyout", $ca_key, "-out", $ca_cert, "-days", "3650", ++ "-nodes", "-subj", "/CN=ca.example.com"]))); ++# Sign cert A with CA (errors on 1.1.1o) ++ok(run(app(["openssl", "x509", "-in", $a_cert, "-CA", $ca_cert, ++ "-CAkey", $ca_key, "-set_serial", "1234567890", ++ "-preserve_dates", "-sha256", "-text", "-out", $a2_cert]))); ++# verify issuer is CA ++ok (get_issuer($a2_cert) =~ /CN = ca.example.com/); ++ ++# Tests for issue #16080 (fixed in 1.1.1o) ++my $b_key = "b-key.pem"; ++my $b_csr = "b-cert.csr"; ++my $b_cert = "b-cert.pem"; ++# Create the CSR ++ok(run(app(["openssl", "req", "-new", "-newkey", "rsa:4096", ++ "-keyout", $b_key, "-out", $b_csr, "-nodes", ++ "-config", $cnf, ++ "-subj", "/CN=b.example.com"]))); ++# Sign it - position of "-text" matters! ++ok(run(app(["openssl", "x509", "-req", "-text", "-CAcreateserial", ++ "-CA", $ca_cert, "-CAkey", $ca_key, ++ "-in", $b_csr, "-out", $b_cert]))); ++# Verify issuer is CA ++ok(get_issuer($b_cert) =~ /CN = ca.example.com/); +-- +2.17.1 + diff --git a/backport-Fix-strict-client-chain-check-with-TLS-1.3.patch b/backport-Fix-strict-client-chain-check-with-TLS-1.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..f13fb2a3f6146ec7e5f78c657e688bb2c27c7c5f --- /dev/null +++ b/backport-Fix-strict-client-chain-check-with-TLS-1.3.patch @@ -0,0 +1,54 @@ +From 3bd976551e549c030bdbd150c7aa8a1980cb00fe Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 29 Mar 2022 13:31:34 +0200 +Subject: [PATCH] Fix strict client chain check with TLS-1.3 + +When TLS-1.3 is used and the server does not send any CA names +the ca_dn will be NULL. sk_X509_NAME_num() returns -1 on null +argument. + +Reviewed-by: Todd Short +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/17986) + +(cherry picked from commit 89dd85430770d39cbfb15eb586c921958ca7687f) +--- + ssl/t1_lib.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index 4de4623a49..5fcb40eaff 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -2369,22 +2369,20 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, + + ca_dn = s->s3->tmp.peer_ca_names; + +- if (!sk_X509_NAME_num(ca_dn)) ++ if (ca_dn == NULL ++ || sk_X509_NAME_num(ca_dn) == 0 ++ || ssl_check_ca_name(ca_dn, x)) + rv |= CERT_PKEY_ISSUER_NAME; +- +- if (!(rv & CERT_PKEY_ISSUER_NAME)) { +- if (ssl_check_ca_name(ca_dn, x)) +- rv |= CERT_PKEY_ISSUER_NAME; +- } +- if (!(rv & CERT_PKEY_ISSUER_NAME)) { ++ else + for (i = 0; i < sk_X509_num(chain); i++) { + X509 *xtmp = sk_X509_value(chain, i); ++ + if (ssl_check_ca_name(ca_dn, xtmp)) { + rv |= CERT_PKEY_ISSUER_NAME; + break; + } + } +- } ++ + if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) + goto end; + } else +-- +2.17.1 + diff --git a/backport-Fix-test-case-for-a2i_IPADDRESS.patch b/backport-Fix-test-case-for-a2i_IPADDRESS.patch new file mode 100644 index 0000000000000000000000000000000000000000..6fb1f30c64d2e200089a5d3fd58edd03f7302f4b --- /dev/null +++ b/backport-Fix-test-case-for-a2i_IPADDRESS.patch @@ -0,0 +1,42 @@ +From c3b0279bda7bf4f0f81a3dba952698fa68a51639 Mon Sep 17 00:00:00 2001 +From: Amir Mohammadi +Date: Wed, 4 Aug 2021 09:44:29 +0430 +Subject: [PATCH] Fix test case for a2i_IPADDRESS + +(cherry picked from commit 9b887d5d5a8ef9aa1c3ce6e54a82ddcba25b9415) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + test/x509_internal_test.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/test/x509_internal_test.c b/test/x509_internal_test.c +index 3eec970352..63f350f74b 100644 +--- a/test/x509_internal_test.c ++++ b/test/x509_internal_test.c +@@ -61,7 +61,6 @@ typedef struct { + const char *ipasc; + const char *data; + int length; +- ASN1_OCTET_STRING ip; + } IP_TESTDATA; + + static IP_TESTDATA a2i_ipaddress_tests[] = { +@@ -81,8 +80,10 @@ static IP_TESTDATA a2i_ipaddress_tests[] = { + {"example.test", NULL, 0}, + {"", NULL, 0}, + ++ {"1.2.3.4 ", "\x01\x02\x03\x04", 4}, ++ {" 1.2.3.4", "\x01\x02\x03\x04", 4}, ++ {" 1.2.3.4 ", "\x01\x02\x03\x04", 4}, + {"1.2.3.4.example.test", NULL, 0}, +- {"1.2.3.4 ", NULL, 0}, + }; + + +-- +2.17.1 + diff --git a/backport-Fix-undefined-behaviour-in-EC_GROUP_new_from_ecparam.patch b/backport-Fix-undefined-behaviour-in-EC_GROUP_new_from_ecparam.patch new file mode 100644 index 0000000000000000000000000000000000000000..072a73798a89eb61ee526883f0c055b13035ebff --- /dev/null +++ b/backport-Fix-undefined-behaviour-in-EC_GROUP_new_from_ecparam.patch @@ -0,0 +1,41 @@ +From e4b84b7514e5cbcbfc80e31b4ce609c7584e14bb Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Fri, 20 May 2022 16:54:41 +0200 +Subject: [PATCH] Fix undefined behaviour in EC_GROUP_new_from_ecparameters + +This happens for instance with +fuzz/corpora/asn1/65cf44e85614c62f10cf3b7a7184c26293a19e4a +and causes the OPENSSL_malloc below to choke on the +zero length allocation request. + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18363) +--- + crypto/ec/ec_asn1.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c +index 4335b3da1a..ad9a54dc50 100644 +--- a/crypto/ec/ec_asn1.c ++++ b/crypto/ec/ec_asn1.c +@@ -751,6 +751,16 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) + + /* extract seed (optional) */ + if (params->curve->seed != NULL) { ++ /* ++ * This happens for instance with ++ * fuzz/corpora/asn1/65cf44e85614c62f10cf3b7a7184c26293a19e4a ++ * and causes the OPENSSL_malloc below to choke on the ++ * zero length allocation request. ++ */ ++ if (params->curve->seed->length == 0) { ++ ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); ++ goto err; ++ } + OPENSSL_free(ret->seed); + if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE); +-- +2.17.1 + diff --git a/backport-Fix-usage-of-SSLfatal.patch b/backport-Fix-usage-of-SSLfatal.patch new file mode 100644 index 0000000000000000000000000000000000000000..abc72ce6a1976aaf6548d741e03f7c93f8304122 --- /dev/null +++ b/backport-Fix-usage-of-SSLfatal.patch @@ -0,0 +1,36 @@ +From 3e8f70c30d84861fcd257a6e280dc49e104eb145 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 30 Mar 2022 14:49:24 +0100 +Subject: [PATCH] Fix usage of SSLfatal + +A cherry-pick from the master branch incorrectly introduced a usage of +3 argument SSLfatal. In 1.1.1 the function code is also required. + +Fixes #17999 + +Reviewed-by: Bernd Edlinger +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/18000) +--- + ssl/statem/statem_clnt.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c +index e3aba393f9..2bc5cf5ec3 100644 +--- a/ssl/statem/statem_clnt.c ++++ b/ssl/statem/statem_clnt.c +@@ -1423,7 +1423,8 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) + && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE + && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { + if (s->hello_retry_request != SSL_HRR_NONE) { +- SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); ++ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ++ SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + s->hello_retry_request = SSL_HRR_PENDING; +-- +2.17.1 + diff --git a/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch b/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5f70b4d29cd8fd50266d98e06dc803c51cede65 --- /dev/null +++ b/backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch @@ -0,0 +1,64 @@ +From 86945b10ccd84f685bd6215bbb00d1e700303e49 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 14 Jul 2022 21:41:48 +0200 +Subject: [PATCH] Fix verify_callback in the openssl s_client/s_server app + +We need to check that error cert is available before printing its data + +Reviewed-by: Tomas Mraz +Reviewed-by: David von Oheimb +Reviewed-by: Viktor Dukhovni +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18805) + +(cherry picked from commit fad0f80eff188ef938fed614245a56ed56110deb) +--- + apps/s_cb.c | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/apps/s_cb.c b/apps/s_cb.c +index d066a423de..a4ff978908 100644 +--- a/apps/s_cb.c ++++ b/apps/s_cb.c +@@ -74,22 +74,28 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) + } + switch (err) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: +- BIO_puts(bio_err, "issuer= "); +- X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), +- 0, get_nameopt()); +- BIO_puts(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_puts(bio_err, "issuer= "); ++ X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), ++ 0, get_nameopt()); ++ BIO_puts(bio_err, "\n"); ++ } + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: +- BIO_printf(bio_err, "notBefore="); +- ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert)); +- BIO_printf(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_printf(bio_err, "notBefore="); ++ ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert)); ++ BIO_printf(bio_err, "\n"); ++ } + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: +- BIO_printf(bio_err, "notAfter="); +- ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert)); +- BIO_printf(bio_err, "\n"); ++ if (err_cert != NULL) { ++ BIO_printf(bio_err, "notAfter="); ++ ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert)); ++ BIO_printf(bio_err, "\n"); ++ } + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + if (!verify_args.quiet) +-- +2.17.1 + diff --git a/backport-Fixes-segfault-occurrence-in-PEM_write.patch b/backport-Fixes-segfault-occurrence-in-PEM_write.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a3888b4cff8e72e23706ee446adee6454b25461 --- /dev/null +++ b/backport-Fixes-segfault-occurrence-in-PEM_write.patch @@ -0,0 +1,37 @@ +From 3b9082c844913d3a0efada9fac0bd2924ce1a8f2 Mon Sep 17 00:00:00 2001 +From: valdaarhun +Date: Mon, 25 Jul 2022 18:49:19 +0530 +Subject: [PATCH] Fixes segfault occurrence in PEM_write() + +Checks if header is NULL or not before calling strlen(). + +CLA: trivial + +Fixes #18825 + +Reviewed-by: Tomas Mraz +Reviewed-by: Ben Kaduk +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/18865) + +(cherry picked from commit 205957405d08ef199e6ab654e333a627bbca9ccc) +--- + crypto/pem/pem_lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c +index 2de093595d..c2cf407931 100644 +--- a/crypto/pem/pem_lib.c ++++ b/crypto/pem/pem_lib.c +@@ -621,7 +621,7 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + +- i = strlen(header); ++ i = header != NULL ? strlen(header) : 0; + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + goto err; +-- +2.17.1 + diff --git a/backport-Make-the-DRBG-seed-propagation-thread-safe.patch b/backport-Make-the-DRBG-seed-propagation-thread-safe.patch new file mode 100644 index 0000000000000000000000000000000000000000..6ba2678781ff6881d8796dcbc981b68bcc667c7f --- /dev/null +++ b/backport-Make-the-DRBG-seed-propagation-thread-safe.patch @@ -0,0 +1,77 @@ +From 17098c116d68b3a01fcb688487dccdc0c10b8f63 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Sat, 23 Oct 2021 11:58:27 +0200 +Subject: [PATCH] Make the DRBG seed propagation thread safe + +Currently there is a race possible because the reseed_counter +of the master drbg may be incremented after the get_entropy call. +Therefore access the parent's reseed_counter while still holding +the rand_drbg_lock. + +This improves commit 958fec77928a28350f6af252ac5e8d0e6e081faa + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/16900) +--- + crypto/rand/drbg_lib.c | 18 ++++-------------- + crypto/rand/rand_lib.c | 6 +++++- + 2 files changed, 9 insertions(+), 15 deletions(-) + +diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c +index 8c7c28c970..0ba20ca326 100644 +--- a/crypto/rand/drbg_lib.c ++++ b/crypto/rand/drbg_lib.c +@@ -354,13 +354,8 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, + drbg->state = DRBG_READY; + drbg->generate_counter = 1; + drbg->reseed_time = time(NULL); +- if (drbg->enable_reseed_propagation) { +- if (drbg->parent == NULL) +- tsan_counter(&drbg->reseed_counter); +- else +- tsan_store(&drbg->reseed_counter, +- tsan_load(&drbg->parent->reseed_counter)); +- } ++ if (drbg->enable_reseed_propagation && drbg->parent == NULL) ++ tsan_counter(&drbg->reseed_counter); + + end: + if (entropy != NULL && drbg->cleanup_entropy != NULL) +@@ -444,13 +439,8 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, + drbg->state = DRBG_READY; + drbg->generate_counter = 1; + drbg->reseed_time = time(NULL); +- if (drbg->enable_reseed_propagation) { +- if (drbg->parent == NULL) +- tsan_counter(&drbg->reseed_counter); +- else +- tsan_store(&drbg->reseed_counter, +- tsan_load(&drbg->parent->reseed_counter)); +- } ++ if (drbg->enable_reseed_propagation && drbg->parent == NULL) ++ tsan_counter(&drbg->reseed_counter); + + end: + if (entropy != NULL && drbg->cleanup_entropy != NULL) +diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c +index 5c72fad8ca..545ab46315 100644 +--- a/crypto/rand/rand_lib.c ++++ b/crypto/rand/rand_lib.c +@@ -172,8 +172,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, + if (RAND_DRBG_generate(drbg->parent, + buffer, bytes_needed, + prediction_resistance, +- (unsigned char *)&drbg, sizeof(drbg)) != 0) ++ (unsigned char *)&drbg, sizeof(drbg)) != 0) { + bytes = bytes_needed; ++ if (drbg->enable_reseed_propagation) ++ tsan_store(&drbg->reseed_counter, ++ tsan_load(&drbg->parent->reseed_counter)); ++ } + rand_drbg_unlock(drbg->parent); + + rand_pool_add_end(pool, bytes, 8 * bytes); +-- +2.17.1 + diff --git a/backport-Moving-notify-check-after-the-no-time-check.patch b/backport-Moving-notify-check-after-the-no-time-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f4dbf5f4bffbab987d2a453d9e091ed908f7a5f --- /dev/null +++ b/backport-Moving-notify-check-after-the-no-time-check.patch @@ -0,0 +1,40 @@ +From 9eae491721209f302a9a475bffd271370e8bcb8f Mon Sep 17 00:00:00 2001 +From: Ryan Kelley +Date: Tue, 16 Aug 2022 05:28:50 +0000 +Subject: [PATCH] Moving notify check after the no time check + +CLA: trivial + +Reviewed-by: Tomas Mraz +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/19007) + +(cherry picked from commit c92c3dfb99485eb2cfb840e92bd0ece8cdd72d0c) +--- + crypto/x509/x509_vfy.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c +index b18489f67f..925fbb5412 100644 +--- a/crypto/x509/x509_vfy.c ++++ b/crypto/x509/x509_vfy.c +@@ -973,14 +973,14 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) + time_t *ptime; + int i; + +- if (notify) +- ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return 1; + else + ptime = NULL; ++ if (notify) ++ ctx->current_crl = crl; + + i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime); + if (i == 0) { +-- +2.17.1 + diff --git a/backport-Set-protocol-in-init_client.patch b/backport-Set-protocol-in-init_client.patch new file mode 100644 index 0000000000000000000000000000000000000000..e2b38410be92e517cb5f2ecc9b7964a15388b167 --- /dev/null +++ b/backport-Set-protocol-in-init_client.patch @@ -0,0 +1,33 @@ +From 3aeed22c593ae036c2503ac07276768c82fe5782 Mon Sep 17 00:00:00 2001 +From: Todd Short +Date: Tue, 8 Mar 2022 09:36:43 -0500 +Subject: [PATCH] Set protocol in init_client() + +If TCP is being used, protocol = 0 is passed to init_client(), then +protocol == IPPROTO_TCP fails when attempting to set BIO_SOCK_NODELAY. + +Reviewed-by: Tomas Mraz +Reviewed-by: Tim Hudson +(Merged from https://github.com/openssl/openssl/pull/17838) + +(cherry picked from commit 54b6755702309487ea860e1cc3e60ccef4cf7878) +--- + apps/s_socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/apps/s_socket.c b/apps/s_socket.c +index aee366d5f4..a518d56200 100644 +--- a/apps/s_socket.c ++++ b/apps/s_socket.c +@@ -147,7 +147,7 @@ int init_client(int *sock, const char *host, const char *port, + #endif + + if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), +- protocol == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) { ++ BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) { + BIO_closesocket(*sock); + *sock = INVALID_SOCKET; + continue; +-- +2.17.1 + diff --git a/backport-Test-case-for-a2i_IPADDRESS.patch b/backport-Test-case-for-a2i_IPADDRESS.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0c1a6a399afd18be5f74a019ac773e87bf6d9ee --- /dev/null +++ b/backport-Test-case-for-a2i_IPADDRESS.patch @@ -0,0 +1,91 @@ +From bd41b84bede84c1a5716be4eafddd1dd052faa72 Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Sat, 15 Aug 2020 20:01:49 +0200 +Subject: [PATCH] Test case for a2i_IPADDRESS + +Unit test to show that a2i_IPADDRESS("1.2.3.4.test.example") ignores +trailing data. + +See: https://github.com/openssl/openssl/issues/12649 +See: https://bugs.python.org/issue41556 + +(cherry picked from commit 1a9411a30b09a98498366979a1ea4898f70f6d19) + +Reviewed-by: Tomas Mraz +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Hugo Landau +(Merged from https://github.com/openssl/openssl/pull/18847) +--- + test/x509_internal_test.c | 54 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/test/x509_internal_test.c b/test/x509_internal_test.c +index d2f41d7085..3eec970352 100644 +--- a/test/x509_internal_test.c ++++ b/test/x509_internal_test.c +@@ -57,8 +57,62 @@ static int test_standard_exts(void) + return good; + } + ++typedef struct { ++ const char *ipasc; ++ const char *data; ++ int length; ++ ASN1_OCTET_STRING ip; ++} IP_TESTDATA; ++ ++static IP_TESTDATA a2i_ipaddress_tests[] = { ++ {"127.0.0.1", "\x7f\x00\x00\x01", 4}, ++ {"1.2.3.4", "\x01\x02\x03\x04", 4}, ++ {"1.2.3.255", "\x01\x02\x03\xff", 4}, ++ {"1.2.3", NULL, 0}, ++ {"1.2.3 .4", NULL, 0}, ++ ++ {"::1", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16}, ++ {"1:1:1:1:1:1:1:1", "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 16}, ++ {"2001:db8::ff00:42:8329", "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00\x42\x83\x29", 16}, ++ {"1:1:1:1:1:1:1:1.test", NULL, 0}, ++ {":::1", NULL, 0}, ++ {"2001::123g", NULL, 0}, ++ ++ {"example.test", NULL, 0}, ++ {"", NULL, 0}, ++ ++ {"1.2.3.4.example.test", NULL, 0}, ++ {"1.2.3.4 ", NULL, 0}, ++}; ++ ++ ++static int test_a2i_ipaddress(int idx) ++{ ++ int good = 1; ++ ASN1_OCTET_STRING *ip; ++ int len = a2i_ipaddress_tests[idx].length; ++ ++ ip = a2i_IPADDRESS(a2i_ipaddress_tests[idx].ipasc); ++ if (len == 0) { ++ if (!TEST_ptr_null(ip)) { ++ good = 0; ++ TEST_note("'%s' should not be parsed as IP address", a2i_ipaddress_tests[idx].ipasc); ++ } ++ } else { ++ if (!TEST_ptr(ip) ++ || !TEST_int_eq(ASN1_STRING_length(ip), len) ++ || !TEST_mem_eq(ASN1_STRING_get0_data(ip), len, ++ a2i_ipaddress_tests[idx].data, len)) { ++ good = 0; ++ } ++ } ++ ASN1_OCTET_STRING_free(ip); ++ return good; ++} ++ + int setup_tests(void) + { + ADD_TEST(test_standard_exts); ++ ADD_ALL_TESTS(test_a2i_ipaddress, OSSL_NELEM(a2i_ipaddress_tests)); + return 1; + } +-- +2.17.1 + diff --git a/backport-Test-processing-of-a-duplicated-HRR.patch b/backport-Test-processing-of-a-duplicated-HRR.patch new file mode 100644 index 0000000000000000000000000000000000000000..2db37448c7e06a86d87122e8a3a76ec94c827cc5 --- /dev/null +++ b/backport-Test-processing-of-a-duplicated-HRR.patch @@ -0,0 +1,100 @@ +From f29ec6563ddf81db46c464d14f2bb29a3fa5592f Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 22 Mar 2022 16:33:52 +0100 +Subject: [PATCH] Test processing of a duplicated HRR + +Reviewed-by: Todd Short +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/17936) + +(cherry picked from commit db44b55aaa42141921217183667800425227b658) +--- + test/recipes/70-test_tls13hrr.t | 51 +++++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) + +diff --git a/test/recipes/70-test_tls13hrr.t b/test/recipes/70-test_tls13hrr.t +index e0b47ed359..411e749971 100644 +--- a/test/recipes/70-test_tls13hrr.t ++++ b/test/recipes/70-test_tls13hrr.t +@@ -37,7 +37,8 @@ my $proxy = TLSProxy::Proxy->new( + + use constant { + CHANGE_HRR_CIPHERSUITE => 0, +- CHANGE_CH1_CIPHERSUITE => 1 ++ CHANGE_CH1_CIPHERSUITE => 1, ++ DUPLICATE_HRR => 2 + }; + + #Test 1: A client should fail if the server changes the ciphersuite between the +@@ -46,7 +47,7 @@ $proxy->filter(\&hrr_filter); + $proxy->serverflags("-curves P-256"); + my $testtype = CHANGE_HRR_CIPHERSUITE; + $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; +-plan tests => 2; ++plan tests => 3; + ok(TLSProxy::Message->fail(), "Server ciphersuite changes"); + + #Test 2: It is an error if the client changes the offered ciphersuites so that +@@ -58,6 +59,19 @@ $testtype = CHANGE_CH1_CIPHERSUITE; + $proxy->start(); + ok(TLSProxy::Message->fail(), "Client ciphersuite changes"); + ++#Test 3: A client should fail with unexpected_message alert if the server ++# sends more than 1 HRR ++my $fatal_alert = 0; ++$proxy->clear(); ++if (disabled("ec")) { ++ $proxy->serverflags("-curves ffdhe3072"); ++} else { ++ $proxy->serverflags("-curves P-256"); ++} ++$testtype = DUPLICATE_HRR; ++$proxy->start(); ++ok($fatal_alert, "Server duplicated HRR"); ++ + sub hrr_filter + { + my $proxy = shift; +@@ -78,6 +92,39 @@ sub hrr_filter + return; + } + ++ if ($testtype == DUPLICATE_HRR) { ++ # We're only interested in the HRR ++ # and the unexpected_message alert from client ++ if ($proxy->flight == 4) { ++ $fatal_alert = 1 ++ if @{$proxy->record_list}[-1]->is_fatal_alert(0) == 10; ++ return; ++ } ++ if ($proxy->flight != 3) { ++ return; ++ } ++ ++ # Find ServerHello record (HRR actually) and insert after that ++ my $i; ++ for ($i = 0; ${$proxy->record_list}[$i]->flight() < 1; $i++) { ++ next; ++ } ++ my $hrr_record = ${$proxy->record_list}[$i]; ++ my $dup_hrr = TLSProxy::Record->new(3, ++ $hrr_record->content_type(), ++ $hrr_record->version(), ++ $hrr_record->len(), ++ $hrr_record->sslv2(), ++ $hrr_record->len_real(), ++ $hrr_record->decrypt_len(), ++ $hrr_record->data(), ++ $hrr_record->decrypt_data()); ++ ++ $i++; ++ splice @{$proxy->record_list}, $i, 0, $dup_hrr; ++ return; ++ } ++ + # CHANGE_CH1_CIPHERSUITE + if ($proxy->flight != 0) { + return; +-- +2.17.1 + diff --git a/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch b/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch new file mode 100644 index 0000000000000000000000000000000000000000..685668168c21b59e86537cdedfeb697cdbf2a08d --- /dev/null +++ b/backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch @@ -0,0 +1,183 @@ +From d87e99df3162b2d56b8d44907fde88b67d7e3900 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Mon, 25 Jul 2022 12:39:52 +0100 +Subject: [PATCH] Test that swapping the first app data record with Finished + msg works + +If the first app data record arrives before the Finished message we should +be able to buffer it and move on to the Finished message. + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18976) +--- + test/dtlstest.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ + test/ssltestlib.c | 33 ++++++++++++++++++ + test/ssltestlib.h | 1 + + 3 files changed, 122 insertions(+) + +diff --git a/test/dtlstest.c b/test/dtlstest.c +index 1d7b105fb6..f5c9dcfcd8 100644 +--- a/test/dtlstest.c ++++ b/test/dtlstest.c +@@ -328,6 +328,93 @@ static int test_dtls_duplicate_records(void) + return testresult; + } + ++/* ++ * Test that swapping an app data record so that it is received before the ++ * Finished message still works. ++ */ ++static int test_swap_app_data(void) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *sssl = NULL, *cssl = NULL; ++ int testresult = 0; ++ BIO *bio; ++ char msg[] = { 0x00, 0x01, 0x02, 0x03 }; ++ char buf[10]; ++ ++ if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), ++ DTLS_client_method(), ++ DTLS1_VERSION, 0, ++ &sctx, &cctx, cert, privkey))) ++ return 0; ++ ++#ifndef OPENSSL_NO_DTLS1_2 ++ if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA"))) ++ goto end; ++#else ++ /* Default sigalgs are SHA1 based in pkts); ++ ++ /* We need at least 2 packets to be able to swap them */ ++ if (numpkts <= 1) ++ return 0; ++ ++ /* Get the penultimate packet */ ++ thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 2); ++ if (thispkt == NULL) ++ return 0; ++ ++ if (sk_MEMPACKET_delete(ctx->pkts, numpkts - 2) != thispkt) ++ return 0; ++ ++ /* Re-add it to the end of the list */ ++ thispkt->num++; ++ if (sk_MEMPACKET_insert(ctx->pkts, thispkt, numpkts - 1) <= 0) ++ return 0; ++ ++ /* We also have to adjust the packet number of the other packet */ ++ thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 2); ++ if (thispkt == NULL) ++ return 0; ++ thispkt->num--; ++ ++ return 1; ++} ++ + int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum, + int type) + { +diff --git a/test/ssltestlib.h b/test/ssltestlib.h +index 17b278219a..b47004f62e 100644 +--- a/test/ssltestlib.h ++++ b/test/ssltestlib.h +@@ -46,6 +46,7 @@ void bio_s_always_retry_free(void); + #define MEMPACKET_CTRL_GET_DROP_REC (3 << 15) + #define MEMPACKET_CTRL_SET_DUPLICATE_REC (4 << 15) + ++int mempacket_swap_recent(BIO *bio); + int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum, + int type); + +-- +2.17.1 + diff --git a/backport-X509-x509_req.c-Set-modified-flag-when-X509_req_info.patch b/backport-X509-x509_req.c-Set-modified-flag-when-X509_req_info.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac2e0f13c2c503665ce0623afae47b0ddc3679de --- /dev/null +++ b/backport-X509-x509_req.c-Set-modified-flag-when-X509_req_info.patch @@ -0,0 +1,111 @@ +From 002cf9a68e20700388326c92b0c9ec8630b5c5d2 Mon Sep 17 00:00:00 2001 +From: Gibeom Gwon +Date: Sat, 27 Aug 2022 22:04:38 +0900 +Subject: [PATCH] X509 x509_req.c: Set 'modified' flag when X509_req_info_st + member data updated + +We need to reencode X509_req_info_st if member data updated. + +Reviewed-by: Tomas Mraz +Reviewed-by: David von Oheimb +(Merged from https://github.com/openssl/openssl/pull/18879) +--- + crypto/x509/x509_req.c | 40 ++++++++++++++++++++++++---------------- + crypto/x509/x_all.c | 2 ++ + 2 files changed, 26 insertions(+), 16 deletions(-) + +diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c +index a69f9a723d..1be47174ac 100644 +--- a/crypto/x509/x509_req.c ++++ b/crypto/x509/x509_req.c +@@ -229,44 +229,52 @@ X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) + + X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) + { +- return X509at_delete_attr(req->req_info.attributes, loc); ++ X509_ATTRIBUTE *attr = X509at_delete_attr(req->req_info.attributes, loc); ++ ++ if (attr != NULL) ++ req->req_info.enc.modified = 1; ++ return attr; + } + + int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) + { +- if (X509at_add1_attr(&req->req_info.attributes, attr)) +- return 1; +- return 0; ++ if (!X509at_add1_attr(&req->req_info.attributes, attr)) ++ return 0; ++ req->req_info.enc.modified = 1; ++ return 1; + } + + int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) + { +- if (X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, +- type, bytes, len)) +- return 1; +- return 0; ++ if (!X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, ++ type, bytes, len)) ++ return 0; ++ req->req_info.enc.modified = 1; ++ return 1; + } + + int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len) + { +- if (X509at_add1_attr_by_NID(&req->req_info.attributes, nid, +- type, bytes, len)) +- return 1; +- return 0; ++ if (!X509at_add1_attr_by_NID(&req->req_info.attributes, nid, ++ type, bytes, len)) ++ return 0; ++ req->req_info.enc.modified = 1; ++ return 1; + } + + int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len) + { +- if (X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, +- type, bytes, len)) +- return 1; +- return 0; ++ if (!X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, ++ type, bytes, len)) ++ return 0; ++ req->req_info.enc.modified = 1; ++ return 1; + } + + long X509_REQ_get_version(const X509_REQ *req) +diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c +index a4e9cdaee8..ae061f234c 100644 +--- a/crypto/x509/x_all.c ++++ b/crypto/x509/x_all.c +@@ -65,12 +65,14 @@ int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) + + int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) + { ++ x->req_info.enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL, + x->signature, &x->req_info, pkey, md)); + } + + int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) + { ++ x->req_info.enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), + &x->sig_alg, NULL, x->signature, &x->req_info, + ctx); +-- +2.17.1 + diff --git a/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch b/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch new file mode 100644 index 0000000000000000000000000000000000000000..1bc0efd209ef1bbf5da015b845a66b53ff4aef7f --- /dev/null +++ b/backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch @@ -0,0 +1,32 @@ +From 0b755cdfb52ff51830aa004799e1f78548423c00 Mon Sep 17 00:00:00 2001 +From: "Dr. David von Oheimb" +Date: Fri, 8 Jan 2021 08:27:17 +0100 +Subject: [PATCH] X509_REQ_get_extensions(): Return empty stack if no + extensions found + +Reviewed-by: Tomas Mraz +Reviewed-by: Todd Short +Reviewed-by: David von Oheimb +(Merged from https://github.com/openssl/openssl/pull/18926) +--- + crypto/x509/x509_req.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c +index dd674926dd..a69f9a723d 100644 +--- a/crypto/x509/x509_req.c ++++ b/crypto/x509/x509_req.c +@@ -167,7 +167,9 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) + ext = X509_ATTRIBUTE_get0_type(attr, 0); + break; + } +- if (!ext || (ext->type != V_ASN1_SEQUENCE)) ++ if (ext == NULL) /* no extensions is not an error */ ++ return sk_X509_EXTENSION_new_null(); ++ if (ext->type != V_ASN1_SEQUENCE) + return NULL; + p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *) +-- +2.17.1 + diff --git a/backport-crypto-x509-v3_utl.c-Add-missing-check-for-OPENSSL_s.patch b/backport-crypto-x509-v3_utl.c-Add-missing-check-for-OPENSSL_s.patch new file mode 100644 index 0000000000000000000000000000000000000000..e4630573b1578adc2e1c6d05dfe2fdbcb823ea3f --- /dev/null +++ b/backport-crypto-x509-v3_utl.c-Add-missing-check-for-OPENSSL_s.patch @@ -0,0 +1,58 @@ +From 999cce6ea7393e1daa40e9994064b2955b24a831 Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Mon, 21 Feb 2022 09:51:54 +0800 +Subject: [PATCH] crypto/x509/v3_utl.c: Add missing check for OPENSSL_strndup + +Since the potential failure of memory allocation, it +should be better to check the return value of the +OPENSSL_strndup(), like x509v3_add_len_value(). +And following the comment of 'if (astrlen < 0)', +return -1 if fails. + +Signed-off-by: Jiasheng Jiang + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/17737) + +(cherry picked from commit 366a16263959c0b6599f0b9ec18124d75560c6ef) +--- + crypto/x509v3/v3_utl.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c +index f41c699b5a..40d8f31554 100644 +--- a/crypto/x509v3/v3_utl.c ++++ b/crypto/x509v3/v3_utl.c +@@ -828,8 +828,11 @@ static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal, + rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); + else if (a->length == (int)blen && !memcmp(a->data, b, blen)) + rv = 1; +- if (rv > 0 && peername) ++ if (rv > 0 && peername != NULL) { + *peername = OPENSSL_strndup((char *)a->data, a->length); ++ if (*peername == NULL) ++ return -1; ++ } + } else { + int astrlen; + unsigned char *astr; +@@ -842,8 +845,13 @@ static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal, + return -1; + } + rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); +- if (rv > 0 && peername) ++ if (rv > 0 && peername != NULL) { + *peername = OPENSSL_strndup((char *)astr, astrlen); ++ if (*peername == NULL) { ++ OPENSSL_free(astr); ++ return -1; ++ } ++ } + OPENSSL_free(astr); + } + return rv; +-- +2.17.1 + diff --git a/backport-ssl_cipher_process_rulestr-don-t-read-outside-rule_s.patch b/backport-ssl_cipher_process_rulestr-don-t-read-outside-rule_s.patch new file mode 100644 index 0000000000000000000000000000000000000000..7cfa6ef9edceaff5aac3e027a4e77e6db0884f38 --- /dev/null +++ b/backport-ssl_cipher_process_rulestr-don-t-read-outside-rule_s.patch @@ -0,0 +1,40 @@ +From 9b3219ba544db82cdad3058b9872058739559944 Mon Sep 17 00:00:00 2001 +From: "Todd C. Miller" +Date: Mon, 24 Oct 2022 08:00:48 -0600 +Subject: [PATCH] ssl_cipher_process_rulestr: don't read outside rule_str + buffer + +If rule_str ended in a "-", "l" was incremented one byte past the +end of the buffer. This resulted in an out-of-bounds read when "l" +is dereferenced at the end of the loop. It is safest to just return +early in this case since the condition occurs inside a nested loop. + +CLA: trivial + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/19166) + +(cherry picked from commit 428511ca66670e169a0e1b12e7540714b0be4cf8) +--- + ssl/ssl_ciph.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index 55f919fcd5..62d0a58b22 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -1026,9 +1026,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); +- retval = found = 0; +- l++; +- break; ++ return 0; + } + + if (rule == CIPHER_SPECIAL) { +-- +2.17.1 + diff --git a/backport-ticket_lifetime_hint-may-exceed-1-week-in-TLSv1.3.patch b/backport-ticket_lifetime_hint-may-exceed-1-week-in-TLSv1.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..e437535db8c22fe6b53ec47e6e50da3919c147a8 --- /dev/null +++ b/backport-ticket_lifetime_hint-may-exceed-1-week-in-TLSv1.3.patch @@ -0,0 +1,156 @@ +From 79dbd85fe27ebabc278417af64ab8e3eb43d2d40 Mon Sep 17 00:00:00 2001 +From: Todd Short +Date: Wed, 23 Mar 2022 18:55:10 -0400 +Subject: [PATCH] ticket_lifetime_hint may exceed 1 week in TLSv1.3 + +For TLSv1.3, limit ticket lifetime hint to 1 week per RFC8446 + +Fixes #17948 + +Reviewed-by: Tomas Mraz +Reviewed-by: Tim Hudson +(Merged from https://github.com/openssl/openssl/pull/17952) + +(cherry picked from commit 0089cc7f9d42f6e39872161199fb8b6a99da2492) +--- + doc/man3/SSL_CTX_set_timeout.pod | 10 ++++++ + ssl/statem/statem_srvr.c | 21 ++++++++---- + test/sslapitest.c | 59 ++++++++++++++++++++++++++++++++ + 3 files changed, 84 insertions(+), 6 deletions(-) + +diff --git a/doc/man3/SSL_CTX_set_timeout.pod b/doc/man3/SSL_CTX_set_timeout.pod +index c32585e45f..54592654ff 100644 +--- a/doc/man3/SSL_CTX_set_timeout.pod ++++ b/doc/man3/SSL_CTX_set_timeout.pod +@@ -42,6 +42,16 @@ basis, see L. + All currently supported protocols have the same default timeout value + of 300 seconds. + ++This timeout value is used as the ticket lifetime hint for stateless session ++tickets. It is also used as the timeout value within the ticket itself. ++ ++For TLSv1.3, RFC8446 limits transmission of this value to 1 week (604800 ++seconds). ++ ++For TLSv1.2, tickets generated during an initial handshake use the value ++as specified. Tickets generated during a resumed handshake have a value ++of 0 for the ticket lifetime hint. ++ + =head1 RETURN VALUES + + SSL_CTX_set_timeout() returns the previously set timeout value. +diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c +index d701c46b43..79cfd1d835 100644 +--- a/ssl/statem/statem_srvr.c ++++ b/ssl/statem/statem_srvr.c +@@ -3820,15 +3820,24 @@ int tls_construct_server_certificate(SSL *s, WPACKET *pkt) + static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, + unsigned char *tick_nonce) + { ++ uint32_t timeout = (uint32_t)s->session->timeout; ++ + /* +- * Ticket lifetime hint: For TLSv1.2 this is advisory only and we leave this +- * unspecified for resumed session (for simplicity). ++ * Ticket lifetime hint: + * In TLSv1.3 we reset the "time" field above, and always specify the +- * timeout. ++ * timeout, limited to a 1 week period per RFC8446. ++ * For TLSv1.2 this is advisory only and we leave this unspecified for ++ * resumed session (for simplicity). + */ +- if (!WPACKET_put_bytes_u32(pkt, +- (s->hit && !SSL_IS_TLS13(s)) +- ? 0 : s->session->timeout)) { ++#define ONE_WEEK_SEC (7 * 24 * 60 * 60) ++ ++ if (SSL_IS_TLS13(s)) { ++ if (s->session->timeout > ONE_WEEK_SEC) ++ timeout = ONE_WEEK_SEC; ++ } else if (s->hit) ++ timeout = 0; ++ ++ if (!WPACKET_put_bytes_u32(pkt, timeout)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CREATE_TICKET_PREQUEL, + ERR_R_INTERNAL_ERROR); + return 0; +diff --git a/test/sslapitest.c b/test/sslapitest.c +index 21322ceec5..09a732f577 100644 +--- a/test/sslapitest.c ++++ b/test/sslapitest.c +@@ -6734,6 +6734,64 @@ end: + SSL_CTX_free(cctx); + return testresult; + } ++ ++/* ++ * Test that the lifetime hint of a TLSv1.3 ticket is no more than 1 week ++ * 0 = TLSv1.2 ++ * 1 = TLSv1.3 ++ */ ++static int test_ticket_lifetime(int idx) ++{ ++ SSL_CTX *cctx = NULL, *sctx = NULL; ++ SSL *clientssl = NULL, *serverssl = NULL; ++ int testresult = 0; ++ int version = TLS1_3_VERSION; ++ ++#define ONE_WEEK_SEC (7 * 24 * 60 * 60) ++#define TWO_WEEK_SEC (2 * ONE_WEEK_SEC) ++ ++ if (idx == 0) { ++ version = TLS1_2_VERSION; ++ } ++ ++ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), ++ TLS_client_method(), version, version, ++ &sctx, &cctx, cert, privkey))) ++ goto end; ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, ++ &clientssl, NULL, NULL))) ++ goto end; ++ ++ /* ++ * Set the timeout to be more than 1 week ++ * make sure the returned value is the default ++ */ ++ if (!TEST_long_eq(SSL_CTX_set_timeout(sctx, TWO_WEEK_SEC), ++ SSL_get_default_timeout(serverssl))) ++ goto end; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) ++ goto end; ++ ++ if (idx == 0) { ++ /* TLSv1.2 uses the set value */ ++ if (!TEST_ulong_eq(SSL_SESSION_get_ticket_lifetime_hint(SSL_get_session(clientssl)), TWO_WEEK_SEC)) ++ goto end; ++ } else { ++ /* TLSv1.3 uses the limited value */ ++ if (!TEST_ulong_le(SSL_SESSION_get_ticket_lifetime_hint(SSL_get_session(clientssl)), ONE_WEEK_SEC)) ++ goto end; ++ } ++ testresult = 1; ++ ++end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ return testresult; ++} + #endif + /* + * Test that setting an ALPN does not violate RFC +@@ -6973,6 +7031,7 @@ int setup_tests(void) + #endif + #ifndef OPENSSL_NO_TLS1_3 + ADD_TEST(test_sni_tls13); ++ ADD_ALL_TESTS(test_ticket_lifetime, 2); + #endif + ADD_TEST(test_set_alpn); + ADD_TEST(test_inherit_verify_param); +-- +2.17.1 + diff --git a/backport-tls_process_server_hello-Disallow-repeated-HRR.patch b/backport-tls_process_server_hello-Disallow-repeated-HRR.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c9576c706dcb8f24729e3799768d4069426c4fc --- /dev/null +++ b/backport-tls_process_server_hello-Disallow-repeated-HRR.patch @@ -0,0 +1,36 @@ +From fb67978a9eb076b23ddf17f6b95f697ed526c584 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 22 Mar 2022 12:34:07 +0100 +Subject: [PATCH] tls_process_server_hello: Disallow repeated HRR + +Repeated HRR must be rejected. + +Fixes #17934 + +Reviewed-by: Todd Short +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/17936) + +(cherry picked from commit d204a50b898435fbf937316d5693008cebf62eef) +--- + ssl/statem/statem_clnt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c +index d1a3969812..e3aba393f9 100644 +--- a/ssl/statem/statem_clnt.c ++++ b/ssl/statem/statem_clnt.c +@@ -1422,6 +1422,10 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) + && sversion == TLS1_2_VERSION + && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE + && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { ++ if (s->hello_retry_request != SSL_HRR_NONE) { ++ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); ++ goto err; ++ } + s->hello_retry_request = SSL_HRR_PENDING; + hrr = 1; + if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) { +-- +2.17.1 + diff --git a/backport-v3_sxnet-add-a-check-for-the-return-of-i2s_ASN1_INTE.patch b/backport-v3_sxnet-add-a-check-for-the-return-of-i2s_ASN1_INTE.patch new file mode 100644 index 0000000000000000000000000000000000000000..214010ecd6d5f8b42855146af1cc3a724009bfa4 --- /dev/null +++ b/backport-v3_sxnet-add-a-check-for-the-return-of-i2s_ASN1_INTE.patch @@ -0,0 +1,30 @@ +From 7a05fcb1fc276a7ecfe599d45655d4e617c5e2d4 Mon Sep 17 00:00:00 2001 +From: xkernel +Date: Mon, 20 Jun 2022 17:46:39 +0800 +Subject: [PATCH] v3_sxnet: add a check for the return of i2s_ASN1_INTEGER() + +Reviewed-by: Matt Caswell +Reviewed-by: Ben Kaduk +(Merged from https://github.com/openssl/openssl/pull/18608) + +(cherry picked from commit 9ef1f848a646565d4dd86e56542cf921d4921ad9) +--- + crypto/x509v3/v3_sxnet.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/crypto/x509v3/v3_sxnet.c b/crypto/x509v3/v3_sxnet.c +index 144e8bee84..3c5508f941 100644 +--- a/crypto/x509v3/v3_sxnet.c ++++ b/crypto/x509v3/v3_sxnet.c +@@ -78,6 +78,8 @@ static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + tmp = i2s_ASN1_INTEGER(NULL, id->zone); ++ if (tmp == NULL) ++ return 0; + BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); + OPENSSL_free(tmp); + ASN1_STRING_print(out, id->user); +-- +2.17.1 + diff --git a/backport-x509-use-actual-issuer-name-if-a-CA-is-used.patch b/backport-x509-use-actual-issuer-name-if-a-CA-is-used.patch new file mode 100644 index 0000000000000000000000000000000000000000..17736899a4cad749f1168160b764a4f72be3131b --- /dev/null +++ b/backport-x509-use-actual-issuer-name-if-a-CA-is-used.patch @@ -0,0 +1,39 @@ +From 91db522f31981b3fafdec4120de1027e8bc4d792 Mon Sep 17 00:00:00 2001 +From: Daniel Fiala +Date: Mon, 18 Apr 2022 11:30:13 +0200 +Subject: [PATCH] x509: use actual issuer name if a CA is used + +Fixes openssl#16080. + +Reviewed-by: Ben Kaduk +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/18129) +--- + apps/x509.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/apps/x509.c b/apps/x509.c +index 1043eba0c8..2329d9b2d4 100644 +--- a/apps/x509.c ++++ b/apps/x509.c +@@ -590,6 +590,8 @@ int x509_main(int argc, char **argv) + xca = load_cert(CAfile, CAformat, "CA Certificate"); + if (xca == NULL) + goto end; ++ if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) ++ goto end; + } + + out = bio_open_default(outfile, 'w', outformat); +@@ -987,8 +989,6 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges + goto end; + } + +- if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) +- goto end; + if (!X509_set_serialNumber(x, bs)) + goto end; + +-- +2.17.1 + diff --git a/compat-openssl11.spec b/compat-openssl11.spec new file mode 100644 index 0000000000000000000000000000000000000000..f558f059be47fc935ff36098ea8a9b3acb8e1e1d --- /dev/null +++ b/compat-openssl11.spec @@ -0,0 +1,238 @@ +%define soversion 1.1 +Name: compat-openssl11 +Version: 1.1.1m +Release: 1 +Epoch: 1 +Summary: Cryptography and SSL/TLS Toolkit +License: OpenSSL and SSLeay +URL: https://www.openssl.org/ +Source0: https://www.openssl.org/source/openssl-%{version}.tar.gz +Source1: Makefile.certificate +Patch1: openssl-1.1.1-build.patch +Patch2: openssl-1.1.1-fips.patch +Patch3: CVE-2022-0778-Add-a-negative-testcase-for-BN_mod_sqrt.patch +Patch4: CVE-2022-0778-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch +Patch5: CVE-2022-1292.patch +Patch6: Backport-Support-raw-input-data-in-apps-pkeyutl.patch +Patch7: Backport-Fix-no-ec-no-sm2-and-no-sm3.patch +Patch8: Backport-Support-SM2-certificate-verification.patch +Patch9: Backport-Guard-some-SM2-functions-with-OPENSSL_NO_SM2.patch +Patch10: Backport-Add-test-cases-for-SM2-cert-verification.patch +Patch11: Backport-Add-documents-for-SM2-cert-verification.patch +Patch12: Backport-Fix-a-memleak-in-apps-verify.patch +Patch13: Backport-Skip-the-correct-number-of-tests-if-SM2-is-disabled.patch +Patch14: Backport-Make-X509_set_sm2_id-consistent-with-other-setters.patch +Patch15: Backport-Support-SM2-certificate-signing.patch +Patch16: Backport-Support-parsing-of-SM2-ID-in-hexdecimal.patch +Patch17: Backport-Fix-a-double-free-issue-when-signing-SM2-cert.patch +Patch18: Backport-Fix-a-document-description-in-apps-req.patch +Patch19: Backport-Update-expired-SCT-certificates.patch +Patch20: Backport-ct_test.c-Update-the-epoch-time.patch +Patch21: Feature-Support-TLCP-protocol.patch +Patch22: Feature-X509-command-supports-SM2-certificate-signing-with-default-sm2id.patch +Patch23: CVE-2022-2068-Fix-file-operations-in-c_rehash.patch +Patch24: CVE-2022-2097-Fix-AES-OCB-encrypt-decrypt-for-x86-AES-NI.patch +Patch25: Feature-add-ARMv8-implementations-of-SM4-in-ECB-and-XTS.patch +Patch26: Fix-reported-performance-degradation-on-aarch64.patch +Patch27: Feature-PKCS7-sign-and-verify-support-SM2-algorithm.patch +Patch28: Backport-SM3-acceleration-with-SM3-hardware-instruction-on-aa.patch +Patch29: Backport-SM4-optimization-for-ARM-by-HW-instruction.patch +Patch30: Feature-SM4-XTS-optimization-for-ARM-by-HW-instruction.patch +Patch31: backport-Fix-failure-to-check-result-of-bn_rshift_fixed_top.patch +Patch32: backport-Test-processing-of-a-duplicated-HRR.patch +Patch33: backport-tls_process_server_hello-Disallow-repeated-HRR.patch +Patch34: backport-Avoid-potential-memory-leak.patch +Patch35: backport-Fix-NULL-pointer-dereference-for-BN_mod_exp2_mont.patch +Patch36: backport-crypto-x509-v3_utl.c-Add-missing-check-for-OPENSSL_s.patch +Patch37: backport-Fix-password_callback-to-handle-short-passwords.patch +Patch38: backport-Fix-usage-of-SSLfatal.patch +Patch39: backport-Fix-integer-overflow-in-evp_EncryptDecryptUpdate.patch +Patch40: backport-Fix-Coverity-1201763-uninitialised-pointer-read.patch +Patch41: backport-Fix-Coverity-1498611-1498608-uninitialised-read.patch +Patch42: backport-Fix-coverity-1498607-uninitialised-value.patch +Patch43: backport-Check-password-length-only-when-verify-is-enabled.patch +Patch44: backport-Fix-issue-where-OBJ_nid2obj-doesn-t-always-raise-an-.patch +Patch45: backport-Set-protocol-in-init_client.patch +Patch46: backport-Fix-a-crash-in-ssl_security_cert_chain.patch +Patch47: backport-Fix-undefined-behaviour-in-EC_GROUP_new_from_ecparam.patch +Patch48: backport-Fix-a-memory-leak-in-ec_key_simple_oct2priv.patch +Patch49: backport-Fix-a-crash-in-asn1_item_embed_new.patch +Patch50: backport-Fix-leakage-when-the-cacheline-is-32-bytes-in-CBC_MA.patch +Patch51: backport-Add-test-for-empty-supported-groups-extension.patch +Patch52: backport-Do-not-send-an-empty-supported-groups-extension.patch +Patch53: backport-x509-use-actual-issuer-name-if-a-CA-is-used.patch +Patch54: backport-ticket_lifetime_hint-may-exceed-1-week-in-TLSv1.3.patch +Patch55: backport-Fix-a-memory-leak-in-crl_set_issuers.patch +Patch56: backport-Fix-a-DTLS-server-hangup-due-to-TLS13_AD_MISSING_EXT.patch +Patch57: backport-Fix-an-assertion-in-the-DTLS-server-code.patch +Patch58: backport-Fix-a-memory-leak-in-X509_issuer_and_serial_hash.patch +Patch59: backport-Fix-strict-client-chain-check-with-TLS-1.3.patch +Patch60: backport-Fix-a-crash-in-X509v3_asid_subset.patch +Patch61: backport-Fix-a-memory-leak-in-EC_GROUP_new_from_ecparameters.patch +Patch62: backport-Fix-range_should_be_prefix-to-actually-return-the-co.patch +Patch63: backport-v3_sxnet-add-a-check-for-the-return-of-i2s_ASN1_INTE.patch +Patch64: backport-Fix-bn_gcd-code-to-check-return-value-when-calling-B.patch +Patch65: backport-Add-missing-header-for-memcmp.patch +Patch66: backport-Fix-a-memory-leak-in-tls13_generate_secret.patch +Patch67: backport-Make-the-DRBG-seed-propagation-thread-safe.patch +Patch68: backport-Fix-memory-leak-in-X509V3_add1_i2d-when-flag-is-X509.patch +Patch69: fix-add-loongarch64-target.patch +Patch70: backport-APPS-x509-With-CA-but-both-CAserial-and-CAcreateseri.patch +Patch71: backport-Fix-verify_callback-in-the-openssl-s_client-s_server.patch +Patch72: backport-Fix-re-signing-certificates-with-different-key-sizes.patch +Patch73: backport-Fix-ipv4_from_asc-behavior-on-invalid-Ip-addresses.patch +Patch74: backport-Test-case-for-a2i_IPADDRESS.patch +Patch75: backport-Fix-test-case-for-a2i_IPADDRESS.patch +Patch76: backport-Fix-a-crash-in-v2i_IPAddrBlocks.patch +Patch77: backport-Fixes-segfault-occurrence-in-PEM_write.patch +Patch78: backport-X509_REQ_get_extensions-Return-empty-stack-if-no-ext.patch +Patch79: backport-Fix-EC_KEY_set_private_key-priv_key-regression.patch +Patch80: backport-Add-test-for-EC_KEY_set_private_key.patch +Patch81: backport-Fix-SSL_pending-and-SSL_has_pending-with-DTLS.patch +Patch82: backport-Test-that-swapping-the-first-app-data-record-with-Fi.patch +Patch83: backport-Always-end-BN_mod_exp_mont_consttime-with-normal-Mon.patch +Patch84: backport-Add-an-extra-reduction-step-to-RSAZ-mod_exp-implemen.patch +Patch85: backport-Coverity-1508534-1508540-misuses-of-time_t.patch +Patch86: backport-Moving-notify-check-after-the-no-time-check.patch +Patch87: backport-Convert-serverinfo-in-SSL_CTX_use_serverinfo-to-v2.patch +Patch88: backport-X509-x509_req.c-Set-modified-flag-when-X509_req_info.patch +Patch89: backport-ssl_cipher_process_rulestr-don-t-read-outside-rule_s.patch + +BuildRequires: gcc perl make lksctp-tools-devel coreutils util-linux zlib-devel +Requires: coreutils %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} +Conflicts: openssl < 1:3.0, openssl-libs < 1:3.0 + +%description +OpenSSL is a robust, commercial-grade, and full-featured toolkit for the +Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. + +%package libs +Summary: A general purpose cryptography library with TLS implementation +Group: System Environment/Libraries +Requires: ca-certificates >= 2008-5 +Requires: crypto-policies >= 20180730 + +%description libs +The openssl-libs package contains the libraries that are used +by various applications which support cryptographic algorithms +and protocols. + + +%package devel +Summary: Development files for openssl +Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} +Requires: krb5-devel zlib-devel pkgconfig + +%description devel +%{summary}. + +%prep +%autosetup -n openssl-%{version} -p1 + +%build + +sslarch=%{_os}-%{_target_cpu} +%ifarch x86_64 aarch64 +sslflags=enable-ec_nistp_64_gcc_128 +%endif +%ifarch loongarch64 +sslflags="--libdir=%{_libdir}" +%endif + +RPM_OPT_FLAGS="$RPM_OPT_FLAGS -Wa,--noexecstack -DPURIFY $RPM_LD_FLAGS" +./Configure \ + --prefix=%{_prefix} \ + --openssldir=%{_sysconfdir}/pki/tls ${sslflags} \ + zlib enable-camellia enable-seed enable-rfc3779 enable-sctp \ + enable-cms enable-md2 enable-rc5 enable-ssl3 enable-ssl3-method \ + enable-weak-ssl-ciphers \ + no-mdc2 no-ec2m enable-sm2 enable-sm3 enable-sm4 enable-tlcp \ + shared ${sslarch} $RPM_OPT_FLAGS '-DDEVRANDOM="\"/dev/urandom\""' + +%make_build all + +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + crypto/fips/fips_standalone_hmac $RPM_BUILD_ROOT%{_libdir}/libcrypto.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{version}.hmac \ + ln -sf .libcrypto.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{soversion}.hmac \ + crypto/fips/fips_standalone_hmac $RPM_BUILD_ROOT%{_libdir}/libssl.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{version}.hmac \ + ln -sf .libssl.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{soversion}.hmac \ +%{nil} + +%install + +%make_install + +# rename so name with actual version +rename so.%{soversion} so.%{version} $RPM_BUILD_ROOT%{_libdir}/*.so.%{soversion} +# create symbolic link +for lib in $RPM_BUILD_ROOT%{_libdir}/*.so.%{version} ; do + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/`basename ${lib} .%{version}` + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/`basename ${lib} .%{version}`.%{soversion} +done + +# Next step of gradual disablement of ssl3. +# Make SSL3 disappear to newly built dependencies. +sed -i '/^\#ifndef OPENSSL_NO_SSL_TRACE/i\ +#ifndef OPENSSL_NO_SSL3\ +# define OPENSSL_NO_SSL3\ +#endif' $RPM_BUILD_ROOT/%{_prefix}/include/openssl/opensslconf.h + +# Delete configuration files +rm -rf $RPM_BUILD_ROOT/%{_sysconfdir}/pki/tls/* + +# Delete man pages +rm -rf $RPM_BUILD_ROOT/%{_mandir}/* +rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc + +# Remove binaries +rm -rf $RPM_BUILD_ROOT/%{_bindir} + +%check +LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +export LD_LIBRARY_PATH +crypto/fips/fips_standalone_hmac libcrypto.so.%{soversion} >.libcrypto.so.%{soversion}.hmac +ln -s .libcrypto.so.%{soversion}.hmac .libcrypto.so.hmac +crypto/fips/fips_standalone_hmac libssl.so.%{soversion} >.libssl.so.%{soversion}.hmac +ln -s .libssl.so.%{soversion}.hmac .libssl.so.hmac +OPENSSL_ENABLE_MD5_VERIFY= +export OPENSSL_ENABLE_MD5_VERIFY +OPENSSL_SYSTEM_CIPHERS_OVERRIDE=xyz_nonexistent_file +export OPENSSL_SYSTEM_CIPHERS_OVERRIDE +make test || : + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%license LICENSE + +%files libs +%defattr(-,root,root) +%license LICENSE +%{_libdir}/libcrypto.so.%{version} +%{_libdir}/libcrypto.so.%{soversion} +%{_libdir}/libssl.so.%{version} +%{_libdir}/libssl.so.%{soversion} +%{_libdir}/engines-%{soversion} +%attr(0644,root,root) %{_libdir}/.libcrypto.so.*.hmac +%attr(0644,root,root) %{_libdir}/.libssl.so.*.hmac + +%files devel +%defattr(-,root,root) +%doc doc/dir-locals.example.el doc/openssl-c-indent.el +%{_prefix}/include/openssl +%{_libdir}/pkgconfig/*.pc +%{_libdir}/*.so +%{_libdir}/*.a + + +%ldconfig_scriptlets libs + +%changelog +* Fri Jan 13 2023 licihua - 1:1.1.1m-1 +- Repackge openssl-1.1.1m into compat-openssl11 diff --git a/fix-add-loongarch64-target.patch b/fix-add-loongarch64-target.patch new file mode 100644 index 0000000000000000000000000000000000000000..527e7daa52f0080ddb3b28f909178f5e677d7d44 --- /dev/null +++ b/fix-add-loongarch64-target.patch @@ -0,0 +1,30 @@ +From 5fd4cc31c0eba0813a005d3559afc1b42df8ee32 Mon Sep 17 00:00:00 2001 +From: Shi Pujin +Date: Wed, 16 Feb 2022 10:53:56 +0800 +Subject: [PATCH] Add loongarch64 target + +--- + Configurations/10-main.conf | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf +index 61c6689..7102c95 100644 +--- a/Configurations/10-main.conf ++++ b/Configurations/10-main.conf +@@ -761,6 +761,13 @@ my %targets = ( + perlasm_scheme => "linux64", + }, + ++ # loongarch64 below refers to contemporary LOONGARCH Architecture ++ # specifications, ++ "linux-loongarch64" => { ++ inherit_from => [ "linux-generic64"], ++ perlasm_scheme => "linux64", ++ }, ++ + #### IA-32 targets... + #### These two targets are a bit aged and are to be used on older Linux + #### machines where gcc doesn't understand -m32 and -m64 +-- +2.27.0 + diff --git a/openssl-1.1.1-build.patch b/openssl-1.1.1-build.patch new file mode 100644 index 0000000000000000000000000000000000000000..c0ef62b786490e364cf7f213505d4e6c2d878f02 --- /dev/null +++ b/openssl-1.1.1-build.patch @@ -0,0 +1,40 @@ +diff -up openssl-1.1.1f/Configurations/10-main.conf.build openssl-1.1.1f/Configurations/10-main.conf +--- openssl-1.1.1f/Configurations/10-main.conf.build 2020-03-31 14:17:45.000000000 +0200 ++++ openssl-1.1.1f/Configurations/10-main.conf 2020-04-07 16:42:10.920546387 +0200 +@@ -678,6 +678,7 @@ my %targets = ( + cxxflags => add("-m64"), + lib_cppflags => add("-DL_ENDIAN"), + perlasm_scheme => "linux64le", ++ multilib => "64", + }, + + "linux-armv4" => { +@@ -718,6 +719,7 @@ my %targets = ( + "linux-aarch64" => { + inherit_from => [ "linux-generic64", asm("aarch64_asm") ], + perlasm_scheme => "linux64", ++ multilib => "64", + }, + "linux-arm64ilp32" => { # https://wiki.linaro.org/Platform/arm64-ilp32 + inherit_from => [ "linux-generic32", asm("aarch64_asm") ], +diff -up openssl-1.1.1f/Configurations/unix-Makefile.tmpl.build openssl-1.1.1f/Configurations/unix-Makefile.tmpl +--- openssl-1.1.1f/Configurations/unix-Makefile.tmpl.build 2020-04-07 16:42:10.920546387 +0200 ++++ openssl-1.1.1f/Configurations/unix-Makefile.tmpl 2020-04-07 16:44:23.539142108 +0200 +@@ -823,7 +823,7 @@ uninstall_runtime_libs: + install_man_docs: + @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) + @$(ECHO) "*** Installing manpages" +- $(PERL) $(SRCDIR)/util/process_docs.pl \ ++ TZ=UTC $(PERL) $(SRCDIR)/util/process_docs.pl \ + "--destdir=$(DESTDIR)$(MANDIR)" --type=man --suffix=$(MANSUFFIX) + + uninstall_man_docs: +@@ -835,7 +835,7 @@ uninstall_man_docs: + install_html_docs: + @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) + @$(ECHO) "*** Installing HTML manpages" +- $(PERL) $(SRCDIR)/util/process_docs.pl \ ++ TZ=UTC $(PERL) $(SRCDIR)/util/process_docs.pl \ + "--destdir=$(DESTDIR)$(HTMLDIR)" --type=html + + uninstall_html_docs: diff --git a/openssl-1.1.1-fips.patch b/openssl-1.1.1-fips.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa3d33d16d79d0b26531e55b8a744b1317df1f93 --- /dev/null +++ b/openssl-1.1.1-fips.patch @@ -0,0 +1,11635 @@ +diff -up openssl-1.1.1j/apps/pkcs12.c.fips openssl-1.1.1j/apps/pkcs12.c +--- openssl-1.1.1j/apps/pkcs12.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/apps/pkcs12.c 2021-03-03 12:57:42.194734484 +0100 +@@ -123,7 +123,7 @@ int pkcs12_main(int argc, char **argv) + int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; + int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; + #ifndef OPENSSL_NO_RC2 +- int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; ++ int cert_pbe = FIPS_mode() ? NID_pbe_WithSHA1And3_Key_TripleDES_CBC : NID_pbe_WithSHA1And40BitRC2_CBC; + #else + int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + #endif +diff -up openssl-1.1.1j/apps/speed.c.fips openssl-1.1.1j/apps/speed.c +--- openssl-1.1.1j/apps/speed.c.fips 2021-03-03 12:57:42.185734409 +0100 ++++ openssl-1.1.1j/apps/speed.c 2021-03-03 12:57:42.195734492 +0100 +@@ -1593,7 +1593,8 @@ int speed_main(int argc, char **argv) + continue; + if (strcmp(*argv, "rsa") == 0) { + for (loop = 0; loop < OSSL_NELEM(rsa_doit); loop++) +- rsa_doit[loop] = 1; ++ if (!FIPS_mode() || loop != R_RSA_512) ++ rsa_doit[loop] = 1; + continue; + } + if (found(*argv, rsa_choices, &i)) { +@@ -1603,7 +1604,9 @@ int speed_main(int argc, char **argv) + #endif + #ifndef OPENSSL_NO_DSA + if (strcmp(*argv, "dsa") == 0) { +- dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] = ++ if (!FIPS_mode()) ++ dsa_doit[R_DSA_512] = 1; ++ dsa_doit[R_DSA_1024] = + dsa_doit[R_DSA_2048] = 1; + continue; + } +@@ -1634,19 +1637,21 @@ int speed_main(int argc, char **argv) + } + if (strcmp(*argv, "ecdh") == 0) { + for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) +- ecdh_doit[loop] = 1; ++ if(!FIPS_mode() || (loop != R_EC_X25519 && loop != R_EC_X448)) ++ ecdh_doit[loop] = 1; + continue; + } + if (found(*argv, ecdh_choices, &i)) { +- ecdh_doit[i] = 2; ++ if(!FIPS_mode() || (i != R_EC_X25519 && i != R_EC_X448)) ++ ecdh_doit[i] = 2; + continue; + } +- if (strcmp(*argv, "eddsa") == 0) { ++ if (!FIPS_mode() && strcmp(*argv, "eddsa") == 0) { + for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) + eddsa_doit[loop] = 1; + continue; + } +- if (found(*argv, eddsa_choices, &i)) { ++ if (!FIPS_mode() && found(*argv, eddsa_choices, &i)) { + eddsa_doit[i] = 2; + continue; + } +@@ -1735,23 +1740,31 @@ int speed_main(int argc, char **argv) + /* No parameters; turn on everything. */ + if ((argc == 0) && !doit[D_EVP]) { + for (i = 0; i < ALGOR_NUM; i++) +- if (i != D_EVP) ++ if (i != D_EVP && ++ (!FIPS_mode() || (i != D_WHIRLPOOL && ++ i != D_MD2 && i != D_MD4 && ++ i != D_MD5 && i != D_MDC2 && ++ i != D_RMD160))) + doit[i] = 1; + #ifndef OPENSSL_NO_RSA + for (i = 0; i < RSA_NUM; i++) +- rsa_doit[i] = 1; ++ if (!FIPS_mode() || i != R_RSA_512) ++ rsa_doit[i] = 1; + #endif + #ifndef OPENSSL_NO_DSA + for (i = 0; i < DSA_NUM; i++) +- dsa_doit[i] = 1; ++ if (!FIPS_mode() || i != R_DSA_512) ++ dsa_doit[i] = 1; + #endif + #ifndef OPENSSL_NO_EC + for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) + ecdsa_doit[loop] = 1; + for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) +- ecdh_doit[loop] = 1; +- for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) +- eddsa_doit[loop] = 1; ++ if(!FIPS_mode() || (loop != R_EC_X25519 && loop != R_EC_X448)) ++ ecdh_doit[loop] = 1; ++ if (!FIPS_mode()) ++ for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) ++ eddsa_doit[loop] = 1; + #endif + } + for (i = 0; i < ALGOR_NUM; i++) +@@ -1799,30 +1812,46 @@ int speed_main(int argc, char **argv) + AES_set_encrypt_key(key24, 192, &aes_ks2); + AES_set_encrypt_key(key32, 256, &aes_ks3); + #ifndef OPENSSL_NO_CAMELLIA +- Camellia_set_key(key16, 128, &camellia_ks1); +- Camellia_set_key(ckey24, 192, &camellia_ks2); +- Camellia_set_key(ckey32, 256, &camellia_ks3); ++ if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) { ++ Camellia_set_key(key16, 128, &camellia_ks1); ++ Camellia_set_key(ckey24, 192, &camellia_ks2); ++ Camellia_set_key(ckey32, 256, &camellia_ks3); ++ } + #endif + #ifndef OPENSSL_NO_IDEA +- IDEA_set_encrypt_key(key16, &idea_ks); ++ if (doit[D_CBC_IDEA]) { ++ IDEA_set_encrypt_key(key16, &idea_ks); ++ } + #endif + #ifndef OPENSSL_NO_SEED +- SEED_set_key(key16, &seed_ks); ++ if (doit[D_CBC_SEED]) { ++ SEED_set_key(key16, &seed_ks); ++ } + #endif + #ifndef OPENSSL_NO_RC4 +- RC4_set_key(&rc4_ks, 16, key16); ++ if (doit[D_RC4]) { ++ RC4_set_key(&rc4_ks, 16, key16); ++ } + #endif + #ifndef OPENSSL_NO_RC2 +- RC2_set_key(&rc2_ks, 16, key16, 128); ++ if (doit[D_CBC_RC2]) { ++ RC2_set_key(&rc2_ks, 16, key16, 128); ++ } + #endif + #ifndef OPENSSL_NO_RC5 +- RC5_32_set_key(&rc5_ks, 16, key16, 12); ++ if (doit[D_CBC_RC5]) { ++ RC5_32_set_key(&rc5_ks, 16, key16, 12); ++ } + #endif + #ifndef OPENSSL_NO_BF +- BF_set_key(&bf_ks, 16, key16); ++ if (doit[D_CBC_BF]) { ++ BF_set_key(&bf_ks, 16, key16); ++ } + #endif + #ifndef OPENSSL_NO_CAST +- CAST_set_key(&cast_ks, 16, key16); ++ if (doit[D_CBC_CAST]) { ++ CAST_set_key(&cast_ks, 16, key16); ++ } + #endif + #ifndef SIGALRM + # ifndef OPENSSL_NO_DES +@@ -2120,6 +2149,7 @@ int speed_main(int argc, char **argv) + + for (i = 0; i < loopargs_len; i++) { + loopargs[i].hctx = HMAC_CTX_new(); ++ HMAC_CTX_set_flags(loopargs[i].hctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (loopargs[i].hctx == NULL) { + BIO_printf(bio_err, "HMAC malloc failure, exiting..."); + exit(1); +diff -up openssl-1.1.1j/Configure.fips openssl-1.1.1j/Configure +--- openssl-1.1.1j/Configure.fips 2021-03-03 12:57:42.192734467 +0100 ++++ openssl-1.1.1j/Configure 2021-03-03 12:57:42.195734492 +0100 +@@ -329,7 +329,7 @@ $config{sdirs} = [ + "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3", + "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes", + "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine", +- "buffer", "bio", "stack", "lhash", "rand", "err", ++ "buffer", "bio", "stack", "lhash", "rand", "err", "fips", + "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", + "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store" + ]; +diff -up openssl-1.1.1j/crypto/cmac/cm_pmeth.c.fips openssl-1.1.1j/crypto/cmac/cm_pmeth.c +--- openssl-1.1.1j/crypto/cmac/cm_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/cmac/cm_pmeth.c 2021-03-03 12:57:42.195734492 +0100 +@@ -129,7 +129,7 @@ static int pkey_cmac_ctrl_str(EVP_PKEY_C + + const EVP_PKEY_METHOD cmac_pkey_meth = { + EVP_PKEY_CMAC, +- EVP_PKEY_FLAG_SIGCTX_CUSTOM, ++ EVP_PKEY_FLAG_SIGCTX_CUSTOM | EVP_PKEY_FLAG_FIPS, + pkey_cmac_init, + pkey_cmac_copy, + pkey_cmac_cleanup, +diff -up openssl-1.1.1j/crypto/dh/dh_err.c.fips openssl-1.1.1j/crypto/dh/dh_err.c +--- openssl-1.1.1j/crypto/dh/dh_err.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dh/dh_err.c 2021-03-03 12:57:42.195734492 +0100 +@@ -25,6 +25,9 @@ static const ERR_STRING_DATA DH_str_func + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_PEERKEY, 0), "dh_cms_set_peerkey"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0), + "dh_cms_set_shared_info"}, ++ {ERR_PACK(ERR_LIB_DH, DH_F_DH_COMPUTE_KEY, 0), "DH_compute_key"}, ++ {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_KEY, 0), "DH_generate_key"}, ++ {ERR_PACK(ERR_LIB_DH, DH_F_DH_GENERATE_PARAMETERS_EX, 0), "DH_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_DUP, 0), "DH_meth_dup"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_NEW, 0), "DH_meth_new"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_SET1_NAME, 0), "DH_meth_set1_name"}, +@@ -72,12 +75,14 @@ static const ERR_STRING_DATA DH_str_reas + {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "invalid public key"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"}, ++ {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), + "not suitable generator"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "no private value"}, ++ {ERR_PACK(ERR_LIB_DH, 0, DH_R_NON_FIPS_METHOD), "non FIPS method"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), + "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, +diff -up openssl-1.1.1j/crypto/dh/dh_gen.c.fips openssl-1.1.1j/crypto/dh/dh_gen.c +--- openssl-1.1.1j/crypto/dh/dh_gen.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dh/dh_gen.c 2021-03-03 12:57:42.195734492 +0100 +@@ -16,6 +16,9 @@ + #include "internal/cryptlib.h" + #include + #include "dh_local.h" ++#ifdef OPENSSL_FIPS ++# include ++#endif + + static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb); +@@ -23,6 +26,13 @@ static int dh_builtin_genparams(DH *ret, + int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, + BN_GENCB *cb) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD) ++ && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW)) { ++ DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD); ++ return 0; ++ } ++#endif + if (ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); + return dh_builtin_genparams(ret, prime_len, generator, cb); +@@ -65,6 +75,18 @@ static int dh_builtin_genparams(DH *ret, + int g, ok = -1; + BN_CTX *ctx = NULL; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN)) { ++ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); ++ goto err; ++ } ++#endif ++ + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; +diff -up openssl-1.1.1j/crypto/dh/dh_key.c.fips openssl-1.1.1j/crypto/dh/dh_key.c +--- openssl-1.1.1j/crypto/dh/dh_key.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dh/dh_key.c 2021-03-03 13:02:45.963247596 +0100 +@@ -11,6 +11,9 @@ + #include "internal/cryptlib.h" + #include "dh_local.h" + #include "crypto/bn.h" ++#ifdef OPENSSL_FIPS ++# include ++#endif + + static int generate_key(DH *dh); + static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +@@ -34,6 +37,13 @@ int DH_compute_key(unsigned char *key, c + int ret = 0, i; + volatile size_t npad = 0, mask = 1; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) ++ && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { ++ DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD); ++ return 0; ++ } ++#endif + /* compute the key; ret is constant unless compute_key is external */ + if ((ret = dh->meth->compute_key(key, pub_key, dh)) <= 0) + return ret; +@@ -109,6 +119,14 @@ static int generate_key(DH *dh) + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() ++ && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { ++ DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); ++ return 0; ++ } ++#endif ++ + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); + return 0; +@@ -206,6 +224,13 @@ static int compute_key(unsigned char *ke + DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); + goto err; + } ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() ++ && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { ++ DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); ++ goto err; ++ } ++#endif + + ctx = BN_CTX_new(); + if (ctx == NULL) +@@ -255,6 +280,9 @@ static int dh_bn_mod_exp(const DH *dh, B + + static int dh_init(DH *dh) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + dh->flags |= DH_FLAG_CACHE_MONT_P; + return 1; + } +diff -up openssl-1.1.1j/crypto/dh/dh_pmeth.c.fips openssl-1.1.1j/crypto/dh/dh_pmeth.c +--- openssl-1.1.1j/crypto/dh/dh_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dh/dh_pmeth.c 2021-03-03 12:57:42.196734500 +0100 +@@ -480,7 +480,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX * + + const EVP_PKEY_METHOD dh_pkey_meth = { + EVP_PKEY_DH, +- 0, ++ EVP_PKEY_FLAG_FIPS, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, +@@ -514,7 +514,7 @@ const EVP_PKEY_METHOD dh_pkey_meth = { + + const EVP_PKEY_METHOD dhx_pkey_meth = { + EVP_PKEY_DHX, +- 0, ++ EVP_PKEY_FLAG_FIPS, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, +diff -up openssl-1.1.1j/crypto/dsa/dsa_err.c.fips openssl-1.1.1j/crypto/dsa/dsa_err.c +--- openssl-1.1.1j/crypto/dsa/dsa_err.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dsa/dsa_err.c 2021-03-03 12:57:42.196734500 +0100 +@@ -16,12 +16,15 @@ + static const ERR_STRING_DATA DSA_str_functs[] = { + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT, 0), "DSAparams_print"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT_FP, 0), "DSAparams_print_fp"}, ++ {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_KEYGEN, 0), "dsa_builtin_keygen"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN, 0), + "dsa_builtin_paramgen"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN2, 0), + "dsa_builtin_paramgen2"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, 0), "DSA_do_sign"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_VERIFY, 0), "DSA_do_verify"}, ++ {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_KEY, 0), "DSA_generate_key"}, ++ {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_GENERATE_PARAMETERS_EX, 0), "DSA_generate_parameters_ex"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_DUP, 0), "DSA_meth_dup"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_NEW, 0), "DSA_meth_new"}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_SET1_NAME, 0), "DSA_meth_set1_name"}, +@@ -51,11 +54,14 @@ static const ERR_STRING_DATA DSA_str_rea + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_DIGEST_TYPE), + "invalid digest type"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_PARAMETERS), "invalid parameters"}, ++ {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_KEY_SIZE_INVALID), "key size invalid"}, ++ {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY), + "missing private key"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set"}, ++ {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NON_FIPS_DSA_METHOD), "non FIPS DSA method"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR), + "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_Q_NOT_PRIME), "q not prime"}, +diff -up openssl-1.1.1j/crypto/dsa/dsa_gen.c.fips openssl-1.1.1j/crypto/dsa/dsa_gen.c +--- openssl-1.1.1j/crypto/dsa/dsa_gen.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dsa/dsa_gen.c 2021-03-03 12:57:42.196734500 +0100 +@@ -22,12 +22,22 @@ + #include + #include + #include "dsa_local.h" ++#ifdef OPENSSL_FIPS ++# include ++#endif + + int DSA_generate_parameters_ex(DSA *ret, int bits, + const unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) + { ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) ++ && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) { ++ DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); ++ return 0; ++ } ++# endif + if (ret->meth->dsa_paramgen) + return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); +@@ -35,9 +45,15 @@ int DSA_generate_parameters_ex(DSA *ret, + const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); + size_t qbits = EVP_MD_size(evpmd) * 8; + ++# ifdef OPENSSL_FIPS ++ return dsa_builtin_paramgen2(ret, bits, qbits, evpmd, ++ seed_in, seed_len, -1, NULL, counter_ret, ++ h_ret, cb); ++# else + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, + seed_in, seed_len, NULL, counter_ret, + h_ret, cb); ++# endif + } + } + +@@ -309,7 +325,7 @@ int dsa_builtin_paramgen2(DSA *ret, size + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) + { +- int ok = -1; ++ int ok = 0; + unsigned char *seed = NULL, *seed_tmp = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdsize; +@@ -332,6 +348,20 @@ int dsa_builtin_paramgen2(DSA *ret, size + goto err; + } + ++# ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN2, FIPS_R_FIPS_SELFTEST_FAILED); ++ goto err; ++ } ++ ++ if (FIPS_mode() && ++ (L != 2048 || N != 224) && (L != 2048 || N != 256) && ++ (L != 3072 || N != 256)) { ++ DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_KEY_SIZE_INVALID); ++ goto err; ++ } ++# endif ++ + if (evpmd == NULL) { + if (N == 160) + evpmd = EVP_sha1(); +@@ -432,9 +462,10 @@ int dsa_builtin_paramgen2(DSA *ret, size + goto err; + /* Provided seed didn't produce a prime: error */ + if (seed_in) { +- ok = 0; +- DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME); +- goto err; ++ /* Different seed_out will indicate that seed_in ++ * did not generate primes. ++ */ ++ seed_in = NULL; + } + + /* do a callback call */ +@@ -520,11 +551,14 @@ int dsa_builtin_paramgen2(DSA *ret, size + if (counter >= (int)(4 * L)) + break; + } ++#if 0 ++ /* Cannot happen */ + if (seed_in) { + ok = 0; + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); + goto err; + } ++#endif + } + end: + if (!BN_GENCB_call(cb, 2, 1)) +@@ -595,7 +629,7 @@ int dsa_builtin_paramgen2(DSA *ret, size + BN_free(ret->g); + ret->g = BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { +- ok = -1; ++ ok = 0; + goto err; + } + if (counter_ret != NULL) +@@ -612,3 +646,53 @@ int dsa_builtin_paramgen2(DSA *ret, size + EVP_MD_CTX_free(mctx); + return ok; + } ++ ++#ifdef OPENSSL_FIPS ++ ++int FIPS_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, ++ const EVP_MD *evpmd, const unsigned char *seed_in, ++ size_t seed_len, int idx, unsigned char *seed_out, ++ int *counter_ret, unsigned long *h_ret, ++ BN_GENCB *cb) ++{ ++ return dsa_builtin_paramgen2(ret, L, N, evpmd, seed_in, seed_len, ++ idx, seed_out, counter_ret, h_ret, cb); ++} ++ ++int FIPS_dsa_paramgen_check_g(DSA *dsa) ++{ ++ BN_CTX *ctx; ++ BIGNUM *tmp; ++ BN_MONT_CTX *mont = NULL; ++ int rv = -1; ++ ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) ++ return -1; ++ if (BN_cmp(dsa->g, BN_value_one()) <= 0) ++ return 0; ++ if (BN_cmp(dsa->g, dsa->p) >= 0) ++ return 0; ++ BN_CTX_start(ctx); ++ tmp = BN_CTX_get(ctx); ++ if (tmp == NULL) ++ goto err; ++ if ((mont=BN_MONT_CTX_new()) == NULL) ++ goto err; ++ if (!BN_MONT_CTX_set(mont,dsa->p,ctx)) ++ goto err; ++ /* Work out g^q mod p */ ++ if (!BN_mod_exp_mont(tmp,dsa->g,dsa->q, dsa->p, ctx, mont)) ++ goto err; ++ if (!BN_cmp(tmp, BN_value_one())) ++ rv = 1; ++ else ++ rv = 0; ++ err: ++ BN_CTX_end(ctx); ++ BN_MONT_CTX_free(mont); ++ BN_CTX_free(ctx); ++ return rv; ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/dsa/dsa_key.c.fips openssl-1.1.1j/crypto/dsa/dsa_key.c +--- openssl-1.1.1j/crypto/dsa/dsa_key.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dsa/dsa_key.c 2021-03-03 12:57:42.196734500 +0100 +@@ -13,10 +13,49 @@ + #include + #include "dsa_local.h" + ++#ifdef OPENSSL_FIPS ++# include ++# include "crypto/fips.h" ++ ++static int fips_check_dsa(DSA *dsa) ++{ ++ EVP_PKEY *pk; ++ unsigned char tbs[] = "DSA Pairwise Check Data"; ++ int ret = 0; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_DSA(pk, dsa); ++ ++ if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL)) ++ ret = 1; ++ ++ err: ++ if (ret == 0) { ++ FIPSerr(FIPS_F_FIPS_CHECK_DSA, FIPS_R_PAIRWISE_TEST_FAILED); ++ fips_set_selftest_fail(); ++ } ++ ++ if (pk) ++ EVP_PKEY_free(pk); ++ ++ return ret; ++} ++ ++#endif ++ + static int dsa_builtin_keygen(DSA *dsa); + + int DSA_generate_key(DSA *dsa) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) ++ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { ++ DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD); ++ return 0; ++ } ++#endif + if (dsa->meth->dsa_keygen) + return dsa->meth->dsa_keygen(dsa); + return dsa_builtin_keygen(dsa); +@@ -28,6 +67,14 @@ static int dsa_builtin_keygen(DSA *dsa) + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN)) { ++ DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); ++ goto err; ++ } ++#endif ++ + if ((ctx = BN_CTX_new()) == NULL) + goto err; + +@@ -65,6 +112,13 @@ static int dsa_builtin_keygen(DSA *dsa) + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !fips_check_dsa(dsa)) { ++ dsa->pub_key = NULL; ++ dsa->priv_key = NULL; ++ goto err; ++ } ++#endif + ok = 1; + + err: +diff -up openssl-1.1.1j/crypto/dsa/dsa_ossl.c.fips openssl-1.1.1j/crypto/dsa/dsa_ossl.c +--- openssl-1.1.1j/crypto/dsa/dsa_ossl.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dsa/dsa_ossl.c 2021-03-03 12:57:42.196734500 +0100 +@@ -14,6 +14,9 @@ + #include + #include "dsa_local.h" + #include ++#ifdef OPENSSL_FIPS ++# include ++#endif + + static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); + static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, +@@ -77,6 +80,19 @@ static DSA_SIG *dsa_do_sign(const unsign + goto err; + } + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_DSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED); ++ return NULL; ++ } ++ ++ if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { ++ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); ++ return NULL; ++ } ++#endif ++ + ret = DSA_SIG_new(); + if (ret == NULL) + goto err; +@@ -315,6 +331,18 @@ static int dsa_do_verify(const unsigned + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); + return -1; + } ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_DSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++ ++ if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { ++ DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); ++ return -1; ++ } ++#endif + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); +@@ -403,6 +431,9 @@ static int dsa_do_verify(const unsigned + + static int dsa_init(DSA *dsa) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + dsa->flags |= DSA_FLAG_CACHE_MONT_P; + return 1; + } +diff -up openssl-1.1.1j/crypto/dsa/dsa_pmeth.c.fips openssl-1.1.1j/crypto/dsa/dsa_pmeth.c +--- openssl-1.1.1j/crypto/dsa/dsa_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/dsa/dsa_pmeth.c 2021-03-03 12:57:42.196734500 +0100 +@@ -211,8 +211,8 @@ static int pkey_dsa_paramgen(EVP_PKEY_CT + BN_GENCB_free(pcb); + return 0; + } +- ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, +- NULL, 0, NULL, NULL, NULL, pcb); ++ ret = dsa_builtin_paramgen2(dsa, dctx->nbits, dctx->qbits, dctx->pmd, ++ NULL, 0, -1, NULL, NULL, NULL, pcb); + BN_GENCB_free(pcb); + if (ret) + EVP_PKEY_assign_DSA(pkey, dsa); +@@ -241,7 +241,7 @@ static int pkey_dsa_keygen(EVP_PKEY_CTX + + const EVP_PKEY_METHOD dsa_pkey_meth = { + EVP_PKEY_DSA, +- EVP_PKEY_FLAG_AUTOARGLEN, ++ EVP_PKEY_FLAG_AUTOARGLEN | EVP_PKEY_FLAG_FIPS, + pkey_dsa_init, + pkey_dsa_copy, + pkey_dsa_cleanup, +diff -up openssl-1.1.1j/crypto/ec/ecdh_ossl.c.fips openssl-1.1.1j/crypto/ec/ecdh_ossl.c +--- openssl-1.1.1j/crypto/ec/ecdh_ossl.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/ec/ecdh_ossl.c 2021-03-03 12:57:42.196734500 +0100 +@@ -19,9 +19,20 @@ + #include + #include "ec_local.h" + ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ + int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen, + const EC_POINT *pub_key, const EC_KEY *ecdh) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_ECDH_COMPUTE_KEY, FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + if (ecdh->group->meth->ecdh_compute_key == NULL) { + ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH); + return 0; +diff -up openssl-1.1.1j/crypto/ec/ecdsa_ossl.c.fips openssl-1.1.1j/crypto/ec/ecdsa_ossl.c +--- openssl-1.1.1j/crypto/ec/ecdsa_ossl.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/ec/ecdsa_ossl.c 2021-03-03 12:57:42.196734500 +0100 +@@ -14,6 +14,10 @@ + #include "crypto/bn.h" + #include "ec_local.h" + ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ + int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) +@@ -163,6 +167,13 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const uns + ECDSA_SIG *ret; + const BIGNUM *priv_key; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_OSSL_ECDSA_SIGN_SIG, FIPS_R_FIPS_SELFTEST_FAILED); ++ return NULL; ++ } ++#endif ++ + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); + +@@ -325,6 +336,13 @@ int ossl_ecdsa_verify_sig(const unsigned + const EC_GROUP *group; + const EC_POINT *pub_key; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_OSSL_ECDSA_VERIFY_SIG, FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { +diff -up openssl-1.1.1j/crypto/ec/ec_key.c.fips openssl-1.1.1j/crypto/ec/ec_key.c +--- openssl-1.1.1j/crypto/ec/ec_key.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/ec/ec_key.c 2021-03-03 12:57:42.196734500 +0100 +@@ -179,14 +179,62 @@ ENGINE *EC_KEY_get0_engine(const EC_KEY + return eckey->engine; + } + ++#ifdef OPENSSL_FIPS ++ ++# include ++# include "crypto/fips.h" ++ ++static int fips_check_ec(EC_KEY *key) ++{ ++ EVP_PKEY *pk; ++ unsigned char tbs[] = "ECDSA Pairwise Check Data"; ++ int ret = 0; ++ ++ if (!EC_KEY_can_sign(key)) /* no test for non-signing keys */ ++ return 1; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_EC_KEY(pk, key); ++ ++ if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL)) ++ ret = 1; ++ ++ err: ++ if (ret == 0) { ++ FIPSerr(FIPS_F_FIPS_CHECK_EC, FIPS_R_PAIRWISE_TEST_FAILED); ++ fips_set_selftest_fail(); ++ } ++ if (pk) ++ EVP_PKEY_free(pk); ++ return ret; ++} ++ ++#endif ++ + int EC_KEY_generate_key(EC_KEY *eckey) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_NOT_INITIALIZED); ++ return 0; ++ } ++#endif + if (eckey == NULL || eckey->group == NULL) { + ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +- if (eckey->meth->keygen != NULL) +- return eckey->meth->keygen(eckey); ++ if (eckey->meth->keygen != NULL) { ++ int rv = eckey->meth->keygen(eckey); ++ ++#ifdef OPENSSL_FIPS ++ if (rv > 0 && FIPS_mode()) { ++ rv = fips_check_ec(eckey); ++ } ++#endif ++ return rv; ++ } + ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED); + return 0; + } +diff -up openssl-1.1.1j/crypto/ec/ec_pmeth.c.fips openssl-1.1.1j/crypto/ec/ec_pmeth.c +--- openssl-1.1.1j/crypto/ec/ec_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/ec/ec_pmeth.c 2021-03-03 12:57:42.197734509 +0100 +@@ -438,7 +438,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX * + + const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, +- 0, ++ EVP_PKEY_FLAG_FIPS, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, +diff -up openssl-1.1.1j/crypto/evp/digest.c.fips openssl-1.1.1j/crypto/evp/digest.c +--- openssl-1.1.1j/crypto/evp/digest.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/digest.c 2021-03-03 12:57:42.197734509 +0100 +@@ -14,6 +14,9 @@ + #include + #include "crypto/evp.h" + #include "evp_local.h" ++#ifdef OPENSSL_FIPS ++# include ++#endif + + /* This call frees resources associated with the context */ + int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +@@ -66,6 +69,12 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) + { + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_EVP_DIGESTINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++#endif + #ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so +@@ -119,6 +128,15 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c + } + #endif + if (ctx->digest != type) { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (!(type->flags & EVP_MD_FLAG_FIPS) ++ && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) { ++ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); ++ return 0; ++ } ++ } ++#endif + if (ctx->digest && ctx->digest->ctx_size) { + OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); + ctx->md_data = NULL; +@@ -150,6 +168,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c + + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif ++ + if (count == 0) + return 1; + +@@ -170,6 +192,9 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, + { + int ret; + ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ret = ctx->digest->final(ctx, md); + if (size != NULL) +diff -up openssl-1.1.1j/crypto/evp/e_aes.c.fips openssl-1.1.1j/crypto/evp/e_aes.c +--- openssl-1.1.1j/crypto/evp/e_aes.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/e_aes.c 2021-03-03 12:57:42.197734509 +0100 +@@ -397,7 +397,7 @@ static int aesni_xts_init_key(EVP_CIPHER + * This addresses Rogaway's vulnerability. + * See comment in aes_xts_init_key() below. + */ +- if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { ++ if (CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } +@@ -817,7 +817,7 @@ static int aes_t4_xts_init_key(EVP_CIPHE + * This addresses Rogaway's vulnerability. + * See comment in aes_xts_init_key() below. + */ +- if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { ++ if (CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AES_T4_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } +@@ -2833,9 +2833,9 @@ static int aes_ctr_cipher(EVP_CIPHER_CTX + return 1; + } + +-BLOCK_CIPHER_generic_pack(NID_aes, 128, 0) +- BLOCK_CIPHER_generic_pack(NID_aes, 192, 0) +- BLOCK_CIPHER_generic_pack(NID_aes, 256, 0) ++BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) ++ BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS) ++ BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS) + + static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) + { +@@ -2869,6 +2869,11 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX * + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg <= 0) + return 0; ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) ++ && arg < 12) ++ return 0; ++# endif + /* Allocate memory for IV if needed */ + if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { + if (gctx->iv != c->iv) +@@ -3318,11 +3323,14 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX + | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH) + + BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | ++ CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | ++ CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | ++ CUSTOM_FLAGS) + + static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) + { +@@ -3380,7 +3388,7 @@ static int aes_xts_init_key(EVP_CIPHER_C + * BEFORE using the keys in the XTS-AES algorithm to process + * data with them." + */ +- if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { ++ if (CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AES_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } +@@ -3484,6 +3492,14 @@ static int aes_xts_cipher(EVP_CIPHER_CTX + return 0; + if (!out || !in || len < AES_BLOCK_SIZE) + return 0; ++# ifdef OPENSSL_FIPS ++ /* Requirement of SP800-38E */ ++ if (FIPS_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && ++ (len > (1UL << 20) * 16)) { ++ EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); ++ return 0; ++ } ++# endif + if (xctx->stream) + (*xctx->stream) (in, out, len, + xctx->xts.key1, xctx->xts.key2, +@@ -3501,8 +3517,10 @@ static int aes_xts_cipher(EVP_CIPHER_CTX + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +-BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, XTS_FLAGS) +- BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, XTS_FLAGS) ++BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, ++ EVP_CIPH_FLAG_FIPS | XTS_FLAGS) ++ BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, ++ EVP_CIPH_FLAG_FIPS | XTS_FLAGS) + + static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) + { +@@ -3772,11 +3790,11 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX + #define aes_ccm_cleanup NULL + + BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, +- EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) ++ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) + + typedef struct { + union { +@@ -3869,7 +3887,7 @@ static int aes_wrap_cipher(EVP_CIPHER_CT + return rv ? (int)rv : -1; + } + +-#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \ ++#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_FLAG_FIPS \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) + +diff -up openssl-1.1.1j/crypto/evp/e_des3.c.fips openssl-1.1.1j/crypto/evp/e_des3.c +--- openssl-1.1.1j/crypto/evp/e_des3.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/e_des3.c 2021-03-03 12:57:42.197734509 +0100 +@@ -211,16 +211,19 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, + # define des_ede3_cbc_cipher des_ede_cbc_cipher + # define des_ede3_ecb_cipher des_ede_ecb_cipher + BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, +- EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, +- des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) ++ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | ++ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, NULL, ++ des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, +- EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, +- des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) ++ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | ++ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, ++ NULL, des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, +- EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, +- des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) ++ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | ++ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, ++ NULL, des3_ctrl) + + static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +diff -up openssl-1.1.1j/crypto/evp/e_null.c.fips openssl-1.1.1j/crypto/evp/e_null.c +--- openssl-1.1.1j/crypto/evp/e_null.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/e_null.c 2021-03-03 12:57:42.197734509 +0100 +@@ -19,7 +19,8 @@ static int null_cipher(EVP_CIPHER_CTX *c + const unsigned char *in, size_t inl); + static const EVP_CIPHER n_cipher = { + NID_undef, +- 1, 0, 0, 0, ++ 1, 0, 0, ++ EVP_CIPH_FLAG_FIPS, + null_init_key, + null_cipher, + NULL, +diff -up openssl-1.1.1j/crypto/evp/evp_enc.c.fips openssl-1.1.1j/crypto/evp/evp_enc.c +--- openssl-1.1.1j/crypto/evp/evp_enc.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/evp_enc.c 2021-03-03 12:57:42.197734509 +0100 +@@ -18,9 +18,18 @@ + #include + #include "crypto/evp.h" + #include "evp_local.h" ++#ifdef OPENSSL_FIPS ++# include ++#endif + + int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_EVP_CIPHER_CTX_RESET, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++#endif + if (c == NULL) + return 1; + if (c->cipher != NULL) { +@@ -40,6 +49,12 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX + + EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_EVP_CIPHER_CTX_NEW, FIPS_R_FIPS_SELFTEST_FAILED); ++ return NULL; ++ } ++#endif + return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX)); + } + +@@ -68,6 +83,12 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct + enc = 1; + ctx->encrypt = enc; + } ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_EVP_CIPHERINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++#endif + #ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so +@@ -137,7 +158,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct + } + ctx->key_len = cipher->key_len; + /* Preserve wrap enable flag, zero everything else */ +- ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; ++ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW | EVP_CIPH_FLAG_NON_FIPS_ALLOW; + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; +@@ -196,6 +217,18 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct + return 0; + } + } ++#ifdef OPENSSL_FIPS ++ /* After 'key' is set no further parameters changes are permissible. ++ * So only check for non FIPS enabling at this point. ++ */ ++ if (key && FIPS_mode()) { ++ if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) ++ & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { ++ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS); ++ return 0; ++ } ++ } ++#endif + + if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (!ctx->cipher->init(ctx, key, iv, enc)) +diff -up openssl-1.1.1j/crypto/evp/evp_err.c.fips openssl-1.1.1j/crypto/evp/evp_err.c +--- openssl-1.1.1j/crypto/evp/evp_err.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/evp_err.c 2021-03-03 12:57:42.198734517 +0100 +@@ -23,6 +23,7 @@ static const ERR_STRING_DATA EVP_str_fun + {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_XTS_INIT_KEY, 0), + "aes_t4_xts_init_key"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"}, ++ {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_CIPHER, 0), "aes_xts_cipher"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_INIT_KEY, 0), "aes_xts_init_key"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"}, +@@ -186,6 +187,7 @@ static const ERR_STRING_DATA EVP_str_rea + "different key types"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), + "different parameters"}, ++ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DISABLED_FOR_FIPS), "disabled for FIPS"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION), + "error loading section"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_SETTING_FIPS_MODE), +@@ -251,6 +253,7 @@ static const ERR_STRING_DATA EVP_str_rea + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR), + "private key encode error"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, ++ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_LARGE), "too large"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"}, +@@ -276,6 +279,8 @@ static const ERR_STRING_DATA EVP_str_rea + "wrap mode not allowed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH), + "wrong final block length"}, ++ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE), ++ "xts data unit is too large"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS), + "xts duplicated keys"}, + {0, NULL} +diff -up openssl-1.1.1j/crypto/evp/evp_lib.c.fips openssl-1.1.1j/crypto/evp/evp_lib.c +--- openssl-1.1.1j/crypto/evp/evp_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/evp_lib.c 2021-03-03 12:57:42.198734517 +0100 +@@ -192,6 +192,9 @@ int EVP_CIPHER_impl_ctx_size(const EVP_C + int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + return ctx->cipher->do_cipher(ctx, out, in, inl); + } + +diff -up openssl-1.1.1j/crypto/evp/m_sha1.c.fips openssl-1.1.1j/crypto/evp/m_sha1.c +--- openssl-1.1.1j/crypto/evp/m_sha1.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/m_sha1.c 2021-03-03 12:57:42.198734517 +0100 +@@ -95,7 +95,7 @@ static const EVP_MD sha1_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init, + update, + final, +@@ -145,7 +145,7 @@ static const EVP_MD sha224_md = { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init224, + update224, + final224, +@@ -164,7 +164,7 @@ static const EVP_MD sha256_md = { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init256, + update256, + final256, +@@ -224,7 +224,7 @@ static const EVP_MD sha512_224_md = { + NID_sha512_224, + NID_sha512_224WithRSAEncryption, + SHA224_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init512_224, + update512, + final512, +@@ -243,7 +243,7 @@ static const EVP_MD sha512_256_md = { + NID_sha512_256, + NID_sha512_256WithRSAEncryption, + SHA256_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init512_256, + update512, + final512, +@@ -262,7 +262,7 @@ static const EVP_MD sha384_md = { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init384, + update384, + final384, +@@ -281,7 +281,7 @@ static const EVP_MD sha512_md = { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, +- EVP_MD_FLAG_DIGALGID_ABSENT, ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, + init512, + update512, + final512, +diff -up openssl-1.1.1j/crypto/evp/m_sha3.c.fips openssl-1.1.1j/crypto/evp/m_sha3.c +--- openssl-1.1.1j/crypto/evp/m_sha3.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/m_sha3.c 2021-03-03 12:57:42.198734517 +0100 +@@ -295,7 +295,7 @@ const EVP_MD *EVP_sha3_##bitlen(void) + NID_sha3_##bitlen, \ + NID_RSA_SHA3_##bitlen, \ + bitlen / 8, \ +- EVP_MD_FLAG_DIGALGID_ABSENT, \ ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, \ + s390x_sha3_init, \ + s390x_sha3_update, \ + s390x_sha3_final, \ +@@ -308,7 +308,7 @@ const EVP_MD *EVP_sha3_##bitlen(void) + NID_sha3_##bitlen, \ + NID_RSA_SHA3_##bitlen, \ + bitlen / 8, \ +- EVP_MD_FLAG_DIGALGID_ABSENT, \ ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, \ + sha3_init, \ + sha3_update, \ + sha3_final, \ +@@ -329,7 +329,7 @@ const EVP_MD *EVP_shake##bitlen(void) + NID_shake##bitlen, \ + 0, \ + bitlen / 8, \ +- EVP_MD_FLAG_XOF, \ ++ EVP_MD_FLAG_XOF | EVP_MD_FLAG_FIPS, \ + s390x_shake_init, \ + s390x_sha3_update, \ + s390x_shake_final, \ +@@ -343,7 +343,7 @@ const EVP_MD *EVP_shake##bitlen(void) + NID_shake##bitlen, \ + 0, \ + bitlen / 8, \ +- EVP_MD_FLAG_XOF, \ ++ EVP_MD_FLAG_XOF | EVP_MD_FLAG_FIPS, \ + shake_init, \ + sha3_update, \ + sha3_final, \ +@@ -367,7 +367,7 @@ const EVP_MD *EVP_sha3_##bitlen(void) + NID_sha3_##bitlen, \ + NID_RSA_SHA3_##bitlen, \ + bitlen / 8, \ +- EVP_MD_FLAG_DIGALGID_ABSENT, \ ++ EVP_MD_FLAG_DIGALGID_ABSENT | EVP_MD_FLAG_FIPS, \ + sha3_init, \ + sha3_update, \ + sha3_final, \ +@@ -386,7 +386,7 @@ const EVP_MD *EVP_shake##bitlen(void) + NID_shake##bitlen, \ + 0, \ + bitlen / 8, \ +- EVP_MD_FLAG_XOF, \ ++ EVP_MD_FLAG_XOF | EVP_MD_FLAG_FIPS, \ + shake_init, \ + sha3_update, \ + sha3_final, \ +diff -up openssl-1.1.1j/crypto/evp/pmeth_lib.c.fips openssl-1.1.1j/crypto/evp/pmeth_lib.c +--- openssl-1.1.1j/crypto/evp/pmeth_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/evp/pmeth_lib.c 2021-03-03 12:57:42.198734517 +0100 +@@ -131,7 +131,15 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKE + pmeth = ENGINE_get_pkey_meth(e, id); + else + #endif ++ { + pmeth = EVP_PKEY_meth_find(id); ++#ifdef OPENSSL_FIPS ++ if (pmeth && !(pmeth->flags & EVP_PKEY_FLAG_FIPS) && FIPS_mode()) { ++ EVPerr(EVP_F_INT_CTX_NEW, EVP_R_DISABLED_FOR_FIPS); ++ return NULL; ++ } ++#endif ++ } + + if (pmeth == NULL) { + #ifndef OPENSSL_NO_ENGINE +diff -up openssl-1.1.1j/crypto/fips/build.info.fips openssl-1.1.1j/crypto/fips/build.info +--- openssl-1.1.1j/crypto/fips/build.info.fips 2021-03-03 12:57:42.198734517 +0100 ++++ openssl-1.1.1j/crypto/fips/build.info 2021-03-03 12:57:42.198734517 +0100 +@@ -0,0 +1,15 @@ ++LIBS=../../libcrypto ++SOURCE[../../libcrypto]=\ ++ fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c \ ++ fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c \ ++ fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \ ++ fips_drbg_lib.c fips_drbg_rand.c fips_drbg_selftest.c fips_rand_lib.c \ ++ fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_selftest.c \ ++ fips_dh_selftest.c fips_ers.c ++ ++PROGRAMS_NO_INST=\ ++ fips_standalone_hmac ++ ++SOURCE[fips_standalone_hmac]=fips_standalone_hmac.c ++INCLUDE[fips_standalone_hmac]=../../include ++DEPEND[fips_standalone_hmac]=../../libcrypto +diff -up openssl-1.1.1j/crypto/fips/fips_aes_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_aes_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_aes_selftest.c.fips 2021-03-03 12:57:42.198734517 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_aes_selftest.c 2021-03-03 12:57:42.198734517 +0100 +@@ -0,0 +1,372 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++# include "crypto/fips.h" ++#endif ++ ++#ifdef OPENSSL_FIPS ++static const struct { ++ const unsigned char key[16]; ++ const unsigned char plaintext[16]; ++ const unsigned char ciphertext[16]; ++} tests[] = { ++ { ++ { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, { ++ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, ++ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, { ++0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30, ++ 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A},},}; ++ ++int FIPS_selftest_aes() ++{ ++ int n; ++ int ret = 0; ++ EVP_CIPHER_CTX *ctx; ++ ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ for (n = 0; n < 1; ++n) { ++ unsigned char key[16]; ++ ++ memcpy(key, tests[n].key, sizeof(key)); ++ if (fips_cipher_test(ctx, EVP_aes_128_ecb(), ++ key, NULL, ++ tests[n].plaintext, ++ tests[n].ciphertext, 16) <= 0) ++ goto err; ++ } ++ ret = 1; ++ err: ++ EVP_CIPHER_CTX_free(ctx); ++ if (ret == 0) ++ FIPSerr(FIPS_F_FIPS_SELFTEST_AES, FIPS_R_SELFTEST_FAILED); ++ return ret; ++} ++ ++/* AES-CCM test data from NIST public test vectors */ ++ ++static const unsigned char ccm_key[] = { ++ 0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6, ++ 0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8 ++}; ++ ++static const unsigned char ccm_nonce[] = { ++ 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7 ++}; ++ ++static const unsigned char ccm_adata[] = { ++ 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7, ++ 0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5, ++ 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4 ++}; ++ ++static const unsigned char ccm_pt[] = { ++ 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f, ++ 0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10 ++}; ++ ++static const unsigned char ccm_ct[] = { ++ 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2, ++ 0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd ++}; ++ ++static const unsigned char ccm_tag[] = { ++ 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44, ++ 0x14, 0xdb, 0x50, 0x6d ++}; ++ ++int FIPS_selftest_aes_ccm(void) ++{ ++ int ret = 0; ++ unsigned char out[128], tag[16]; ++ EVP_CIPHER_CTX *ctx; ++ ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ memset(out, 0, sizeof(out)); ++ if (!EVP_CipherInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 1)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, ++ sizeof(ccm_nonce), NULL)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, ++ sizeof(ccm_tag), NULL)) ++ goto err; ++ if (!EVP_CipherInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce, 1)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, NULL, sizeof(ccm_pt)) != sizeof(ccm_pt)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) ++ goto err; ++ if (EVP_Cipher(ctx, out, ccm_pt, sizeof(ccm_pt)) != sizeof(ccm_ct)) ++ goto err; ++ ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, 16, tag)) ++ goto err; ++ if (memcmp(tag, ccm_tag, sizeof(ccm_tag)) ++ || memcmp(out, ccm_ct, sizeof(ccm_ct))) ++ goto err; ++ ++ memset(out, 0, sizeof(out)); ++ ++ if (!EVP_CipherInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 0)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, ++ sizeof(ccm_nonce), NULL)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, 16, tag)) ++ goto err; ++ if (!EVP_CipherInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce, 0)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, NULL, sizeof(ccm_ct)) != sizeof(ccm_ct)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) ++ goto err; ++ if (EVP_Cipher(ctx, out, ccm_ct, sizeof(ccm_ct)) != sizeof(ccm_pt)) ++ goto err; ++ ++ if (memcmp(out, ccm_pt, sizeof(ccm_pt))) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ EVP_CIPHER_CTX_free(ctx); ++ ++ if (ret == 0) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_AES_CCM, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } else ++ return ret; ++ ++} ++ ++/* AES-GCM test data from NIST public test vectors */ ++ ++static const unsigned char gcm_key[] = { ++ 0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66, ++ 0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69, ++ 0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f ++}; ++ ++static const unsigned char gcm_iv[] = { ++ 0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 ++}; ++ ++static const unsigned char gcm_pt[] = { ++ 0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea, ++ 0xcc, 0x2b, 0xf2, 0xa5 ++}; ++ ++static const unsigned char gcm_aad[] = { ++ 0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43, ++ 0x7f, 0xec, 0x78, 0xde ++}; ++ ++static const unsigned char gcm_ct[] = { ++ 0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e, ++ 0xb9, 0xf2, 0x17, 0x36 ++}; ++ ++static const unsigned char gcm_tag[] = { ++ 0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62, ++ 0x98, 0xf7, 0x7e, 0x0c ++}; ++ ++int FIPS_selftest_aes_gcm(void) ++{ ++ int ret = 0; ++ unsigned char out[128], tag[16]; ++ EVP_CIPHER_CTX *ctx; ++ ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ memset(out, 0, sizeof(out)); ++ memset(tag, 0, sizeof(tag)); ++ if (!EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 1)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ++ sizeof(gcm_iv), NULL)) ++ goto err; ++ if (!EVP_CipherInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv, 1)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) ++ goto err; ++ if (EVP_Cipher(ctx, out, gcm_pt, sizeof(gcm_pt)) != sizeof(gcm_ct)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, NULL, 0) < 0) ++ goto err; ++ ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) ++ goto err; ++ ++ if (memcmp(tag, gcm_tag, 16) || memcmp(out, gcm_ct, 16)) ++ goto err; ++ ++ memset(out, 0, sizeof(out)); ++ ++ if (!EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 0)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ++ sizeof(gcm_iv), NULL)) ++ goto err; ++ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) ++ goto err; ++ if (!EVP_CipherInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv, 0)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) ++ goto err; ++ if (EVP_Cipher(ctx, out, gcm_ct, sizeof(gcm_ct)) != sizeof(gcm_pt)) ++ goto err; ++ if (EVP_Cipher(ctx, NULL, NULL, 0) < 0) ++ goto err; ++ ++ if (memcmp(out, gcm_pt, 16)) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ EVP_CIPHER_CTX_free(ctx); ++ ++ if (ret == 0) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_AES_GCM, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } else ++ return ret; ++ ++} ++ ++static const unsigned char XTS_128_key[] = { ++ 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, 0x3b, 0x2c, 0x34, 0x38, ++ 0x76, 0x08, 0x17, 0x62, 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, ++ 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f ++}; ++ ++static const unsigned char XTS_128_i[] = { ++ 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, 0x6e, 0x4b, 0x92, 0x01, ++ 0x3e, 0x76, 0x8a, 0xd5 ++}; ++ ++static const unsigned char XTS_128_pt[] = { ++ 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, ++ 0x07, 0x90, 0x31, 0x1c ++}; ++ ++static const unsigned char XTS_128_ct[] = { ++ 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, 0x82, 0x50, 0x81, 0xd5, ++ 0xbe, 0x47, 0x1c, 0x63 ++}; ++ ++static const unsigned char XTS_256_key[] = { ++ 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, 0x48, 0x01, 0xe4, 0x2f, ++ 0x4b, 0x09, 0x47, 0x14, 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, ++ 0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c, 0xd6, 0xe1, 0x3f, 0xfd, ++ 0xf2, 0x41, 0x8d, 0x8d, 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3, ++ 0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, 0x31, 0x8e, 0xea, 0x39, ++ 0x2c, 0xf4, 0x1b, 0x08 ++}; ++ ++static const unsigned char XTS_256_i[] = { ++ 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, 0xf0, 0x42, 0x8e, 0x84, ++ 0xa9, 0xf8, 0x75, 0x64 ++}; ++ ++static const unsigned char XTS_256_pt[] = { ++ 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, 0xac, 0xc6, 0x47, 0xe8, ++ 0x10, 0xbb, 0xc3, 0x64, 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, ++ 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e ++}; ++ ++static const unsigned char XTS_256_ct[] = { ++ 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, 0x0b, 0x37, 0xf9, 0x34, ++ 0xd4, 0x6a, 0x9b, 0x13, 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, ++ 0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb ++}; ++ ++int FIPS_selftest_aes_xts() ++{ ++ int ret = 1; ++ EVP_CIPHER_CTX *ctx; ++ ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ if (fips_cipher_test(ctx, EVP_aes_128_xts(), ++ XTS_128_key, XTS_128_i, XTS_128_pt, XTS_128_ct, ++ sizeof(XTS_128_pt)) <= 0) ++ ret = 0; ++ ++ if (fips_cipher_test(ctx, EVP_aes_256_xts(), ++ XTS_256_key, XTS_256_i, XTS_256_pt, XTS_256_ct, ++ sizeof(XTS_256_pt)) <= 0) ++ ret = 0; ++ ++ EVP_CIPHER_CTX_free(ctx); ++ ++ err: ++ if (ret == 0) ++ FIPSerr(FIPS_F_FIPS_SELFTEST_AES_XTS, FIPS_R_SELFTEST_FAILED); ++ return ret; ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips.c.fips openssl-1.1.1j/crypto/fips/fips.c +--- openssl-1.1.1j/crypto/fips/fips.c.fips 2021-03-03 12:57:42.198734517 +0100 ++++ openssl-1.1.1j/crypto/fips/fips.c 2021-03-03 12:57:42.198734517 +0100 +@@ -0,0 +1,526 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++# include ++# include "internal/thread_once.h" ++ ++# ifndef PATH_MAX ++# define PATH_MAX 1024 ++# endif ++ ++static int fips_selftest_fail = 0; ++static int fips_mode = 0; ++static int fips_started = 0; ++ ++static int fips_is_owning_thread(void); ++static int fips_set_owning_thread(void); ++static int fips_clear_owning_thread(void); ++ ++static CRYPTO_RWLOCK *fips_lock = NULL; ++static CRYPTO_RWLOCK *fips_owning_lock = NULL; ++static CRYPTO_ONCE fips_lock_init = CRYPTO_ONCE_STATIC_INIT; ++ ++DEFINE_RUN_ONCE_STATIC(do_fips_lock_init) ++{ ++ fips_lock = CRYPTO_THREAD_lock_new(); ++ fips_owning_lock = CRYPTO_THREAD_lock_new(); ++ return fips_lock != NULL && fips_owning_lock != NULL; ++} ++ ++# define fips_w_lock() CRYPTO_THREAD_write_lock(fips_lock) ++# define fips_w_unlock() CRYPTO_THREAD_unlock(fips_lock) ++# define fips_r_lock() CRYPTO_THREAD_read_lock(fips_lock) ++# define fips_r_unlock() CRYPTO_THREAD_unlock(fips_lock) ++ ++static void fips_set_mode(int onoff) ++{ ++ int owning_thread = fips_is_owning_thread(); ++ ++ if (fips_started) { ++ if (!owning_thread) ++ fips_w_lock(); ++ fips_mode = onoff; ++ if (!owning_thread) ++ fips_w_unlock(); ++ } ++} ++ ++int FIPS_module_mode(void) ++{ ++ int ret = 0; ++ int owning_thread = fips_is_owning_thread(); ++ ++ if (fips_started) { ++ if (!owning_thread) ++ fips_r_lock(); ++ ret = fips_mode; ++ if (!owning_thread) ++ fips_r_unlock(); ++ } ++ return ret; ++} ++ ++/* just a compat symbol - return NULL */ ++int FIPS_selftest_failed(void) ++{ ++ int ret = 0; ++ if (fips_started) { ++ int owning_thread = fips_is_owning_thread(); ++ ++ if (!owning_thread) ++ fips_r_lock(); ++ ret = fips_selftest_fail; ++ if (!owning_thread) ++ fips_r_unlock(); ++ } ++ return ret; ++} ++ ++/* Selftest failure fatal exit routine. This will be called ++ * during *any* cryptographic operation. It has the minimum ++ * overhead possible to avoid too big a performance hit. ++ */ ++ ++void FIPS_selftest_check(void) ++{ ++ if (fips_selftest_fail) { ++ OpenSSLDie(__FILE__, __LINE__, "FATAL FIPS SELFTEST FAILURE"); ++ } ++} ++ ++void fips_set_selftest_fail(void) ++{ ++ fips_selftest_fail = 1; ++} ++ ++/* we implement what libfipscheck does ourselves */ ++ ++static int ++get_library_path(const char *libname, const char *symbolname, char *path, ++ size_t pathlen) ++{ ++ Dl_info info; ++ void *dl, *sym; ++ int rv = -1; ++ ++ dl = dlopen(libname, RTLD_LAZY); ++ if (dl == NULL) { ++ return -1; ++ } ++ ++ sym = dlsym(dl, symbolname); ++ ++ if (sym != NULL && dladdr(sym, &info)) { ++ strncpy(path, info.dli_fname, pathlen - 1); ++ path[pathlen - 1] = '\0'; ++ rv = 0; ++ } ++ ++ dlclose(dl); ++ ++ return rv; ++} ++ ++static const char conv[] = "0123456789abcdef"; ++ ++static char *bin2hex(void *buf, size_t len) ++{ ++ char *hex, *p; ++ unsigned char *src = buf; ++ ++ hex = malloc(len * 2 + 1); ++ if (hex == NULL) ++ return NULL; ++ ++ p = hex; ++ ++ while (len > 0) { ++ unsigned c; ++ ++ c = *src; ++ src++; ++ ++ *p = conv[c >> 4]; ++ ++p; ++ *p = conv[c & 0x0f]; ++ ++p; ++ --len; ++ } ++ *p = '\0'; ++ return hex; ++} ++ ++# define HMAC_PREFIX "." ++# ifndef HMAC_SUFFIX ++# define HMAC_SUFFIX ".hmac" ++# endif ++# define READ_BUFFER_LENGTH 16384 ++ ++static char *make_hmac_path(const char *origpath) ++{ ++ char *path, *p; ++ const char *fn; ++ ++ path = ++ malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath)); ++ if (path == NULL) { ++ return NULL; ++ } ++ ++ fn = strrchr(origpath, '/'); ++ if (fn == NULL) { ++ fn = origpath; ++ } else { ++ ++fn; ++ } ++ ++ strncpy(path, origpath, fn - origpath); ++ p = path + (fn - origpath); ++ p = stpcpy(p, HMAC_PREFIX); ++ p = stpcpy(p, fn); ++ p = stpcpy(p, HMAC_SUFFIX); ++ ++ return path; ++} ++ ++static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP"; ++ ++static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen) ++{ ++ FILE *f = NULL; ++ int rv = -1; ++ unsigned char rbuf[READ_BUFFER_LENGTH]; ++ size_t len; ++ unsigned int hlen; ++ HMAC_CTX *c; ++ ++ c = HMAC_CTX_new(); ++ if (c == NULL) ++ return rv; ++ ++ f = fopen(path, "r"); ++ ++ if (f == NULL) { ++ goto end; ++ } ++ ++ if (HMAC_Init_ex(c, hmackey, sizeof(hmackey) - 1, EVP_sha256(), NULL) <= 0) { ++ goto end; ++ } ++ ++ while ((len = fread(rbuf, 1, sizeof(rbuf), f)) != 0) { ++ if (HMAC_Update(c, rbuf, len) <= 0) { ++ goto end; ++ } ++ } ++ ++ len = sizeof(rbuf); ++ /* reuse rbuf for hmac */ ++ if (HMAC_Final(c, rbuf, &hlen) <= 0) { ++ goto end; ++ } ++ ++ *buf = malloc(hlen); ++ if (*buf == NULL) { ++ goto end; ++ } ++ ++ *hmaclen = hlen; ++ ++ memcpy(*buf, rbuf, hlen); ++ ++ rv = 0; ++ end: ++ HMAC_CTX_free(c); ++ ++ if (f) ++ fclose(f); ++ ++ return rv; ++} ++ ++static int FIPSCHECK_verify(const char *path) ++{ ++ int rv = 0; ++ FILE *hf; ++ char *hmacpath, *p; ++ char *hmac = NULL; ++ size_t n; ++ ++ hmacpath = make_hmac_path(path); ++ if (hmacpath == NULL) ++ return 0; ++ ++ hf = fopen(hmacpath, "r"); ++ if (hf == NULL) { ++ free(hmacpath); ++ return 0; ++ } ++ ++ if (getline(&hmac, &n, hf) > 0) { ++ void *buf; ++ size_t hmaclen; ++ char *hex; ++ ++ if ((p = strchr(hmac, '\n')) != NULL) ++ *p = '\0'; ++ ++ if (compute_file_hmac(path, &buf, &hmaclen) < 0) { ++ rv = -4; ++ goto end; ++ } ++ ++ if ((hex = bin2hex(buf, hmaclen)) == NULL) { ++ free(buf); ++ rv = -5; ++ goto end; ++ } ++ ++ if (strcmp(hex, hmac) != 0) { ++ rv = -1; ++ } ++ free(buf); ++ free(hex); ++ } else { ++ rv = -1; ++ } ++ ++ end: ++ free(hmac); ++ free(hmacpath); ++ fclose(hf); ++ ++ if (rv < 0) ++ return 0; ++ ++ /* check successful */ ++ return 1; ++} ++ ++static int verify_checksums(void) ++{ ++ int rv; ++ char path[PATH_MAX + 1]; ++ char *p; ++ ++ /* we need to avoid dlopening libssl, assume both libcrypto and libssl ++ are in the same directory */ ++ ++ rv = get_library_path("libcrypto.so." SHLIB_VERSION_NUMBER, ++ "FIPS_mode_set", path, sizeof(path)); ++ if (rv < 0) ++ return 0; ++ ++ rv = FIPSCHECK_verify(path); ++ if (!rv) ++ return 0; ++ ++ /* replace libcrypto with libssl */ ++ while ((p = strstr(path, "libcrypto.so")) != NULL) { ++ p = stpcpy(p, "libssl"); ++ memmove(p, p + 3, strlen(p + 2)); ++ } ++ ++ rv = FIPSCHECK_verify(path); ++ if (!rv) ++ return 0; ++ return 1; ++} ++ ++# ifndef FIPS_MODULE_PATH ++# define FIPS_MODULE_PATH "/etc/system-fips" ++# endif ++ ++int FIPS_module_installed(void) ++{ ++ int rv; ++ rv = access(FIPS_MODULE_PATH, F_OK); ++ if (rv < 0 && errno != ENOENT) ++ rv = 0; ++ ++ /* Installed == true */ ++ return !rv || FIPS_module_mode(); ++} ++ ++int FIPS_module_mode_set(int onoff) ++{ ++ int ret = 0; ++ ++ if (!RUN_ONCE(&fips_lock_init, do_fips_lock_init)) ++ return 0; ++ ++ fips_w_lock(); ++ fips_started = 1; ++ fips_set_owning_thread(); ++ ++ if (onoff) { ++ ++ fips_selftest_fail = 0; ++ ++ /* Don't go into FIPS mode twice, just so we can do automagic ++ seeding */ ++ if (FIPS_module_mode()) { ++ FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, ++ FIPS_R_FIPS_MODE_ALREADY_SET); ++ fips_selftest_fail = 1; ++ ret = 0; ++ goto end; ++ } ++# ifdef OPENSSL_IA32_SSE2 ++ { ++ extern unsigned int OPENSSL_ia32cap_P[2]; ++ if ((OPENSSL_ia32cap_P[0] & (1 << 25 | 1 << 26)) != ++ (1 << 25 | 1 << 26)) { ++ FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, ++ FIPS_R_UNSUPPORTED_PLATFORM); ++ fips_selftest_fail = 1; ++ ret = 0; ++ goto end; ++ } ++ } ++# endif ++ ++ if (!FIPS_selftest()) { ++ fips_selftest_fail = 1; ++ ret = 0; ++ goto end; ++ } ++ ++ if (!verify_checksums()) { ++ FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, ++ FIPS_R_FINGERPRINT_DOES_NOT_MATCH); ++ fips_selftest_fail = 1; ++ ret = 0; ++ goto end; ++ } ++ ++ fips_set_mode(onoff); ++ ret = 1; ++ goto end; ++ } ++ fips_set_mode(0); ++ fips_selftest_fail = 0; ++ ret = 1; ++ end: ++ fips_clear_owning_thread(); ++ fips_w_unlock(); ++ return ret; ++} ++ ++static CRYPTO_THREAD_ID fips_threadid; ++static int fips_thread_set = 0; ++ ++static int fips_is_owning_thread(void) ++{ ++ int ret = 0; ++ ++ if (fips_started) { ++ CRYPTO_THREAD_read_lock(fips_owning_lock); ++ if (fips_thread_set) { ++ CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id(); ++ if (CRYPTO_THREAD_compare_id(fips_threadid, cur)) ++ ret = 1; ++ } ++ CRYPTO_THREAD_unlock(fips_owning_lock); ++ } ++ return ret; ++} ++ ++int fips_set_owning_thread(void) ++{ ++ int ret = 0; ++ ++ if (fips_started) { ++ CRYPTO_THREAD_write_lock(fips_owning_lock); ++ if (!fips_thread_set) { ++ fips_threadid = CRYPTO_THREAD_get_current_id(); ++ ret = 1; ++ fips_thread_set = 1; ++ } ++ CRYPTO_THREAD_unlock(fips_owning_lock); ++ } ++ return ret; ++} ++ ++int fips_clear_owning_thread(void) ++{ ++ int ret = 0; ++ ++ if (fips_started) { ++ CRYPTO_THREAD_write_lock(fips_owning_lock); ++ if (fips_thread_set) { ++ CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id(); ++ if (CRYPTO_THREAD_compare_id(fips_threadid, cur)) ++ fips_thread_set = 0; ++ } ++ CRYPTO_THREAD_unlock(fips_owning_lock); ++ } ++ return ret; ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_cmac_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_cmac_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_cmac_selftest.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_cmac_selftest.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,156 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++typedef struct { ++ int nid; ++ const unsigned char key[EVP_MAX_KEY_LENGTH]; ++ size_t keysize; ++ const unsigned char msg[64]; ++ size_t msgsize; ++ const unsigned char mac[32]; ++ size_t macsize; ++} CMAC_KAT; ++ ++/* from http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf */ ++static const CMAC_KAT vector[] = { ++ {NID_aes_128_cbc, /* Count = 32 from CMACGenAES128.txt */ ++ {0x77, 0xa7, 0x7f, 0xaf, 0x29, 0x0c, 0x1f, 0xa3, ++ 0x0c, 0x68, 0x3d, 0xf1, 0x6b, 0xa7, 0xa7, 0x7b,}, 128, ++ {0x02, 0x06, 0x83, 0xe1, 0xf0, 0x39, 0x2f, 0x4c, ++ 0xac, 0x54, 0x31, 0x8b, 0x60, 0x29, 0x25, 0x9e, ++ 0x9c, 0x55, 0x3d, 0xbc, 0x4b, 0x6a, 0xd9, 0x98, ++ 0xe6, 0x4d, 0x58, 0xe4, 0xe7, 0xdc, 0x2e, 0x13,}, 256, ++ {0xfb, 0xfe, 0xa4, 0x1b,}, 32}, ++ {NID_aes_192_cbc, /* Count = 23 from CMACGenAES192.txt */ ++ {0x7b, 0x32, 0x39, 0x13, 0x69, 0xaa, 0x4c, 0xa9, ++ 0x75, 0x58, 0x09, 0x5b, 0xe3, 0xc3, 0xec, 0x86, ++ 0x2b, 0xd0, 0x57, 0xce, 0xf1, 0xe3, 0x2d, 0x62,}, 192, ++ {0x0}, 0, ++ {0xe4, 0xd9, 0x34, 0x0b, 0x03, 0xe6, 0x7d, 0xef, ++ 0xd4, 0x96, 0x9c, 0xc1, 0xed, 0x37, 0x35, 0xe6,}, 128, ++ }, ++ {NID_aes_256_cbc, /* Count = 33 from CMACGenAES256.txt */ ++ {0x0b, 0x12, 0x2a, 0xc8, 0xf3, 0x4e, 0xd1, 0xfe, ++ 0x08, 0x2a, 0x36, 0x25, 0xd1, 0x57, 0x56, 0x14, ++ 0x54, 0x16, 0x7a, 0xc1, 0x45, 0xa1, 0x0b, 0xbf, ++ 0x77, 0xc6, 0xa7, 0x05, 0x96, 0xd5, 0x74, 0xf1,}, 256, ++ {0x49, 0x8b, 0x53, 0xfd, 0xec, 0x87, 0xed, 0xcb, ++ 0xf0, 0x70, 0x97, 0xdc, 0xcd, 0xe9, 0x3a, 0x08, ++ 0x4b, 0xad, 0x75, 0x01, 0xa2, 0x24, 0xe3, 0x88, ++ 0xdf, 0x34, 0x9c, 0xe1, 0x89, 0x59, 0xfe, 0x84, ++ 0x85, 0xf8, 0xad, 0x15, 0x37, 0xf0, 0xd8, 0x96, ++ 0xea, 0x73, 0xbe, 0xdc, 0x72, 0x14, 0x71, 0x3f,}, 384, ++ {0xf6, 0x2c, 0x46, 0x32, 0x9b,}, 40, ++ }, ++ {NID_des_ede3_cbc, /* Count = 41 from CMACGenTDES3.req */ ++ {0x89, 0xbc, 0xd9, 0x52, 0xa8, 0xc8, 0xab, 0x37, ++ 0x1a, 0xf4, 0x8a, 0xc7, 0xd0, 0x70, 0x85, 0xd5, ++ 0xef, 0xf7, 0x02, 0xe6, 0xd6, 0x2c, 0xdc, 0x23,}, 192, ++ {0xfa, 0x62, 0x0c, 0x1b, 0xbe, 0x97, 0x31, 0x9e, ++ 0x9a, 0x0c, 0xf0, 0x49, 0x21, 0x21, 0xf7, 0xa2, ++ 0x0e, 0xb0, 0x8a, 0x6a, 0x70, 0x9d, 0xcb, 0xd0, ++ 0x0a, 0xaf, 0x38, 0xe4, 0xf9, 0x9e, 0x75, 0x4e,}, 256, ++ {0x8f, 0x49, 0xa1, 0xb7, 0xd6, 0xaa, 0x22, 0x58,}, 64, ++ }, ++}; ++ ++int FIPS_selftest_cmac() ++{ ++ size_t n, outlen; ++ unsigned char out[32]; ++ const EVP_CIPHER *cipher; ++ CMAC_CTX *ctx = CMAC_CTX_new(); ++ const CMAC_KAT *t; ++ int rv = 1; ++ ++ for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) { ++ cipher = EVP_get_cipherbynid(t->nid); ++ if (!cipher) { ++ rv = -1; ++ goto err; ++ } ++ if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) { ++ rv = -1; ++ goto err; ++ } ++ if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!CMAC_Final(ctx, out, &outlen)) { ++ rv = -1; ++ goto err; ++ } ++ ++ if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) { ++ rv = 0; ++ } ++ } ++ ++ err: ++ CMAC_CTX_free(ctx); ++ ++ if (rv == -1) { ++ rv = 0; ++ } ++ if (!rv) ++ FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED); ++ ++ return rv; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_des_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_des_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_des_selftest.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_des_selftest.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,133 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++# include "crypto/fips.h" ++#endif ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++static const struct { ++ const unsigned char key[16]; ++ const unsigned char plaintext[8]; ++ const unsigned char ciphertext[8]; ++} tests2[] = { ++ { ++ { ++ 0x7c, 0x4f, 0x6e, 0xf7, 0xa2, 0x04, 0x16, 0xec, ++ 0x0b, 0x6b, 0x7c, 0x9e, 0x5e, 0x19, 0xa7, 0xc4}, { ++ 0x06, 0xa7, 0xd8, 0x79, 0xaa, 0xce, 0x69, 0xef}, { ++ 0x4c, 0x11, 0x17, 0x55, 0xbf, 0xc4, 0x4e, 0xfd} ++ }, { ++ { ++ 0x5d, 0x9e, 0x01, 0xd3, 0x25, 0xc7, 0x3e, 0x34, ++ 0x01, 0x16, 0x7c, 0x85, 0x23, 0xdf, 0xe0, 0x68}, { ++ 0x9c, 0x50, 0x09, 0x0f, 0x5e, 0x7d, 0x69, 0x7e}, { ++ 0xd2, 0x0b, 0x18, 0xdf, 0xd9, 0x0d, 0x9e, 0xff},} ++}; ++ ++static const struct { ++ const unsigned char key[24]; ++ const unsigned char plaintext[8]; ++ const unsigned char ciphertext[8]; ++} tests3[] = { ++ { ++ { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, ++ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, { ++ 0x8f, 0x8f, 0xbf, 0x9b, 0x5d, 0x48, 0xb4, 0x1c}, { ++ 0x59, 0x8c, 0xe5, 0xd3, 0x6c, 0xa2, 0xea, 0x1b},}, { ++ { ++ 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, ++ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, ++ 0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4}, { ++ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, { ++0x11, 0x25, 0xb0, 0x35, 0xbe, 0xa0, 0x82, 0x86},},}; ++ ++int FIPS_selftest_des() ++{ ++ int n, ret = 0; ++ EVP_CIPHER_CTX *ctx; ++ ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ /* Encrypt/decrypt with 2-key 3DES and compare to known answers */ ++ for (n = 0; n < 2; ++n) { ++ unsigned char plaintext[8]; ++ ++ memcpy(plaintext, tests2[n].plaintext, sizeof(plaintext)); ++ if (!fips_cipher_test(ctx, EVP_des_ede_ecb(), ++ tests2[n].key, NULL, ++ plaintext, tests2[n].ciphertext, 8)) ++ goto err; ++ } ++ ++ /* Encrypt/decrypt with 3DES and compare to known answers */ ++ for (n = 0; n < 2; ++n) { ++ if (!fips_cipher_test(ctx, EVP_des_ede3_ecb(), ++ tests3[n].key, NULL, ++ tests3[n].plaintext, tests3[n].ciphertext, 8)) ++ goto err; ++ } ++ ret = 1; ++ err: ++ EVP_CIPHER_CTX_free(ctx); ++ if (ret == 0) ++ FIPSerr(FIPS_F_FIPS_SELFTEST_DES, FIPS_R_SELFTEST_FAILED); ++ ++ return ret; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_dh_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_dh_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_dh_selftest.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_dh_selftest.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,180 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 2013 Red Hat, Inc. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++static const unsigned char dh_test_2048_p[] = { ++ 0xAE, 0xEC, 0xEE, 0x22, 0xFA, 0x3A, 0xA5, 0x22, 0xC0, 0xDE, 0x0F, 0x09, ++ 0x7E, 0x17, 0xC0, 0x05, 0xF9, 0xF1, 0xE7, 0xC6, 0x87, 0x14, 0x6D, 0x11, ++ 0xE7, 0xAE, 0xED, 0x2F, 0x72, 0x59, 0xC5, 0xA9, 0x9B, 0xB8, 0x02, 0xA5, ++ 0xF3, 0x69, 0x70, 0xD6, 0xDD, 0x90, 0xF9, 0x19, 0x79, 0xBE, 0x60, 0x8F, ++ 0x25, 0x92, 0x30, 0x1C, 0x51, 0x51, 0x38, 0x26, 0x82, 0x25, 0xE6, 0xFC, ++ 0xED, 0x65, 0x96, 0x8F, 0x57, 0xE5, 0x53, 0x8B, 0x38, 0x63, 0xC7, 0xCE, ++ 0xBC, 0x1B, 0x4D, 0x18, 0x2A, 0x5B, 0x04, 0x3F, 0x6A, 0x3C, 0x94, 0x39, ++ 0xAE, 0x36, 0xD6, 0x5E, 0x0F, 0xA2, 0xCC, 0xD0, 0xD4, 0xD5, 0xC6, 0x1E, ++ 0xF6, 0xA0, 0xF5, 0x89, 0x4E, 0xB4, 0x0B, 0xA4, 0xB3, 0x2B, 0x3D, 0xE2, ++ 0x4E, 0xE1, 0x49, 0x25, 0x99, 0x5F, 0x32, 0x16, 0x33, 0x32, 0x1B, 0x7A, ++ 0xA5, 0x5C, 0x6B, 0x34, 0x0D, 0x39, 0x99, 0xDC, 0xF0, 0x76, 0xE5, 0x5A, ++ 0xD4, 0x71, 0x00, 0xED, 0x5A, 0x73, 0xFB, 0xC8, 0x01, 0xAD, 0x99, 0xCF, ++ 0x99, 0x52, 0x7C, 0x9C, 0x64, 0xC6, 0x76, 0x40, 0x57, 0xAF, 0x59, 0xD7, ++ 0x38, 0x0B, 0x40, 0xDE, 0x33, 0x0D, 0xB8, 0x76, 0xEC, 0xA9, 0xD8, 0x73, ++ 0xF8, 0xEF, 0x26, 0x66, 0x06, 0x27, 0xDD, 0x7C, 0xA4, 0x10, 0x9C, 0xA6, ++ 0xAA, 0xF9, 0x53, 0x62, 0x73, 0x1D, 0xBA, 0x1C, 0xF1, 0x67, 0xF4, 0x35, ++ 0xED, 0x6F, 0x37, 0x92, 0xE8, 0x4F, 0x6C, 0xBA, 0x52, 0x6E, 0xA1, 0xED, ++ 0xDA, 0x9F, 0x85, 0x11, 0x82, 0x52, 0x62, 0x08, 0x44, 0xF1, 0x30, 0x03, ++ 0xC3, 0x38, 0x2C, 0x79, 0xBD, 0xD4, 0x43, 0x45, 0xEE, 0x8E, 0x50, 0xFC, ++ 0x29, 0x46, 0x9A, 0xFE, 0x54, 0x1A, 0x19, 0x8F, 0x4B, 0x84, 0x08, 0xDE, ++ 0x20, 0x62, 0x73, 0xCC, 0xDD, 0x7E, 0xF0, 0xEF, 0xA2, 0xFD, 0x86, 0x58, ++ 0x4B, 0xD8, 0x37, 0xEB ++}; ++ ++static const unsigned char dh_test_2048_g[] = { ++ 0x02 ++}; ++ ++static const unsigned char dh_test_2048_pub_key[] = { ++ 0xA0, 0x39, 0x11, 0x77, 0x9A, 0xC1, 0x30, 0x1F, 0xBE, 0x48, 0xA7, 0xAA, ++ 0xA0, 0x84, 0x54, 0x64, 0xAD, 0x1B, 0x70, 0xFA, 0x13, 0x55, 0x63, 0xD2, ++ 0x1F, 0x62, 0x32, 0x93, 0x8E, 0xC9, 0x3E, 0x09, 0xA7, 0x64, 0xE4, 0x12, ++ 0x6E, 0x1B, 0xF2, 0x92, 0x3B, 0xB9, 0xCB, 0x56, 0xEA, 0x07, 0x88, 0xB5, ++ 0xA6, 0xBC, 0x16, 0x1F, 0x27, 0xFE, 0xD8, 0xAA, 0x40, 0xB2, 0xB0, 0x2D, ++ 0x37, 0x76, 0xA6, 0xA4, 0x82, 0x2C, 0x0E, 0x22, 0x64, 0x9D, 0xCB, 0xD1, ++ 0x00, 0xB7, 0x89, 0x14, 0x72, 0x4E, 0xBE, 0x48, 0x41, 0xF8, 0xB2, 0x51, ++ 0x11, 0x09, 0x4B, 0x22, 0x01, 0x23, 0x39, 0x96, 0xE0, 0x15, 0xD7, 0x9F, ++ 0x60, 0xD1, 0xB7, 0xAE, 0xFE, 0x5F, 0xDB, 0xE7, 0x03, 0x17, 0x97, 0xA6, ++ 0x16, 0x74, 0xBD, 0x53, 0x81, 0x19, 0xC5, 0x47, 0x5E, 0xCE, 0x8D, 0xED, ++ 0x45, 0x5D, 0x3C, 0x00, 0xA0, 0x0A, 0x68, 0x6A, 0xE0, 0x8E, 0x06, 0x46, ++ 0x6F, 0xD7, 0xF9, 0xDF, 0x31, 0x7E, 0x77, 0x44, 0x0D, 0x98, 0xE0, 0xCA, ++ 0x98, 0x09, 0x52, 0x04, 0x90, 0xEA, 0x6D, 0xF4, 0x30, 0x69, 0x8F, 0xB1, ++ 0x9B, 0xC1, 0x43, 0xDB, 0xD5, 0x8D, 0xC8, 0x8E, 0xB6, 0x0B, 0x05, 0xBE, ++ 0x0E, 0xC5, 0x99, 0xC8, 0x6E, 0x4E, 0xF3, 0xCB, 0xC3, 0x5E, 0x9B, 0x53, ++ 0xF7, 0x06, 0x1C, 0x4F, 0xC7, 0xB8, 0x6E, 0x30, 0x18, 0xCA, 0x9B, 0xB9, ++ 0xBC, 0x5F, 0x17, 0x72, 0x29, 0x5A, 0xE5, 0xD9, 0x96, 0xB7, 0x0B, 0xF3, ++ 0x2D, 0x8C, 0xF1, 0xE1, 0x0E, 0x0D, 0x74, 0xD5, 0x9D, 0xF0, 0x06, 0xA9, ++ 0xB4, 0x95, 0x63, 0x76, 0x46, 0x55, 0x48, 0x82, 0x39, 0x90, 0xEF, 0x56, ++ 0x75, 0x34, 0xB8, 0x34, 0xC3, 0x18, 0x6E, 0x1E, 0xAD, 0xE3, 0x48, 0x7E, ++ 0x93, 0x2C, 0x23, 0xE7, 0xF8, 0x90, 0x73, 0xB1, 0x77, 0x80, 0x67, 0xA9, ++ 0x36, 0x9E, 0xDA, 0xD2 ++}; ++ ++static const unsigned char dh_test_2048_priv_key[] = { ++ 0x0C, 0x4B, 0x30, 0x89, 0xD1, 0xB8, 0x62, 0xCB, 0x3C, 0x43, 0x64, 0x91, ++ 0xF0, 0x91, 0x54, 0x70, 0xC5, 0x27, 0x96, 0xE3, 0xAC, 0xBE, 0xE8, 0x00, ++ 0xEC, 0x55, 0xF6, 0xCC ++}; ++ ++int FIPS_selftest_dh() ++{ ++ DH *dh = NULL; ++ int ret = 0; ++ void *pub_key_bin = NULL; ++ int len; ++ BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *tmp_pub_key = NULL; ++ const BIGNUM *pub_key; ++ ++ fips_load_key_component(p, dh_test_2048); ++ fips_load_key_component(g, dh_test_2048); ++ /* note that the private key is much shorter than normally used ++ * but still g ** priv_key > p ++ */ ++ fips_load_key_component(priv_key, dh_test_2048); ++ if ((tmp_pub_key = BN_new()) == NULL) ++ goto err; ++ ++ dh = DH_new(); ++ ++ if (dh == NULL) ++ goto err; ++ ++ DH_set0_pqg(dh, p, NULL, g); ++ DH_set0_key(dh, tmp_pub_key, priv_key); ++ ++ if (DH_generate_key(dh) <= 0) ++ goto err; ++ ++ DH_get0_key(dh, &pub_key, NULL); ++ ++ if (pub_key == NULL) ++ goto err; ++ ++ len = BN_num_bytes(pub_key); ++ if ((pub_key_bin = OPENSSL_malloc(len)) == NULL) ++ goto err; ++ BN_bn2bin(pub_key, pub_key_bin); ++ ++ if (len != sizeof(dh_test_2048_pub_key) || ++ memcmp(pub_key_bin, dh_test_2048_pub_key, len) != 0) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ if (dh) ++ DH_free(dh); ++ else { ++ BN_free(p); ++ BN_free(g); ++ BN_free(priv_key); ++ BN_free(tmp_pub_key); ++ } ++ ++ OPENSSL_free(pub_key_bin); ++ return ret; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_ctr.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_ctr.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_ctr.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_ctr.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,406 @@ ++/* fips/rand/fips_drbg_ctr.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "fips_rand_lcl.h" ++ ++static void inc_128(DRBG_CTR_CTX * cctx) ++{ ++ int i; ++ unsigned char c; ++ unsigned char *p = cctx->V + 15; ++ for (i = 0; i < 16; i++) { ++ c = *p; ++ c++; ++ *p = c; ++ if (c) ++ return; ++ p--; ++ } ++} ++ ++static void ctr_XOR(DRBG_CTR_CTX * cctx, const unsigned char *in, ++ size_t inlen) ++{ ++ size_t i, n; ++ /* Any zero padding will have no effect on the result as we ++ * are XORing. So just process however much input we have. ++ */ ++ ++ if (!in || !inlen) ++ return; ++ ++ if (inlen < cctx->keylen) ++ n = inlen; ++ else ++ n = cctx->keylen; ++ ++ for (i = 0; i < n; i++) ++ cctx->K[i] ^= in[i]; ++ if (inlen <= cctx->keylen) ++ return; ++ ++ n = inlen - cctx->keylen; ++ /* Should never happen */ ++ if (n > 16) ++ n = 16; ++ for (i = 0; i < 16; i++) ++ cctx->V[i] ^= in[i + cctx->keylen]; ++} ++ ++/* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */ ++ ++static void ctr_BCC_block(DRBG_CTR_CTX * cctx, unsigned char *out, ++ const unsigned char *in) ++{ ++ int i; ++ for (i = 0; i < 16; i++) ++ out[i] ^= in[i]; ++ AES_encrypt(out, out, &cctx->df_ks); ++#if 0 ++ fprintf(stderr, "BCC in+out\n"); ++ BIO_dump_fp(stderr, in, 16); ++ BIO_dump_fp(stderr, out, 16); ++#endif ++} ++ ++/* Handle several BCC operations for as much data as we need for K and X */ ++static void ctr_BCC_blocks(DRBG_CTR_CTX * cctx, const unsigned char *in) ++{ ++ ctr_BCC_block(cctx, cctx->KX, in); ++ ctr_BCC_block(cctx, cctx->KX + 16, in); ++ if (cctx->keylen != 16) ++ ctr_BCC_block(cctx, cctx->KX + 32, in); ++} ++ ++/* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions: ++ * see 10.4.2 stage 7. ++ */ ++static void ctr_BCC_init(DRBG_CTR_CTX * cctx) ++{ ++ memset(cctx->KX, 0, 48); ++ memset(cctx->bltmp, 0, 16); ++ ctr_BCC_block(cctx, cctx->KX, cctx->bltmp); ++ cctx->bltmp[3] = 1; ++ ctr_BCC_block(cctx, cctx->KX + 16, cctx->bltmp); ++ if (cctx->keylen != 16) { ++ cctx->bltmp[3] = 2; ++ ctr_BCC_block(cctx, cctx->KX + 32, cctx->bltmp); ++ } ++} ++ ++/* Process several blocks into BCC algorithm, some possibly partial */ ++static void ctr_BCC_update(DRBG_CTR_CTX * cctx, ++ const unsigned char *in, size_t inlen) ++{ ++ if (!in || !inlen) ++ return; ++ /* If we have partial block handle it first */ ++ if (cctx->bltmp_pos) { ++ size_t left = 16 - cctx->bltmp_pos; ++ /* If we now have a complete block process it */ ++ if (inlen >= left) { ++ memcpy(cctx->bltmp + cctx->bltmp_pos, in, left); ++ ctr_BCC_blocks(cctx, cctx->bltmp); ++ cctx->bltmp_pos = 0; ++ inlen -= left; ++ in += left; ++ } ++ } ++ /* Process zero or more complete blocks */ ++ while (inlen >= 16) { ++ ctr_BCC_blocks(cctx, in); ++ in += 16; ++ inlen -= 16; ++ } ++ /* Copy any remaining partial block to the temporary buffer */ ++ if (inlen > 0) { ++ memcpy(cctx->bltmp + cctx->bltmp_pos, in, inlen); ++ cctx->bltmp_pos += inlen; ++ } ++} ++ ++static void ctr_BCC_final(DRBG_CTR_CTX * cctx) ++{ ++ if (cctx->bltmp_pos) { ++ memset(cctx->bltmp + cctx->bltmp_pos, 0, 16 - cctx->bltmp_pos); ++ ctr_BCC_blocks(cctx, cctx->bltmp); ++ } ++} ++ ++static void ctr_df(DRBG_CTR_CTX * cctx, ++ const unsigned char *in1, size_t in1len, ++ const unsigned char *in2, size_t in2len, ++ const unsigned char *in3, size_t in3len) ++{ ++ size_t inlen; ++ unsigned char *p = cctx->bltmp; ++ static unsigned char c80 = 0x80; ++ ++ ctr_BCC_init(cctx); ++ if (!in1) ++ in1len = 0; ++ if (!in2) ++ in2len = 0; ++ if (!in3) ++ in3len = 0; ++ inlen = in1len + in2len + in3len; ++ /* Initialise L||N in temporary block */ ++ *p++ = (inlen >> 24) & 0xff; ++ *p++ = (inlen >> 16) & 0xff; ++ *p++ = (inlen >> 8) & 0xff; ++ *p++ = inlen & 0xff; ++ /* NB keylen is at most 32 bytes */ ++ *p++ = 0; ++ *p++ = 0; ++ *p++ = 0; ++ *p = (unsigned char)((cctx->keylen + 16) & 0xff); ++ cctx->bltmp_pos = 8; ++ ctr_BCC_update(cctx, in1, in1len); ++ ctr_BCC_update(cctx, in2, in2len); ++ ctr_BCC_update(cctx, in3, in3len); ++ ctr_BCC_update(cctx, &c80, 1); ++ ctr_BCC_final(cctx); ++ /* Set up key K */ ++ AES_set_encrypt_key(cctx->KX, cctx->keylen * 8, &cctx->df_kxks); ++ /* X follows key K */ ++ AES_encrypt(cctx->KX + cctx->keylen, cctx->KX, &cctx->df_kxks); ++ AES_encrypt(cctx->KX, cctx->KX + 16, &cctx->df_kxks); ++ if (cctx->keylen != 16) ++ AES_encrypt(cctx->KX + 16, cctx->KX + 32, &cctx->df_kxks); ++#if 0 ++ fprintf(stderr, "Output of ctr_df:\n"); ++ BIO_dump_fp(stderr, cctx->KX, cctx->keylen + 16); ++#endif ++} ++ ++/* NB the no-df Update in SP800-90 specifies a constant input length ++ * of seedlen, however other uses of this algorithm pad the input with ++ * zeroes if necessary and have up to two parameters XORed together, ++ * handle both cases in this function instead. ++ */ ++ ++static void ctr_Update(DRBG_CTX *dctx, ++ const unsigned char *in1, size_t in1len, ++ const unsigned char *in2, size_t in2len, ++ const unsigned char *nonce, size_t noncelen) ++{ ++ DRBG_CTR_CTX *cctx = &dctx->d.ctr; ++ /* ks is already setup for correct key */ ++ inc_128(cctx); ++ AES_encrypt(cctx->V, cctx->K, &cctx->ks); ++ /* If keylen longer than 128 bits need extra encrypt */ ++ if (cctx->keylen != 16) { ++ inc_128(cctx); ++ AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks); ++ } ++ inc_128(cctx); ++ AES_encrypt(cctx->V, cctx->V, &cctx->ks); ++ /* If 192 bit key part of V is on end of K */ ++ if (cctx->keylen == 24) { ++ memcpy(cctx->V + 8, cctx->V, 8); ++ memcpy(cctx->V, cctx->K + 24, 8); ++ } ++ ++ if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { ++ /* If no input reuse existing derived value */ ++ if (in1 || nonce || in2) ++ ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len); ++ /* If this a reuse input in1len != 0 */ ++ if (in1len) ++ ctr_XOR(cctx, cctx->KX, dctx->seedlen); ++ } else { ++ ctr_XOR(cctx, in1, in1len); ++ ctr_XOR(cctx, in2, in2len); ++ } ++ ++ AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); ++#if 0 ++ fprintf(stderr, "K+V after update is:\n"); ++ BIO_dump_fp(stderr, cctx->K, cctx->keylen); ++ BIO_dump_fp(stderr, cctx->V, 16); ++#endif ++} ++ ++static int drbg_ctr_instantiate(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t entlen, ++ const unsigned char *nonce, size_t noncelen, ++ const unsigned char *pers, size_t perslen) ++{ ++ DRBG_CTR_CTX *cctx = &dctx->d.ctr; ++ memset(cctx->K, 0, sizeof(cctx->K)); ++ memset(cctx->V, 0, sizeof(cctx->V)); ++ AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); ++ ctr_Update(dctx, ent, entlen, pers, perslen, nonce, noncelen); ++ return 1; ++} ++ ++static int drbg_ctr_reseed(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t entlen, ++ const unsigned char *adin, size_t adinlen) ++{ ++ ctr_Update(dctx, ent, entlen, adin, adinlen, NULL, 0); ++ return 1; ++} ++ ++static int drbg_ctr_generate(DRBG_CTX *dctx, ++ unsigned char *out, size_t outlen, ++ const unsigned char *adin, size_t adinlen) ++{ ++ DRBG_CTR_CTX *cctx = &dctx->d.ctr; ++ if (adin && adinlen) { ++ ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); ++ /* This means we reuse derived value */ ++ if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { ++ adin = NULL; ++ adinlen = 1; ++ } ++ } else ++ adinlen = 0; ++ ++ for (;;) { ++ inc_128(cctx); ++ if (outlen < 16) { ++ /* Use K as temp space as it will be updated */ ++ AES_encrypt(cctx->V, cctx->K, &cctx->ks); ++ memcpy(out, cctx->K, outlen); ++ break; ++ } ++ AES_encrypt(cctx->V, out, &cctx->ks); ++ out += 16; ++ outlen -= 16; ++ if (outlen == 0) ++ break; ++ } ++ ++ ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); ++ ++ return 1; ++ ++} ++ ++static int drbg_ctr_uninstantiate(DRBG_CTX *dctx) ++{ ++ memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX)); ++ return 1; ++} ++ ++int fips_drbg_ctr_init(DRBG_CTX *dctx) ++{ ++ DRBG_CTR_CTX *cctx = &dctx->d.ctr; ++ ++ size_t keylen; ++ ++ switch (dctx->type) { ++ case NID_aes_128_ctr: ++ keylen = 16; ++ break; ++ ++ case NID_aes_192_ctr: ++ keylen = 24; ++ break; ++ ++ case NID_aes_256_ctr: ++ keylen = 32; ++ break; ++ ++ default: ++ return -2; ++ } ++ ++ dctx->instantiate = drbg_ctr_instantiate; ++ dctx->reseed = drbg_ctr_reseed; ++ dctx->generate = drbg_ctr_generate; ++ dctx->uninstantiate = drbg_ctr_uninstantiate; ++ ++ cctx->keylen = keylen; ++ dctx->strength = keylen * 8; ++ dctx->blocklength = 16; ++ dctx->seedlen = keylen + 16; ++ ++ if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { ++ /* df initialisation */ ++ static unsigned char df_key[32] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f ++ }; ++ /* Set key schedule for df_key */ ++ AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks); ++ ++ dctx->min_entropy = cctx->keylen; ++ dctx->max_entropy = DRBG_MAX_LENGTH; ++ dctx->min_nonce = dctx->min_entropy / 2; ++ dctx->max_nonce = DRBG_MAX_LENGTH; ++ dctx->max_pers = DRBG_MAX_LENGTH; ++ dctx->max_adin = DRBG_MAX_LENGTH; ++ } else { ++ dctx->min_entropy = dctx->seedlen; ++ dctx->max_entropy = dctx->seedlen; ++ /* Nonce not used */ ++ dctx->min_nonce = 0; ++ dctx->max_nonce = 0; ++ dctx->max_pers = dctx->seedlen; ++ dctx->max_adin = dctx->seedlen; ++ } ++ ++ dctx->max_request = 1 << 16; ++ dctx->reseed_interval = 1 << 24; ++ ++ return 1; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_hash.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_hash.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_hash.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_hash.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,354 @@ ++/* fips/rand/fips_drbg_hash.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include "fips_rand_lcl.h" ++ ++/* This is Hash_df from SP 800-90 10.4.1 */ ++ ++static int hash_df(DRBG_CTX *dctx, unsigned char *out, ++ const unsigned char *in1, size_t in1len, ++ const unsigned char *in2, size_t in2len, ++ const unsigned char *in3, size_t in3len, ++ const unsigned char *in4, size_t in4len) ++{ ++ EVP_MD_CTX *mctx = dctx->d.hash.mctx; ++ unsigned char *vtmp = dctx->d.hash.vtmp; ++ unsigned char tmp[6]; ++ /* Standard only ever needs seedlen bytes which is always less than ++ * maximum permitted so no need to check length. ++ */ ++ size_t outlen = dctx->seedlen; ++ tmp[0] = 1; ++ tmp[1] = ((outlen * 8) >> 24) & 0xff; ++ tmp[2] = ((outlen * 8) >> 16) & 0xff; ++ tmp[3] = ((outlen * 8) >> 8) & 0xff; ++ tmp[4] = (outlen * 8) & 0xff; ++ if (!in1) { ++ tmp[5] = (unsigned char)in1len; ++ in1 = tmp + 5; ++ in1len = 1; ++ } ++ for (;;) { ++ if (!FIPS_digestinit(mctx, dctx->d.hash.md)) ++ return 0; ++ if (!FIPS_digestupdate(mctx, tmp, 5)) ++ return 0; ++ if (in1 && !FIPS_digestupdate(mctx, in1, in1len)) ++ return 0; ++ if (in2 && !FIPS_digestupdate(mctx, in2, in2len)) ++ return 0; ++ if (in3 && !FIPS_digestupdate(mctx, in3, in3len)) ++ return 0; ++ if (in4 && !FIPS_digestupdate(mctx, in4, in4len)) ++ return 0; ++ if (outlen < dctx->blocklength) { ++ if (!FIPS_digestfinal(mctx, vtmp, NULL)) ++ return 0; ++ memcpy(out, vtmp, outlen); ++ OPENSSL_cleanse(vtmp, dctx->blocklength); ++ return 1; ++ } else if (!FIPS_digestfinal(mctx, out, NULL)) ++ return 0; ++ ++ outlen -= dctx->blocklength; ++ if (outlen == 0) ++ return 1; ++ tmp[0]++; ++ out += dctx->blocklength; ++ } ++} ++ ++/* Add an unsigned buffer to the buf value, storing the result in buf. For ++ * this algorithm the length of input never exceeds the seed length. ++ */ ++ ++static void ctx_add_buf(DRBG_CTX *dctx, unsigned char *buf, ++ unsigned char *in, size_t inlen) ++{ ++ size_t i = inlen; ++ const unsigned char *q; ++ unsigned char c, *p; ++ p = buf + dctx->seedlen; ++ q = in + inlen; ++ ++ OPENSSL_assert(i <= dctx->seedlen); ++ ++ /* Special case: zero length, just increment buffer */ ++ if (i) ++ c = 0; ++ else ++ c = 1; ++ ++ while (i) { ++ int r; ++ p--; ++ q--; ++ r = *p + *q + c; ++ /* Carry */ ++ if (r > 0xff) ++ c = 1; ++ else ++ c = 0; ++ *p = r & 0xff; ++ i--; ++ } ++ ++ i = dctx->seedlen - inlen; ++ ++ /* If not adding whole buffer handle final carries */ ++ if (c && i) { ++ do { ++ p--; ++ c = *p; ++ c++; ++ *p = c; ++ if (c) ++ return; ++ } while (i--); ++ } ++} ++ ++/* Finalise and add hash to V */ ++ ++static int ctx_add_md(DRBG_CTX *dctx) ++{ ++ if (!FIPS_digestfinal(dctx->d.hash.mctx, dctx->d.hash.vtmp, NULL)) ++ return 0; ++ ctx_add_buf(dctx, dctx->d.hash.V, dctx->d.hash.vtmp, dctx->blocklength); ++ return 1; ++} ++ ++static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen) ++{ ++ DRBG_HASH_CTX *hctx = &dctx->d.hash; ++ if (outlen == 0) ++ return 1; ++ memcpy(hctx->vtmp, hctx->V, dctx->seedlen); ++ for (;;) { ++ FIPS_digestinit(hctx->mctx, hctx->md); ++ FIPS_digestupdate(hctx->mctx, hctx->vtmp, dctx->seedlen); ++ if (outlen < dctx->blocklength) { ++ FIPS_digestfinal(hctx->mctx, hctx->vtmp, NULL); ++ memcpy(out, hctx->vtmp, outlen); ++ return 1; ++ } else { ++ FIPS_digestfinal(hctx->mctx, out, NULL); ++ outlen -= dctx->blocklength; ++ if (outlen == 0) ++ return 1; ++ out += dctx->blocklength; ++ } ++ ctx_add_buf(dctx, hctx->vtmp, NULL, 0); ++ } ++} ++ ++static int drbg_hash_instantiate(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t ent_len, ++ const unsigned char *nonce, size_t nonce_len, ++ const unsigned char *pstr, size_t pstr_len) ++{ ++ DRBG_HASH_CTX *hctx = &dctx->d.hash; ++ if (!hash_df(dctx, hctx->V, ++ ent, ent_len, nonce, nonce_len, pstr, pstr_len, NULL, 0)) ++ return 0; ++ if (!hash_df(dctx, hctx->C, ++ NULL, 0, hctx->V, dctx->seedlen, NULL, 0, NULL, 0)) ++ return 0; ++ ++#ifdef HASH_DRBG_TRACE ++ fprintf(stderr, "V+C after instantiate:\n"); ++ hexprint(stderr, hctx->V, dctx->seedlen); ++ hexprint(stderr, hctx->C, dctx->seedlen); ++#endif ++ return 1; ++} ++ ++static int drbg_hash_reseed(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t ent_len, ++ const unsigned char *adin, size_t adin_len) ++{ ++ DRBG_HASH_CTX *hctx = &dctx->d.hash; ++ /* V about to be updated so use C as output instead */ ++ if (!hash_df(dctx, hctx->C, ++ NULL, 1, hctx->V, dctx->seedlen, ++ ent, ent_len, adin, adin_len)) ++ return 0; ++ memcpy(hctx->V, hctx->C, dctx->seedlen); ++ if (!hash_df(dctx, hctx->C, NULL, 0, ++ hctx->V, dctx->seedlen, NULL, 0, NULL, 0)) ++ return 0; ++#ifdef HASH_DRBG_TRACE ++ fprintf(stderr, "V+C after reseed:\n"); ++ hexprint(stderr, hctx->V, dctx->seedlen); ++ hexprint(stderr, hctx->C, dctx->seedlen); ++#endif ++ return 1; ++} ++ ++static int drbg_hash_generate(DRBG_CTX *dctx, ++ unsigned char *out, size_t outlen, ++ const unsigned char *adin, size_t adin_len) ++{ ++ DRBG_HASH_CTX *hctx = &dctx->d.hash; ++ EVP_MD_CTX *mctx = hctx->mctx; ++ unsigned char tmp[4]; ++ if (adin && adin_len) { ++ tmp[0] = 2; ++ if (!FIPS_digestinit(mctx, hctx->md)) ++ return 0; ++ if (!EVP_DigestUpdate(mctx, tmp, 1)) ++ return 0; ++ if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) ++ return 0; ++ if (!EVP_DigestUpdate(mctx, adin, adin_len)) ++ return 0; ++ if (!ctx_add_md(dctx)) ++ return 0; ++ } ++ if (!hash_gen(dctx, out, outlen)) ++ return 0; ++ ++ tmp[0] = 3; ++ if (!FIPS_digestinit(mctx, hctx->md)) ++ return 0; ++ if (!EVP_DigestUpdate(mctx, tmp, 1)) ++ return 0; ++ if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) ++ return 0; ++ ++ if (!ctx_add_md(dctx)) ++ return 0; ++ ++ ctx_add_buf(dctx, hctx->V, hctx->C, dctx->seedlen); ++ ++ tmp[0] = (dctx->reseed_counter >> 24) & 0xff; ++ tmp[1] = (dctx->reseed_counter >> 16) & 0xff; ++ tmp[2] = (dctx->reseed_counter >> 8) & 0xff; ++ tmp[3] = dctx->reseed_counter & 0xff; ++ ctx_add_buf(dctx, hctx->V, tmp, 4); ++#ifdef HASH_DRBG_TRACE ++ fprintf(stderr, "V+C after generate:\n"); ++ hexprint(stderr, hctx->V, dctx->seedlen); ++ hexprint(stderr, hctx->C, dctx->seedlen); ++#endif ++ return 1; ++} ++ ++static int drbg_hash_uninstantiate(DRBG_CTX *dctx) ++{ ++ EVP_MD_CTX_free(dctx->d.hash.mctx); ++ OPENSSL_cleanse(&dctx->d.hash, sizeof(DRBG_HASH_CTX)); ++ return 1; ++} ++ ++int fips_drbg_hash_init(DRBG_CTX *dctx) ++{ ++ const EVP_MD *md; ++ DRBG_HASH_CTX *hctx = &dctx->d.hash; ++ md = EVP_get_digestbynid(dctx->type); ++ if (!md) ++ return -2; ++ switch (dctx->type) { ++ case NID_sha1: ++ dctx->strength = 128; ++ break; ++ ++ case NID_sha224: ++ dctx->strength = 192; ++ break; ++ ++ default: ++ dctx->strength = 256; ++ break; ++ } ++ ++ dctx->instantiate = drbg_hash_instantiate; ++ dctx->reseed = drbg_hash_reseed; ++ dctx->generate = drbg_hash_generate; ++ dctx->uninstantiate = drbg_hash_uninstantiate; ++ ++ dctx->d.hash.md = md; ++ hctx->mctx = EVP_MD_CTX_new(); ++ if (hctx->mctx == NULL) ++ return -1; ++ ++ /* These are taken from SP 800-90 10.1 table 2 */ ++ ++ dctx->blocklength = EVP_MD_size(md); ++ if (dctx->blocklength > 32) ++ dctx->seedlen = 111; ++ else ++ dctx->seedlen = 55; ++ ++ dctx->min_entropy = dctx->strength / 8; ++ dctx->max_entropy = DRBG_MAX_LENGTH; ++ ++ dctx->min_nonce = dctx->min_entropy / 2; ++ dctx->max_nonce = DRBG_MAX_LENGTH; ++ ++ dctx->max_pers = DRBG_MAX_LENGTH; ++ dctx->max_adin = DRBG_MAX_LENGTH; ++ ++ dctx->max_request = 1 << 16; ++ dctx->reseed_interval = 1 << 24; ++ ++ return 1; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_hmac.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_hmac.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_hmac.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_hmac.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,262 @@ ++/* fips/rand/fips_drbg_hmac.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fips_rand_lcl.h" ++ ++static int drbg_hmac_update(DRBG_CTX *dctx, ++ const unsigned char *in1, size_t in1len, ++ const unsigned char *in2, size_t in2len, ++ const unsigned char *in3, size_t in3len) ++{ ++ static unsigned char c0 = 0, c1 = 1; ++ DRBG_HMAC_CTX *hmac = &dctx->d.hmac; ++ HMAC_CTX *hctx = hmac->hctx; ++ ++ if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) ++ return 0; ++ if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) ++ return 0; ++ if (!HMAC_Update(hctx, &c0, 1)) ++ return 0; ++ if (in1len && !HMAC_Update(hctx, in1, in1len)) ++ return 0; ++ if (in2len && !HMAC_Update(hctx, in2, in2len)) ++ return 0; ++ if (in3len && !HMAC_Update(hctx, in3, in3len)) ++ return 0; ++ ++ if (!HMAC_Final(hctx, hmac->K, NULL)) ++ return 0; ++ ++ if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) ++ return 0; ++ if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) ++ return 0; ++ ++ if (!HMAC_Final(hctx, hmac->V, NULL)) ++ return 0; ++ ++ if (!in1len && !in2len && !in3len) ++ return 1; ++ ++ if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) ++ return 0; ++ if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) ++ return 0; ++ if (!HMAC_Update(hctx, &c1, 1)) ++ return 0; ++ if (in1len && !HMAC_Update(hctx, in1, in1len)) ++ return 0; ++ if (in2len && !HMAC_Update(hctx, in2, in2len)) ++ return 0; ++ if (in3len && !HMAC_Update(hctx, in3, in3len)) ++ return 0; ++ ++ if (!HMAC_Final(hctx, hmac->K, NULL)) ++ return 0; ++ ++ if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) ++ return 0; ++ if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) ++ return 0; ++ ++ if (!HMAC_Final(hctx, hmac->V, NULL)) ++ return 0; ++ ++ return 1; ++ ++} ++ ++static int drbg_hmac_instantiate(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t ent_len, ++ const unsigned char *nonce, size_t nonce_len, ++ const unsigned char *pstr, size_t pstr_len) ++{ ++ DRBG_HMAC_CTX *hmac = &dctx->d.hmac; ++ memset(hmac->K, 0, dctx->blocklength); ++ memset(hmac->V, 1, dctx->blocklength); ++ if (!drbg_hmac_update(dctx, ++ ent, ent_len, nonce, nonce_len, pstr, pstr_len)) ++ return 0; ++ ++#ifdef HMAC_DRBG_TRACE ++ fprintf(stderr, "K+V after instantiate:\n"); ++ hexprint(stderr, hmac->K, hmac->blocklength); ++ hexprint(stderr, hmac->V, hmac->blocklength); ++#endif ++ return 1; ++} ++ ++static int drbg_hmac_reseed(DRBG_CTX *dctx, ++ const unsigned char *ent, size_t ent_len, ++ const unsigned char *adin, size_t adin_len) ++{ ++ if (!drbg_hmac_update(dctx, ent, ent_len, adin, adin_len, NULL, 0)) ++ return 0; ++ ++#ifdef HMAC_DRBG_TRACE ++ { ++ DRBG_HMAC_CTX *hmac = &dctx->d.hmac; ++ fprintf(stderr, "K+V after reseed:\n"); ++ hexprint(stderr, hmac->K, hmac->blocklength); ++ hexprint(stderr, hmac->V, hmac->blocklength); ++ } ++#endif ++ return 1; ++} ++ ++static int drbg_hmac_generate(DRBG_CTX *dctx, ++ unsigned char *out, size_t outlen, ++ const unsigned char *adin, size_t adin_len) ++{ ++ DRBG_HMAC_CTX *hmac = &dctx->d.hmac; ++ HMAC_CTX *hctx = hmac->hctx; ++ const unsigned char *Vtmp = hmac->V; ++ if (adin_len && !drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0)) ++ return 0; ++ for (;;) { ++ if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) ++ return 0; ++ if (!HMAC_Update(hctx, Vtmp, dctx->blocklength)) ++ return 0; ++ if (outlen > dctx->blocklength) { ++ if (!HMAC_Final(hctx, out, NULL)) ++ return 0; ++ Vtmp = out; ++ } else { ++ if (!HMAC_Final(hctx, hmac->V, NULL)) ++ return 0; ++ memcpy(out, hmac->V, outlen); ++ break; ++ } ++ out += dctx->blocklength; ++ outlen -= dctx->blocklength; ++ } ++ if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0)) ++ return 0; ++ ++ return 1; ++} ++ ++static int drbg_hmac_uninstantiate(DRBG_CTX *dctx) ++{ ++ HMAC_CTX_free(dctx->d.hmac.hctx); ++ OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX)); ++ return 1; ++} ++ ++int fips_drbg_hmac_init(DRBG_CTX *dctx) ++{ ++ const EVP_MD *md = NULL; ++ DRBG_HMAC_CTX *hctx = &dctx->d.hmac; ++ dctx->strength = 256; ++ switch (dctx->type) { ++ case NID_hmacWithSHA1: ++ md = EVP_sha1(); ++ dctx->strength = 128; ++ break; ++ ++ case NID_hmacWithSHA224: ++ md = EVP_sha224(); ++ dctx->strength = 192; ++ break; ++ ++ case NID_hmacWithSHA256: ++ md = EVP_sha256(); ++ break; ++ ++ case NID_hmacWithSHA384: ++ md = EVP_sha384(); ++ break; ++ ++ case NID_hmacWithSHA512: ++ md = EVP_sha512(); ++ break; ++ ++ default: ++ dctx->strength = 0; ++ return -2; ++ } ++ dctx->instantiate = drbg_hmac_instantiate; ++ dctx->reseed = drbg_hmac_reseed; ++ dctx->generate = drbg_hmac_generate; ++ dctx->uninstantiate = drbg_hmac_uninstantiate; ++ hctx->hctx = HMAC_CTX_new(); ++ if (hctx->hctx == NULL) ++ return -1; ++ hctx->md = md; ++ dctx->blocklength = M_EVP_MD_size(md); ++ dctx->seedlen = M_EVP_MD_size(md); ++ ++ dctx->min_entropy = dctx->strength / 8; ++ dctx->max_entropy = DRBG_MAX_LENGTH; ++ ++ dctx->min_nonce = dctx->min_entropy / 2; ++ dctx->max_nonce = DRBG_MAX_LENGTH; ++ ++ dctx->max_pers = DRBG_MAX_LENGTH; ++ dctx->max_adin = DRBG_MAX_LENGTH; ++ ++ dctx->max_request = 1 << 16; ++ dctx->reseed_interval = 1 << 24; ++ ++ return 1; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_lib.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_lib.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_lib.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_lib.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,528 @@ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#include ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include "fips_locl.h" ++#include "fips_rand_lcl.h" ++ ++/* Support framework for SP800-90 DRBGs */ ++ ++int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags) ++{ ++ int rv; ++ memset(dctx, 0, sizeof(DRBG_CTX)); ++ dctx->status = DRBG_STATUS_UNINITIALISED; ++ dctx->xflags = flags; ++ dctx->type = type; ++ ++ dctx->iflags = 0; ++ dctx->entropy_blocklen = 0; ++ dctx->health_check_cnt = 0; ++ dctx->health_check_interval = DRBG_HEALTH_INTERVAL; ++ ++ rv = fips_drbg_hash_init(dctx); ++ ++ if (rv == -2) ++ rv = fips_drbg_ctr_init(dctx); ++ if (rv == -2) ++ rv = fips_drbg_hmac_init(dctx); ++ ++ if (rv <= 0) { ++ if (rv == -2) ++ FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_UNSUPPORTED_DRBG_TYPE); ++ else ++ FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_ERROR_INITIALISING_DRBG); ++ } ++ ++ /* If not in test mode run selftests on DRBG of the same type */ ++ ++ if (!(dctx->xflags & DRBG_FLAG_TEST)) { ++ if (!FIPS_drbg_health_check(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_SELFTEST_FAILURE); ++ return 0; ++ } ++ } ++ ++ return rv; ++} ++ ++DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags) ++{ ++ DRBG_CTX *dctx; ++ dctx = OPENSSL_malloc(sizeof(DRBG_CTX)); ++ if (!dctx) { ++ FIPSerr(FIPS_F_FIPS_DRBG_NEW, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ if (type == 0) { ++ memset(dctx, 0, sizeof(DRBG_CTX)); ++ dctx->type = 0; ++ dctx->status = DRBG_STATUS_UNINITIALISED; ++ return dctx; ++ } ++ ++ if (FIPS_drbg_init(dctx, type, flags) <= 0) { ++ OPENSSL_free(dctx); ++ return NULL; ++ } ++ ++ return dctx; ++} ++ ++void FIPS_drbg_free(DRBG_CTX *dctx) ++{ ++ if (dctx->uninstantiate) ++ dctx->uninstantiate(dctx); ++ /* Don't free up default DRBG */ ++ if (dctx == FIPS_get_default_drbg()) { ++ memset(dctx, 0, sizeof(DRBG_CTX)); ++ dctx->type = 0; ++ dctx->status = DRBG_STATUS_UNINITIALISED; ++ } else { ++ OPENSSL_cleanse(&dctx->d, sizeof(dctx->d)); ++ OPENSSL_free(dctx); ++ } ++} ++ ++static size_t fips_get_entropy(DRBG_CTX *dctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len) ++{ ++ unsigned char *tout, *p; ++ size_t bl = dctx->entropy_blocklen, rv; ++ if (!dctx->get_entropy) ++ return 0; ++ if (dctx->xflags & DRBG_FLAG_TEST || !bl) ++ return dctx->get_entropy(dctx, pout, entropy, min_len, max_len); ++ rv = dctx->get_entropy(dctx, &tout, entropy + bl, ++ min_len + bl, max_len + bl); ++ if (tout == NULL) ++ return 0; ++ *pout = tout + bl; ++ if (rv < (min_len + bl) || (rv % bl)) ++ return 0; ++ /* Compare consecutive blocks for continuous PRNG test */ ++ for (p = tout; p < tout + rv - bl; p += bl) { ++ if (!memcmp(p, p + bl, bl)) { ++ FIPSerr(FIPS_F_FIPS_GET_ENTROPY, FIPS_R_ENTROPY_SOURCE_STUCK); ++ return 0; ++ } ++ } ++ rv -= bl; ++ if (rv > max_len) ++ return max_len; ++ return rv; ++} ++ ++static void fips_cleanup_entropy(DRBG_CTX *dctx, ++ unsigned char *out, size_t olen) ++{ ++ size_t bl; ++ if (dctx->xflags & DRBG_FLAG_TEST) ++ bl = 0; ++ else ++ bl = dctx->entropy_blocklen; ++ /* Call cleanup with original arguments */ ++ dctx->cleanup_entropy(dctx, out - bl, olen + bl); ++} ++ ++int FIPS_drbg_instantiate(DRBG_CTX *dctx, ++ const unsigned char *pers, size_t perslen) ++{ ++ size_t entlen = 0, noncelen = 0; ++ unsigned char *nonce = NULL, *entropy = NULL; ++ ++#if 0 ++ /* Put here so error script picks them up */ ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, ++ FIPS_R_PERSONALISATION_STRING_TOO_LONG); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_IN_ERROR_STATE); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ALREADY_INSTANTIATED); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_ENTROPY); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_NONCE); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_INSTANTIATE_ERROR); ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_DRBG_NOT_INITIALISED); ++#endif ++ ++ int r = 0; ++ ++ if (perslen > dctx->max_pers) { ++ r = FIPS_R_PERSONALISATION_STRING_TOO_LONG; ++ goto end; ++ } ++ ++ if (!dctx->instantiate) { ++ r = FIPS_R_DRBG_NOT_INITIALISED; ++ goto end; ++ } ++ ++ if (dctx->status != DRBG_STATUS_UNINITIALISED) { ++ if (dctx->status == DRBG_STATUS_ERROR) ++ r = FIPS_R_IN_ERROR_STATE; ++ else ++ r = FIPS_R_ALREADY_INSTANTIATED; ++ goto end; ++ } ++ ++ dctx->status = DRBG_STATUS_ERROR; ++ ++ entlen = fips_get_entropy(dctx, &entropy, dctx->strength, ++ dctx->min_entropy, dctx->max_entropy); ++ ++ if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) { ++ r = FIPS_R_ERROR_RETRIEVING_ENTROPY; ++ goto end; ++ } ++ ++ if (dctx->max_nonce > 0 && dctx->get_nonce) { ++ noncelen = dctx->get_nonce(dctx, &nonce, ++ dctx->strength / 2, ++ dctx->min_nonce, dctx->max_nonce); ++ ++ if (noncelen < dctx->min_nonce || noncelen > dctx->max_nonce) { ++ r = FIPS_R_ERROR_RETRIEVING_NONCE; ++ goto end; ++ } ++ ++ } ++ ++ if (!dctx->instantiate(dctx, ++ entropy, entlen, nonce, noncelen, pers, perslen)) { ++ r = FIPS_R_ERROR_INSTANTIATING_DRBG; ++ goto end; ++ } ++ ++ dctx->status = DRBG_STATUS_READY; ++ if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) ++ dctx->reseed_counter = 1; ++ ++ end: ++ ++ if (entropy && dctx->cleanup_entropy) ++ fips_cleanup_entropy(dctx, entropy, entlen); ++ ++ if (nonce && dctx->cleanup_nonce) ++ dctx->cleanup_nonce(dctx, nonce, noncelen); ++ ++ if (dctx->status == DRBG_STATUS_READY) ++ return 1; ++ ++ if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) ++ FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, r); ++ ++ return 0; ++ ++} ++ ++static int drbg_reseed(DRBG_CTX *dctx, ++ const unsigned char *adin, size_t adinlen, int hcheck) ++{ ++ unsigned char *entropy = NULL; ++ size_t entlen = 0; ++ int r = 0; ++ ++#if 0 ++ FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_NOT_INSTANTIATED); ++ FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_ADDITIONAL_INPUT_TOO_LONG); ++#endif ++ if (dctx->status != DRBG_STATUS_READY ++ && dctx->status != DRBG_STATUS_RESEED) { ++ if (dctx->status == DRBG_STATUS_ERROR) ++ r = FIPS_R_IN_ERROR_STATE; ++ else if (dctx->status == DRBG_STATUS_UNINITIALISED) ++ r = FIPS_R_NOT_INSTANTIATED; ++ goto end; ++ } ++ ++ if (!adin) ++ adinlen = 0; ++ else if (adinlen > dctx->max_adin) { ++ r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; ++ goto end; ++ } ++ ++ dctx->status = DRBG_STATUS_ERROR; ++ /* Peform health check on all reseed operations if not a prediction ++ * resistance request and not in test mode. ++ */ ++ if (hcheck && !(dctx->xflags & DRBG_FLAG_TEST)) { ++ if (!FIPS_drbg_health_check(dctx)) { ++ r = FIPS_R_SELFTEST_FAILURE; ++ goto end; ++ } ++ } ++ ++ entlen = fips_get_entropy(dctx, &entropy, dctx->strength, ++ dctx->min_entropy, dctx->max_entropy); ++ ++ if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) { ++ r = FIPS_R_ERROR_RETRIEVING_ENTROPY; ++ goto end; ++ } ++ ++ if (!dctx->reseed(dctx, entropy, entlen, adin, adinlen)) ++ goto end; ++ ++ dctx->status = DRBG_STATUS_READY; ++ if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) ++ dctx->reseed_counter = 1; ++ end: ++ ++ if (entropy && dctx->cleanup_entropy) ++ fips_cleanup_entropy(dctx, entropy, entlen); ++ ++ if (dctx->status == DRBG_STATUS_READY) ++ return 1; ++ ++ if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) ++ FIPSerr(FIPS_F_DRBG_RESEED, r); ++ ++ return 0; ++} ++ ++int FIPS_drbg_reseed(DRBG_CTX *dctx, ++ const unsigned char *adin, size_t adinlen) ++{ ++ return drbg_reseed(dctx, adin, adinlen, 1); ++} ++ ++static int fips_drbg_check(DRBG_CTX *dctx) ++{ ++ if (dctx->xflags & DRBG_FLAG_TEST) ++ return 1; ++ dctx->health_check_cnt++; ++ if (dctx->health_check_cnt >= dctx->health_check_interval) { ++ if (!FIPS_drbg_health_check(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE); ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, ++ int prediction_resistance, ++ const unsigned char *adin, size_t adinlen) ++{ ++ int r = 0; ++ ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ if (!fips_drbg_check(dctx)) ++ return 0; ++ ++ if (dctx->status != DRBG_STATUS_READY ++ && dctx->status != DRBG_STATUS_RESEED) { ++ if (dctx->status == DRBG_STATUS_ERROR) ++ r = FIPS_R_IN_ERROR_STATE; ++ else if (dctx->status == DRBG_STATUS_UNINITIALISED) ++ r = FIPS_R_NOT_INSTANTIATED; ++ goto end; ++ } ++ ++ if (outlen > dctx->max_request) { ++ r = FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG; ++ return 0; ++ } ++ ++ if (adinlen > dctx->max_adin) { ++ r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; ++ goto end; ++ } ++ ++ if (dctx->iflags & DRBG_CUSTOM_RESEED) ++ dctx->generate(dctx, NULL, outlen, NULL, 0); ++ else if (dctx->reseed_counter >= dctx->reseed_interval) ++ dctx->status = DRBG_STATUS_RESEED; ++ ++ if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance) { ++ /* If prediction resistance request don't do health check */ ++ int hcheck = prediction_resistance ? 0 : 1; ++ ++ if (!drbg_reseed(dctx, adin, adinlen, hcheck)) { ++ r = FIPS_R_RESEED_ERROR; ++ goto end; ++ } ++ adin = NULL; ++ adinlen = 0; ++ } ++ ++ if (!dctx->generate(dctx, out, outlen, adin, adinlen)) { ++ r = FIPS_R_GENERATE_ERROR; ++ dctx->status = DRBG_STATUS_ERROR; ++ goto end; ++ } ++ if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) { ++ if (dctx->reseed_counter >= dctx->reseed_interval) ++ dctx->status = DRBG_STATUS_RESEED; ++ else ++ dctx->reseed_counter++; ++ } ++ ++ end: ++ if (r) { ++ if (!(dctx->iflags & DRBG_FLAG_NOERR)) ++ FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++int FIPS_drbg_uninstantiate(DRBG_CTX *dctx) ++{ ++ int rv; ++ if (!dctx->uninstantiate) ++ rv = 1; ++ else ++ rv = dctx->uninstantiate(dctx); ++ /* Although we'd like to cleanse here we can't because we have to ++ * test the uninstantiate really zeroes the data. ++ */ ++ memset(&dctx->d, 0, sizeof(dctx->d)); ++ dctx->status = DRBG_STATUS_UNINITIALISED; ++ /* If method has problems uninstantiating, return error */ ++ return rv; ++} ++ ++int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, ++ size_t (*get_entropy) (DRBG_CTX *ctx, ++ unsigned char **pout, ++ int entropy, ++ size_t min_len, ++ size_t max_len), ++ void (*cleanup_entropy) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen), ++ size_t entropy_blocklen, ++ size_t (*get_nonce) (DRBG_CTX *ctx, ++ unsigned char **pout, ++ int entropy, size_t min_len, ++ size_t max_len), ++ void (*cleanup_nonce) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen)) ++{ ++ if (dctx->status != DRBG_STATUS_UNINITIALISED) ++ return 0; ++ dctx->entropy_blocklen = entropy_blocklen; ++ dctx->get_entropy = get_entropy; ++ dctx->cleanup_entropy = cleanup_entropy; ++ dctx->get_nonce = get_nonce; ++ dctx->cleanup_nonce = cleanup_nonce; ++ return 1; ++} ++ ++int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, ++ size_t (*get_adin) (DRBG_CTX *ctx, ++ unsigned char **pout), ++ void (*cleanup_adin) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen), ++ int (*rand_seed_cb) (DRBG_CTX *ctx, ++ const void *buf, ++ int num), ++ int (*rand_add_cb) (DRBG_CTX *ctx, ++ const void *buf, int num, ++ double entropy)) ++{ ++ if (dctx->status != DRBG_STATUS_UNINITIALISED) ++ return 0; ++ dctx->get_adin = get_adin; ++ dctx->cleanup_adin = cleanup_adin; ++ dctx->rand_seed_cb = rand_seed_cb; ++ dctx->rand_add_cb = rand_add_cb; ++ return 1; ++} ++ ++void *FIPS_drbg_get_app_data(DRBG_CTX *dctx) ++{ ++ return dctx->app_data; ++} ++ ++void FIPS_drbg_set_app_data(DRBG_CTX *dctx, void *app_data) ++{ ++ dctx->app_data = app_data; ++} ++ ++size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx) ++{ ++ return dctx->blocklength; ++} ++ ++int FIPS_drbg_get_strength(DRBG_CTX *dctx) ++{ ++ return dctx->strength; ++} ++ ++void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval) ++{ ++ dctx->health_check_interval = interval; ++} ++ ++void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval) ++{ ++ dctx->reseed_interval = interval; ++} ++ ++void FIPS_drbg_stick(int onoff) ++{ ++ /* Just backwards compatibility API call with no effect. */ ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_rand.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_rand.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_rand.c.fips 2021-03-03 12:57:42.199734525 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_rand.c 2021-03-03 12:57:42.199734525 +0100 +@@ -0,0 +1,185 @@ ++/* fips/rand/fips_drbg_rand.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#include ++#include ++#include "internal/thread_once.h" ++#include ++#include ++#include ++#include ++#include "fips_rand_lcl.h" ++ ++/* Mapping of SP800-90 DRBGs to OpenSSL RAND_METHOD */ ++ ++/* Since we only have one global PRNG used at any time in OpenSSL use a global ++ * variable to store context. ++ */ ++ ++static DRBG_CTX ossl_dctx; ++ ++static CRYPTO_RWLOCK *fips_rand_lock = NULL; ++static CRYPTO_ONCE fips_rand_lock_init = CRYPTO_ONCE_STATIC_INIT; ++ ++DEFINE_RUN_ONCE_STATIC(do_fips_rand_lock_init) ++{ ++ fips_rand_lock = CRYPTO_THREAD_lock_new(); ++ return fips_rand_lock != NULL; ++} ++ ++DRBG_CTX *FIPS_get_default_drbg(void) ++{ ++ if (!RUN_ONCE(&fips_rand_lock_init, do_fips_rand_lock_init)) ++ return NULL; ++ return &ossl_dctx; ++} ++ ++static int fips_drbg_bytes(unsigned char *out, int count) ++{ ++ DRBG_CTX *dctx = &ossl_dctx; ++ int rv = 0; ++ unsigned char *adin = NULL; ++ size_t adinlen = 0; ++ CRYPTO_THREAD_write_lock(fips_rand_lock); ++ do { ++ size_t rcnt; ++ if (count > (int)dctx->max_request) ++ rcnt = dctx->max_request; ++ else ++ rcnt = count; ++ if (dctx->get_adin) { ++ adinlen = dctx->get_adin(dctx, &adin); ++ if (adinlen && !adin) { ++ FIPSerr(FIPS_F_FIPS_DRBG_BYTES, ++ FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT); ++ goto err; ++ } ++ } ++ rv = FIPS_drbg_generate(dctx, out, rcnt, 0, adin, adinlen); ++ if (adin) { ++ if (dctx->cleanup_adin) ++ dctx->cleanup_adin(dctx, adin, adinlen); ++ adin = NULL; ++ } ++ if (!rv) ++ goto err; ++ out += rcnt; ++ count -= rcnt; ++ } ++ while (count); ++ rv = 1; ++ err: ++ CRYPTO_THREAD_unlock(fips_rand_lock); ++ return rv; ++} ++ ++static int fips_drbg_pseudo(unsigned char *out, int count) ++{ ++ if (fips_drbg_bytes(out, count) <= 0) ++ return -1; ++ return 1; ++} ++ ++static int fips_drbg_status(void) ++{ ++ DRBG_CTX *dctx = &ossl_dctx; ++ int rv; ++ CRYPTO_THREAD_read_lock(fips_rand_lock); ++ rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; ++ CRYPTO_THREAD_unlock(fips_rand_lock); ++ return rv; ++} ++ ++static void fips_drbg_cleanup(void) ++{ ++ DRBG_CTX *dctx = &ossl_dctx; ++ CRYPTO_THREAD_write_lock(fips_rand_lock); ++ FIPS_drbg_uninstantiate(dctx); ++ CRYPTO_THREAD_unlock(fips_rand_lock); ++} ++ ++static int fips_drbg_seed(const void *seed, int seedlen) ++{ ++ DRBG_CTX *dctx = &ossl_dctx; ++ int ret = 1; ++ CRYPTO_THREAD_write_lock(fips_rand_lock); ++ if (dctx->rand_seed_cb) ++ ret = dctx->rand_seed_cb(dctx, seed, seedlen); ++ CRYPTO_THREAD_unlock(fips_rand_lock); ++ return ret; ++} ++ ++static int fips_drbg_add(const void *seed, int seedlen, double add_entropy) ++{ ++ DRBG_CTX *dctx = &ossl_dctx; ++ int ret = 1; ++ CRYPTO_THREAD_write_lock(fips_rand_lock); ++ if (dctx->rand_add_cb) ++ ret = dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); ++ CRYPTO_THREAD_unlock(fips_rand_lock); ++ return ret; ++} ++ ++static const RAND_METHOD rand_drbg_meth = { ++ fips_drbg_seed, ++ fips_drbg_bytes, ++ fips_drbg_cleanup, ++ fips_drbg_add, ++ fips_drbg_pseudo, ++ fips_drbg_status ++}; ++ ++const RAND_METHOD *FIPS_drbg_method(void) ++{ ++ return &rand_drbg_meth; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_drbg_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_drbg_selftest.c.fips 2021-03-03 12:57:42.200734534 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_selftest.c 2021-03-03 12:57:42.200734534 +0100 +@@ -0,0 +1,828 @@ ++/* fips/rand/fips_drbg_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "fips_rand_lcl.h" ++#include "fips_locl.h" ++ ++#include "fips_drbg_selftest.h" ++ ++typedef struct { ++ int post; ++ int nid; ++ unsigned int flags; ++ ++ /* KAT data for no PR */ ++ const unsigned char *ent; ++ size_t entlen; ++ const unsigned char *nonce; ++ size_t noncelen; ++ const unsigned char *pers; ++ size_t perslen; ++ const unsigned char *adin; ++ size_t adinlen; ++ const unsigned char *entreseed; ++ size_t entreseedlen; ++ const unsigned char *adinreseed; ++ size_t adinreseedlen; ++ const unsigned char *adin2; ++ size_t adin2len; ++ const unsigned char *kat; ++ size_t katlen; ++ const unsigned char *kat2; ++ size_t kat2len; ++ ++ /* KAT data for PR */ ++ const unsigned char *ent_pr; ++ size_t entlen_pr; ++ const unsigned char *nonce_pr; ++ size_t noncelen_pr; ++ const unsigned char *pers_pr; ++ size_t perslen_pr; ++ const unsigned char *adin_pr; ++ size_t adinlen_pr; ++ const unsigned char *entpr_pr; ++ size_t entprlen_pr; ++ const unsigned char *ading_pr; ++ size_t adinglen_pr; ++ const unsigned char *entg_pr; ++ size_t entglen_pr; ++ const unsigned char *kat_pr; ++ size_t katlen_pr; ++ const unsigned char *kat2_pr; ++ size_t kat2len_pr; ++ ++} DRBG_SELFTEST_DATA; ++ ++#define make_drbg_test_data(nid, flag, pr, p) {p, nid, flag | DRBG_FLAG_TEST, \ ++ pr##_entropyinput, sizeof(pr##_entropyinput), \ ++ pr##_nonce, sizeof(pr##_nonce), \ ++ pr##_personalizationstring, sizeof(pr##_personalizationstring), \ ++ pr##_additionalinput, sizeof(pr##_additionalinput), \ ++ pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \ ++ pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \ ++ pr##_additionalinput2, sizeof(pr##_additionalinput2), \ ++ pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \ ++ pr##_returnedbits, sizeof(pr##_returnedbits), \ ++ pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \ ++ pr##_pr_nonce, sizeof(pr##_pr_nonce), \ ++ pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \ ++ pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \ ++ pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \ ++ pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \ ++ pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \ ++ pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \ ++ pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits), \ ++ } ++ ++#define make_drbg_test_data_df(nid, pr, p) \ ++ make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p) ++ ++#define make_drbg_test_data_ec(curve, md, pr, p) \ ++ make_drbg_test_data((curve << 16) | md , 0, pr, p) ++ ++static DRBG_SELFTEST_DATA drbg_test[] = { ++ make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), ++ make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), ++ make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1), ++ make_drbg_test_data(NID_aes_128_ctr, 0, aes_128_no_df, 0), ++ make_drbg_test_data(NID_aes_192_ctr, 0, aes_192_no_df, 0), ++ make_drbg_test_data(NID_aes_256_ctr, 0, aes_256_no_df, 1), ++ make_drbg_test_data(NID_sha1, 0, sha1, 0), ++ make_drbg_test_data(NID_sha224, 0, sha224, 0), ++ make_drbg_test_data(NID_sha256, 0, sha256, 1), ++ make_drbg_test_data(NID_sha384, 0, sha384, 0), ++ make_drbg_test_data(NID_sha512, 0, sha512, 0), ++ make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1, 0), ++ make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224, 0), ++ make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1), ++ make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0), ++ make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0), ++ {0, 0, 0} ++}; ++ ++typedef struct { ++ const unsigned char *ent; ++ size_t entlen; ++ int entcnt; ++ const unsigned char *nonce; ++ size_t noncelen; ++ int noncecnt; ++} TEST_ENT; ++ ++static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len) ++{ ++ TEST_ENT *t = FIPS_drbg_get_app_data(dctx); ++ *pout = (unsigned char *)t->ent; ++ t->entcnt++; ++ return t->entlen; ++} ++ ++static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len) ++{ ++ TEST_ENT *t = FIPS_drbg_get_app_data(dctx); ++ *pout = (unsigned char *)t->nonce; ++ t->noncecnt++; ++ return t->noncelen; ++} ++ ++static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, ++ int quick) ++{ ++ TEST_ENT t; ++ int rv = 0; ++ size_t adinlen; ++ unsigned char randout[1024]; ++ ++ /* Initial test without PR */ ++ ++ /* Instantiate DRBG with test entropy, nonce and personalisation ++ * string. ++ */ ++ ++ if (!FIPS_drbg_init(dctx, td->nid, td->flags)) ++ return 0; ++ if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) ++ return 0; ++ ++ FIPS_drbg_set_app_data(dctx, &t); ++ ++ t.ent = td->ent; ++ t.entlen = td->entlen; ++ t.nonce = td->nonce; ++ t.noncelen = td->noncelen; ++ t.entcnt = 0; ++ t.noncecnt = 0; ++ ++ if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) ++ goto err; ++ ++ /* Note for CTR without DF some additional input values ++ * ignore bytes after the keylength: so reduce adinlen ++ * to half to ensure invalid data is fed in. ++ */ ++ if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) ++ adinlen = td->adinlen / 2; ++ else ++ adinlen = td->adinlen; ++ ++ /* Generate with no PR and verify output matches expected data */ ++ if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, adinlen)) ++ goto err; ++ ++ if (memcmp(randout, td->kat, td->katlen)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE); ++ goto err2; ++ } ++ /* If abbreviated POST end of test */ ++ if (quick) { ++ rv = 1; ++ goto err; ++ } ++ /* Reseed DRBG with test entropy and additional input */ ++ t.ent = td->entreseed; ++ t.entlen = td->entreseedlen; ++ ++ if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen)) ++ goto err; ++ ++ /* Generate with no PR and verify output matches expected data */ ++ if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0, ++ td->adin2, td->adin2len)) ++ goto err; ++ ++ if (memcmp(randout, td->kat2, td->kat2len)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE); ++ goto err2; ++ } ++ ++ FIPS_drbg_uninstantiate(dctx); ++ ++ /* Now test with PR */ ++ ++ /* Instantiate DRBG with test entropy, nonce and personalisation ++ * string. ++ */ ++ if (!FIPS_drbg_init(dctx, td->nid, td->flags)) ++ return 0; ++ if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) ++ return 0; ++ ++ FIPS_drbg_set_app_data(dctx, &t); ++ ++ t.ent = td->ent_pr; ++ t.entlen = td->entlen_pr; ++ t.nonce = td->nonce_pr; ++ t.noncelen = td->noncelen_pr; ++ t.entcnt = 0; ++ t.noncecnt = 0; ++ ++ if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr)) ++ goto err; ++ ++ /* Now generate with PR: we need to supply entropy as this will ++ * perform a reseed operation. Check output matches expected value. ++ */ ++ ++ t.ent = td->entpr_pr; ++ t.entlen = td->entprlen_pr; ++ ++ /* Note for CTR without DF some additional input values ++ * ignore bytes after the keylength: so reduce adinlen ++ * to half to ensure invalid data is fed in. ++ */ ++ if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) ++ adinlen = td->adinlen_pr / 2; ++ else ++ adinlen = td->adinlen_pr; ++ if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1, ++ td->adin_pr, adinlen)) ++ goto err; ++ ++ if (memcmp(randout, td->kat_pr, td->katlen_pr)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE); ++ goto err2; ++ } ++ ++ /* Now generate again with PR: supply new entropy again. ++ * Check output matches expected value. ++ */ ++ ++ t.ent = td->entg_pr; ++ t.entlen = td->entglen_pr; ++ ++ if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1, ++ td->ading_pr, td->adinglen_pr)) ++ goto err; ++ ++ if (memcmp(randout, td->kat2_pr, td->kat2len_pr)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE); ++ goto err2; ++ } ++ /* All OK, test complete */ ++ rv = 1; ++ ++ err: ++ if (rv == 0) ++ FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED); ++ err2: ++ FIPS_drbg_uninstantiate(dctx); ++ ++ return rv; ++ ++} ++ ++/* Initialise a DRBG based on selftest data */ ++ ++static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, TEST_ENT * t) ++{ ++ ++ if (!FIPS_drbg_init(dctx, td->nid, td->flags)) ++ return 0; ++ ++ if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) ++ return 0; ++ ++ FIPS_drbg_set_app_data(dctx, t); ++ ++ t->ent = td->ent; ++ t->entlen = td->entlen; ++ t->nonce = td->nonce; ++ t->noncelen = td->noncelen; ++ t->entcnt = 0; ++ t->noncecnt = 0; ++ return 1; ++} ++ ++/* Initialise and instantiate DRBG based on selftest data */ ++static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, ++ TEST_ENT * t) ++{ ++ if (!do_drbg_init(dctx, td, t)) ++ return 0; ++ if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) ++ return 0; ++ ++ return 1; ++} ++ ++/* This function performs extensive error checking as required by SP800-90. ++ * Induce several failure modes and check an error condition is set. ++ * This function along with fips_drbg_single_kat peforms the health checking ++ * operation. ++ */ ++ ++static int fips_drbg_error_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td) ++{ ++ unsigned char randout[1024]; ++ TEST_ENT t; ++ size_t i; ++ unsigned int reseed_counter_tmp; ++ unsigned char *p = (unsigned char *)dctx; ++ ++ /* Initialise DRBG */ ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ /* Don't report induced errors */ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ /* Personalisation string tests */ ++ ++ /* Test detection of too large personlisation string */ ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_PERSONALISATION_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ /* Entropy source tests */ ++ ++ /* Test entropy source failure detecion: i.e. returns no data */ ++ ++ t.entlen = 0; ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ /* Try to generate output from uninstantiated DRBG */ ++ if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, ++ td->adin, td->adinlen)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_GENERATE_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ /* Test insufficient entropy */ ++ ++ t.entlen = dctx->min_entropy - 1; ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Test too much entropy */ ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ t.entlen = dctx->max_entropy + 1; ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Nonce tests */ ++ ++ /* Test too small nonce */ ++ ++ if (dctx->min_nonce) { ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ t.noncelen = dctx->min_nonce - 1; ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_NONCE_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ } ++ ++ /* Test too large nonce */ ++ ++ if (dctx->max_nonce) { ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ t.noncelen = dctx->max_nonce + 1; ++ ++ if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_NONCE_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ } ++ ++ /* Instantiate with valid data. */ ++ if (!do_drbg_instantiate(dctx, td, &t)) ++ goto err; ++ ++ /* Check generation is now OK */ ++ if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, ++ td->adin, td->adinlen)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ /* Request too much data for one request */ ++ if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0, ++ td->adin, td->adinlen)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ /* Try too large additional input */ ++ if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, ++ td->adin, dctx->max_adin + 1)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ /* Check prediction resistance request fails if entropy source ++ * failure. ++ */ ++ ++ t.entlen = 0; ++ ++ if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, ++ td->adin, td->adinlen)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Instantiate again with valid data */ ++ ++ if (!do_drbg_instantiate(dctx, td, &t)) ++ goto err; ++ /* Test reseed counter works */ ++ /* Save initial reseed counter */ ++ reseed_counter_tmp = dctx->reseed_counter; ++ /* Set reseed counter to beyond interval */ ++ dctx->reseed_counter = dctx->reseed_interval; ++ ++ /* Generate output and check entropy has been requested for reseed */ ++ t.entcnt = 0; ++ if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, ++ td->adin, td->adinlen)) ++ goto err; ++ if (t.entcnt != 1) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); ++ goto err; ++ } ++ /* Check reseed counter has been reset */ ++ if (dctx->reseed_counter != reseed_counter_tmp + 1) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Check prediction resistance request fails if entropy source ++ * failure. ++ */ ++ ++ t.entlen = 0; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, ++ td->adin, td->adinlen)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ if (!do_drbg_instantiate(dctx, td, &t)) ++ goto err; ++ /* Test reseed counter works */ ++ /* Save initial reseed counter */ ++ reseed_counter_tmp = dctx->reseed_counter; ++ /* Set reseed counter to beyond interval */ ++ dctx->reseed_counter = dctx->reseed_interval; ++ ++ /* Generate output and check entropy has been requested for reseed */ ++ t.entcnt = 0; ++ if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, ++ td->adin, td->adinlen)) ++ goto err; ++ if (t.entcnt != 1) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); ++ goto err; ++ } ++ /* Check reseed counter has been reset */ ++ if (dctx->reseed_counter != reseed_counter_tmp + 1) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); ++ goto err; ++ } ++ ++ dctx->iflags &= ~DRBG_FLAG_NOERR; ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Explicit reseed tests */ ++ ++ /* Test explicit reseed with too large additional input */ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ /* Test explicit reseed with entropy source failure */ ++ ++ t.entlen = 0; ++ ++ if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Test explicit reseed with too much entropy */ ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ t.entlen = dctx->max_entropy + 1; ++ ++ if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ /* Test explicit reseed with too little entropy */ ++ ++ if (!do_drbg_init(dctx, td, &t)) ++ goto err; ++ ++ dctx->iflags |= DRBG_FLAG_NOERR; ++ ++ t.entlen = dctx->min_entropy - 1; ++ ++ if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_ENTROPY_ERROR_UNDETECTED); ++ goto err; ++ } ++ ++ if (!FIPS_drbg_uninstantiate(dctx)) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); ++ goto err; ++ } ++ ++ p = (unsigned char *)&dctx->d; ++ /* Standard says we have to check uninstantiate really zeroes ++ * the data... ++ */ ++ for (i = 0; i < sizeof(dctx->d); i++) { ++ if (*p != 0) { ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, ++ FIPS_R_UNINSTANTIATE_ZEROISE_ERROR); ++ goto err; ++ } ++ p++; ++ } ++ ++ return 1; ++ ++ err: ++ /* A real error as opposed to an induced one: underlying function will ++ * indicate the error. ++ */ ++ if (!(dctx->iflags & DRBG_FLAG_NOERR)) ++ FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_FUNCTION_ERROR); ++ FIPS_drbg_uninstantiate(dctx); ++ return 0; ++ ++} ++ ++int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) ++{ ++ DRBG_SELFTEST_DATA *td; ++ flags |= DRBG_FLAG_TEST; ++ for (td = drbg_test; td->nid != 0; td++) { ++ if (td->nid == nid && td->flags == flags) { ++ if (!fips_drbg_single_kat(dctx, td, 0)) ++ return 0; ++ return fips_drbg_error_check(dctx, td); ++ } ++ } ++ return 0; ++} ++ ++int FIPS_drbg_health_check(DRBG_CTX *dctx) ++{ ++ int rv; ++ DRBG_CTX *tctx = NULL; ++ tctx = FIPS_drbg_new(0, 0); ++ fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); ++ if (!tctx) ++ return 0; ++ rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags); ++ if (tctx) ++ FIPS_drbg_free(tctx); ++ if (rv) ++ fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); ++ else ++ fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); ++ if (!rv) ++ dctx->status = DRBG_STATUS_ERROR; ++ else ++ dctx->health_check_cnt = 0; ++ return rv; ++} ++ ++int FIPS_selftest_drbg(void) ++{ ++ DRBG_CTX *dctx; ++ DRBG_SELFTEST_DATA *td; ++ int rv = 1; ++ dctx = FIPS_drbg_new(0, 0); ++ if (!dctx) ++ return 0; ++ for (td = drbg_test; td->nid != 0; td++) { ++ if (td->post != 1) ++ continue; ++ if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) ++ return 1; ++ if (!fips_drbg_single_kat(dctx, td, 1)) { ++ fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); ++ rv = 0; ++ continue; ++ } ++ if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) ++ return 0; ++ } ++ FIPS_drbg_free(dctx); ++ return rv; ++} ++ ++int FIPS_selftest_drbg_all(void) ++{ ++ DRBG_CTX *dctx; ++ DRBG_SELFTEST_DATA *td; ++ int rv = 1; ++ dctx = FIPS_drbg_new(0, 0); ++ if (!dctx) ++ return 0; ++ for (td = drbg_test; td->nid != 0; td++) { ++ if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) ++ return 1; ++ if (!fips_drbg_single_kat(dctx, td, 0)) { ++ fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); ++ rv = 0; ++ continue; ++ } ++ if (!fips_drbg_error_check(dctx, td)) { ++ fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); ++ rv = 0; ++ continue; ++ } ++ if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) ++ return 0; ++ } ++ FIPS_drbg_free(dctx); ++ return rv; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_drbg_selftest.h.fips openssl-1.1.1j/crypto/fips/fips_drbg_selftest.h +--- openssl-1.1.1j/crypto/fips/fips_drbg_selftest.h.fips 2021-03-03 12:57:42.200734534 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_drbg_selftest.h 2021-03-03 12:57:42.200734534 +0100 +@@ -0,0 +1,1791 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++/* Selftest and health check data for the SP800-90 DRBG */ ++ ++#define __fips_constseg ++ ++/* AES-128 use df PR */ ++__fips_constseg static const unsigned char aes_128_use_df_pr_entropyinput[] = { ++ 0x61, 0x52, 0x7c, 0xe3, 0x23, 0x7d, 0x0a, 0x07, 0x10, 0x0c, 0x50, 0x33, ++ 0xc8, 0xdb, 0xff, 0x12 ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_pr_nonce[] = { ++ 0x51, 0x0d, 0x85, 0x77, 0xed, 0x22, 0x97, 0x28 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_personalizationstring[] = { ++ 0x59, 0x9f, 0xbb, 0xcd, 0xd5, 0x25, 0x69, 0xb5, 0xcb, 0xb5, 0x03, 0xfe, ++ 0xd7, 0xd7, 0x01, 0x67 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_additionalinput[] = { ++ 0xef, 0x88, 0x76, 0x01, 0xaf, 0x3c, 0xfe, 0x8b, 0xaf, 0x26, 0x06, 0x9e, ++ 0x9a, 0x47, 0x08, 0x76 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_entropyinputpr[] = { ++ 0xe2, 0x76, 0xf9, 0xf6, 0x3a, 0xba, 0x10, 0x9f, 0xbf, 0x47, 0x0e, 0x51, ++ 0x09, 0xfb, 0xa3, 0xb6 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_int_returnedbits[] = { ++ 0xd4, 0x98, 0x8a, 0x46, 0x80, 0x4c, 0xdb, 0xa3, 0x59, 0x02, 0x57, 0x52, ++ 0x66, 0x1c, 0xea, 0x5b ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_additionalinput2[] = { ++ 0x88, 0x8c, 0x91, 0xd6, 0xbe, 0x56, 0x6e, 0x08, 0x9a, 0x62, 0x2b, 0x11, ++ 0x3f, 0x5e, 0x31, 0x06 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_pr_entropyinputpr2[] = { ++ 0xc0, 0x5c, 0x6b, 0x98, 0x01, 0x0d, 0x58, 0x18, 0x51, 0x18, 0x96, 0xae, ++ 0xa7, 0xe3, 0xa8, 0x67 ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_pr_returnedbits[] = { ++ 0xcf, 0x01, 0xac, 0x22, 0x31, 0x06, 0x8e, 0xfc, 0xce, 0x56, 0xea, 0x24, ++ 0x0f, 0x38, 0x43, 0xc6 ++}; ++ ++/* AES-128 use df No PR */ ++__fips_constseg static const unsigned char aes_128_use_df_entropyinput[] = { ++ 0x1f, 0x8e, 0x34, 0x82, 0x0c, 0xb7, 0xbe, 0xc5, 0x01, 0x3e, 0xd0, 0xa3, ++ 0x9d, 0x7d, 0x1c, 0x9b ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_nonce[] = { ++ 0xd5, 0x4d, 0xbd, 0x4a, 0x93, 0x7f, 0xb8, 0x96 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_personalizationstring[] = { ++ 0xab, 0xd6, 0x3f, 0x04, 0xfe, 0x27, 0x6b, 0x2d, 0xd7, 0xc3, 0x1c, 0xf3, ++ 0x38, 0x66, 0xba, 0x1b ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_additionalinput[] = { ++ 0xfe, 0xf4, 0x09, 0xa8, 0xb7, 0x73, 0x27, 0x9c, 0x5f, 0xa7, 0xea, 0x46, ++ 0xb5, 0xe2, 0xb2, 0x41 ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_int_returnedbits[] = { ++ 0x42, 0xe4, 0x4e, 0x7b, 0x27, 0xdd, 0xcb, 0xbc, 0x0a, 0xcf, 0xa6, 0x67, ++ 0xe7, 0x57, 0x11, 0xb4 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_entropyinputreseed[] = { ++ 0x14, 0x26, 0x69, 0xd9, 0xf3, 0x65, 0x03, 0xd6, 0x6b, 0xb9, 0x44, 0x0b, ++ 0xc7, 0xc4, 0x9e, 0x39 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_use_df_additionalinputreseed[] = { ++ 0x55, 0x2e, 0x60, 0x9a, 0x05, 0x72, 0x8a, 0xa8, 0xef, 0x22, 0x81, 0x5a, ++ 0xc8, 0x93, 0xfa, 0x84 ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_additionalinput2[] = { ++ 0x3c, 0x40, 0xc8, 0xc4, 0x16, 0x0c, 0x21, 0xa4, 0x37, 0x2c, 0x8f, 0xa5, ++ 0x06, 0x0c, 0x15, 0x2c ++}; ++ ++__fips_constseg static const unsigned char aes_128_use_df_returnedbits[] = { ++ 0xe1, 0x3e, 0x99, 0x98, 0x86, 0x67, 0x0b, 0x63, 0x7b, 0xbe, 0x3f, 0x88, ++ 0x46, 0x81, 0xc7, 0x19 ++}; ++ ++/* AES-192 use df PR */ ++__fips_constseg static const unsigned char aes_192_use_df_pr_entropyinput[] = { ++ 0x2b, 0x4e, 0x8b, 0xe1, 0xf1, 0x34, 0x80, 0x56, 0x81, 0xf9, 0x74, 0xec, ++ 0x17, 0x44, 0x2a, 0xf1, 0x14, 0xb0, 0xbf, 0x97, 0x39, 0xb7, 0x04, 0x7d ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_pr_nonce[] = { ++ 0xd6, 0x9d, 0xeb, 0x14, 0x4e, 0x6c, 0x30, 0x1e, 0x39, 0x55, 0x73, 0xd0, ++ 0xd1, 0x80, 0x78, 0xfa ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_personalizationstring[] = { ++ 0xfc, 0x43, 0x4a, 0xf8, 0x9a, 0x55, 0xb3, 0x53, 0x83, 0xe2, 0x18, 0x16, ++ 0x0c, 0xdc, 0xcd, 0x5e, 0x4f, 0xa0, 0x03, 0x01, 0x2b, 0x9f, 0xe4, 0xd5, ++ 0x7d, 0x49, 0xf0, 0x41, 0x9e, 0x3d, 0x99, 0x04 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_additionalinput[] = { ++ 0x5e, 0x9f, 0x49, 0x6f, 0x21, 0x8b, 0x1d, 0x32, 0xd5, 0x84, 0x5c, 0xac, ++ 0xaf, 0xdf, 0xe4, 0x79, 0x9e, 0xaf, 0xa9, 0x82, 0xd0, 0xf8, 0x4f, 0xcb, ++ 0x69, 0x10, 0x0a, 0x7e, 0x81, 0x57, 0xb5, 0x36 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_entropyinputpr[] = { ++ 0xd4, 0x81, 0x0c, 0xd7, 0x66, 0x39, 0xec, 0x42, 0x53, 0x87, 0x41, 0xa5, ++ 0x1e, 0x7d, 0x80, 0x91, 0x8e, 0xbb, 0xed, 0xac, 0x14, 0x02, 0x1a, 0xd5 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_int_returnedbits[] = { ++ 0xdf, 0x1d, 0x39, 0x45, 0x7c, 0x9b, 0xc6, 0x2b, 0x7d, 0x8c, 0x93, 0xe9, ++ 0x19, 0x30, 0x6b, 0x67 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_additionalinput2[] = { ++ 0x00, 0x71, 0x27, 0x4e, 0xd3, 0x14, 0xf1, 0x20, 0x7f, 0x4a, 0x41, 0x32, ++ 0x2a, 0x97, 0x11, 0x43, 0x8f, 0x4a, 0x15, 0x7b, 0x9b, 0x51, 0x79, 0xda, ++ 0x49, 0x3d, 0xde, 0xe8, 0xbc, 0x93, 0x91, 0x99 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_pr_entropyinputpr2[] = { ++ 0x90, 0xee, 0x76, 0xa1, 0x45, 0x8d, 0xb7, 0x40, 0xb0, 0x11, 0xbf, 0xd0, ++ 0x65, 0xd7, 0x3c, 0x7c, 0x4f, 0x20, 0x3f, 0x4e, 0x11, 0x9d, 0xb3, 0x5e ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_pr_returnedbits[] = { ++ 0x24, 0x3b, 0x20, 0xa4, 0x37, 0x66, 0xba, 0x72, 0x39, 0x3f, 0xcf, 0x3c, ++ 0x7e, 0x1a, 0x2b, 0x83 ++}; ++ ++/* AES-192 use df No PR */ ++__fips_constseg static const unsigned char aes_192_use_df_entropyinput[] = { ++ 0x8d, 0x74, 0xa4, 0x50, 0x1a, 0x02, 0x68, 0x0c, 0x2a, 0x69, 0xc4, 0x82, ++ 0x3b, 0xbb, 0xda, 0x0e, 0x7f, 0x77, 0xa3, 0x17, 0x78, 0x57, 0xb2, 0x7b ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_nonce[] = { ++ 0x75, 0xd5, 0x1f, 0xac, 0xa4, 0x8d, 0x42, 0x78, 0xd7, 0x69, 0x86, 0x9d, ++ 0x77, 0xd7, 0x41, 0x0e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_personalizationstring[] = { ++ 0x4e, 0x33, 0x41, 0x3c, 0x9c, 0xc2, 0xd2, 0x53, 0xaf, 0x90, 0xea, 0xcf, ++ 0x19, 0x50, 0x1e, 0xe6, 0x6f, 0x63, 0xc8, 0x32, 0x22, 0xdc, 0x07, 0x65, ++ 0x9c, 0xd3, 0xf8, 0x30, 0x9e, 0xed, 0x35, 0x70 ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_additionalinput[] = { ++ 0x5d, 0x8b, 0x8c, 0xc1, 0xdf, 0x0e, 0x02, 0x78, 0xfb, 0x19, 0xb8, 0x69, ++ 0x78, 0x4e, 0x9c, 0x52, 0xbc, 0xc7, 0x20, 0xc9, 0xe6, 0x5e, 0x77, 0x22, ++ 0x28, 0x3d, 0x0c, 0x9e, 0x68, 0xa8, 0x45, 0xd7 ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_int_returnedbits[] = { ++ 0xd5, 0xe7, 0x08, 0xc5, 0x19, 0x99, 0xd5, 0x31, 0x03, 0x0a, 0x74, 0xb6, ++ 0xb7, 0xed, 0xe9, 0xea ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_entropyinputreseed[] = { ++ 0x9c, 0x26, 0xda, 0xf1, 0xac, 0xd9, 0x5a, 0xd6, 0xa8, 0x65, 0xf5, 0x02, ++ 0x8f, 0xdc, 0xa2, 0x09, 0x54, 0xa6, 0xe2, 0xa4, 0xde, 0x32, 0xe0, 0x01 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_use_df_additionalinputreseed[] = { ++ 0x9b, 0x90, 0xb0, 0x3a, 0x0e, 0x3a, 0x80, 0x07, 0x4a, 0xf4, 0xda, 0x76, ++ 0x28, 0x30, 0x3c, 0xee, 0x54, 0x1b, 0x94, 0x59, 0x51, 0x43, 0x56, 0x77, ++ 0xaf, 0x88, 0xdd, 0x63, 0x89, 0x47, 0x06, 0x65 ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_additionalinput2[] = { ++ 0x3c, 0x11, 0x64, 0x7a, 0x96, 0xf5, 0xd8, 0xb8, 0xae, 0xd6, 0x70, 0x4e, ++ 0x16, 0x96, 0xde, 0xe9, 0x62, 0xbc, 0xee, 0x28, 0x2f, 0x26, 0xa6, 0xf0, ++ 0x56, 0xef, 0xa3, 0xf1, 0x6b, 0xa1, 0xb1, 0x77 ++}; ++ ++__fips_constseg static const unsigned char aes_192_use_df_returnedbits[] = { ++ 0x0b, 0xe2, 0x56, 0x03, 0x1e, 0xdb, 0x2c, 0x6d, 0x7f, 0x1b, 0x15, 0x58, ++ 0x1a, 0xf9, 0x13, 0x28 ++}; ++ ++/* AES-256 use df PR */ ++__fips_constseg static const unsigned char aes_256_use_df_pr_entropyinput[] = { ++ 0x61, 0x68, 0xfc, 0x1a, 0xf0, 0xb5, 0x95, 0x6b, 0x85, 0x09, 0x9b, 0x74, ++ 0x3f, 0x13, 0x78, 0x49, 0x3b, 0x85, 0xec, 0x93, 0x13, 0x3b, 0xa9, 0x4f, ++ 0x96, 0xab, 0x2c, 0xe4, 0xc8, 0x8f, 0xdd, 0x6a ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_pr_nonce[] = { ++ 0xad, 0xd2, 0xbb, 0xba, 0xb7, 0x65, 0x89, 0xc3, 0x21, 0x6c, 0x55, 0x33, ++ 0x2b, 0x36, 0xff, 0xa4 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_personalizationstring[] = { ++ 0x6e, 0xca, 0xe7, 0x20, 0x72, 0xd3, 0x84, 0x5a, 0x32, 0xd3, 0x4b, 0x24, ++ 0x72, 0xc4, 0x63, 0x2b, 0x9d, 0x12, 0x24, 0x0c, 0x23, 0x26, 0x8e, 0x83, ++ 0x16, 0x37, 0x0b, 0xd1, 0x06, 0x4f, 0x68, 0x6d ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_additionalinput[] = { ++ 0x7e, 0x08, 0x4a, 0xbb, 0xe3, 0x21, 0x7c, 0xc9, 0x23, 0xd2, 0xf8, 0xb0, ++ 0x73, 0x98, 0xba, 0x84, 0x74, 0x23, 0xab, 0x06, 0x8a, 0xe2, 0x22, 0xd3, ++ 0x7b, 0xce, 0x9b, 0xd2, 0x4a, 0x76, 0xb8, 0xde ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_entropyinputpr[] = { ++ 0x0b, 0x23, 0xaf, 0xdf, 0xf1, 0x62, 0xd7, 0xd3, 0x43, 0x97, 0xf8, 0x77, ++ 0x04, 0xa8, 0x42, 0x20, 0xbd, 0xf6, 0x0f, 0xc1, 0x17, 0x2f, 0x9f, 0x54, ++ 0xbb, 0x56, 0x17, 0x86, 0x68, 0x0e, 0xba, 0xa9 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_int_returnedbits[] = { ++ 0x31, 0x8e, 0xad, 0xaf, 0x40, 0xeb, 0x6b, 0x74, 0x31, 0x46, 0x80, 0xc7, ++ 0x17, 0xab, 0x3c, 0x7a ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_additionalinput2[] = { ++ 0x94, 0x6b, 0xc9, 0x9f, 0xab, 0x8d, 0xc5, 0xec, 0x71, 0x88, 0x1d, 0x00, ++ 0x8c, 0x89, 0x68, 0xe4, 0xc8, 0x07, 0x77, 0x36, 0x17, 0x6d, 0x79, 0x78, ++ 0xc7, 0x06, 0x4e, 0x99, 0x04, 0x28, 0x29, 0xc3 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_pr_entropyinputpr2[] = { ++ 0xbf, 0x6c, 0x59, 0x2a, 0x0d, 0x44, 0x0f, 0xae, 0x9a, 0x5e, 0x03, 0x73, ++ 0xd8, 0xa6, 0xe1, 0xcf, 0x25, 0x61, 0x38, 0x24, 0x86, 0x9e, 0x53, 0xe8, ++ 0xa4, 0xdf, 0x56, 0xf4, 0x06, 0x07, 0x9c, 0x0f ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_pr_returnedbits[] = { ++ 0x22, 0x4a, 0xb4, 0xb8, 0xb6, 0xee, 0x7d, 0xb1, 0x9e, 0xc9, 0xf9, 0xa0, ++ 0xd9, 0xe2, 0x97, 0x00 ++}; ++ ++/* AES-256 use df No PR */ ++__fips_constseg static const unsigned char aes_256_use_df_entropyinput[] = { ++ 0xa5, 0x3e, 0x37, 0x10, 0x17, 0x43, 0x91, 0x93, 0x59, 0x1e, 0x47, 0x50, ++ 0x87, 0xaa, 0xdd, 0xd5, 0xc1, 0xc3, 0x86, 0xcd, 0xca, 0x0d, 0xdb, 0x68, ++ 0xe0, 0x02, 0xd8, 0x0f, 0xdc, 0x40, 0x1a, 0x47 ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_nonce[] = { ++ 0xa9, 0x4d, 0xa5, 0x5a, 0xfd, 0xc5, 0x0c, 0xe5, 0x1c, 0x9a, 0x3b, 0x8a, ++ 0x4c, 0x44, 0x84, 0x40 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_personalizationstring[] = { ++ 0x8b, 0x52, 0xa2, 0x4a, 0x93, 0xc3, 0x4e, 0xa7, 0x1e, 0x1c, 0xa7, 0x05, ++ 0xeb, 0x82, 0x9b, 0xa6, 0x5d, 0xe4, 0xd4, 0xe0, 0x7f, 0xa3, 0xd8, 0x6b, ++ 0x37, 0x84, 0x5f, 0xf1, 0xc7, 0xd5, 0xf6, 0xd2 ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_additionalinput[] = { ++ 0x20, 0xf4, 0x22, 0xed, 0xf8, 0x5c, 0xa1, 0x6a, 0x01, 0xcf, 0xbe, 0x5f, ++ 0x8d, 0x6c, 0x94, 0x7f, 0xae, 0x12, 0xa8, 0x57, 0xdb, 0x2a, 0xa9, 0xbf, ++ 0xc7, 0xb3, 0x65, 0x81, 0x80, 0x8d, 0x0d, 0x46 ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_int_returnedbits[] = { ++ 0x4e, 0x44, 0xfd, 0xf3, 0x9e, 0x29, 0xa2, 0xb8, 0x0f, 0x5d, 0x6c, 0xe1, ++ 0x28, 0x0c, 0x3b, 0xc1 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_entropyinputreseed[] = { ++ 0xdd, 0x40, 0xe5, 0x98, 0x7b, 0x27, 0x16, 0x73, 0x15, 0x68, 0xd2, 0x76, ++ 0xbf, 0x0c, 0x67, 0x15, 0x75, 0x79, 0x03, 0xd3, 0xde, 0xde, 0x91, 0x46, ++ 0x42, 0xdd, 0xd4, 0x67, 0xc8, 0x79, 0xc8, 0x1e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_use_df_additionalinputreseed[] = { ++ 0x7f, 0xd8, 0x1f, 0xbd, 0x2a, 0xb5, 0x1c, 0x11, 0x5d, 0x83, 0x4e, 0x99, ++ 0xf6, 0x5c, 0xa5, 0x40, 0x20, 0xed, 0x38, 0x8e, 0xd5, 0x9e, 0xe0, 0x75, ++ 0x93, 0xfe, 0x12, 0x5e, 0x5d, 0x73, 0xfb, 0x75 ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_additionalinput2[] = { ++ 0xcd, 0x2c, 0xff, 0x14, 0x69, 0x3e, 0x4c, 0x9e, 0xfd, 0xfe, 0x26, 0x0d, ++ 0xe9, 0x86, 0x00, 0x49, 0x30, 0xba, 0xb1, 0xc6, 0x50, 0x57, 0x77, 0x2a, ++ 0x62, 0x39, 0x2c, 0x3b, 0x74, 0xeb, 0xc9, 0x0d ++}; ++ ++__fips_constseg static const unsigned char aes_256_use_df_returnedbits[] = { ++ 0x4f, 0x78, 0xbe, 0xb9, 0x4d, 0x97, 0x8c, 0xe9, 0xd0, 0x97, 0xfe, 0xad, ++ 0xfa, 0xfd, 0x35, 0x5e ++}; ++ ++/* AES-128 no df PR */ ++__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinput[] = { ++ 0x9a, 0x25, 0x65, 0x10, 0x67, 0xd5, 0xb6, 0x6b, 0x70, 0xa1, 0xb3, 0xa4, ++ 0x43, 0x95, 0x80, 0xc0, 0x84, 0x0a, 0x79, 0xb0, 0x88, 0x74, 0xf2, 0xbf, ++ 0x31, 0x6c, 0x33, 0x38, 0x0b, 0x00, 0xb2, 0x5a ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_pr_nonce[] = { ++ 0x78, 0x47, 0x6b, 0xf7, 0x90, 0x8e, 0x87, 0xf1 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_pr_personalizationstring[] = { ++ 0xf7, 0x22, 0x1d, 0x3a, 0xbe, 0x1d, 0xca, 0x32, 0x1b, 0xbd, 0x87, 0x0c, ++ 0x51, 0x24, 0x19, 0xee, 0xa3, 0x23, 0x09, 0x63, 0x33, 0x3d, 0xa8, 0x0c, ++ 0x1c, 0xfa, 0x42, 0x89, 0xcc, 0x6f, 0xa0, 0xa8 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_pr_additionalinput[] = { ++ 0xc9, 0xe0, 0x80, 0xbf, 0x8c, 0x45, 0x58, 0x39, 0xff, 0x00, 0xab, 0x02, ++ 0x4c, 0x3e, 0x3a, 0x95, 0x9b, 0x80, 0xa8, 0x21, 0x2a, 0xee, 0xba, 0x73, ++ 0xb1, 0xd9, 0xcf, 0x28, 0xf6, 0x8f, 0x9b, 0x12 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinputpr[] = { ++ 0x4c, 0xa8, 0xc5, 0xf0, 0x59, 0x9e, 0xa6, 0x8d, 0x26, 0x53, 0xd7, 0x8a, ++ 0xa9, 0xd8, 0xf7, 0xed, 0xb2, 0xf9, 0x12, 0x42, 0xe1, 0xe5, 0xbd, 0xe7, ++ 0xe7, 0x1d, 0x74, 0x99, 0x00, 0x9d, 0x31, 0x3e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_pr_int_returnedbits[] = { ++ 0xe2, 0xac, 0x20, 0xf0, 0x80, 0xe7, 0xbc, 0x7e, 0x9c, 0x7b, 0x65, 0x71, ++ 0xaf, 0x19, 0x32, 0x16 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_pr_additionalinput2[] = { ++ 0x32, 0x7f, 0x38, 0x8b, 0x73, 0x0a, 0x78, 0x83, 0xdc, 0x30, 0xbe, 0x9f, ++ 0x10, 0x1f, 0xf5, 0x1f, 0xca, 0x00, 0xb5, 0x0d, 0xd6, 0x9d, 0x60, 0x83, ++ 0x51, 0x54, 0x7d, 0x38, 0x23, 0x3a, 0x52, 0x50 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_pr_entropyinputpr2[] = { ++ 0x18, 0x61, 0x53, 0x56, 0xed, 0xed, 0xd7, 0x20, 0xfb, 0x71, 0x04, 0x7a, ++ 0xb2, 0xac, 0xc1, 0x28, 0xcd, 0xf2, 0xc2, 0xfc, 0xaa, 0xb1, 0x06, 0x07, ++ 0xe9, 0x46, 0x95, 0x02, 0x48, 0x01, 0x78, 0xf9 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_pr_returnedbits[] = { ++ 0x29, 0xc8, 0x1b, 0x15, 0xb1, 0xd1, 0xc2, 0xf6, 0x71, 0x86, 0x68, 0x33, ++ 0x57, 0x82, 0x33, 0xaf ++}; ++ ++/* AES-128 no df No PR */ ++__fips_constseg static const unsigned char aes_128_no_df_entropyinput[] = { ++ 0xc9, 0xc5, 0x79, 0xbc, 0xe8, 0xc5, 0x19, 0xd8, 0xbc, 0x66, 0x73, 0x67, ++ 0xf6, 0xd3, 0x72, 0xaa, 0xa6, 0x16, 0xb8, 0x50, 0xb7, 0x47, 0x3a, 0x42, ++ 0xab, 0xf4, 0x16, 0xb2, 0x96, 0xd2, 0xb6, 0x60 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_nonce[] = { ++ 0x5f, 0xbf, 0x97, 0x0c, 0x4b, 0xa4, 0x87, 0x13 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_personalizationstring[] = { ++ 0xce, 0xfb, 0x7b, 0x3f, 0xd4, 0x6b, 0x29, 0x0d, 0x69, 0x06, 0xff, 0xbb, ++ 0xf2, 0xe5, 0xc6, 0x6c, 0x0a, 0x10, 0xa0, 0xcf, 0x1a, 0x48, 0xc7, 0x8b, ++ 0x3c, 0x16, 0x88, 0xed, 0x50, 0x13, 0x81, 0xce ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_additionalinput[] = { ++ 0x4b, 0x22, 0x46, 0x18, 0x02, 0x7b, 0xd2, 0x1b, 0x22, 0x42, 0x7c, 0x37, ++ 0xd9, 0xf6, 0xe8, 0x9b, 0x12, 0x30, 0x5f, 0xe9, 0x90, 0xe8, 0x08, 0x24, ++ 0x4f, 0x06, 0x66, 0xdb, 0x19, 0x2b, 0x13, 0x95 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_int_returnedbits[] = { ++ 0x2e, 0x96, 0x70, 0x64, 0xfa, 0xdf, 0xdf, 0x57, 0xb5, 0x82, 0xee, 0xd6, ++ 0xed, 0x3e, 0x65, 0xc2 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_entropyinputreseed[] = { ++ 0x26, 0xc0, 0x72, 0x16, 0x3a, 0x4b, 0xb7, 0x99, 0xd4, 0x07, 0xaf, 0x66, ++ 0x62, 0x36, 0x96, 0xa4, 0x51, 0x17, 0xfa, 0x07, 0x8b, 0x17, 0x5e, 0xa1, ++ 0x2f, 0x3c, 0x10, 0xe7, 0x90, 0xd0, 0x46, 0x00 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_128_no_df_additionalinputreseed[] = { ++ 0x83, 0x39, 0x37, 0x7b, 0x02, 0x06, 0xd2, 0x12, 0x13, 0x8d, 0x8b, 0xf2, ++ 0xf0, 0xf6, 0x26, 0xeb, 0xa4, 0x22, 0x7b, 0xc2, 0xe7, 0xba, 0x79, 0xe4, ++ 0x3b, 0x77, 0x5d, 0x4d, 0x47, 0xb2, 0x2d, 0xb4 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_additionalinput2[] = { ++ 0x0b, 0xb9, 0x67, 0x37, 0xdb, 0x83, 0xdf, 0xca, 0x81, 0x8b, 0xf9, 0x3f, ++ 0xf1, 0x11, 0x1b, 0x2f, 0xf0, 0x61, 0xa6, 0xdf, 0xba, 0xa3, 0xb1, 0xac, ++ 0xd3, 0xe6, 0x09, 0xb8, 0x2c, 0x6a, 0x67, 0xd6 ++}; ++ ++__fips_constseg static const unsigned char aes_128_no_df_returnedbits[] = { ++ 0x1e, 0xa7, 0xa4, 0xe4, 0xe1, 0xa6, 0x7c, 0x69, 0x9a, 0x44, 0x6c, 0x36, ++ 0x81, 0x37, 0x19, 0xd4 ++}; ++ ++/* AES-192 no df PR */ ++__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinput[] = { ++ 0x9d, 0x2c, 0xd2, 0x55, 0x66, 0xea, 0xe0, 0xbe, 0x18, 0xb7, 0x76, 0xe7, ++ 0x73, 0x35, 0xd8, 0x1f, 0xad, 0x3a, 0xe3, 0x81, 0x0e, 0x92, 0xd0, 0x61, ++ 0xc9, 0x12, 0x26, 0xf6, 0x1c, 0xdf, 0xfe, 0x47, 0xaa, 0xfe, 0x7d, 0x5a, ++ 0x17, 0x1f, 0x8d, 0x9a ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_pr_nonce[] = { ++ 0x44, 0x82, 0xed, 0xe8, 0x4c, 0x28, 0x5a, 0x14, 0xff, 0x88, 0x8d, 0x19, ++ 0x61, 0x5c, 0xee, 0x0f ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_pr_personalizationstring[] = { ++ 0x47, 0xd7, 0x9b, 0x99, 0xaa, 0xcb, 0xe7, 0xd2, 0x57, 0x66, 0x2c, 0xe1, ++ 0x78, 0xd6, 0x2c, 0xea, 0xa3, 0x23, 0x5f, 0x2a, 0xc1, 0x3a, 0xf0, 0xa4, ++ 0x20, 0x3b, 0xfa, 0x07, 0xd5, 0x05, 0x02, 0xe4, 0x57, 0x01, 0xb6, 0x10, ++ 0x57, 0x2e, 0xe7, 0x55 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_pr_additionalinput[] = { ++ 0x4b, 0x74, 0x0b, 0x40, 0xce, 0x6b, 0xc2, 0x6a, 0x24, 0xb4, 0xf3, 0xad, ++ 0x7a, 0xa5, 0x7a, 0xa2, 0x15, 0xe2, 0xc8, 0x61, 0x15, 0xc6, 0xb7, 0x85, ++ 0x69, 0x11, 0xad, 0x7b, 0x14, 0xd2, 0xf6, 0x12, 0xa1, 0x95, 0x5d, 0x3f, ++ 0xe2, 0xd0, 0x0c, 0x2f ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinputpr[] = { ++ 0x0c, 0x9c, 0xad, 0x05, 0xee, 0xae, 0x48, 0x23, 0x89, 0x59, 0xa1, 0x94, ++ 0xd7, 0xd8, 0x75, 0xd5, 0x54, 0x93, 0xc7, 0x4a, 0xd9, 0x26, 0xde, 0xeb, ++ 0xba, 0xb0, 0x7e, 0x30, 0x1d, 0x5f, 0x69, 0x40, 0x9c, 0x3b, 0x17, 0x58, ++ 0x1d, 0x30, 0xb3, 0x78 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_pr_int_returnedbits[] = { ++ 0xf7, 0x93, 0xb0, 0x6d, 0x77, 0x83, 0xd5, 0x38, 0x01, 0xe1, 0x52, 0x40, ++ 0x7e, 0x3e, 0x0c, 0x26 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_pr_additionalinput2[] = { ++ 0xbc, 0x4b, 0x37, 0x44, 0x1c, 0xc5, 0x45, 0x5f, 0x8f, 0x51, 0x62, 0x8a, ++ 0x85, 0x30, 0x1d, 0x7c, 0xe4, 0xcf, 0xf7, 0x44, 0xce, 0x32, 0x3e, 0x57, ++ 0x95, 0xa4, 0x2a, 0xdf, 0xfd, 0x9e, 0x38, 0x41, 0xb3, 0xf6, 0xc5, 0xee, ++ 0x0c, 0x4b, 0xee, 0x6e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_pr_entropyinputpr2[] = { ++ 0xec, 0xaf, 0xf6, 0x4f, 0xb1, 0xa0, 0x54, 0xb5, 0x5b, 0xe3, 0x46, 0xb0, ++ 0x76, 0x5a, 0x7c, 0x3f, 0x7b, 0x94, 0x69, 0x21, 0x51, 0x02, 0xe5, 0x9f, ++ 0x04, 0x59, 0x02, 0x98, 0xc6, 0x43, 0x2c, 0xcc, 0x26, 0x4c, 0x87, 0x6b, ++ 0x8e, 0x0a, 0x83, 0xdf ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_pr_returnedbits[] = { ++ 0x74, 0x45, 0xfb, 0x53, 0x84, 0x96, 0xbe, 0xff, 0x15, 0xcc, 0x41, 0x91, ++ 0xb9, 0xa1, 0x21, 0x68 ++}; ++ ++/* AES-192 no df No PR */ ++__fips_constseg static const unsigned char aes_192_no_df_entropyinput[] = { ++ 0x3c, 0x7d, 0xb5, 0xe0, 0x54, 0xd9, 0x6e, 0x8c, 0xa9, 0x86, 0xce, 0x4e, ++ 0x6b, 0xaf, 0xeb, 0x2f, 0xe7, 0x75, 0xe0, 0x8b, 0xa4, 0x3b, 0x07, 0xfe, ++ 0xbe, 0x33, 0x75, 0x93, 0x80, 0x27, 0xb5, 0x29, 0x47, 0x8b, 0xc7, 0x28, ++ 0x94, 0xc3, 0x59, 0x63 ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_nonce[] = { ++ 0x43, 0xf1, 0x7d, 0xb8, 0xc3, 0xfe, 0xd0, 0x23, 0x6b, 0xb4, 0x92, 0xdb, ++ 0x29, 0xfd, 0x45, 0x71 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_personalizationstring[] = { ++ 0x9f, 0x24, 0x29, 0x99, 0x9e, 0x01, 0xab, 0xe9, 0x19, 0xd8, 0x23, 0x08, ++ 0xb7, 0xd6, 0x7e, 0x8c, 0xc0, 0x9e, 0x7f, 0x6e, 0x5b, 0x33, 0x20, 0x96, ++ 0x0b, 0x23, 0x2c, 0xa5, 0x6a, 0xf8, 0x1b, 0x04, 0x26, 0xdb, 0x2e, 0x2b, ++ 0x3b, 0x88, 0xce, 0x35 ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_additionalinput[] = { ++ 0x94, 0xe9, 0x7c, 0x3d, 0xa7, 0xdb, 0x60, 0x83, 0x1f, 0x98, 0x3f, 0x0b, ++ 0x88, 0x59, 0x57, 0x51, 0x88, 0x9f, 0x76, 0x49, 0x9f, 0xa6, 0xda, 0x71, ++ 0x1d, 0x0d, 0x47, 0x16, 0x63, 0xc5, 0x68, 0xe4, 0x5d, 0x39, 0x69, 0xb3, ++ 0x3e, 0xbe, 0xd4, 0x8e ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_int_returnedbits[] = { ++ 0xf9, 0xd7, 0xad, 0x69, 0xab, 0x8f, 0x23, 0x56, 0x70, 0x17, 0x4f, 0x2a, ++ 0x45, 0xe7, 0x4a, 0xc5 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_entropyinputreseed[] = { ++ 0xa6, 0x71, 0x6a, 0x3d, 0xba, 0xd1, 0xe8, 0x66, 0xa6, 0xef, 0xb2, 0x0e, ++ 0xa8, 0x9c, 0xaa, 0x4e, 0xaf, 0x17, 0x89, 0x50, 0x00, 0xda, 0xa1, 0xb1, ++ 0x0b, 0xa4, 0xd9, 0x35, 0x89, 0xc8, 0xe5, 0xb0, 0xd9, 0xb7, 0xc4, 0x33, ++ 0x9b, 0xcb, 0x7e, 0x75 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_192_no_df_additionalinputreseed[] = { ++ 0x27, 0x21, 0xfc, 0xc2, 0xbd, 0xf3, 0x3c, 0xce, 0xc3, 0xca, 0xc1, 0x01, ++ 0xe0, 0xff, 0x93, 0x12, 0x7d, 0x54, 0x42, 0xe3, 0x9f, 0x03, 0xdf, 0x27, ++ 0x04, 0x07, 0x3c, 0x53, 0x7f, 0xa8, 0x66, 0xc8, 0x97, 0x4b, 0x61, 0x40, ++ 0x5d, 0x7a, 0x25, 0x79 ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_additionalinput2[] = { ++ 0x2d, 0x8e, 0x16, 0x5d, 0x0b, 0x9f, 0xeb, 0xaa, 0xd6, 0xec, 0x28, 0x71, ++ 0x7c, 0x0b, 0xc1, 0x1d, 0xd4, 0x44, 0x19, 0x47, 0xfd, 0x1d, 0x7c, 0xe5, ++ 0xf3, 0x27, 0xe1, 0xb6, 0x72, 0x0a, 0xe0, 0xec, 0x0e, 0xcd, 0xef, 0x1a, ++ 0x91, 0x6a, 0xe3, 0x5f ++}; ++ ++__fips_constseg static const unsigned char aes_192_no_df_returnedbits[] = { ++ 0xe5, 0xda, 0xb8, 0xe0, 0x63, 0x59, 0x5a, 0xcc, 0x3d, 0xdc, 0x9f, 0xe8, ++ 0x66, 0x67, 0x2c, 0x92 ++}; ++ ++/* AES-256 no df PR */ ++__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinput[] = { ++ 0x15, 0xc7, 0x5d, 0xcb, 0x41, 0x4b, 0x16, 0x01, 0x3a, 0xd1, 0x44, 0xe8, ++ 0x22, 0x32, 0xc6, 0x9c, 0x3f, 0xe7, 0x43, 0xf5, 0x9a, 0xd3, 0xea, 0xf2, ++ 0xd7, 0x4e, 0x6e, 0x6a, 0x55, 0x73, 0x40, 0xef, 0x89, 0xad, 0x0d, 0x03, ++ 0x96, 0x7e, 0x78, 0x81, 0x2f, 0x91, 0x1b, 0x44, 0xb0, 0x02, 0xba, 0x1c ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_pr_nonce[] = { ++ 0xdc, 0xe4, 0xd4, 0x27, 0x7a, 0x90, 0xd7, 0x99, 0x43, 0xa1, 0x3c, 0x30, ++ 0xcc, 0x4b, 0xee, 0x2e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_pr_personalizationstring[] = { ++ 0xe3, 0xe6, 0xb9, 0x11, 0xe4, 0x7a, 0xa4, 0x40, 0x6b, 0xf8, 0x73, 0xf7, ++ 0x7e, 0xec, 0xc7, 0xb9, 0x97, 0xbf, 0xf8, 0x25, 0x7b, 0xbe, 0x11, 0x9b, ++ 0x5b, 0x6a, 0x0c, 0x2e, 0x2b, 0x01, 0x51, 0xcd, 0x41, 0x4b, 0x6b, 0xac, ++ 0x31, 0xa8, 0x0b, 0xf7, 0xe6, 0x59, 0x42, 0xb8, 0x03, 0x0c, 0xf8, 0x06 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_pr_additionalinput[] = { ++ 0x6a, 0x9f, 0x00, 0x91, 0xae, 0xfe, 0xcf, 0x84, 0x99, 0xce, 0xb1, 0x40, ++ 0x6d, 0x5d, 0x33, 0x28, 0x84, 0xf4, 0x8c, 0x63, 0x4c, 0x7e, 0xbd, 0x2c, ++ 0x80, 0x76, 0xee, 0x5a, 0xaa, 0x15, 0x07, 0x31, 0xd8, 0xbb, 0x8c, 0x69, ++ 0x9d, 0x9d, 0xbc, 0x7e, 0x49, 0xae, 0xec, 0x39, 0x6b, 0xd1, 0x1f, 0x7e ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinputpr[] = { ++ 0xf3, 0xb9, 0x75, 0x9c, 0xbd, 0x88, 0xea, 0xa2, 0x50, 0xad, 0xd6, 0x16, ++ 0x1a, 0x12, 0x3c, 0x86, 0x68, 0xaf, 0x6f, 0xbe, 0x19, 0xf2, 0xee, 0xcc, ++ 0xa5, 0x70, 0x84, 0x53, 0x50, 0xcb, 0x9f, 0x14, 0xa9, 0xe5, 0xee, 0xb9, ++ 0x48, 0x45, 0x40, 0xe2, 0xc7, 0xc9, 0x9a, 0x74, 0xff, 0x8c, 0x99, 0x1f ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_pr_int_returnedbits[] = { ++ 0x2e, 0xf2, 0x45, 0x4c, 0x62, 0x2e, 0x0a, 0xb9, 0x6b, 0xa2, 0xfd, 0x56, ++ 0x79, 0x60, 0x93, 0xcf ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_pr_additionalinput2[] = { ++ 0xaf, 0x69, 0x20, 0xe9, 0x3b, 0x37, 0x9d, 0x3f, 0xb4, 0x80, 0x02, 0x7a, ++ 0x25, 0x7d, 0xb8, 0xde, 0x71, 0xc5, 0x06, 0x0c, 0xb4, 0xe2, 0x8f, 0x35, ++ 0xd8, 0x14, 0x0d, 0x7f, 0x76, 0x63, 0x4e, 0xb5, 0xee, 0xe9, 0x6f, 0x34, ++ 0xc7, 0x5f, 0x56, 0x14, 0x4a, 0xe8, 0x73, 0x95, 0x5b, 0x1c, 0xb9, 0xcb ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_pr_entropyinputpr2[] = { ++ 0xe5, 0xb0, 0x2e, 0x7e, 0x52, 0x30, 0xe3, 0x63, 0x82, 0xb6, 0x44, 0xd3, ++ 0x25, 0x19, 0x05, 0x24, 0x9a, 0x9f, 0x5f, 0x27, 0x6a, 0x29, 0xab, 0xfa, ++ 0x07, 0xa2, 0x42, 0x0f, 0xc5, 0xa8, 0x94, 0x7c, 0x17, 0x7b, 0x85, 0x83, ++ 0x0c, 0x25, 0x0e, 0x63, 0x0b, 0xe9, 0x12, 0x60, 0xcd, 0xef, 0x80, 0x0f ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_pr_returnedbits[] = { ++ 0x5e, 0xf2, 0x26, 0xef, 0x9f, 0x58, 0x5d, 0xd5, 0x4a, 0x10, 0xfe, 0xa7, ++ 0x2d, 0x5f, 0x4a, 0x46 ++}; ++ ++/* AES-256 no df No PR */ ++__fips_constseg static const unsigned char aes_256_no_df_entropyinput[] = { ++ 0xfb, 0xcf, 0x1b, 0x61, 0x16, 0x89, 0x78, 0x23, 0xf5, 0xd8, 0x96, 0xe3, ++ 0x4e, 0x64, 0x0b, 0x29, 0x9a, 0x3f, 0xf8, 0xa5, 0xed, 0xf2, 0xfe, 0xdb, ++ 0x16, 0xca, 0x7f, 0x10, 0xfa, 0x5e, 0x18, 0x76, 0x2c, 0x63, 0x5e, 0x96, ++ 0xcf, 0xb3, 0xd6, 0xfc, 0xaf, 0x99, 0x39, 0x28, 0x9c, 0x61, 0xe8, 0xb3 ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_nonce[] = { ++ 0x12, 0x96, 0xf0, 0x52, 0xf3, 0x8d, 0x81, 0xcf, 0xde, 0x86, 0xf2, 0x99, ++ 0x43, 0x96, 0xb9, 0xf0 ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_personalizationstring[] = { ++ 0x63, 0x0d, 0x78, 0xf5, 0x90, 0x8e, 0x32, 0x47, 0xb0, 0x4d, 0x37, 0x60, ++ 0x09, 0x96, 0xbc, 0xbf, 0x97, 0x7a, 0x62, 0x14, 0x45, 0xbd, 0x8d, 0xcc, ++ 0x69, 0xfb, 0x03, 0xe1, 0x80, 0x1c, 0xc7, 0xe2, 0x2a, 0xf9, 0x37, 0x3f, ++ 0x66, 0x4d, 0x62, 0xd9, 0x10, 0xe0, 0xad, 0xc8, 0x9a, 0xf0, 0xa8, 0x6d ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_additionalinput[] = { ++ 0x36, 0xc6, 0x13, 0x60, 0xbb, 0x14, 0xad, 0x22, 0xb0, 0x38, 0xac, 0xa6, ++ 0x18, 0x16, 0x93, 0x25, 0x86, 0xb7, 0xdc, 0xdc, 0x36, 0x98, 0x2b, 0xf9, ++ 0x68, 0x33, 0xd3, 0xc6, 0xff, 0xce, 0x8d, 0x15, 0x59, 0x82, 0x76, 0xed, ++ 0x6f, 0x8d, 0x49, 0x74, 0x2f, 0xda, 0xdc, 0x1f, 0x17, 0xd0, 0xde, 0x17 ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_int_returnedbits[] = { ++ 0x16, 0x2f, 0x8e, 0x3f, 0x21, 0x7a, 0x1c, 0x20, 0x56, 0xd1, 0x92, 0xf6, ++ 0xd2, 0x25, 0x75, 0x0e ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_entropyinputreseed[] = { ++ 0x91, 0x79, 0x76, 0xee, 0xe0, 0xcf, 0x9e, 0xc2, 0xd5, 0xd4, 0x23, 0x9b, ++ 0x12, 0x8c, 0x7e, 0x0a, 0xb7, 0xd2, 0x8b, 0xd6, 0x7c, 0xa3, 0xc6, 0xe5, ++ 0x0e, 0xaa, 0xc7, 0x6b, 0xae, 0x0d, 0xfa, 0x53, 0x06, 0x79, 0xa1, 0xed, ++ 0x4d, 0x6a, 0x0e, 0xd8, 0x9d, 0xbe, 0x1b, 0x31, 0x93, 0x7b, 0xec, 0xfb ++}; ++ ++__fips_constseg ++ static const unsigned char aes_256_no_df_additionalinputreseed[] = { ++ 0xd2, 0x46, 0x50, 0x22, 0x10, 0x14, 0x63, 0xf7, 0xea, 0x0f, 0xb9, 0x7e, ++ 0x0d, 0xe1, 0x94, 0x07, 0xaf, 0x09, 0x44, 0x31, 0xea, 0x64, 0xa4, 0x18, ++ 0x5b, 0xf9, 0xd8, 0xc2, 0xfa, 0x03, 0x47, 0xc5, 0x39, 0x43, 0xd5, 0x3b, ++ 0x62, 0x86, 0x64, 0xea, 0x2c, 0x73, 0x8c, 0xae, 0x9d, 0x98, 0x98, 0x29 ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_additionalinput2[] = { ++ 0x8c, 0xab, 0x18, 0xf8, 0xc3, 0xec, 0x18, 0x5c, 0xb3, 0x1e, 0x9d, 0xbe, ++ 0x3f, 0x03, 0xb4, 0x00, 0x98, 0x9d, 0xae, 0xeb, 0xf4, 0x94, 0xf8, 0x42, ++ 0x8f, 0xe3, 0x39, 0x07, 0xe1, 0xc9, 0xad, 0x0b, 0x1f, 0xed, 0xc0, 0xba, ++ 0xf6, 0xd1, 0xec, 0x27, 0x86, 0x7b, 0xd6, 0x55, 0x9b, 0x60, 0xa5, 0xc6 ++}; ++ ++__fips_constseg static const unsigned char aes_256_no_df_returnedbits[] = { ++ 0xef, 0xd2, 0xd8, 0x5c, 0xdc, 0x62, 0x25, 0x9f, 0xaa, 0x1e, 0x2c, 0x67, ++ 0xf6, 0x02, 0x32, 0xe2 ++}; ++ ++/* SHA-1 PR */ ++__fips_constseg static const unsigned char sha1_pr_entropyinput[] = { ++ 0xd2, 0x36, 0xa5, 0x27, 0x31, 0x73, 0xdd, 0x11, 0x4f, 0x93, 0xbd, 0xe2, ++ 0x31, 0xa5, 0x91, 0x13 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_nonce[] = { ++ 0xb5, 0xb3, 0x60, 0xef, 0xf7, 0x63, 0x31, 0xf3 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_personalizationstring[] = { ++ 0xd4, 0xbb, 0x02, 0x10, 0xb2, 0x71, 0xdb, 0x81, 0xd6, 0xf0, 0x42, 0x60, ++ 0xda, 0xea, 0x77, 0x52 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_additionalinput[] = { ++ 0x4d, 0xd2, 0x6c, 0x87, 0xfb, 0x2c, 0x4f, 0xa6, 0x8d, 0x16, 0x63, 0x22, ++ 0x6a, 0x51, 0xe3, 0xf8 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_entropyinputpr[] = { ++ 0xc9, 0x83, 0x9e, 0x16, 0xf6, 0x1c, 0x0f, 0xb2, 0xec, 0x60, 0x31, 0xa9, ++ 0xcb, 0xa9, 0x36, 0x7a ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_int_returnedbits[] = { ++ 0xa8, 0x13, 0x4f, 0xf4, 0x31, 0x02, 0x44, 0xe3, 0xd3, 0x3d, 0x61, 0x9e, ++ 0xe5, 0xc6, 0x3e, 0x89, 0xb5, 0x9b, 0x0f, 0x35 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_additionalinput2[] = { ++ 0xf9, 0xe8, 0xd2, 0x72, 0x13, 0x34, 0x95, 0x6f, 0x15, 0x49, 0x47, 0x99, ++ 0x16, 0x03, 0x19, 0x47 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_entropyinputpr2[] = { ++ 0x4e, 0x8c, 0x49, 0x9b, 0x4a, 0x5c, 0x9b, 0x9c, 0x3a, 0xee, 0xfb, 0xd2, ++ 0xae, 0xcd, 0x8c, 0xc4 ++}; ++ ++__fips_constseg static const unsigned char sha1_pr_returnedbits[] = { ++ 0x50, 0xb4, 0xb4, 0xcd, 0x68, 0x57, 0xfc, 0x2e, 0xc1, 0x52, 0xcc, 0xf6, ++ 0x68, 0xa4, 0x81, 0xed, 0x7e, 0xe4, 0x1d, 0x87 ++}; ++ ++/* SHA-1 No PR */ ++__fips_constseg static const unsigned char sha1_entropyinput[] = { ++ 0xa9, 0x47, 0x1b, 0x29, 0x2d, 0x1c, 0x05, 0xdf, 0x76, 0xd0, 0x62, 0xf9, ++ 0xe2, 0x7f, 0x4c, 0x7b ++}; ++ ++__fips_constseg static const unsigned char sha1_nonce[] = { ++ 0x53, 0x23, 0x24, 0xe3, 0xec, 0x0c, 0x54, 0x14 ++}; ++ ++__fips_constseg static const unsigned char sha1_personalizationstring[] = { ++ 0x7a, 0x87, 0xa1, 0xac, 0x1c, 0xfd, 0xab, 0xae, 0xf7, 0xd6, 0xfb, 0x76, ++ 0x28, 0xec, 0x6d, 0xca ++}; ++ ++__fips_constseg static const unsigned char sha1_additionalinput[] = { ++ 0xfc, 0x92, 0x35, 0xd6, 0x7e, 0xb7, 0x24, 0x65, 0xfd, 0x12, 0x27, 0x35, ++ 0xc0, 0x72, 0xca, 0x28 ++}; ++ ++__fips_constseg static const unsigned char sha1_int_returnedbits[] = { ++ 0x57, 0x88, 0x82, 0xe5, 0x25, 0xa5, 0x2c, 0x4a, 0x06, 0x20, 0x6c, 0x72, ++ 0x55, 0x61, 0xdd, 0x90, 0x71, 0x9f, 0x95, 0xea ++}; ++ ++__fips_constseg static const unsigned char sha1_entropyinputreseed[] = { ++ 0x69, 0xa5, 0x40, 0x62, 0x98, 0x47, 0x56, 0x73, 0x4a, 0x8f, 0x60, 0x96, ++ 0xd6, 0x99, 0x27, 0xed ++}; ++ ++__fips_constseg static const unsigned char sha1_additionalinputreseed[] = { ++ 0xe5, 0x40, 0x4e, 0xbd, 0x50, 0x00, 0xf5, 0x15, 0xa6, 0xee, 0x45, 0xda, ++ 0x84, 0x3d, 0xd4, 0xc0 ++}; ++ ++__fips_constseg static const unsigned char sha1_additionalinput2[] = { ++ 0x11, 0x51, 0x14, 0xf0, 0x09, 0x1b, 0x4e, 0x56, 0x0d, 0xe9, 0xf6, 0x1e, ++ 0x52, 0x65, 0xcd, 0x96 ++}; ++ ++__fips_constseg static const unsigned char sha1_returnedbits[] = { ++ 0xa1, 0x9c, 0x94, 0x6e, 0x29, 0xe1, 0x33, 0x0d, 0x32, 0xd6, 0xaa, 0xce, ++ 0x71, 0x3f, 0x52, 0x72, 0x8b, 0x42, 0xa8, 0xd7 ++}; ++ ++/* SHA-224 PR */ ++__fips_constseg static const unsigned char sha224_pr_entropyinput[] = { ++ 0x12, 0x69, 0x32, 0x4f, 0x83, 0xa6, 0xf5, 0x14, 0xe3, 0x49, 0x3e, 0x75, ++ 0x3e, 0xde, 0xad, 0xa1, 0x29, 0xc3, 0xf3, 0x19, 0x20, 0xb5, 0x4c, 0xd9 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_nonce[] = { ++ 0x6a, 0x78, 0xd0, 0xeb, 0xbb, 0x5a, 0xf0, 0xee, 0xe8, 0xc3, 0xba, 0x71 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_personalizationstring[] = { ++ 0xd5, 0xb8, 0xb6, 0xbc, 0xc1, 0x5b, 0x60, 0x31, 0x3c, 0xf5, 0xe5, 0xc0, ++ 0x8e, 0x52, 0x7a, 0xbd, 0xea, 0x47, 0xa9, 0x5f, 0x8f, 0xf9, 0x8b, 0xae ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_additionalinput[] = { ++ 0x1f, 0x55, 0xec, 0xae, 0x16, 0x12, 0x84, 0xba, 0x84, 0x16, 0x19, 0x88, ++ 0x8e, 0xb8, 0x33, 0x25, 0x54, 0xff, 0xca, 0x79, 0xaf, 0x07, 0x25, 0x50 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_entropyinputpr[] = { ++ 0x92, 0xa3, 0x32, 0xa8, 0x9a, 0x0a, 0x58, 0x7c, 0x1d, 0x5a, 0x7e, 0xe1, ++ 0xb2, 0x73, 0xab, 0x0e, 0x16, 0x79, 0x23, 0xd3, 0x29, 0x89, 0x81, 0xe1 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_int_returnedbits[] = { ++ 0xf3, 0x38, 0x91, 0x40, 0x37, 0x7a, 0x51, 0x72, 0x42, 0x74, 0x78, 0x0a, ++ 0x69, 0xfd, 0xa6, 0x44, 0x43, 0x45, 0x6c, 0x0c, 0x5a, 0x19, 0xff, 0xf1, ++ 0x54, 0x60, 0xee, 0x6a ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_additionalinput2[] = { ++ 0x75, 0xf3, 0x04, 0x25, 0xdd, 0x36, 0xa8, 0x37, 0x46, 0xae, 0x0c, 0x52, ++ 0x05, 0x79, 0x4c, 0x26, 0xdb, 0xe9, 0x71, 0x16, 0x4c, 0x0a, 0xf2, 0x60 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_entropyinputpr2[] = { ++ 0xea, 0xc5, 0x03, 0x0a, 0x4f, 0xb0, 0x38, 0x8d, 0x23, 0xd4, 0xc8, 0x77, ++ 0xe2, 0x6d, 0x9c, 0x0b, 0x44, 0xf7, 0x2d, 0x5b, 0xbf, 0x5d, 0x2a, 0x11 ++}; ++ ++__fips_constseg static const unsigned char sha224_pr_returnedbits[] = { ++ 0x60, 0x50, 0x2b, 0xe7, 0x86, 0xd8, 0x26, 0x73, 0xe3, 0x1d, 0x95, 0x20, ++ 0xb3, 0x2c, 0x32, 0x1c, 0xf5, 0xce, 0x57, 0xa6, 0x67, 0x2b, 0xdc, 0x4e, ++ 0xdd, 0x11, 0x4c, 0xc4 ++}; ++ ++/* SHA-224 No PR */ ++__fips_constseg static const unsigned char sha224_entropyinput[] = { ++ 0xb2, 0x1c, 0x77, 0x4d, 0xf6, 0xd3, 0xb6, 0x40, 0xb7, 0x30, 0x3e, 0x29, ++ 0xb0, 0x85, 0x1c, 0xbe, 0x4a, 0xea, 0x6b, 0x5a, 0xb5, 0x8a, 0x97, 0xeb ++}; ++ ++__fips_constseg static const unsigned char sha224_nonce[] = { ++ 0x42, 0x02, 0x0a, 0x1c, 0x98, 0x9a, 0x77, 0x9e, 0x9f, 0x80, 0xba, 0xe0 ++}; ++ ++__fips_constseg static const unsigned char sha224_personalizationstring[] = { ++ 0x98, 0xb8, 0x04, 0x41, 0xfc, 0xc1, 0x5d, 0xc5, 0xe9, 0xb9, 0x08, 0xda, ++ 0xf9, 0xfa, 0x0d, 0x90, 0xce, 0xdf, 0x1d, 0x10, 0xa9, 0x8d, 0x50, 0x0c ++}; ++ ++__fips_constseg static const unsigned char sha224_additionalinput[] = { ++ 0x9a, 0x8d, 0x39, 0x49, 0x42, 0xd5, 0x0b, 0xae, 0xe1, 0xaf, 0xb7, 0x00, ++ 0x02, 0xfa, 0x96, 0xb1, 0xa5, 0x1d, 0x2d, 0x25, 0x78, 0xee, 0x83, 0x3f ++}; ++ ++__fips_constseg static const unsigned char sha224_int_returnedbits[] = { ++ 0xe4, 0xf5, 0x53, 0x79, 0x5a, 0x97, 0x58, 0x06, 0x08, 0xba, 0x7b, 0xfa, ++ 0xf0, 0x83, 0x05, 0x8c, 0x22, 0xc0, 0xc9, 0xdb, 0x15, 0xe7, 0xde, 0x20, ++ 0x55, 0x22, 0x9a, 0xad ++}; ++ ++__fips_constseg static const unsigned char sha224_entropyinputreseed[] = { ++ 0x67, 0x09, 0x48, 0xaa, 0x07, 0x16, 0x99, 0x89, 0x7f, 0x6d, 0xa0, 0xe5, ++ 0x8f, 0xdf, 0xbc, 0xdb, 0xfe, 0xe5, 0x6c, 0x7a, 0x95, 0x4a, 0x66, 0x17 ++}; ++ ++__fips_constseg static const unsigned char sha224_additionalinputreseed[] = { ++ 0x0f, 0x4b, 0x1c, 0x6f, 0xb7, 0xe3, 0x47, 0xe5, 0x5d, 0x7d, 0x38, 0xd6, ++ 0x28, 0x9b, 0xeb, 0x55, 0x63, 0x09, 0x3e, 0x7c, 0x56, 0xea, 0xf8, 0x19 ++}; ++ ++__fips_constseg static const unsigned char sha224_additionalinput2[] = { ++ 0x2d, 0x26, 0x7c, 0x37, 0xe4, 0x7a, 0x28, 0x5e, 0x5a, 0x3c, 0xaf, 0x3d, ++ 0x5a, 0x8e, 0x55, 0xa2, 0x1a, 0x6e, 0xc0, 0xe5, 0xf6, 0x21, 0xd3, 0xf6 ++}; ++ ++__fips_constseg static const unsigned char sha224_returnedbits[] = { ++ 0x4d, 0x83, 0x35, 0xdf, 0x67, 0xa9, 0xfc, 0x17, 0xda, 0x70, 0xcc, 0x8b, ++ 0x7f, 0x77, 0xae, 0xa2, 0x5f, 0xb9, 0x7e, 0x74, 0x4c, 0x26, 0xc1, 0x7a, ++ 0x3b, 0xa7, 0x5c, 0x93 ++}; ++ ++/* SHA-256 PR */ ++__fips_constseg static const unsigned char sha256_pr_entropyinput[] = { ++ 0xce, 0x49, 0x00, 0x7a, 0x56, 0xe3, 0x67, 0x8f, 0xe1, 0xb6, 0xa7, 0xd4, ++ 0x4f, 0x08, 0x7a, 0x1b, 0x01, 0xf4, 0xfa, 0x6b, 0xef, 0xb7, 0xe5, 0xeb, ++ 0x07, 0x3d, 0x11, 0x0d, 0xc8, 0xea, 0x2b, 0xfe ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_nonce[] = { ++ 0x73, 0x41, 0xc8, 0x92, 0x94, 0xe2, 0xc5, 0x5f, 0x93, 0xfd, 0x39, 0x5d, ++ 0x2b, 0x91, 0x4d, 0x38 ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_personalizationstring[] = { ++ 0x50, 0x6d, 0x01, 0x01, 0x07, 0x5a, 0x80, 0x35, 0x7a, 0x56, 0x1a, 0x56, ++ 0x2f, 0x9a, 0x0b, 0x35, 0xb2, 0xb1, 0xc9, 0xe5, 0xca, 0x69, 0x61, 0x48, ++ 0xff, 0xfb, 0x0f, 0xd9, 0x4b, 0x79, 0x1d, 0xba ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_additionalinput[] = { ++ 0x20, 0xb8, 0xdf, 0x44, 0x77, 0x5a, 0xb8, 0xd3, 0xbf, 0xf6, 0xcf, 0xac, ++ 0x5e, 0xa6, 0x96, 0x62, 0x73, 0x44, 0x40, 0x4a, 0x30, 0xfb, 0x38, 0xa5, ++ 0x7b, 0x0d, 0xe4, 0x0d, 0xc6, 0xe4, 0x9a, 0x1f ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_entropyinputpr[] = { ++ 0x04, 0xc4, 0x65, 0xf4, 0xd3, 0xbf, 0x83, 0x4b, 0xab, 0xc8, 0x41, 0xa8, ++ 0xc2, 0xe0, 0x44, 0x63, 0x77, 0x4c, 0x6f, 0x6c, 0x49, 0x46, 0xff, 0x94, ++ 0x17, 0xea, 0xe6, 0x1a, 0x9d, 0x5e, 0x66, 0x78 ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_int_returnedbits[] = { ++ 0x07, 0x4d, 0xac, 0x9b, 0x86, 0xca, 0x4a, 0xaa, 0x6e, 0x7a, 0x03, 0xa2, ++ 0x5d, 0x10, 0xea, 0x0b, 0xf9, 0x83, 0xcc, 0xd1, 0xfc, 0xe2, 0x07, 0xc7, ++ 0x06, 0x34, 0x60, 0x6f, 0x83, 0x94, 0x99, 0x76 ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_additionalinput2[] = { ++ 0x89, 0x4e, 0x45, 0x8c, 0x11, 0xf9, 0xbc, 0x5b, 0xac, 0x74, 0x8b, 0x4b, ++ 0x5f, 0xf7, 0x19, 0xf3, 0xf5, 0x24, 0x54, 0x14, 0xd1, 0x15, 0xb1, 0x43, ++ 0x12, 0xa4, 0x5f, 0xd4, 0xec, 0xfc, 0xcd, 0x09 ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_entropyinputpr2[] = { ++ 0x0e, 0xeb, 0x1f, 0xd7, 0xfc, 0xd1, 0x9d, 0xd4, 0x05, 0x36, 0x8b, 0xb2, ++ 0xfb, 0xe4, 0xf4, 0x51, 0x0c, 0x87, 0x9b, 0x02, 0x44, 0xd5, 0x92, 0x4d, ++ 0x44, 0xfe, 0x1a, 0x03, 0x43, 0x56, 0xbd, 0x86 ++}; ++ ++__fips_constseg static const unsigned char sha256_pr_returnedbits[] = { ++ 0x02, 0xaa, 0xb6, 0x1d, 0x7e, 0x2a, 0x40, 0x03, 0x69, 0x2d, 0x49, 0xa3, ++ 0x41, 0xe7, 0x44, 0x0b, 0xaf, 0x7b, 0x85, 0xe4, 0x5f, 0x53, 0x3b, 0x64, ++ 0xbc, 0x89, 0xc8, 0x82, 0xd4, 0x78, 0x37, 0xa2 ++}; ++ ++/* SHA-256 No PR */ ++__fips_constseg static const unsigned char sha256_entropyinput[] = { ++ 0x5b, 0x1b, 0xec, 0x4d, 0xa9, 0x38, 0x74, 0x5a, 0x34, 0x0b, 0x7b, 0xc5, ++ 0xe5, 0xd7, 0x66, 0x7c, 0xbc, 0x82, 0xb9, 0x0e, 0x2d, 0x1f, 0x92, 0xd7, ++ 0xc1, 0xbc, 0x67, 0x69, 0xec, 0x6b, 0x03, 0x3c ++}; ++ ++__fips_constseg static const unsigned char sha256_nonce[] = { ++ 0xa4, 0x0c, 0xd8, 0x9c, 0x61, 0xd8, 0xc3, 0x54, 0xfe, 0x53, 0xc9, 0xe5, ++ 0x5d, 0x6f, 0x6d, 0x35 ++}; ++ ++__fips_constseg static const unsigned char sha256_personalizationstring[] = { ++ 0x22, 0x5e, 0x62, 0x93, 0x42, 0x83, 0x78, 0x24, 0xd8, 0x40, 0x8c, 0xde, ++ 0x6f, 0xf9, 0xa4, 0x7a, 0xc5, 0xa7, 0x3b, 0x88, 0xa3, 0xee, 0x42, 0x20, ++ 0xfd, 0x61, 0x56, 0xc6, 0x4c, 0x13, 0x41, 0x9c ++}; ++ ++__fips_constseg static const unsigned char sha256_additionalinput[] = { ++ 0xbf, 0x74, 0x5b, 0xf6, 0xc5, 0x64, 0x5e, 0x99, 0x34, 0x8f, 0xbc, 0xa4, ++ 0xe2, 0xbd, 0xd8, 0x85, 0x26, 0x37, 0xea, 0xba, 0x4f, 0xf2, 0x9a, 0x9a, ++ 0x66, 0xfc, 0xdf, 0x63, 0x26, 0x26, 0x19, 0x87 ++}; ++ ++__fips_constseg static const unsigned char sha256_int_returnedbits[] = { ++ 0xb3, 0xc6, 0x07, 0x07, 0xd6, 0x75, 0xf6, 0x2b, 0xd6, 0x21, 0x96, 0xf1, ++ 0xae, 0xdb, 0x2b, 0xac, 0x25, 0x2a, 0xae, 0xae, 0x41, 0x72, 0x03, 0x5e, ++ 0xbf, 0xd3, 0x64, 0xbc, 0x59, 0xf9, 0xc0, 0x76 ++}; ++ ++__fips_constseg static const unsigned char sha256_entropyinputreseed[] = { ++ 0xbf, 0x20, 0x33, 0x56, 0x29, 0xa8, 0x37, 0x04, 0x1f, 0x78, 0x34, 0x3d, ++ 0x81, 0x2a, 0xc9, 0x86, 0xc6, 0x7a, 0x2f, 0x88, 0x5e, 0xd5, 0xbe, 0x34, ++ 0x46, 0x20, 0xa4, 0x35, 0xeb, 0xc7, 0xe2, 0x9d ++}; ++ ++__fips_constseg static const unsigned char sha256_additionalinputreseed[] = { ++ 0x9b, 0xae, 0x2d, 0x2d, 0x61, 0xa4, 0x89, 0xeb, 0x43, 0x46, 0xa7, 0xda, ++ 0xef, 0x40, 0xca, 0x4a, 0x99, 0x11, 0x41, 0xdc, 0x5c, 0x94, 0xe9, 0xac, ++ 0xd4, 0xd0, 0xe6, 0xbd, 0xfb, 0x03, 0x9c, 0xa8 ++}; ++ ++__fips_constseg static const unsigned char sha256_additionalinput2[] = { ++ 0x23, 0xaa, 0x0c, 0xbd, 0x28, 0x33, 0xe2, 0x51, 0xfc, 0x71, 0xd2, 0x15, ++ 0x1f, 0x76, 0xfd, 0x0d, 0xe0, 0xb7, 0xb5, 0x84, 0x75, 0x5b, 0xbe, 0xf3, ++ 0x5c, 0xca, 0xc5, 0x30, 0xf2, 0x75, 0x1f, 0xda ++}; ++ ++__fips_constseg static const unsigned char sha256_returnedbits[] = { ++ 0x90, 0x3c, 0xc1, 0x10, 0x8c, 0x12, 0x01, 0xc6, 0xa6, 0x3a, 0x0f, 0x4d, ++ 0xb6, 0x3a, 0x4f, 0x41, 0x9c, 0x61, 0x75, 0x84, 0xe9, 0x74, 0x75, 0xfd, ++ 0xfe, 0xf2, 0x1f, 0x43, 0xd8, 0x5e, 0x24, 0xa3 ++}; ++ ++/* SHA-384 PR */ ++__fips_constseg static const unsigned char sha384_pr_entropyinput[] = { ++ 0x71, 0x9d, 0xb2, 0x5a, 0x71, 0x6d, 0x04, 0xe9, 0x1e, 0xc7, 0x92, 0x24, ++ 0x6e, 0x12, 0x33, 0xa9, 0x52, 0x64, 0x31, 0xef, 0x71, 0xeb, 0x22, 0x55, ++ 0x28, 0x97, 0x06, 0x6a, 0xc0, 0x0c, 0xa0, 0x7e ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_nonce[] = { ++ 0xf5, 0x0d, 0xfa, 0xb0, 0xec, 0x6a, 0x7c, 0xd6, 0xbd, 0x9b, 0x05, 0xfd, ++ 0x38, 0x3e, 0x2e, 0x56 ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_personalizationstring[] = { ++ 0x74, 0xac, 0x7e, 0x6d, 0xb1, 0xa4, 0xe7, 0x21, 0xd1, 0x1e, 0x6e, 0x96, ++ 0x6d, 0x4d, 0x53, 0x46, 0x82, 0x96, 0x6e, 0xcf, 0xaa, 0x81, 0x8d, 0x7d, ++ 0x9e, 0xe1, 0x0f, 0x15, 0xea, 0x41, 0xbf, 0xe3 ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_additionalinput[] = { ++ 0xda, 0x95, 0xd4, 0xd0, 0xb8, 0x11, 0xd3, 0x49, 0x27, 0x5d, 0xa9, 0x39, ++ 0x68, 0xf3, 0xa8, 0xe9, 0x5d, 0x19, 0x8a, 0x2b, 0x66, 0xe8, 0x69, 0x06, ++ 0x7c, 0x9e, 0x03, 0xa1, 0x8b, 0x26, 0x2d, 0x6e ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_entropyinputpr[] = { ++ 0x49, 0xdf, 0x44, 0x00, 0xe4, 0x1c, 0x75, 0x0b, 0x26, 0x5a, 0x59, 0x64, ++ 0x1f, 0x4e, 0xb1, 0xb2, 0x13, 0xf1, 0x22, 0x4e, 0xb4, 0x6d, 0x9a, 0xcc, ++ 0xa0, 0x48, 0xe6, 0xcf, 0x1d, 0xd1, 0x92, 0x0d ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_int_returnedbits[] = { ++ 0xc8, 0x52, 0xae, 0xbf, 0x04, 0x3c, 0x27, 0xb7, 0x78, 0x18, 0xaa, 0x8f, ++ 0xff, 0xcf, 0xa4, 0xf1, 0xcc, 0xe7, 0x68, 0xfa, 0x22, 0xa2, 0x13, 0x45, ++ 0xe8, 0xdd, 0x87, 0xe6, 0xf2, 0x6e, 0xdd, 0xc7, 0x52, 0x90, 0x9f, 0x7b, ++ 0xfa, 0x61, 0x2d, 0x9d, 0x9e, 0xcf, 0x98, 0xac, 0x52, 0x40, 0xce, 0xaf ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_additionalinput2[] = { ++ 0x61, 0x7c, 0x03, 0x9a, 0x3e, 0x50, 0x57, 0x60, 0xc5, 0x83, 0xc9, 0xb2, ++ 0xd1, 0x87, 0x85, 0x66, 0x92, 0x5d, 0x84, 0x0e, 0x53, 0xfb, 0x70, 0x03, ++ 0x72, 0xfd, 0xba, 0xae, 0x9c, 0x8f, 0xf8, 0x18 ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_entropyinputpr2[] = { ++ 0xf8, 0xeb, 0x89, 0xb1, 0x8d, 0x78, 0xbe, 0x21, 0xe0, 0xbb, 0x9d, 0xb7, ++ 0x95, 0x0e, 0xd9, 0x46, 0x0c, 0x8c, 0xe2, 0x63, 0xb7, 0x9d, 0x67, 0x90, ++ 0xbd, 0xc7, 0x0b, 0xa5, 0xce, 0xb2, 0x65, 0x81 ++}; ++ ++__fips_constseg static const unsigned char sha384_pr_returnedbits[] = { ++ 0xe6, 0x9f, 0xfe, 0x68, 0xd6, 0xb5, 0x79, 0xf1, 0x06, 0x5f, 0xa3, 0xbb, ++ 0x23, 0x85, 0xd8, 0xf0, 0x29, 0x5a, 0x68, 0x9e, 0xf5, 0xf4, 0xa6, 0x12, ++ 0xe0, 0x9a, 0xe2, 0xac, 0x00, 0x1d, 0x98, 0x26, 0xfc, 0x53, 0x95, 0x53, ++ 0xe4, 0x3e, 0x17, 0xd5, 0x08, 0x0b, 0x70, 0x3d, 0x67, 0x99, 0xac, 0x66 ++}; ++ ++/* SHA-384 No PR */ ++__fips_constseg static const unsigned char sha384_entropyinput[] = { ++ 0x07, 0x15, 0x27, 0x2a, 0xaf, 0x74, 0x24, 0x37, 0xbc, 0xd5, 0x14, 0x69, ++ 0xce, 0x11, 0xff, 0xa2, 0x6b, 0xb8, 0x05, 0x67, 0x34, 0xf8, 0xbd, 0x6d, ++ 0x6a, 0xcc, 0xcd, 0x60, 0xa3, 0x68, 0xca, 0xf4 ++}; ++ ++__fips_constseg static const unsigned char sha384_nonce[] = { ++ 0x70, 0x17, 0xc2, 0x5b, 0x5d, 0x22, 0x0b, 0x06, 0x15, 0x54, 0x78, 0x77, ++ 0x44, 0xaf, 0x2f, 0x09 ++}; ++ ++__fips_constseg static const unsigned char sha384_personalizationstring[] = { ++ 0x89, 0x39, 0x28, 0xb0, 0x60, 0xeb, 0x3d, 0xdc, 0x55, 0x75, 0x86, 0xeb, ++ 0xae, 0xa2, 0x8f, 0xbc, 0x1b, 0x75, 0xd4, 0xe1, 0x0f, 0xaa, 0x38, 0xca, ++ 0x62, 0x8b, 0xcb, 0x2c, 0x26, 0xf6, 0xbc, 0xb1 ++}; ++ ++__fips_constseg static const unsigned char sha384_additionalinput[] = { ++ 0x30, 0x2b, 0x42, 0x35, 0xef, 0xda, 0x40, 0x55, 0x28, 0xc6, 0x95, 0xfb, ++ 0x54, 0x01, 0x62, 0xd7, 0x87, 0x14, 0x48, 0x6d, 0x90, 0x4c, 0xa9, 0x02, ++ 0x54, 0x40, 0x22, 0xc8, 0x66, 0xa5, 0x48, 0x48 ++}; ++ ++__fips_constseg static const unsigned char sha384_int_returnedbits[] = { ++ 0x82, 0xc4, 0xa1, 0x9c, 0x21, 0xd2, 0xe7, 0xa5, 0xa6, 0xf6, 0x5f, 0x04, ++ 0x5c, 0xc7, 0x31, 0x9d, 0x8d, 0x59, 0x74, 0x50, 0x19, 0x89, 0x2f, 0x63, ++ 0xd5, 0xb7, 0x7e, 0xeb, 0x15, 0xe3, 0x70, 0x83, 0xa1, 0x24, 0x59, 0xfa, ++ 0x2c, 0x56, 0xf6, 0x88, 0x3a, 0x92, 0x93, 0xa1, 0xfb, 0x79, 0xc1, 0x7a ++}; ++ ++__fips_constseg static const unsigned char sha384_entropyinputreseed[] = { ++ 0x39, 0xa6, 0xe8, 0x5c, 0x82, 0x17, 0x71, 0x26, 0x57, 0x4f, 0x9f, 0xc2, ++ 0x55, 0xff, 0x5c, 0x9b, 0x53, 0x1a, 0xd1, 0x5f, 0xbc, 0x62, 0xe4, 0x27, ++ 0x2d, 0x32, 0xf0, 0xe4, 0x52, 0x8c, 0xc5, 0x0c ++}; ++ ++__fips_constseg static const unsigned char sha384_additionalinputreseed[] = { ++ 0x8d, 0xcb, 0x8d, 0xce, 0x08, 0xea, 0x80, 0xe8, 0x9b, 0x61, 0xa8, 0x0f, ++ 0xaf, 0x49, 0x20, 0x9e, 0x74, 0xcb, 0x57, 0x80, 0x42, 0xb0, 0x84, 0x5e, ++ 0x30, 0x2a, 0x67, 0x08, 0xf4, 0xe3, 0x40, 0x22 ++}; ++ ++__fips_constseg static const unsigned char sha384_additionalinput2[] = { ++ 0x7c, 0x8f, 0xc2, 0xae, 0x22, 0x4a, 0xd6, 0xf6, 0x05, 0xa4, 0x7a, 0xea, ++ 0xbb, 0x25, 0xd0, 0xb7, 0x5a, 0xd6, 0xcf, 0x9d, 0xf3, 0x6c, 0xe2, 0xb2, ++ 0x4e, 0xb4, 0xbd, 0xf4, 0xe5, 0x40, 0x80, 0x94 ++}; ++ ++__fips_constseg static const unsigned char sha384_returnedbits[] = { ++ 0x9e, 0x7e, 0xfb, 0x59, 0xbb, 0xaa, 0x3c, 0xf7, 0xe1, 0xf8, 0x76, 0xdd, ++ 0x63, 0x5f, 0xaf, 0x23, 0xd6, 0x64, 0x61, 0xc0, 0x9a, 0x09, 0x47, 0xc9, ++ 0x33, 0xdf, 0x6d, 0x55, 0x91, 0x34, 0x79, 0x70, 0xc4, 0x99, 0x6e, 0x54, ++ 0x09, 0x64, 0x21, 0x1a, 0xbd, 0x1e, 0x80, 0x40, 0x34, 0xad, 0xfa, 0xd7 ++}; ++ ++/* SHA-512 PR */ ++__fips_constseg static const unsigned char sha512_pr_entropyinput[] = { ++ 0x13, 0xf7, 0x61, 0x75, 0x65, 0x28, 0xa2, 0x59, 0x13, 0x5a, 0x4a, 0x4f, ++ 0x56, 0x60, 0x8c, 0x53, 0x7d, 0xb0, 0xbd, 0x06, 0x4f, 0xed, 0xcc, 0xd2, ++ 0xa2, 0xb5, 0xfd, 0x5b, 0x3a, 0xab, 0xec, 0x28 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_nonce[] = { ++ 0xbe, 0xa3, 0x91, 0x93, 0x1d, 0xc3, 0x31, 0x3a, 0x23, 0x33, 0x50, 0x67, ++ 0x88, 0xc7, 0xa2, 0xc4 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_personalizationstring[] = { ++ 0x1f, 0x59, 0x4d, 0x7b, 0xe6, 0x46, 0x91, 0x48, 0xc1, 0x25, 0xfa, 0xff, ++ 0x89, 0x12, 0x77, 0x35, 0xdf, 0x3e, 0xf4, 0x80, 0x5f, 0xd9, 0xb0, 0x07, ++ 0x22, 0x41, 0xdd, 0x48, 0x78, 0x6b, 0x77, 0x2b ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_additionalinput[] = { ++ 0x30, 0xff, 0x63, 0x6f, 0xac, 0xd9, 0x84, 0x39, 0x6f, 0xe4, 0x99, 0xce, ++ 0x91, 0x7d, 0x7e, 0xc8, 0x58, 0xf2, 0x12, 0xc3, 0xb6, 0xad, 0xda, 0x22, ++ 0x04, 0xa0, 0xd2, 0x21, 0xfe, 0xf2, 0x95, 0x1d ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_entropyinputpr[] = { ++ 0x64, 0x54, 0x13, 0xec, 0x4f, 0x77, 0xda, 0xb2, 0x92, 0x2e, 0x52, 0x80, ++ 0x11, 0x10, 0xc2, 0xf8, 0xe6, 0xa7, 0xcd, 0x4b, 0xfc, 0x32, 0x2e, 0x9e, ++ 0xeb, 0xbb, 0xb1, 0xbf, 0x15, 0x5c, 0x73, 0x08 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_int_returnedbits[] = { ++ 0xef, 0x1e, 0xdc, 0x0a, 0xa4, 0x36, 0x91, 0x9c, 0x3d, 0x27, 0x97, 0x50, ++ 0x8d, 0x36, 0x29, 0x8d, 0xce, 0x6a, 0x0c, 0xf7, 0x21, 0xc0, 0x91, 0xae, ++ 0x0c, 0x96, 0x72, 0xbd, 0x52, 0x81, 0x58, 0xfc, 0x6d, 0xe5, 0xf7, 0xa5, ++ 0xfd, 0x5d, 0xa7, 0x58, 0x68, 0xc8, 0x99, 0x58, 0x8e, 0xc8, 0xce, 0x95, ++ 0x01, 0x7d, 0xff, 0xa4, 0xc8, 0xf7, 0x63, 0xfe, 0x5f, 0x69, 0x83, 0x53, ++ 0xe2, 0xc6, 0x8b, 0xc3 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_additionalinput2[] = { ++ 0xe6, 0x9b, 0xc4, 0x88, 0x34, 0xca, 0xea, 0x29, 0x2f, 0x98, 0x05, 0xa4, ++ 0xd3, 0xc0, 0x7b, 0x11, 0xe8, 0xbb, 0x75, 0xf2, 0xbd, 0x29, 0xb7, 0x40, ++ 0x25, 0x7f, 0xc1, 0xb7, 0xb1, 0xf1, 0x25, 0x61 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_entropyinputpr2[] = { ++ 0x23, 0x6d, 0xff, 0xde, 0xfb, 0xd1, 0xba, 0x33, 0x18, 0xe6, 0xbe, 0xb5, ++ 0x48, 0x77, 0x6d, 0x7f, 0xa7, 0xe1, 0x4d, 0x48, 0x1e, 0x3c, 0xa7, 0x34, ++ 0x1a, 0xc8, 0x60, 0xdb, 0x8f, 0x99, 0x15, 0x99 ++}; ++ ++__fips_constseg static const unsigned char sha512_pr_returnedbits[] = { ++ 0x70, 0x27, 0x31, 0xdb, 0x92, 0x70, 0x21, 0xfe, 0x16, 0xb6, 0xc8, 0x51, ++ 0x34, 0x87, 0x65, 0xd0, 0x4e, 0xfd, 0xfe, 0x68, 0xec, 0xac, 0xdc, 0x93, ++ 0x41, 0x38, 0x92, 0x90, 0xb4, 0x94, 0xf9, 0x0d, 0xa4, 0xf7, 0x4e, 0x80, ++ 0x92, 0x67, 0x48, 0x40, 0xa7, 0x08, 0xc7, 0xbc, 0x66, 0x00, 0xfd, 0xf7, ++ 0x4c, 0x8b, 0x17, 0x6e, 0xd1, 0x8f, 0x9b, 0xf3, 0x6f, 0xf6, 0x34, 0xdd, ++ 0x67, 0xf7, 0x68, 0xdd ++}; ++ ++/* SHA-512 No PR */ ++__fips_constseg static const unsigned char sha512_entropyinput[] = { ++ 0xb6, 0x0b, 0xb7, 0xbc, 0x84, 0x56, 0xf6, 0x12, 0xaf, 0x45, 0x67, 0x17, ++ 0x7c, 0xd1, 0xb2, 0x78, 0x2b, 0xa0, 0xf2, 0xbe, 0xb6, 0x6d, 0x8b, 0x56, ++ 0xc6, 0xbc, 0x4d, 0xe1, 0xf7, 0xbe, 0xce, 0xbd ++}; ++ ++__fips_constseg static const unsigned char sha512_nonce[] = { ++ 0x9d, 0xed, 0xc0, 0xe5, 0x5a, 0x98, 0x6a, 0xcb, 0x51, 0x7d, 0x76, 0x31, ++ 0x5a, 0x64, 0xf0, 0xf7 ++}; ++ ++__fips_constseg static const unsigned char sha512_personalizationstring[] = { ++ 0xc2, 0x6d, 0xa3, 0xc3, 0x06, 0x74, 0xe5, 0x01, 0x5c, 0x10, 0x17, 0xc7, ++ 0xaf, 0x83, 0x9d, 0x59, 0x8d, 0x2d, 0x29, 0x38, 0xc5, 0x59, 0x70, 0x8b, ++ 0x46, 0x48, 0x2d, 0xcf, 0x36, 0x7d, 0x59, 0xc0 ++}; ++ ++__fips_constseg static const unsigned char sha512_additionalinput[] = { ++ 0xec, 0x8c, 0xd4, 0xf7, 0x61, 0x6e, 0x0d, 0x95, 0x79, 0xb7, 0x28, 0xad, ++ 0x5f, 0x69, 0x74, 0x5f, 0x2d, 0x36, 0x06, 0x8a, 0x6b, 0xac, 0x54, 0x97, ++ 0xc4, 0xa1, 0x12, 0x85, 0x0a, 0xdf, 0x4b, 0x34 ++}; ++ ++__fips_constseg static const unsigned char sha512_int_returnedbits[] = { ++ 0x84, 0x2f, 0x1f, 0x68, 0x6a, 0xa3, 0xad, 0x1e, 0xfb, 0xf4, 0x15, 0xbd, ++ 0xde, 0x38, 0xd4, 0x30, 0x80, 0x51, 0xe9, 0xd3, 0xc7, 0x20, 0x88, 0xe9, ++ 0xf5, 0xcc, 0xdf, 0x57, 0x5c, 0x47, 0x2f, 0x57, 0x3c, 0x5f, 0x13, 0x56, ++ 0xcc, 0xc5, 0x4f, 0x84, 0xf8, 0x10, 0x41, 0xd5, 0x7e, 0x58, 0x6e, 0x19, ++ 0x19, 0x9e, 0xaf, 0xc2, 0x22, 0x58, 0x41, 0x50, 0x79, 0xc2, 0xd8, 0x04, ++ 0x28, 0xd4, 0x39, 0x9a ++}; ++ ++__fips_constseg static const unsigned char sha512_entropyinputreseed[] = { ++ 0xfa, 0x7f, 0x46, 0x51, 0x83, 0x62, 0x98, 0x16, 0x9a, 0x19, 0xa2, 0x49, ++ 0xa9, 0xe6, 0x4a, 0xd8, 0x85, 0xe7, 0xd4, 0x3b, 0x2c, 0x82, 0xc5, 0x82, ++ 0xbf, 0x11, 0xf9, 0x9e, 0xbc, 0xd0, 0x01, 0xee ++}; ++ ++__fips_constseg static const unsigned char sha512_additionalinputreseed[] = { ++ 0xb9, 0x12, 0xe0, 0x4f, 0xf7, 0xa7, 0xc4, 0xd8, 0xd0, 0x8e, 0x99, 0x29, ++ 0x7c, 0x9a, 0xe9, 0xcf, 0xc4, 0x6c, 0xf8, 0xc3, 0xa7, 0x41, 0x83, 0xd6, ++ 0x2e, 0xfa, 0xb8, 0x5e, 0x8e, 0x6b, 0x78, 0x20 ++}; ++ ++__fips_constseg static const unsigned char sha512_additionalinput2[] = { ++ 0xd7, 0x07, 0x52, 0xb9, 0x83, 0x2c, 0x03, 0x71, 0xee, 0xc9, 0xc0, 0x85, ++ 0xe1, 0x57, 0xb2, 0xcd, 0x3a, 0xf0, 0xc9, 0x34, 0x24, 0x41, 0x1c, 0x42, ++ 0x99, 0xb2, 0x84, 0xe9, 0x17, 0xd2, 0x76, 0x92 ++}; ++ ++__fips_constseg static const unsigned char sha512_returnedbits[] = { ++ 0x36, 0x17, 0x5d, 0x98, 0x2b, 0x65, 0x25, 0x8e, 0xc8, 0x29, 0xdf, 0x27, ++ 0x05, 0x36, 0x26, 0x12, 0x8a, 0x68, 0x74, 0x27, 0x37, 0xd4, 0x7f, 0x32, ++ 0xb1, 0x12, 0xd6, 0x85, 0x83, 0xeb, 0x2e, 0xa0, 0xed, 0x4b, 0xb5, 0x7b, ++ 0x6f, 0x39, 0x3c, 0x71, 0x77, 0x02, 0x12, 0xcc, 0x2c, 0x3a, 0x8e, 0x63, ++ 0xdf, 0x4a, 0xbd, 0x6f, 0x6e, 0x2e, 0xed, 0x0a, 0x85, 0xa5, 0x2f, 0xa2, ++ 0x68, 0xde, 0x42, 0xb5 ++}; ++ ++/* HMAC SHA-1 PR */ ++__fips_constseg static const unsigned char hmac_sha1_pr_entropyinput[] = { ++ 0x26, 0x5f, 0x36, 0x14, 0xff, 0x3d, 0x83, 0xfa, 0x73, 0x5e, 0x75, 0xdc, ++ 0x2c, 0x18, 0x17, 0x1b ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_nonce[] = { ++ 0xc8, 0xe3, 0x57, 0xa5, 0x7b, 0x74, 0x86, 0x6e ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha1_pr_personalizationstring[] = { ++ 0x6e, 0xdb, 0x0d, 0xfe, 0x7d, 0xac, 0x79, 0xd0, 0xa5, 0x3a, 0x48, 0x85, ++ 0x80, 0xe2, 0x7f, 0x2a ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput[] = { ++ 0x31, 0xcd, 0x5e, 0x43, 0xdc, 0xfb, 0x7a, 0x79, 0xca, 0x88, 0xde, 0x1f, ++ 0xd7, 0xbb, 0x42, 0x09 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr[] = { ++ 0x7c, 0x23, 0x95, 0x38, 0x00, 0x95, 0xc1, 0x78, 0x1f, 0x8f, 0xd7, 0x63, ++ 0x23, 0x87, 0x2a, 0xed ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_int_returnedbits[] = { ++ 0xbb, 0x34, 0xe7, 0x93, 0xa3, 0x02, 0x2c, 0x4a, 0xd0, 0x89, 0xda, 0x7f, ++ 0xed, 0xf4, 0x4c, 0xde, 0x17, 0xec, 0xe5, 0x6c ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput2[] = { ++ 0x49, 0xbc, 0x2d, 0x2c, 0xb7, 0x32, 0xcb, 0x20, 0xdf, 0xf5, 0x77, 0x58, ++ 0xa0, 0x4b, 0x93, 0x6e ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr2[] = { ++ 0x3c, 0xaa, 0xb0, 0x21, 0x42, 0xb0, 0xdd, 0x34, 0xf0, 0x16, 0x7f, 0x0c, ++ 0x0f, 0xff, 0x2e, 0xaf ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_pr_returnedbits[] = { ++ 0x8e, 0xcb, 0xa3, 0x64, 0xb2, 0xb8, 0x33, 0x6c, 0x64, 0x3b, 0x78, 0x16, ++ 0x99, 0x35, 0xc8, 0x30, 0xcb, 0x3e, 0xa0, 0xd8 ++}; ++ ++/* HMAC SHA-1 No PR */ ++__fips_constseg static const unsigned char hmac_sha1_entropyinput[] = { ++ 0x32, 0x9a, 0x2a, 0x87, 0x7b, 0x89, 0x7c, 0xf6, 0xcb, 0x95, 0xd5, 0x40, ++ 0x17, 0xfe, 0x47, 0x70 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_nonce[] = { ++ 0x16, 0xd8, 0xe0, 0xc7, 0x52, 0xcf, 0x4a, 0x25 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_personalizationstring[] = { ++ 0x35, 0x35, 0xa9, 0xa5, 0x40, 0xbe, 0x9b, 0xd1, 0x56, 0xdd, 0x44, 0x00, ++ 0x72, 0xf7, 0xd3, 0x5e ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_additionalinput[] = { ++ 0x1b, 0x2c, 0x84, 0x2d, 0x4a, 0x89, 0x8f, 0x69, 0x19, 0xf1, 0xf3, 0xdb, ++ 0xbb, 0xe3, 0xaa, 0xea ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_int_returnedbits[] = { ++ 0xcf, 0xfa, 0x7d, 0x72, 0x0f, 0xe6, 0xc7, 0x96, 0xa0, 0x69, 0x31, 0x11, ++ 0x9b, 0x0b, 0x1a, 0x20, 0x1f, 0x3f, 0xaa, 0xd1 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_entropyinputreseed[] = { ++ 0x90, 0x75, 0x15, 0x04, 0x95, 0xf1, 0xba, 0x81, 0x0c, 0x37, 0x94, 0x6f, ++ 0x86, 0x52, 0x6d, 0x9c ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_additionalinputreseed[] = { ++ 0x5b, 0x40, 0xba, 0x5f, 0x17, 0x70, 0xf0, 0x4b, 0xdf, 0xc9, 0x97, 0x92, ++ 0x79, 0xc5, 0x82, 0x28 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_additionalinput2[] = { ++ 0x97, 0xc8, 0x80, 0x90, 0xb3, 0xaa, 0x6e, 0x60, 0xea, 0x83, 0x7a, 0xe3, ++ 0x8a, 0xca, 0xa4, 0x7f ++}; ++ ++__fips_constseg static const unsigned char hmac_sha1_returnedbits[] = { ++ 0x90, 0xbd, 0x05, 0x56, 0x6d, 0xb5, 0x22, 0xd5, 0xb9, 0x5a, 0x29, 0x2d, ++ 0xe9, 0x0b, 0xe1, 0xac, 0xde, 0x27, 0x0b, 0xb0 ++}; ++ ++/* HMAC SHA-224 PR */ ++__fips_constseg static const unsigned char hmac_sha224_pr_entropyinput[] = { ++ 0x17, 0x32, 0x2b, 0x2e, 0x6f, 0x1b, 0x9c, 0x6d, 0x31, 0xe0, 0x34, 0x07, ++ 0xcf, 0xed, 0xf6, 0xb6, 0x5a, 0x76, 0x4c, 0xbc, 0x62, 0x85, 0x01, 0x90 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_nonce[] = { ++ 0x38, 0xbf, 0x5f, 0x20, 0xb3, 0x68, 0x2f, 0x43, 0x61, 0x05, 0x8f, 0x23 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha224_pr_personalizationstring[] = { ++ 0xc0, 0xc9, 0x45, 0xac, 0x8d, 0x27, 0x77, 0x08, 0x0b, 0x17, 0x6d, 0xed, ++ 0xc1, 0x7d, 0xd5, 0x07, 0x9d, 0x6e, 0xf8, 0x23, 0x2a, 0x22, 0x13, 0xbd ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput[] = { ++ 0xa4, 0x3c, 0xe7, 0x3b, 0xea, 0x19, 0x45, 0x32, 0xc2, 0x83, 0x6d, 0x21, ++ 0x8a, 0xc0, 0xee, 0x67, 0x45, 0xde, 0x13, 0x7d, 0x9d, 0x61, 0x00, 0x3b ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr[] = { ++ 0x15, 0x05, 0x74, 0x4a, 0x7f, 0x8d, 0x5c, 0x60, 0x16, 0xe5, 0x7b, 0xad, ++ 0xf5, 0x41, 0x8f, 0x55, 0x60, 0xc4, 0x09, 0xee, 0x1e, 0x11, 0x81, 0xab ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_int_returnedbits[] = { ++ 0x6f, 0xf5, 0x9a, 0xe2, 0x54, 0x53, 0x30, 0x3d, 0x5a, 0x27, 0x29, 0x38, ++ 0x27, 0xf2, 0x0d, 0x05, 0xe9, 0x26, 0xcb, 0x16, 0xc3, 0x51, 0x5f, 0x13, ++ 0x41, 0xfe, 0x99, 0xf2 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput2[] = { ++ 0x73, 0x81, 0x88, 0x84, 0x8f, 0xed, 0x6f, 0x10, 0x9f, 0x93, 0xbf, 0x17, ++ 0x35, 0x7c, 0xef, 0xd5, 0x8d, 0x26, 0xa6, 0x7a, 0xe8, 0x09, 0x36, 0x4f ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr2[] = { ++ 0xe6, 0xcf, 0xcf, 0x7e, 0x12, 0xe5, 0x43, 0xd2, 0x38, 0xd8, 0x24, 0x6f, ++ 0x5a, 0x37, 0x68, 0xbf, 0x4f, 0xa0, 0xff, 0xd5, 0x61, 0x8a, 0x93, 0xe0 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_pr_returnedbits[] = { ++ 0xaf, 0xf9, 0xd8, 0x19, 0x91, 0x30, 0x82, 0x6f, 0xa9, 0x1e, 0x9d, 0xd7, ++ 0xf3, 0x50, 0xe0, 0xc7, 0xd5, 0x64, 0x96, 0x7d, 0x4c, 0x4d, 0x78, 0x03, ++ 0x6d, 0xd8, 0x9e, 0x72 ++}; ++ ++/* HMAC SHA-224 No PR */ ++__fips_constseg static const unsigned char hmac_sha224_entropyinput[] = { ++ 0x11, 0x82, 0xfd, 0xd9, 0x42, 0xf4, 0xfa, 0xc8, 0xf2, 0x41, 0xe6, 0x54, ++ 0x01, 0xae, 0x22, 0x6e, 0xc6, 0xaf, 0xaf, 0xd0, 0xa6, 0xb2, 0xe2, 0x6d ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_nonce[] = { ++ 0xa9, 0x48, 0xd7, 0x92, 0x39, 0x7e, 0x2a, 0xdc, 0x30, 0x1f, 0x0e, 0x2b ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha224_personalizationstring[] = { ++ 0x11, 0xd5, 0xf4, 0xbd, 0x67, 0x8c, 0x31, 0xcf, 0xa3, 0x3f, 0x1e, 0x6b, ++ 0xa8, 0x07, 0x02, 0x0b, 0xc8, 0x2e, 0x6c, 0x64, 0x41, 0x5b, 0xc8, 0x37 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_additionalinput[] = { ++ 0x68, 0x18, 0xc2, 0x06, 0xeb, 0x3e, 0x04, 0x95, 0x44, 0x5e, 0xfb, 0xe6, ++ 0x41, 0xc1, 0x5c, 0xcc, 0x40, 0x2f, 0xb7, 0xd2, 0x0f, 0xf3, 0x6b, 0xe7 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_int_returnedbits[] = { ++ 0x7f, 0x45, 0xc7, 0x5d, 0x32, 0xe6, 0x17, 0x60, 0xba, 0xdc, 0xb8, 0x42, ++ 0x1b, 0x9c, 0xf1, 0xfa, 0x3b, 0x4d, 0x29, 0x54, 0xc6, 0x90, 0xff, 0x5c, ++ 0xcd, 0xd6, 0xa9, 0xcc ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_entropyinputreseed[] = { ++ 0xc4, 0x8e, 0x37, 0x95, 0x69, 0x53, 0x28, 0xd7, 0x37, 0xbb, 0x70, 0x95, ++ 0x1c, 0x07, 0x1d, 0xd9, 0xb7, 0xe6, 0x1b, 0xbb, 0xfe, 0x41, 0xeb, 0xc9 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha224_additionalinputreseed[] = { ++ 0x53, 0x17, 0xa1, 0x6a, 0xfa, 0x77, 0x47, 0xb0, 0x95, 0x56, 0x9a, 0x20, ++ 0x57, 0xde, 0x5c, 0x89, 0x9f, 0x7f, 0xe2, 0xde, 0x17, 0x3a, 0x50, 0x23 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_additionalinput2[] = { ++ 0x3a, 0x32, 0xf9, 0x85, 0x0c, 0xc1, 0xed, 0x76, 0x2d, 0xdf, 0x40, 0xc3, ++ 0x06, 0x22, 0x66, 0xd4, 0x9a, 0x9a, 0xff, 0x5a, 0x7e, 0x7a, 0xf3, 0x96 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha224_returnedbits[] = { ++ 0x43, 0xb4, 0x57, 0x5c, 0x38, 0x25, 0x9d, 0xae, 0xec, 0x96, 0xd1, 0x85, ++ 0x3a, 0x84, 0x8d, 0xfe, 0x68, 0xd5, 0x0e, 0x5c, 0x8f, 0x65, 0xa5, 0x4e, ++ 0x45, 0x84, 0xa8, 0x94 ++}; ++ ++/* HMAC SHA-256 PR */ ++__fips_constseg static const unsigned char hmac_sha256_pr_entropyinput[] = { ++ 0x4d, 0xb0, 0x43, 0xd8, 0x34, 0x4b, 0x10, 0x70, 0xb1, 0x8b, 0xed, 0xea, ++ 0x07, 0x92, 0x9f, 0x6c, 0x79, 0x31, 0xaf, 0x81, 0x29, 0xeb, 0x6e, 0xca, ++ 0x32, 0x48, 0x28, 0xe7, 0x02, 0x5d, 0xa6, 0xa6 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_nonce[] = { ++ 0x3a, 0xae, 0x15, 0xa9, 0x99, 0xdc, 0xe4, 0x67, 0x34, 0x3b, 0x70, 0x15, ++ 0xaa, 0xd3, 0x30, 0x9a ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha256_pr_personalizationstring[] = { ++ 0x13, 0x1d, 0x24, 0x04, 0xb0, 0x18, 0x81, 0x15, 0x21, 0x51, 0x2a, 0x24, ++ 0x52, 0x61, 0xbe, 0x64, 0x82, 0x6b, 0x55, 0x2f, 0xe2, 0xf1, 0x40, 0x7d, ++ 0x71, 0xd8, 0x01, 0x86, 0x15, 0xb7, 0x8b, 0xb5 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput[] = { ++ 0x8f, 0xa6, 0x54, 0x5f, 0xb1, 0xd0, 0xd8, 0xc3, 0xe7, 0x0c, 0x15, 0xa9, ++ 0x23, 0x6e, 0xfe, 0xfb, 0x93, 0xf7, 0x3a, 0xbd, 0x59, 0x01, 0xfa, 0x18, ++ 0x8e, 0xe9, 0x1a, 0xa9, 0x78, 0xfc, 0x79, 0x0b ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr[] = { ++ 0xcf, 0x24, 0xb9, 0xeb, 0xb3, 0xd4, 0xcd, 0x17, 0x37, 0x38, 0x75, 0x79, ++ 0x15, 0xcb, 0x2d, 0x75, 0x51, 0xf1, 0xcc, 0xaa, 0x32, 0xa4, 0xa7, 0x36, ++ 0x7c, 0x5c, 0xe4, 0x47, 0xf1, 0x3e, 0x1d, 0xe5 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_int_returnedbits[] = { ++ 0x52, 0x42, 0xfa, 0xeb, 0x85, 0xe0, 0x30, 0x22, 0x79, 0x00, 0x16, 0xb2, ++ 0x88, 0x2f, 0x14, 0x6a, 0xb7, 0xfc, 0xb7, 0x53, 0xdc, 0x4a, 0x12, 0xef, ++ 0x54, 0xd6, 0x33, 0xe9, 0x20, 0xd6, 0xfd, 0x56 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput2[] = { ++ 0xf4, 0xf6, 0x49, 0xa1, 0x2d, 0x64, 0x2b, 0x30, 0x58, 0xf8, 0xbd, 0xb8, ++ 0x75, 0xeb, 0xbb, 0x5e, 0x1c, 0x9b, 0x81, 0x6a, 0xda, 0x14, 0x86, 0x6e, ++ 0xd0, 0xda, 0x18, 0xb7, 0x88, 0xfb, 0x59, 0xf3 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr2[] = { ++ 0x21, 0xcd, 0x6e, 0x46, 0xad, 0x99, 0x07, 0x17, 0xb4, 0x3d, 0x76, 0x0a, ++ 0xff, 0x5b, 0x52, 0x50, 0x78, 0xdf, 0x1f, 0x24, 0x06, 0x0d, 0x3f, 0x74, ++ 0xa9, 0xc9, 0x37, 0xcf, 0xd8, 0x26, 0x25, 0x91 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_pr_returnedbits[] = { ++ 0xa7, 0xaf, 0x2f, 0x29, 0xe0, 0x3a, 0x72, 0x95, 0x96, 0x1c, 0xa9, 0xf0, ++ 0x4a, 0x17, 0x4d, 0x66, 0x06, 0x10, 0xbf, 0x39, 0x89, 0x88, 0xb8, 0x91, ++ 0x37, 0x18, 0x99, 0xcf, 0x8c, 0x53, 0x3b, 0x7e ++}; ++ ++/* HMAC SHA-256 No PR */ ++__fips_constseg static const unsigned char hmac_sha256_entropyinput[] = { ++ 0x96, 0xb7, 0x53, 0x22, 0x1e, 0x52, 0x2a, 0x96, 0xb1, 0x15, 0x3c, 0x35, ++ 0x5a, 0x8b, 0xd3, 0x4a, 0xa6, 0x6c, 0x83, 0x0a, 0x7d, 0xa3, 0x23, 0x3d, ++ 0x43, 0xa1, 0x07, 0x2c, 0x2d, 0xe3, 0x81, 0xcc ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_nonce[] = { ++ 0xf1, 0xac, 0x97, 0xcb, 0x5e, 0x06, 0x48, 0xd2, 0x94, 0xbe, 0x15, 0x2e, ++ 0xc7, 0xfc, 0xc2, 0x01 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha256_personalizationstring[] = { ++ 0x98, 0xc5, 0x1e, 0x35, 0x5e, 0x89, 0x0d, 0xce, 0x64, 0x6d, 0x18, 0xa7, ++ 0x5a, 0xc6, 0xf3, 0xe7, 0xd6, 0x9e, 0xc0, 0xea, 0xb7, 0x3a, 0x8d, 0x65, ++ 0xb8, 0xeb, 0x10, 0xd7, 0x57, 0x18, 0xa0, 0x32 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_additionalinput[] = { ++ 0x1b, 0x10, 0xaf, 0xac, 0xd0, 0x65, 0x95, 0xad, 0x04, 0xad, 0x03, 0x1c, ++ 0xe0, 0x40, 0xd6, 0x3e, 0x1c, 0x46, 0x53, 0x39, 0x7c, 0xe2, 0xbc, 0xda, ++ 0x8c, 0xa2, 0x33, 0xa7, 0x9a, 0x26, 0xd3, 0x27 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_int_returnedbits[] = { ++ 0xba, 0x61, 0x0e, 0x55, 0xfe, 0x11, 0x8a, 0x9e, 0x0f, 0x80, 0xdf, 0x1d, ++ 0x03, 0x0a, 0xfe, 0x15, 0x94, 0x28, 0x4b, 0xba, 0xf4, 0x9f, 0x51, 0x25, ++ 0x88, 0xe5, 0x4e, 0xfb, 0xaf, 0xce, 0x69, 0x90 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_entropyinputreseed[] = { ++ 0x62, 0x7f, 0x1e, 0x6b, 0xe8, 0x8e, 0xe1, 0x35, 0x7d, 0x9b, 0x4f, 0xc7, ++ 0xec, 0xc8, 0xac, 0xef, 0x6b, 0x13, 0x9e, 0x05, 0x56, 0xc1, 0x08, 0xf9, ++ 0x2f, 0x0f, 0x27, 0x9c, 0xd4, 0x15, 0xed, 0x2d ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha256_additionalinputreseed[] = { ++ 0xc7, 0x76, 0x6e, 0xa9, 0xd2, 0xb2, 0x76, 0x40, 0x82, 0x25, 0x2c, 0xb3, ++ 0x6f, 0xac, 0xe9, 0x74, 0xef, 0x8f, 0x3c, 0x8e, 0xcd, 0xf1, 0xbf, 0xb3, ++ 0x49, 0x77, 0x34, 0x88, 0x52, 0x36, 0xe6, 0x2e ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_additionalinput2[] = { ++ 0x8d, 0xb8, 0x0c, 0xd1, 0xbf, 0x70, 0xf6, 0x19, 0xc3, 0x41, 0x80, 0x9f, ++ 0xe1, 0xa5, 0xa4, 0x1f, 0x2c, 0x26, 0xb1, 0xe5, 0xd8, 0xeb, 0xbe, 0xf8, ++ 0xdf, 0x88, 0x6a, 0x89, 0xd6, 0x05, 0xd8, 0x9d ++}; ++ ++__fips_constseg static const unsigned char hmac_sha256_returnedbits[] = { ++ 0x43, 0x12, 0x2a, 0x2c, 0x40, 0x53, 0x2e, 0x7c, 0x66, 0x34, 0xac, 0xc3, ++ 0x43, 0xe3, 0xe0, 0x6a, 0xfc, 0xfa, 0xea, 0x87, 0x21, 0x1f, 0xe2, 0x26, ++ 0xc4, 0xf9, 0x09, 0x9a, 0x0d, 0x6e, 0x7f, 0xe0 ++}; ++ ++/* HMAC SHA-384 PR */ ++__fips_constseg static const unsigned char hmac_sha384_pr_entropyinput[] = { ++ 0x69, 0x81, 0x98, 0x88, 0x44, 0xf5, 0xd6, 0x2e, 0x00, 0x08, 0x3b, 0xc5, ++ 0xfb, 0xd7, 0x8e, 0x6f, 0x23, 0xf8, 0x6d, 0x09, 0xd6, 0x85, 0x49, 0xd1, ++ 0xf8, 0x6d, 0xa4, 0x58, 0x54, 0xfd, 0x88, 0xa9 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_nonce[] = { ++ 0x6e, 0x38, 0x81, 0xca, 0xb7, 0xe8, 0x6e, 0x66, 0x49, 0x8a, 0xb2, 0x59, ++ 0xee, 0x16, 0xc9, 0xde ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha384_pr_personalizationstring[] = { ++ 0xfe, 0x4c, 0xd9, 0xf4, 0x78, 0x3b, 0x08, 0x41, 0x8d, 0x8f, 0x55, 0xc4, ++ 0x43, 0x56, 0xb6, 0x12, 0x36, 0x6b, 0x30, 0xb7, 0x5e, 0xe1, 0xb9, 0x47, ++ 0x04, 0xb1, 0x4e, 0xa9, 0x00, 0xa1, 0x52, 0xa1 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput[] = { ++ 0x89, 0xe9, 0xcc, 0x8f, 0x27, 0x3c, 0x26, 0xd1, 0x95, 0xc8, 0x7d, 0x0f, ++ 0x5b, 0x1a, 0xf0, 0x78, 0x39, 0x56, 0x6f, 0xa4, 0x23, 0xe7, 0xd1, 0xda, ++ 0x7c, 0x66, 0x33, 0xa0, 0x90, 0xc9, 0x92, 0x88 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr[] = { ++ 0xbe, 0x3d, 0x7c, 0x0d, 0xca, 0xda, 0x7c, 0x49, 0xb8, 0x12, 0x36, 0xc0, ++ 0xdb, 0xad, 0x35, 0xa8, 0xc7, 0x0b, 0x2a, 0x2c, 0x69, 0x6d, 0x25, 0x56, ++ 0x63, 0x82, 0x11, 0x3e, 0xa7, 0x33, 0x70, 0x72 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_int_returnedbits[] = { ++ 0x82, 0x3d, 0xe6, 0x54, 0x80, 0x42, 0xf8, 0xba, 0x90, 0x4f, 0x06, 0xa6, ++ 0xd2, 0x7f, 0xbf, 0x79, 0x7c, 0x12, 0x7d, 0xa6, 0xa2, 0x66, 0xe8, 0xa6, ++ 0xc0, 0xd6, 0x4a, 0x55, 0xbf, 0xd8, 0x0a, 0xc5, 0xf8, 0x03, 0x88, 0xdd, ++ 0x8e, 0x87, 0xd1, 0x5a, 0x48, 0x26, 0x72, 0x2a, 0x8e, 0xcf, 0xee, 0xba ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput2[] = { ++ 0x8f, 0xff, 0xd9, 0x84, 0xbb, 0x85, 0x3a, 0x66, 0xa1, 0x21, 0xce, 0xb2, ++ 0x3a, 0x3a, 0x17, 0x22, 0x19, 0xae, 0xc7, 0xb6, 0x63, 0x81, 0xd5, 0xff, ++ 0x0d, 0xc8, 0xe1, 0xaf, 0x57, 0xd2, 0xcb, 0x60 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr2[] = { ++ 0xd7, 0xfb, 0xc9, 0xe8, 0xe2, 0xf2, 0xaa, 0x4c, 0xb8, 0x51, 0x2f, 0xe1, ++ 0x22, 0xba, 0xf3, 0xda, 0x0a, 0x19, 0x76, 0x71, 0x57, 0xb2, 0x1d, 0x94, ++ 0x09, 0x69, 0x6c, 0xd3, 0x97, 0x51, 0x81, 0x87 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_pr_returnedbits[] = { ++ 0xe6, 0x19, 0x28, 0xa8, 0x21, 0xce, 0x5e, 0xdb, 0x24, 0x79, 0x8c, 0x76, ++ 0x5d, 0x73, 0xb2, 0xdf, 0xac, 0xef, 0x85, 0xa7, 0x3b, 0x19, 0x09, 0x8b, ++ 0x7f, 0x98, 0x28, 0xa9, 0x93, 0xd8, 0x7a, 0xad, 0x55, 0x8b, 0x24, 0x9d, ++ 0xe6, 0x98, 0xfe, 0x47, 0xd5, 0x48, 0xc1, 0x23, 0xd8, 0x1d, 0x62, 0x75 ++}; ++ ++/* HMAC SHA-384 No PR */ ++__fips_constseg static const unsigned char hmac_sha384_entropyinput[] = { ++ 0xc3, 0x56, 0x2b, 0x1d, 0xc2, 0xbb, 0xa8, 0xf0, 0xae, 0x1b, 0x0d, 0xd3, ++ 0x5a, 0x6c, 0xda, 0x57, 0x8e, 0xa5, 0x8a, 0x0d, 0x6c, 0x4b, 0x18, 0xb1, ++ 0x04, 0x3e, 0xb4, 0x99, 0x35, 0xc4, 0xc0, 0x5f ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_nonce[] = { ++ 0xc5, 0x49, 0x1e, 0x66, 0x27, 0x92, 0xbe, 0xec, 0xb5, 0x1e, 0x4b, 0xb1, ++ 0x38, 0xe3, 0xeb, 0x62 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha384_personalizationstring[] = { ++ 0xbe, 0xe7, 0x6b, 0x57, 0xde, 0x88, 0x11, 0x96, 0x9b, 0x6e, 0xea, 0xe5, ++ 0x63, 0x83, 0x4c, 0xb6, 0x8d, 0x66, 0xaa, 0x1f, 0x8b, 0x54, 0xe7, 0x62, ++ 0x6d, 0x5a, 0xfc, 0xbf, 0x97, 0xba, 0xcd, 0x77 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_additionalinput[] = { ++ 0xe5, 0x28, 0x5f, 0x43, 0xf5, 0x83, 0x6e, 0x0a, 0x83, 0x5c, 0xe3, 0x81, ++ 0x03, 0xf2, 0xf8, 0x78, 0x00, 0x7c, 0x95, 0x87, 0x16, 0xd6, 0x6c, 0x58, ++ 0x33, 0x6c, 0x53, 0x35, 0x0d, 0x66, 0xe3, 0xce ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_int_returnedbits[] = { ++ 0xe2, 0x1f, 0xf3, 0xda, 0x0d, 0x19, 0x99, 0x87, 0xc4, 0x90, 0xa2, 0x31, ++ 0xca, 0x2a, 0x89, 0x58, 0x43, 0x44, 0xb8, 0xde, 0xcf, 0xa4, 0xbe, 0x3b, ++ 0x53, 0x26, 0x22, 0x31, 0x76, 0x41, 0x22, 0xb5, 0xa8, 0x70, 0x2f, 0x4b, ++ 0x64, 0x95, 0x4d, 0x48, 0x96, 0x35, 0xe6, 0xbd, 0x3c, 0x34, 0xdb, 0x1b ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_entropyinputreseed[] = { ++ 0x77, 0x61, 0xba, 0xbc, 0xf2, 0xc1, 0xf3, 0x4b, 0x86, 0x65, 0xfd, 0x48, ++ 0x0e, 0x3c, 0x02, 0x5e, 0xa2, 0x7a, 0x6b, 0x7c, 0xed, 0x21, 0x5e, 0xf9, ++ 0xcd, 0xcd, 0x77, 0x07, 0x2b, 0xbe, 0xc5, 0x5c ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha384_additionalinputreseed[] = { ++ 0x18, 0x24, 0x5f, 0xc6, 0x84, 0xd1, 0x67, 0xc3, 0x9a, 0x11, 0xa5, 0x8c, ++ 0x07, 0x39, 0x21, 0x83, 0x4d, 0x04, 0xc4, 0x6a, 0x28, 0x19, 0xcf, 0x92, ++ 0x21, 0xd9, 0x9e, 0x41, 0x72, 0x6c, 0x9e, 0x63 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_additionalinput2[] = { ++ 0x96, 0x67, 0x41, 0x28, 0x9b, 0xb7, 0x92, 0x8d, 0x64, 0x3b, 0xe4, 0xcf, ++ 0x7e, 0xaa, 0x1e, 0xb1, 0x4b, 0x1d, 0x09, 0x56, 0x67, 0x9c, 0xc6, 0x6d, ++ 0x3b, 0xe8, 0x91, 0x9d, 0xe1, 0x8a, 0xb7, 0x32 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha384_returnedbits[] = { ++ 0xe3, 0x59, 0x61, 0x38, 0x92, 0xec, 0xe2, 0x3c, 0xff, 0xb7, 0xdb, 0x19, ++ 0x0f, 0x5b, 0x93, 0x68, 0x0d, 0xa4, 0x94, 0x40, 0x72, 0x0b, 0xe0, 0xed, ++ 0x4d, 0xcd, 0x68, 0xa0, 0x1e, 0xfe, 0x67, 0xb2, 0xfa, 0x21, 0x56, 0x74, ++ 0xa4, 0xad, 0xcf, 0xb7, 0x60, 0x66, 0x2e, 0x40, 0xde, 0x82, 0xca, 0xfb ++}; ++ ++/* HMAC SHA-512 PR */ ++__fips_constseg static const unsigned char hmac_sha512_pr_entropyinput[] = { ++ 0xaa, 0x9e, 0x45, 0x67, 0x0e, 0x00, 0x2a, 0x67, 0x98, 0xd6, 0xda, 0x0b, ++ 0x0f, 0x17, 0x7e, 0xac, 0xfd, 0x27, 0xc4, 0xca, 0x84, 0xdf, 0xde, 0xba, ++ 0x85, 0xd9, 0xbe, 0x8f, 0xf3, 0xff, 0x91, 0x4d ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_nonce[] = { ++ 0x8c, 0x49, 0x2f, 0x58, 0x1e, 0x7a, 0xda, 0x4b, 0x7e, 0x8a, 0x30, 0x7b, ++ 0x86, 0xea, 0xaf, 0xa2 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha512_pr_personalizationstring[] = { ++ 0x71, 0xe1, 0xbb, 0xad, 0xa7, 0x4b, 0x2e, 0x31, 0x3b, 0x0b, 0xec, 0x24, ++ 0x99, 0x38, 0xbc, 0xaa, 0x05, 0x4c, 0x46, 0x44, 0xfa, 0xad, 0x8e, 0x02, ++ 0xc1, 0x7e, 0xad, 0xec, 0x54, 0xa6, 0xd0, 0xad ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput[] = { ++ 0x3d, 0x6e, 0xa6, 0xa8, 0x29, 0x2a, 0xb2, 0xf5, 0x98, 0x42, 0xe4, 0x92, ++ 0x78, 0x22, 0x67, 0xfd, 0x1b, 0x15, 0x1e, 0x29, 0xaa, 0x71, 0x3c, 0x3c, ++ 0xe7, 0x05, 0x20, 0xa9, 0x29, 0xc6, 0x75, 0x71 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr[] = { ++ 0xab, 0xb9, 0x16, 0xd8, 0x55, 0x35, 0x54, 0xb7, 0x97, 0x3f, 0x94, 0xbc, ++ 0x2f, 0x7c, 0x70, 0xc7, 0xd0, 0xed, 0xb7, 0x4b, 0xf7, 0xf6, 0x6c, 0x03, ++ 0x0c, 0xb0, 0x03, 0xd8, 0xbb, 0x71, 0xd9, 0x10 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_int_returnedbits[] = { ++ 0x8e, 0xd3, 0xfd, 0x52, 0x9e, 0x83, 0x08, 0x49, 0x18, 0x6e, 0x23, 0x56, ++ 0x5c, 0x45, 0x93, 0x34, 0x05, 0xe2, 0x98, 0x8f, 0x0c, 0xd4, 0x32, 0x0c, ++ 0xfd, 0xda, 0x5f, 0x92, 0x3a, 0x8c, 0x81, 0xbd, 0xf6, 0x6c, 0x55, 0xfd, ++ 0xb8, 0x20, 0xce, 0x8d, 0x97, 0x27, 0xe8, 0xe8, 0xe0, 0xb3, 0x85, 0x50, ++ 0xa2, 0xc2, 0xb2, 0x95, 0x1d, 0x48, 0xd3, 0x7b, 0x4b, 0x78, 0x13, 0x35, ++ 0x05, 0x17, 0xbe, 0x0d ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput2[] = { ++ 0xc3, 0xfc, 0x95, 0xaa, 0x69, 0x06, 0xae, 0x59, 0x41, 0xce, 0x26, 0x08, ++ 0x29, 0x6d, 0x45, 0xda, 0xe8, 0xb3, 0x6c, 0x95, 0x60, 0x0f, 0x70, 0x2c, ++ 0x10, 0xba, 0x38, 0x8c, 0xcf, 0x29, 0x99, 0xaa ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr2[] = { ++ 0x3b, 0x9a, 0x25, 0xce, 0xd7, 0xf9, 0x5c, 0xd1, 0x3a, 0x3e, 0xaa, 0x71, ++ 0x14, 0x3e, 0x19, 0xe8, 0xce, 0xe6, 0xfe, 0x51, 0x84, 0xe9, 0x1b, 0xfe, ++ 0x3f, 0xa7, 0xf2, 0xfd, 0x76, 0x5f, 0x6a, 0xe7 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_pr_returnedbits[] = { ++ 0xb7, 0x82, 0xa9, 0x57, 0x81, 0x67, 0x53, 0xb5, 0xa1, 0xe9, 0x3d, 0x35, ++ 0xf9, 0xe4, 0x97, 0xbe, 0xa6, 0xca, 0xf1, 0x01, 0x13, 0x09, 0xe7, 0x21, ++ 0xc0, 0xed, 0x93, 0x5d, 0x4b, 0xf4, 0xeb, 0x8d, 0x53, 0x25, 0x8a, 0xc4, ++ 0xb1, 0x6f, 0x6e, 0x37, 0xcd, 0x2e, 0xac, 0x39, 0xb2, 0xb6, 0x99, 0xa3, ++ 0x82, 0x00, 0xb0, 0x21, 0xf0, 0xc7, 0x2f, 0x4c, 0x73, 0x92, 0xfd, 0x00, ++ 0xb6, 0xaf, 0xbc, 0xd3 ++}; ++ ++/* HMAC SHA-512 No PR */ ++__fips_constseg static const unsigned char hmac_sha512_entropyinput[] = { ++ 0x6e, 0x85, 0xe6, 0x25, 0x96, 0x29, 0xa7, 0x52, 0x5b, 0x60, 0xba, 0xaa, ++ 0xde, 0xdb, 0x36, 0x0a, 0x51, 0x9a, 0x15, 0xae, 0x6e, 0x18, 0xd3, 0xfe, ++ 0x39, 0xb9, 0x4a, 0x96, 0xf8, 0x77, 0xcb, 0x95 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_nonce[] = { ++ 0xe0, 0xa6, 0x5d, 0x08, 0xc3, 0x7c, 0xae, 0x25, 0x2e, 0x80, 0xd1, 0x3e, ++ 0xd9, 0xaf, 0x43, 0x3c ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha512_personalizationstring[] = { ++ 0x53, 0x99, 0x52, 0x5f, 0x11, 0xa9, 0x64, 0x66, 0x20, 0x5e, 0x1b, 0x5f, ++ 0x42, 0xb3, 0xf4, 0xda, 0xed, 0xbb, 0x63, 0xc1, 0x23, 0xaf, 0xd0, 0x01, ++ 0x90, 0x3b, 0xd0, 0x78, 0xe4, 0x0b, 0xa7, 0x20 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_additionalinput[] = { ++ 0x85, 0x90, 0x80, 0xd3, 0x98, 0xf1, 0x53, 0x6d, 0x68, 0x15, 0x8f, 0xe5, ++ 0x60, 0x3f, 0x17, 0x29, 0x55, 0x8d, 0x33, 0xb1, 0x45, 0x64, 0x64, 0x8d, ++ 0x50, 0x21, 0x89, 0xae, 0xf6, 0xfd, 0x32, 0x73 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_int_returnedbits[] = { ++ 0x28, 0x56, 0x30, 0x6f, 0xf4, 0xa1, 0x48, 0xe0, 0xc9, 0xf5, 0x75, 0x90, ++ 0xcc, 0xfb, 0xdf, 0xdf, 0x71, 0x3d, 0x0a, 0x9a, 0x03, 0x65, 0x3b, 0x18, ++ 0x61, 0xe3, 0xd1, 0xda, 0xcc, 0x4a, 0xfe, 0x55, 0x38, 0xf8, 0x21, 0x6b, ++ 0xfa, 0x18, 0x01, 0x42, 0x39, 0x2f, 0x99, 0x53, 0x38, 0x15, 0x82, 0x34, ++ 0xc5, 0x93, 0x92, 0xbc, 0x4d, 0x75, 0x1a, 0x5f, 0x21, 0x27, 0xcc, 0xa1, ++ 0xb1, 0x57, 0x69, 0xe8 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_entropyinputreseed[] = { ++ 0x8c, 0x52, 0x7e, 0x77, 0x72, 0x3f, 0xa3, 0x04, 0x97, 0x10, 0x9b, 0x41, ++ 0xbd, 0xe8, 0xff, 0x89, 0xed, 0x80, 0xe3, 0xbd, 0xaa, 0x12, 0x2d, 0xca, ++ 0x75, 0x82, 0x36, 0x77, 0x88, 0xcd, 0xa6, 0x73 ++}; ++ ++__fips_constseg ++ static const unsigned char hmac_sha512_additionalinputreseed[] = { ++ 0x7e, 0x32, 0xe3, 0x69, 0x69, 0x07, 0x34, 0xa2, 0x16, 0xa2, 0x5d, 0x1a, ++ 0x10, 0x91, 0xd3, 0xe2, 0x21, 0xa2, 0xa3, 0xdd, 0xcd, 0x0c, 0x09, 0x86, ++ 0x11, 0xe1, 0x50, 0xff, 0x5c, 0xb7, 0xeb, 0x5c ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_additionalinput2[] = { ++ 0x7f, 0x78, 0x66, 0xd8, 0xfb, 0x67, 0xcf, 0x8d, 0x8c, 0x08, 0x30, 0xa5, ++ 0xf8, 0x7d, 0xcf, 0x44, 0x59, 0xce, 0xf8, 0xdf, 0x58, 0xd3, 0x60, 0xcb, ++ 0xa8, 0x60, 0xb9, 0x07, 0xc4, 0xb1, 0x95, 0x48 ++}; ++ ++__fips_constseg static const unsigned char hmac_sha512_returnedbits[] = { ++ 0xdf, 0xa7, 0x36, 0xd4, 0xdc, 0x5d, 0x4d, 0x31, 0xad, 0x69, 0x46, 0x9f, ++ 0xf1, 0x7c, 0xd7, 0x3b, 0x4f, 0x55, 0xf2, 0xd7, 0xb9, 0x9d, 0xad, 0x7a, ++ 0x79, 0x08, 0x59, 0xa5, 0xdc, 0x74, 0xf5, 0x9b, 0x73, 0xd2, 0x13, 0x25, ++ 0x0b, 0x81, 0x08, 0x08, 0x25, 0xfb, 0x39, 0xf2, 0xf0, 0xa3, 0xa4, 0x8d, ++ 0xef, 0x05, 0x9e, 0xb8, 0xc7, 0x52, 0xe4, 0x0e, 0x42, 0xaa, 0x7c, 0x79, ++ 0xc2, 0xd6, 0xfd, 0xa5 ++}; +diff -up openssl-1.1.1j/crypto/fips/fips_dsa_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_dsa_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_dsa_selftest.c.fips 2021-03-03 12:57:42.200734534 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_dsa_selftest.c 2021-03-03 12:57:42.200734534 +0100 +@@ -0,0 +1,195 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++static const unsigned char dsa_test_2048_p[] = { ++ 0xa8, 0x53, 0x78, 0xd8, 0xfd, 0x3f, 0x8d, 0x72, 0xec, 0x74, 0x18, 0x08, ++ 0x0d, 0xa2, 0x13, 0x17, 0xe4, 0x3e, 0xc4, 0xb6, 0x2b, 0xa8, 0xc8, 0x62, ++ 0x3b, 0x7e, 0x4d, 0x04, 0x44, 0x1d, 0xd1, 0xa0, 0x65, 0x86, 0x62, 0x59, ++ 0x64, 0x93, 0xca, 0x8e, 0x9e, 0x8f, 0xbb, 0x7e, 0x34, 0xaa, 0xdd, 0xb6, ++ 0x2e, 0x5d, 0x67, 0xb6, 0xd0, 0x9a, 0x6e, 0x61, 0xb7, 0x69, 0xe7, 0xc3, ++ 0x52, 0xaa, 0x2b, 0x10, 0xe2, 0x0c, 0xa0, 0x63, 0x69, 0x63, 0xb5, 0x52, ++ 0x3e, 0x86, 0x47, 0x0d, 0xec, 0xbb, 0xed, 0xa0, 0x27, 0xe7, 0x97, 0xe7, ++ 0xb6, 0x76, 0x35, 0xd4, 0xd4, 0x9c, 0x30, 0x70, 0x0e, 0x74, 0xaf, 0x8a, ++ 0x0f, 0xf1, 0x56, 0xa8, 0x01, 0xaf, 0x57, 0xa2, 0x6e, 0x70, 0x78, 0xf1, ++ 0xd8, 0x2f, 0x74, 0x90, 0x8e, 0xcb, 0x6d, 0x07, 0xe7, 0x0b, 0x35, 0x03, ++ 0xee, 0xd9, 0x4f, 0xa3, 0x2c, 0xf1, 0x7a, 0x7f, 0xc3, 0xd6, 0xcf, 0x40, ++ 0xdc, 0x7b, 0x00, 0x83, 0x0e, 0x6a, 0x25, 0x66, 0xdc, 0x07, 0x3e, 0x34, ++ 0x33, 0x12, 0x51, 0x7c, 0x6a, 0xa5, 0x15, 0x2b, 0x4b, 0xfe, 0xcd, 0x2e, ++ 0x55, 0x1f, 0xee, 0x34, 0x63, 0x18, 0xa1, 0x53, 0x42, 0x3c, 0x99, 0x6b, ++ 0x0d, 0x5d, 0xcb, 0x91, 0x02, 0xae, 0xdd, 0x38, 0x79, 0x86, 0x16, 0xf1, ++ 0xf1, 0xe0, 0xd6, 0xc4, 0x03, 0x52, 0x5b, 0x1f, 0x9b, 0x3d, 0x4d, 0xc7, ++ 0x66, 0xde, 0x2d, 0xfc, 0x4a, 0x56, 0xd7, 0xb8, 0xba, 0x59, 0x63, 0xd6, ++ 0x0f, 0x3e, 0x16, 0x31, 0x88, 0x70, 0xad, 0x43, 0x69, 0x52, 0xe5, 0x57, ++ 0x65, 0x37, 0x4e, 0xab, 0x85, 0xe8, 0xec, 0x17, 0xd6, 0xb9, 0xa4, 0x54, ++ 0x7b, 0x9b, 0x5f, 0x27, 0x52, 0xf3, 0x10, 0x5b, 0xe8, 0x09, 0xb2, 0x3a, ++ 0x2c, 0x8d, 0x74, 0x69, 0xdb, 0x02, 0xe2, 0x4d, 0x59, 0x23, 0x94, 0xa7, ++ 0xdb, 0xa0, 0x69, 0xe9 ++}; ++ ++static const unsigned char dsa_test_2048_q[] = { ++ 0xd2, 0x77, 0x04, 0x4e, 0x50, 0xf5, 0xa4, 0xe3, 0xf5, 0x10, 0xa5, 0x0a, ++ 0x0b, 0x84, 0xfd, 0xff, 0xbc, 0xa0, 0x47, 0xed, 0x27, 0x60, 0x20, 0x56, ++ 0x74, 0x41, 0xa0, 0xa5 ++}; ++ ++static const unsigned char dsa_test_2048_g[] = { ++ 0x13, 0xd7, 0x54, 0xe2, 0x1f, 0xd2, 0x41, 0x65, 0x5d, 0xa8, 0x91, 0xc5, ++ 0x22, 0xa6, 0x5a, 0x72, 0xa8, 0x9b, 0xdc, 0x64, 0xec, 0x9b, 0x54, 0xa8, ++ 0x21, 0xed, 0x4a, 0x89, 0x8b, 0x49, 0x0e, 0x0c, 0x4f, 0xcb, 0x72, 0x19, ++ 0x2a, 0x4a, 0x20, 0xf5, 0x41, 0xf3, 0xf2, 0x92, 0x53, 0x99, 0xf0, 0xba, ++ 0xec, 0xf9, 0x29, 0xaa, 0xfb, 0xf7, 0x9d, 0xfe, 0x43, 0x32, 0x39, 0x3b, ++ 0x32, 0xcd, 0x2e, 0x2f, 0xcf, 0x27, 0x2f, 0x32, 0xa6, 0x27, 0x43, 0x4a, ++ 0x0d, 0xf2, 0x42, 0xb7, 0x5b, 0x41, 0x4d, 0xf3, 0x72, 0x12, 0x1e, 0x53, ++ 0xa5, 0x53, 0xf2, 0x22, 0xf8, 0x36, 0xb0, 0x00, 0xf0, 0x16, 0x48, 0x5b, ++ 0x6b, 0xd0, 0x89, 0x84, 0x51, 0x80, 0x1d, 0xcd, 0x8d, 0xe6, 0x4c, 0xd5, ++ 0x36, 0x56, 0x96, 0xff, 0xc5, 0x32, 0xd5, 0x28, 0xc5, 0x06, 0x62, 0x0a, ++ 0x94, 0x2a, 0x03, 0x05, 0x04, 0x6d, 0x8f, 0x18, 0x76, 0x34, 0x1f, 0x1e, ++ 0x57, 0x0b, 0xc3, 0x97, 0x4b, 0xa6, 0xb9, 0xa4, 0x38, 0xe9, 0x70, 0x23, ++ 0x02, 0xa2, 0xe6, 0xe6, 0x7b, 0xfd, 0x06, 0xd3, 0x2b, 0xc6, 0x79, 0x96, ++ 0x22, 0x71, 0xd7, 0xb4, 0x0c, 0xd7, 0x2f, 0x38, 0x6e, 0x64, 0xe0, 0xd7, ++ 0xef, 0x86, 0xca, 0x8c, 0xa5, 0xd1, 0x42, 0x28, 0xdc, 0x2a, 0x4f, 0x16, ++ 0xe3, 0x18, 0x98, 0x86, 0xb5, 0x99, 0x06, 0x74, 0xf4, 0x20, 0x0f, 0x3a, ++ 0x4c, 0xf6, 0x5a, 0x3f, 0x0d, 0xdb, 0xa1, 0xfa, 0x67, 0x2d, 0xff, 0x2f, ++ 0x5e, 0x14, 0x3d, 0x10, 0xe4, 0xe9, 0x7a, 0xe8, 0x4f, 0x6d, 0xa0, 0x95, ++ 0x35, 0xd5, 0xb9, 0xdf, 0x25, 0x91, 0x81, 0xa7, 0x9b, 0x63, 0xb0, 0x69, ++ 0xe9, 0x49, 0x97, 0x2b, 0x02, 0xba, 0x36, 0xb3, 0x58, 0x6a, 0xab, 0x7e, ++ 0x45, 0xf3, 0x22, 0xf8, 0x2e, 0x4e, 0x85, 0xca, 0x3a, 0xb8, 0x55, 0x91, ++ 0xb3, 0xc2, 0xa9, 0x66 ++}; ++ ++static const unsigned char dsa_test_2048_pub_key[] = { ++ 0x24, 0x52, 0xf3, 0xcc, 0xbe, 0x9e, 0xd5, 0xca, 0x7d, 0xc7, 0x4c, 0x60, ++ 0x2b, 0x99, 0x22, 0x6e, 0x8f, 0x2f, 0xab, 0x38, 0xe7, 0xd7, 0xdd, 0xfb, ++ 0x75, 0x53, 0x9b, 0x17, 0x15, 0x5e, 0x9f, 0xcf, 0xd1, 0xab, 0xa5, 0x64, ++ 0xeb, 0x85, 0x35, 0xd8, 0x12, 0xc9, 0xc2, 0xdc, 0xf9, 0x72, 0x84, 0x44, ++ 0x1b, 0xc4, 0x82, 0x24, 0x36, 0x24, 0xc7, 0xf4, 0x57, 0x58, 0x0c, 0x1c, ++ 0x38, 0xa5, 0x7c, 0x46, 0xc4, 0x57, 0x39, 0x24, 0x70, 0xed, 0xb5, 0x2c, ++ 0xb5, 0xa6, 0xe0, 0x3f, 0xe6, 0x28, 0x7b, 0xb6, 0xf4, 0x9a, 0x42, 0xa2, ++ 0x06, 0x5a, 0x05, 0x4f, 0x03, 0x08, 0x39, 0xdf, 0x1f, 0xd3, 0x14, 0x9c, ++ 0x4c, 0xa0, 0x53, 0x1d, 0xd8, 0xca, 0x8a, 0xaa, 0x9c, 0xc7, 0x33, 0x71, ++ 0x93, 0x38, 0x73, 0x48, 0x33, 0x61, 0x18, 0x22, 0x45, 0x45, 0xe8, 0x8c, ++ 0x80, 0xff, 0xd8, 0x76, 0x5d, 0x74, 0x36, 0x03, 0x33, 0xcc, 0xab, 0x99, ++ 0x72, 0x77, 0x9b, 0x65, 0x25, 0xa6, 0x5b, 0xdd, 0x0d, 0x10, 0xc6, 0x75, ++ 0xc1, 0x09, 0xbb, 0xd3, 0xe5, 0xbe, 0x4d, 0x72, 0xef, 0x6e, 0xba, 0x6e, ++ 0x43, 0x8d, 0x52, 0x26, 0x23, 0x7d, 0xb8, 0x88, 0x37, 0x9c, 0x5f, 0xcc, ++ 0x47, 0xa3, 0x84, 0x7f, 0xf6, 0x37, 0x11, 0xba, 0xed, 0x6d, 0x03, 0xaf, ++ 0xe8, 0x1e, 0x69, 0x4a, 0x41, 0x3b, 0x68, 0x0b, 0xd3, 0x8a, 0xb4, 0x90, ++ 0x3f, 0x83, 0x70, 0xa7, 0x07, 0xef, 0x55, 0x1d, 0x49, 0x41, 0x02, 0x6d, ++ 0x95, 0x79, 0xd6, 0x91, 0xde, 0x8e, 0xda, 0xa1, 0x61, 0x05, 0xeb, 0x9d, ++ 0xba, 0x3c, 0x2f, 0x4c, 0x1b, 0xec, 0x50, 0x82, 0x75, 0xaa, 0x02, 0x07, ++ 0xe2, 0x51, 0xb5, 0xec, 0xcb, 0x28, 0x6a, 0x4b, 0x01, 0xd4, 0x49, 0xd3, ++ 0x0a, 0xcb, 0x67, 0x37, 0x17, 0xa0, 0xd2, 0xfb, 0x3b, 0x50, 0xc8, 0x93, ++ 0xf7, 0xda, 0xb1, 0x4f ++}; ++ ++static const unsigned char dsa_test_2048_priv_key[] = { ++ 0x0c, 0x4b, 0x30, 0x89, 0xd1, 0xb8, 0x62, 0xcb, 0x3c, 0x43, 0x64, 0x91, ++ 0xf0, 0x91, 0x54, 0x70, 0xc5, 0x27, 0x96, 0xe3, 0xac, 0xbe, 0xe8, 0x00, ++ 0xec, 0x55, 0xf6, 0xcc ++}; ++ ++int FIPS_selftest_dsa() ++{ ++ DSA *dsa = NULL; ++ EVP_PKEY *pk = NULL; ++ int ret = 0; ++ BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; ++ ++ fips_load_key_component(p, dsa_test_2048); ++ fips_load_key_component(q, dsa_test_2048); ++ fips_load_key_component(g, dsa_test_2048); ++ fips_load_key_component(pub_key, dsa_test_2048); ++ fips_load_key_component(priv_key, dsa_test_2048); ++ ++ dsa = DSA_new(); ++ ++ if (dsa == NULL) ++ goto err; ++ ++ DSA_set0_pqg(dsa, p, q, g); ++ ++ DSA_set0_key(dsa, pub_key, priv_key); ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_assign_DSA(pk, dsa); ++ ++ if (!fips_pkey_signature_test(pk, NULL, 0, ++ NULL, 0, EVP_sha256(), 0, "DSA SHA256")) ++ goto err; ++ ret = 1; ++ ++ err: ++ if (pk) ++ EVP_PKEY_free(pk); ++ else if (dsa) ++ DSA_free(dsa); ++ else { ++ BN_free(p); ++ BN_free(q); ++ BN_free(g); ++ BN_free(pub_key); ++ BN_free(priv_key); ++ } ++ return ret; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_ecdh_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_ecdh_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_ecdh_selftest.c.fips 2021-03-03 12:57:42.200734534 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_ecdh_selftest.c 2021-03-03 12:57:42.200734534 +0100 +@@ -0,0 +1,242 @@ ++/* fips/ecdh/fips_ecdh_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++# include "fips_locl.h" ++ ++static const unsigned char p256_qcavsx[] = { ++ 0x52, 0xc6, 0xa5, 0x75, 0xf3, 0x04, 0x98, 0xb3, 0x29, 0x66, 0x0c, 0x62, ++ 0x18, 0x60, 0x55, 0x41, 0x59, 0xd4, 0x60, 0x85, 0x99, 0xc1, 0x51, 0x13, ++ 0x6f, 0x97, 0x85, 0x93, 0x33, 0x34, 0x07, 0x50 ++}; ++ ++static const unsigned char p256_qcavsy[] = { ++ 0x6f, 0x69, 0x24, 0xeb, 0xe9, 0x3b, 0xa7, 0xcc, 0x47, 0x17, 0xaa, 0x3f, ++ 0x70, 0xfc, 0x10, 0x73, 0x0a, 0xcd, 0x21, 0xee, 0x29, 0x19, 0x1f, 0xaf, ++ 0xb4, 0x1c, 0x1e, 0xc2, 0x8e, 0x97, 0x81, 0x6e ++}; ++ ++static const unsigned char p256_qiutx[] = { ++ 0x71, 0x46, 0x88, 0x08, 0x92, 0x21, 0x1b, 0x10, 0x21, 0x74, 0xff, 0x0c, ++ 0x94, 0xde, 0x34, 0x7c, 0x86, 0x74, 0xbe, 0x67, 0x41, 0x68, 0xd4, 0xc1, ++ 0xe5, 0x75, 0x63, 0x9c, 0xa7, 0x46, 0x93, 0x6f ++}; ++ ++static const unsigned char p256_qiuty[] = { ++ 0x33, 0x40, 0xa9, 0x6a, 0xf5, 0x20, 0xb5, 0x9e, 0xfc, 0x60, 0x1a, 0xae, ++ 0x3d, 0xf8, 0x21, 0xd2, 0xa7, 0xca, 0x52, 0x34, 0xb9, 0x5f, 0x27, 0x75, ++ 0x6c, 0x81, 0xbe, 0x32, 0x4d, 0xba, 0xbb, 0xf8 ++}; ++ ++static const unsigned char p256_qiutd[] = { ++ 0x1a, 0x48, 0x55, 0x6b, 0x11, 0xbe, 0x92, 0xd4, 0x1c, 0xd7, 0x45, 0xc3, ++ 0x82, 0x81, 0x51, 0xf1, 0x23, 0x40, 0xb7, 0x83, 0xfd, 0x01, 0x6d, 0xbc, ++ 0xa1, 0x66, 0xaf, 0x0a, 0x03, 0x23, 0xcd, 0xc8 ++}; ++ ++static const unsigned char p256_ziut[] = { ++ 0x77, 0x2a, 0x1e, 0x37, 0xee, 0xe6, 0x51, 0x02, 0x71, 0x40, 0xf8, 0x6a, ++ 0x36, 0xf8, 0x65, 0x61, 0x2b, 0x18, 0x71, 0x82, 0x23, 0xe6, 0xf2, 0x77, ++ 0xce, 0xec, 0xb8, 0x49, 0xc7, 0xbf, 0x36, 0x4f ++}; ++ ++typedef struct { ++ int curve; ++ const unsigned char *x1; ++ size_t x1len; ++ const unsigned char *y1; ++ size_t y1len; ++ const unsigned char *d1; ++ size_t d1len; ++ const unsigned char *x2; ++ size_t x2len; ++ const unsigned char *y2; ++ size_t y2len; ++ const unsigned char *z; ++ size_t zlen; ++} ECDH_SELFTEST_DATA; ++ ++# define make_ecdh_test(nid, pr) { nid, \ ++ pr##_qiutx, sizeof(pr##_qiutx), \ ++ pr##_qiuty, sizeof(pr##_qiuty), \ ++ pr##_qiutd, sizeof(pr##_qiutd), \ ++ pr##_qcavsx, sizeof(pr##_qcavsx), \ ++ pr##_qcavsy, sizeof(pr##_qcavsy), \ ++ pr##_ziut, sizeof(pr##_ziut) } ++ ++static ECDH_SELFTEST_DATA test_ecdh_data[] = { ++ make_ecdh_test(NID_X9_62_prime256v1, p256), ++}; ++ ++int FIPS_selftest_ecdh(void) ++{ ++ EC_KEY *ec1 = NULL, *ec2 = NULL; ++ const EC_POINT *ecp = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ unsigned char *ztmp = NULL; ++ int rv = 1; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) { ++ ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i; ++ if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0)) ++ continue; ++ ztmp = OPENSSL_malloc(ecd->zlen); ++ ++ x = BN_bin2bn(ecd->x1, ecd->x1len, x); ++ y = BN_bin2bn(ecd->y1, ecd->y1len, y); ++ d = BN_bin2bn(ecd->d1, ecd->d1len, d); ++ ++ if (!x || !y || !d || !ztmp) { ++ rv = 0; ++ goto err; ++ } ++ ++ ec1 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec1) { ++ rv = 0; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) { ++ rv = 0; ++ goto err; ++ } ++ ++ if (!EC_KEY_set_private_key(ec1, d)) { ++ rv = 0; ++ goto err; ++ } ++ ++ x = BN_bin2bn(ecd->x2, ecd->x2len, x); ++ y = BN_bin2bn(ecd->y2, ecd->y2len, y); ++ ++ if (!x || !y) { ++ rv = 0; ++ goto err; ++ } ++ ++ ec2 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec2) { ++ rv = 0; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) { ++ rv = 0; ++ goto err; ++ } ++ ++ ecp = EC_KEY_get0_public_key(ec2); ++ if (!ecp) { ++ rv = 0; ++ goto err; ++ } ++ ++ if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) { ++ rv = 0; ++ goto err; ++ } ++ ++ if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL)) ++ ztmp[0] ^= 0x1; ++ ++ if (memcmp(ztmp, ecd->z, ecd->zlen)) { ++ fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0); ++ rv = 0; ++ } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0)) ++ goto err; ++ ++ EC_KEY_free(ec1); ++ ec1 = NULL; ++ EC_KEY_free(ec2); ++ ec2 = NULL; ++ OPENSSL_free(ztmp); ++ ztmp = NULL; ++ } ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (ec1) ++ EC_KEY_free(ec1); ++ if (ec2) ++ EC_KEY_free(ec2); ++ if (ztmp) ++ OPENSSL_free(ztmp); ++ ++ return rv; ++ ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_ecdsa_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_ecdsa_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_ecdsa_selftest.c.fips 2021-03-03 12:57:42.200734534 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_ecdsa_selftest.c 2021-03-03 12:57:42.200734534 +0100 +@@ -0,0 +1,166 @@ ++/* fips/ecdsa/fips_ecdsa_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++static const char P_256_name[] = "ECDSA P-256"; ++ ++static const unsigned char P_256_d[] = { ++ 0x51, 0xbd, 0x06, 0xa1, 0x1c, 0xda, 0xe2, 0x12, 0x99, 0xc9, 0x52, 0x3f, ++ 0xea, 0xa4, 0xd2, 0xd1, 0xf4, 0x7f, 0xd4, 0x3e, 0xbd, 0xf8, 0xfc, 0x87, ++ 0xdc, 0x82, 0x53, 0x21, 0xee, 0xa0, 0xdc, 0x64 ++}; ++ ++static const unsigned char P_256_qx[] = { ++ 0x23, 0x89, 0xe0, 0xf4, 0x69, 0xe0, 0x49, 0xe5, 0xc7, 0xe5, 0x40, 0x6e, ++ 0x8f, 0x25, 0xdd, 0xad, 0x11, 0x16, 0x14, 0x9b, 0xab, 0x44, 0x06, 0x31, ++ 0xbf, 0x5e, 0xa6, 0x44, 0xac, 0x86, 0x00, 0x07 ++}; ++ ++static const unsigned char P_256_qy[] = { ++ 0xb3, 0x05, 0x0d, 0xd0, 0xdc, 0xf7, 0x40, 0xe6, 0xf9, 0xd8, 0x6d, 0x7b, ++ 0x63, 0xca, 0x97, 0xe6, 0x12, 0xf9, 0xd4, 0x18, 0x59, 0xbe, 0xb2, 0x5e, ++ 0x4a, 0x6a, 0x77, 0x23, 0xf4, 0x11, 0x9d, 0xeb ++}; ++ ++typedef struct { ++ int curve; ++ const char *name; ++ const unsigned char *x; ++ size_t xlen; ++ const unsigned char *y; ++ size_t ylen; ++ const unsigned char *d; ++ size_t dlen; ++} EC_SELFTEST_DATA; ++ ++# define make_ecdsa_test(nid, pr) { nid, pr##_name, \ ++ pr##_qx, sizeof(pr##_qx), \ ++ pr##_qy, sizeof(pr##_qy), \ ++ pr##_d, sizeof(pr##_d)} ++ ++static EC_SELFTEST_DATA test_ec_data[] = { ++ make_ecdsa_test(NID_X9_62_prime256v1, P_256), ++}; ++ ++int FIPS_selftest_ecdsa() ++{ ++ EC_KEY *ec = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ EVP_PKEY *pk = NULL; ++ int rv = 0; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ec_data) / sizeof(EC_SELFTEST_DATA); i++) { ++ EC_SELFTEST_DATA *ecd = test_ec_data + i; ++ ++ x = BN_bin2bn(ecd->x, ecd->xlen, x); ++ y = BN_bin2bn(ecd->y, ecd->ylen, y); ++ d = BN_bin2bn(ecd->d, ecd->dlen, d); ++ ++ if (!x || !y || !d) ++ goto err; ++ ++ ec = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec) ++ goto err; ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y)) ++ goto err; ++ ++ if (!EC_KEY_set_private_key(ec, d)) ++ goto err; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_assign_EC_KEY(pk, ec); ++ ++ if (!fips_pkey_signature_test(pk, NULL, 0, ++ NULL, 0, EVP_sha256(), 0, ecd->name)) ++ goto err; ++ } ++ ++ rv = 1; ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (pk) ++ EVP_PKEY_free(pk); ++ else if (ec) ++ EC_KEY_free(ec); ++ ++ return rv; ++ ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_err.h.fips openssl-1.1.1j/crypto/fips/fips_err.h +--- openssl-1.1.1j/crypto/fips/fips_err.h.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_err.h 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,197 @@ ++/* crypto/fips_err.h */ ++/* ==================================================================== ++ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++/* ++ * NOTE: this file was auto generated by the mkerr.pl script: any changes ++ * made to it will be overwritten when the script next updates this file, ++ * only reason strings will be preserved. ++ */ ++ ++#include ++#include ++#include ++ ++/* BEGIN ERROR CODES */ ++#ifndef OPENSSL_NO_ERR ++ ++# define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) ++# define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) ++ ++static ERR_STRING_DATA FIPS_str_functs[] = { ++ {ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "dh_builtin_genparams"}, ++ {ERR_FUNC(FIPS_F_DRBG_RESEED), "drbg_reseed"}, ++ {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "dsa_builtin_paramgen2"}, ++ {ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, ++ {ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, ++ {ERR_FUNC(FIPS_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, ++ {ERR_FUNC(FIPS_F_EVP_CIPHER_CTX_NEW), "EVP_CIPHER_CTX_new"}, ++ {ERR_FUNC(FIPS_F_EVP_CIPHER_CTX_RESET), "EVP_CIPHER_CTX_reset"}, ++ {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "fips_check_dsa"}, ++ {ERR_FUNC(FIPS_F_FIPS_CHECK_EC), "fips_check_ec"}, ++ {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "fips_check_rsa"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES), "fips_drbg_bytes"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "fips_drbg_check"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "fips_drbg_cprng_test"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK), "fips_drbg_error_check"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED), "FIPS_drbg_reseed"}, ++ {ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT), "FIPS_DRBG_SINGLE_KAT"}, ++ {ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY), "fips_get_entropy"}, ++ {ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET), "FIPS_module_mode_set"}, ++ {ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, ++ {ERR_FUNC(FIPS_F_FIPS_RAND_BYTES), "FIPS_rand_bytes"}, ++ {ERR_FUNC(FIPS_F_FIPS_RAND_SEED), "FIPS_rand_seed"}, ++ {ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD), "FIPS_rand_set_method"}, ++ {ERR_FUNC(FIPS_F_FIPS_RAND_STATUS), "FIPS_rand_status"}, ++ {ERR_FUNC(FIPS_F_FIPS_RSA_BUILTIN_KEYGEN), "fips_rsa_builtin_keygen"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST), "FIPS_selftest"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM), "FIPS_selftest_aes_ccm"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM), "FIPS_selftest_aes_gcm"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS), "FIPS_selftest_aes_xts"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC), "FIPS_selftest_cmac"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, ++ {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA2), "FIPS_selftest_sha2"}, ++ {ERR_FUNC(FIPS_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"}, ++ {ERR_FUNC(FIPS_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"}, ++ {ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "rsa_builtin_keygen"}, ++ {ERR_FUNC(FIPS_F_RSA_OSSL_INIT), "rsa_ossl_init"}, ++ {ERR_FUNC(FIPS_F_RSA_OSSL_PRIVATE_DECRYPT), "rsa_ossl_private_decrypt"}, ++ {ERR_FUNC(FIPS_F_RSA_OSSL_PRIVATE_ENCRYPT), "rsa_ossl_private_encrypt"}, ++ {ERR_FUNC(FIPS_F_RSA_OSSL_PUBLIC_DECRYPT), "rsa_ossl_public_decrypt"}, ++ {ERR_FUNC(FIPS_F_RSA_OSSL_PUBLIC_ENCRYPT), "rsa_ossl_public_encrypt"}, ++ {0, NULL} ++}; ++ ++static ERR_STRING_DATA FIPS_str_reasons[] = { ++ {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED), ++ "additional input error undetected"}, ++ {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG), ++ "additional input too long"}, ++ {ERR_REASON(FIPS_R_ALREADY_INSTANTIATED), "already instantiated"}, ++ {ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED), "drbg not initialised"}, ++ {ERR_REASON(FIPS_R_DRBG_STUCK), "drbg stuck"}, ++ {ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED), "entropy error undetected"}, ++ {ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED), ++ "entropy not requested for reseed"}, ++ {ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK), "entropy source stuck"}, ++ {ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, ++ {ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, ++ {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT), ++ "error retrieving additional input"}, ++ {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY), "error retrieving entropy"}, ++ {ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE), "error retrieving nonce"}, ++ {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH), ++ "fingerprint does not match"}, ++ {ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET), "fips mode already set"}, ++ {ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED), "fips selftest failed"}, ++ {ERR_REASON(FIPS_R_FUNCTION_ERROR), "function error"}, ++ {ERR_REASON(FIPS_R_GENERATE_ERROR), "generate error"}, ++ {ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED), ++ "generate error undetected"}, ++ {ERR_REASON(FIPS_R_INSTANTIATE_ERROR), "instantiate error"}, ++ {ERR_REASON(FIPS_R_INTERNAL_ERROR), "internal error"}, ++ {ERR_REASON(FIPS_R_INVALID_KEY_LENGTH), "invalid key length"}, ++ {ERR_REASON(FIPS_R_IN_ERROR_STATE), "in error state"}, ++ {ERR_REASON(FIPS_R_KEY_TOO_SHORT), "key too short"}, ++ {ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED), "nonce error undetected"}, ++ {ERR_REASON(FIPS_R_NON_FIPS_METHOD), "non fips method"}, ++ {ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE), "nopr test1 failure"}, ++ {ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE), "nopr test2 failure"}, ++ {ERR_REASON(FIPS_R_NOT_INSTANTIATED), "not instantiated"}, ++ {ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED), "pairwise test failed"}, ++ {ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED), ++ "personalisation error undetected"}, ++ {ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG), ++ "personalisation string too long"}, ++ {ERR_REASON(FIPS_R_PR_TEST1_FAILURE), "pr test1 failure"}, ++ {ERR_REASON(FIPS_R_PR_TEST2_FAILURE), "pr test2 failure"}, ++ {ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED), ++ "request length error undetected"}, ++ {ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG), ++ "request too large for drbg"}, ++ {ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR), "reseed counter error"}, ++ {ERR_REASON(FIPS_R_RESEED_ERROR), "reseed error"}, ++ {ERR_REASON(FIPS_R_SELFTEST_FAILED), "selftest failed"}, ++ {ERR_REASON(FIPS_R_SELFTEST_FAILURE), "selftest failure"}, ++ {ERR_REASON(FIPS_R_TEST_FAILURE), "test failure"}, ++ {ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR), "uninstantiate error"}, ++ {ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR), ++ "uninstantiate zeroise error"}, ++ {ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE), "unsupported drbg type"}, ++ {ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM), "unsupported platform"}, ++ {0, NULL} ++}; ++ ++#endif ++ ++int ERR_load_FIPS_strings(void) ++{ ++#ifndef OPENSSL_NO_ERR ++ ++ if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) { ++ ERR_load_strings(0, FIPS_str_functs); ++ ERR_load_strings(0, FIPS_str_reasons); ++ } ++#endif ++ return 1; ++} +diff -up openssl-1.1.1j/crypto/fips/fips_ers.c.fips openssl-1.1.1j/crypto/fips/fips_ers.c +--- openssl-1.1.1j/crypto/fips/fips_ers.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_ers.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,7 @@ ++#include ++ ++#ifdef OPENSSL_FIPS ++# include "fips_err.h" ++#else ++static void *dummy = &dummy; ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_hmac_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_hmac_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_hmac_selftest.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_hmac_selftest.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,134 @@ ++/* ==================================================================== ++ * Copyright (c) 2005 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++ ++#ifdef OPENSSL_FIPS ++typedef struct { ++ const EVP_MD *(*alg) (void); ++ const char *key, *iv; ++ unsigned char kaval[EVP_MAX_MD_SIZE]; ++} HMAC_KAT; ++ ++static const HMAC_KAT vector[] = { ++ {EVP_sha1, ++ /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */ ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x09, 0x22, 0xd3, 0x40, 0x5f, 0xaa, 0x3d, 0x19, ++ 0x4f, 0x82, 0xa4, 0x58, 0x30, 0x73, 0x7d, 0x5c, ++ 0xc6, 0xc7, 0x5d, 0x24} ++ }, ++ {EVP_sha224, ++ /* just keep extending the above... */ ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0xdd, 0xef, 0x0a, 0x40, 0xcb, 0x7d, 0x50, 0xfb, ++ 0x6e, 0xe6, 0xce, 0xa1, 0x20, 0xba, 0x26, 0xaa, ++ 0x08, 0xf3, 0x07, 0x75, 0x87, 0xb8, 0xad, 0x1b, ++ 0x8c, 0x8d, 0x12, 0xc7} ++ }, ++ {EVP_sha256, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0xb8, 0xf2, 0x0d, 0xb5, 0x41, 0xea, 0x43, 0x09, ++ 0xca, 0x4e, 0xa9, 0x38, 0x0c, 0xd0, 0xe8, 0x34, ++ 0xf7, 0x1f, 0xbe, 0x91, 0x74, 0xa2, 0x61, 0x38, ++ 0x0d, 0xc1, 0x7e, 0xae, 0x6a, 0x34, 0x51, 0xd9} ++ }, ++ {EVP_sha384, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x08, 0xbc, 0xb0, 0xda, 0x49, 0x1e, 0x87, 0xad, ++ 0x9a, 0x1d, 0x6a, 0xce, 0x23, 0xc5, 0x0b, 0xf6, ++ 0xb7, 0x18, 0x06, 0xa5, 0x77, 0xcd, 0x49, 0x04, ++ 0x89, 0xf1, 0xe6, 0x23, 0x44, 0x51, 0x51, 0x9f, ++ 0x85, 0x56, 0x80, 0x79, 0x0c, 0xbd, 0x4d, 0x50, ++ 0xa4, 0x5f, 0x29, 0xe3, 0x93, 0xf0, 0xe8, 0x7f} ++ }, ++ {EVP_sha512, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x80, 0x9d, 0x44, 0x05, 0x7c, 0x5b, 0x95, 0x41, ++ 0x05, 0xbd, 0x04, 0x13, 0x16, 0xdb, 0x0f, 0xac, ++ 0x44, 0xd5, 0xa4, 0xd5, 0xd0, 0x89, 0x2b, 0xd0, ++ 0x4e, 0x86, 0x64, 0x12, 0xc0, 0x90, 0x77, 0x68, ++ 0xf1, 0x87, 0xb7, 0x7c, 0x4f, 0xae, 0x2c, 0x2f, ++ 0x21, 0xa5, 0xb5, 0x65, 0x9a, 0x4f, 0x4b, 0xa7, ++ 0x47, 0x02, 0xa3, 0xde, 0x9b, 0x51, 0xf1, 0x45, ++ 0xbd, 0x4f, 0x25, 0x27, 0x42, 0x98, 0x99, 0x05} ++ }, ++}; ++ ++int FIPS_selftest_hmac() ++{ ++ int n; ++ unsigned int outlen; ++ unsigned char out[EVP_MAX_MD_SIZE]; ++ const EVP_MD *md; ++ const HMAC_KAT *t; ++ ++ for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) { ++ md = (*t->alg) (); ++ HMAC(md, t->key, strlen(t->key), ++ (const unsigned char *)t->iv, strlen(t->iv), out, &outlen); ++ ++ if (memcmp(out, t->kaval, outlen)) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ } ++ return 1; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_locl.h.fips openssl-1.1.1j/crypto/fips/fips_locl.h +--- openssl-1.1.1j/crypto/fips/fips_locl.h.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_locl.h 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,71 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#ifdef OPENSSL_FIPS ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++# define FIPS_MAX_CIPHER_TEST_SIZE 32 ++# define fips_load_key_component(comp, pre) \ ++ comp = BN_bin2bn(pre##_##comp, sizeof(pre##_##comp), NULL); \ ++ if (!comp) \ ++ goto err ++ ++# define fips_post_started(id, subid, ex) 1 ++# define fips_post_success(id, subid, ex) 1 ++# define fips_post_failed(id, subid, ex) 1 ++# define fips_post_corrupt(id, subid, ex) 1 ++# define fips_post_status() 1 ++ ++# ifdef __cplusplus ++} ++# endif ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_post.c.fips openssl-1.1.1j/crypto/fips/fips_post.c +--- openssl-1.1.1j/crypto/fips/fips_post.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_post.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,224 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++/* Power on self test (POST) support functions */ ++ ++# include ++# include "crypto/fips.h" ++# include "fips_locl.h" ++ ++/* Run all selftests */ ++int FIPS_selftest(void) ++{ ++ int rv = 1; ++ if (!FIPS_selftest_drbg()) ++ rv = 0; ++ if (!FIPS_selftest_sha1()) ++ rv = 0; ++ if (!FIPS_selftest_sha2()) ++ rv = 0; ++ if (!FIPS_selftest_sha3()) ++ rv = 0; ++ if (!FIPS_selftest_hmac()) ++ rv = 0; ++ if (!FIPS_selftest_cmac()) ++ rv = 0; ++ if (!FIPS_selftest_aes()) ++ rv = 0; ++ if (!FIPS_selftest_aes_ccm()) ++ rv = 0; ++ if (!FIPS_selftest_aes_gcm()) ++ rv = 0; ++ if (!FIPS_selftest_aes_xts()) ++ rv = 0; ++ if (!FIPS_selftest_des()) ++ rv = 0; ++ if (!FIPS_selftest_rsa()) ++ rv = 0; ++ if (!FIPS_selftest_ecdsa()) ++ rv = 0; ++ if (!FIPS_selftest_dsa()) ++ rv = 0; ++ if (!FIPS_selftest_dh()) ++ rv = 0; ++ if (!FIPS_selftest_ecdh()) ++ rv = 0; ++ return rv; ++} ++ ++/* Generalized public key test routine. Signs and verifies the data ++ * supplied in tbs using mesage digest md and setting option digest ++ * flags md_flags. If the 'kat' parameter is not NULL it will ++ * additionally check the signature matches it: a known answer test ++ * The string "fail_str" is used for identification purposes in case ++ * of failure. If "pkey" is NULL just perform a message digest check. ++ */ ++ ++int fips_pkey_signature_test(EVP_PKEY *pkey, ++ const unsigned char *tbs, int tbslen, ++ const unsigned char *kat, unsigned int katlen, ++ const EVP_MD *digest, unsigned int flags, ++ const char *fail_str) ++{ ++ int ret = 0; ++ unsigned char sigtmp[256], *sig = sigtmp; ++ size_t siglen = sizeof(sigtmp); ++ EVP_MD_CTX *mctx; ++ EVP_PKEY_CTX *pctx; ++ ++ if (digest == NULL) ++ digest = EVP_sha256(); ++ ++ mctx = EVP_MD_CTX_new(); ++ ++ if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ++ && (RSA_size(EVP_PKEY_get0_RSA(pkey)) > sizeof(sigtmp))) { ++ sig = OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pkey))); ++ siglen = RSA_size(EVP_PKEY_get0_RSA(pkey)); ++ } ++ if (!sig || ! mctx) { ++ EVP_MD_CTX_free(mctx); ++ FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ if (tbslen == -1) ++ tbslen = strlen((char *)tbs); ++ ++ if (EVP_DigestSignInit(mctx, &pctx, digest, NULL, pkey) <= 0) ++ goto error; ++ ++ if (flags == EVP_MD_CTX_FLAG_PAD_PSS) { ++ EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING); ++ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, 0); ++ } ++ ++ if (EVP_DigestSignUpdate(mctx, tbs, tbslen) <= 0) ++ goto error; ++ ++ if (EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) ++ goto error; ++ ++ if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) ++ goto error; ++ ++ if (EVP_DigestVerifyInit(mctx, &pctx, digest, NULL, pkey) <= 0) ++ goto error; ++ ++ if (flags == EVP_MD_CTX_FLAG_PAD_PSS) { ++ EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING); ++ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, 0); ++ } ++ ++ if (EVP_DigestVerifyUpdate(mctx, tbs, tbslen) <= 0) ++ goto error; ++ ++ ret = EVP_DigestVerifyFinal(mctx, sig, siglen); ++ ++ error: ++ if (sig != sigtmp) ++ OPENSSL_free(sig); ++ EVP_MD_CTX_free(mctx); ++ if (ret <= 0) { ++ FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, FIPS_R_TEST_FAILURE); ++ if (fail_str) ++ ERR_add_error_data(2, "Type=", fail_str); ++ return 0; ++ } ++ return 1; ++} ++ ++/* Generalized symmetric cipher test routine. Encrypt data, verify result ++ * against known answer, decrypt and compare with original plaintext. ++ */ ++ ++int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ++ const unsigned char *key, ++ const unsigned char *iv, ++ const unsigned char *plaintext, ++ const unsigned char *ciphertext, int len) ++{ ++ unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; ++ unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; ++ ++ OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); ++ memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); ++ memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); ++ ++ if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) ++ return 0; ++ if (EVP_Cipher(ctx, citmp, plaintext, len) <= 0) ++ return 0; ++ if (memcmp(citmp, ciphertext, len)) ++ return 0; ++ if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) ++ return 0; ++ if (EVP_Cipher(ctx, pltmp, citmp, len) <= 0) ++ return 0; ++ if (memcmp(pltmp, plaintext, len)) ++ return 0; ++ return 1; ++} ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_rand_lcl.h.fips openssl-1.1.1j/crypto/fips/fips_rand_lcl.h +--- openssl-1.1.1j/crypto/fips/fips_rand_lcl.h.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_rand_lcl.h 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,203 @@ ++/* fips/rand/fips_rand_lcl.h */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++typedef struct drbg_hash_ctx_st DRBG_HASH_CTX; ++typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX; ++typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX; ++ ++/* 888 bits from 10.1 table 2 */ ++#define HASH_PRNG_MAX_SEEDLEN 111 ++ ++struct drbg_hash_ctx_st { ++ const EVP_MD *md; ++ EVP_MD_CTX *mctx; ++ unsigned char V[HASH_PRNG_MAX_SEEDLEN]; ++ unsigned char C[HASH_PRNG_MAX_SEEDLEN]; ++ /* Temporary value storage: should always exceed max digest length */ ++ unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN]; ++}; ++ ++struct drbg_hmac_ctx_st { ++ const EVP_MD *md; ++ HMAC_CTX *hctx; ++ unsigned char K[EVP_MAX_MD_SIZE]; ++ unsigned char V[EVP_MAX_MD_SIZE]; ++}; ++ ++struct drbg_ctr_ctx_st { ++ AES_KEY ks; ++ size_t keylen; ++ unsigned char K[32]; ++ unsigned char V[16]; ++ /* Temp variables used by derivation function */ ++ AES_KEY df_ks; ++ AES_KEY df_kxks; ++ /* Temporary block storage used by ctr_df */ ++ unsigned char bltmp[16]; ++ size_t bltmp_pos; ++ unsigned char KX[48]; ++}; ++ ++/* DRBG internal flags */ ++ ++/* Functions shouldn't call err library */ ++#define DRBG_FLAG_NOERR 0x1 ++/* Custom reseed checking */ ++#define DRBG_CUSTOM_RESEED 0x2 ++ ++/* DRBG status values */ ++/* not initialised */ ++#define DRBG_STATUS_UNINITIALISED 0 ++/* ok and ready to generate random bits */ ++#define DRBG_STATUS_READY 1 ++/* reseed required */ ++#define DRBG_STATUS_RESEED 2 ++/* fatal error condition */ ++#define DRBG_STATUS_ERROR 3 ++ ++/* A default maximum length: larger than any reasonable value used in pratice */ ++ ++#define DRBG_MAX_LENGTH 0x7ffffff0 ++/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes ++ * so use max digest length. ++ */ ++#define DRBG_MAX_BLOCK EVP_MAX_MD_SIZE ++ ++#define DRBG_HEALTH_INTERVAL (1 << 24) ++ ++/* DRBG context structure */ ++ ++struct drbg_ctx_st { ++ /* First types common to all implementations */ ++ /* DRBG type: a NID for the underlying algorithm */ ++ int type; ++ /* Various external flags */ ++ unsigned int xflags; ++ /* Various internal use only flags */ ++ unsigned int iflags; ++ /* Used for periodic health checks */ ++ int health_check_cnt, health_check_interval; ++ ++ /* The following parameters are setup by mechanism drbg_init() call */ ++ int strength; ++ size_t blocklength; ++ size_t max_request; ++ ++ size_t min_entropy, max_entropy; ++ size_t min_nonce, max_nonce; ++ size_t max_pers, max_adin; ++ unsigned int reseed_counter; ++ unsigned int reseed_interval; ++ size_t seedlen; ++ int status; ++ /* Application data: typically used by test get_entropy */ ++ void *app_data; ++ /* Implementation specific structures */ ++ union { ++ DRBG_HASH_CTX hash; ++ DRBG_HMAC_CTX hmac; ++ DRBG_CTR_CTX ctr; ++ } d; ++ /* Initialiase PRNG and setup callbacks below */ ++ int (*init) (DRBG_CTX *ctx, int nid, int security, unsigned int flags); ++ /* Intantiate PRNG */ ++ int (*instantiate) (DRBG_CTX *ctx, ++ const unsigned char *ent, size_t entlen, ++ const unsigned char *nonce, size_t noncelen, ++ const unsigned char *pers, size_t perslen); ++ /* reseed */ ++ int (*reseed) (DRBG_CTX *ctx, ++ const unsigned char *ent, size_t entlen, ++ const unsigned char *adin, size_t adinlen); ++ /* generat output */ ++ int (*generate) (DRBG_CTX *ctx, ++ unsigned char *out, size_t outlen, ++ const unsigned char *adin, size_t adinlen); ++ /* uninstantiate */ ++ int (*uninstantiate) (DRBG_CTX *ctx); ++ ++ /* Entropy source block length */ ++ size_t entropy_blocklen; ++ ++ /* entropy gathering function */ ++ size_t (*get_entropy) (DRBG_CTX *ctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len); ++ /* Indicates we have finished with entropy buffer */ ++ void (*cleanup_entropy) (DRBG_CTX *ctx, unsigned char *out, size_t olen); ++ ++ /* nonce gathering function */ ++ size_t (*get_nonce) (DRBG_CTX *ctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len); ++ /* Indicates we have finished with nonce buffer */ ++ void (*cleanup_nonce) (DRBG_CTX *ctx, unsigned char *out, size_t olen); ++ ++ /* Callbacks used when called through RAND interface */ ++ /* Get any additional input for generate */ ++ size_t (*get_adin) (DRBG_CTX *ctx, unsigned char **pout); ++ void (*cleanup_adin) (DRBG_CTX *ctx, unsigned char *out, size_t olen); ++ /* Callback for RAND_seed(), RAND_add() */ ++ int (*rand_seed_cb) (DRBG_CTX *ctx, const void *buf, int num); ++ int (*rand_add_cb) (DRBG_CTX *ctx, ++ const void *buf, int num, double entropy); ++}; ++ ++int fips_drbg_ctr_init(DRBG_CTX *dctx); ++int fips_drbg_hash_init(DRBG_CTX *dctx); ++int fips_drbg_hmac_init(DRBG_CTX *dctx); ++int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags); ++int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out); ++ ++#define FIPS_digestinit EVP_DigestInit ++#define FIPS_digestupdate EVP_DigestUpdate ++#define FIPS_digestfinal EVP_DigestFinal ++#define M_EVP_MD_size EVP_MD_size +diff -up openssl-1.1.1j/crypto/fips/fips_rand_lib.c.fips openssl-1.1.1j/crypto/fips/fips_rand_lib.c +--- openssl-1.1.1j/crypto/fips/fips_rand_lib.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_rand_lib.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,234 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't ++ be defined and gettimeofday() won't be declared with strict compilers ++ like DEC C in ANSI C mode. */ ++#ifndef _XOPEN_SOURCE_EXTENDED ++# define _XOPEN_SOURCE_EXTENDED 1 ++#endif ++ ++#include ++#include ++#include ++#include ++#include "crypto/fips.h" ++#include ++#include "e_os.h" ++ ++#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)) ++# include ++#endif ++#if defined(OPENSSL_SYS_VXWORKS) ++# include ++#endif ++#ifndef OPENSSL_SYS_WIN32 ++# ifdef OPENSSL_UNISTD ++# include OPENSSL_UNISTD ++# else ++# include ++# endif ++#endif ++ ++/* FIPS API for PRNG use. Similar to RAND functionality but without ++ * ENGINE and additional checking for non-FIPS rand methods. ++ */ ++ ++static const RAND_METHOD *fips_rand_meth = NULL; ++static int fips_approved_rand_meth = 0; ++static int fips_rand_bits = 0; ++ ++/* Allows application to override number of bits and uses non-FIPS methods */ ++void FIPS_rand_set_bits(int nbits) ++{ ++ fips_rand_bits = nbits; ++} ++ ++int FIPS_rand_set_method(const RAND_METHOD *meth) ++{ ++ if (!fips_rand_bits) { ++ if (meth == FIPS_drbg_method()) ++ fips_approved_rand_meth = 1; ++ else { ++ fips_approved_rand_meth = 0; ++ if (FIPS_module_mode()) { ++ FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, FIPS_R_NON_FIPS_METHOD); ++ return 0; ++ } ++ } ++ } ++ fips_rand_meth = meth; ++ return 1; ++} ++ ++const RAND_METHOD *FIPS_rand_get_method(void) ++{ ++ return fips_rand_meth; ++} ++ ++void FIPS_rand_reset(void) ++{ ++ if (fips_rand_meth && fips_rand_meth->cleanup) ++ fips_rand_meth->cleanup(); ++} ++ ++int FIPS_rand_seed(const void *buf, int num) ++{ ++ if (!fips_approved_rand_meth && FIPS_module_mode()) { ++ FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD); ++ return 0; ++ } ++ if (fips_rand_meth && fips_rand_meth->seed) ++ fips_rand_meth->seed(buf, num); ++ return 1; ++} ++ ++int FIPS_rand_bytes(unsigned char *buf, int num) ++{ ++ if (!fips_approved_rand_meth && FIPS_module_mode()) { ++ FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD); ++ return 0; ++ } ++ if (fips_rand_meth && fips_rand_meth->bytes) ++ return fips_rand_meth->bytes(buf, num); ++ return 0; ++} ++ ++int FIPS_rand_status(void) ++{ ++ if (!fips_approved_rand_meth && FIPS_module_mode()) { ++ FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD); ++ return 0; ++ } ++ if (fips_rand_meth && fips_rand_meth->status) ++ return fips_rand_meth->status(); ++ return 0; ++} ++ ++/* Return instantiated strength of PRNG. For DRBG this is an internal ++ * parameter. Any other type of PRNG is not approved and returns 0 in ++ * FIPS mode and maximum 256 outside FIPS mode. ++ */ ++ ++int FIPS_rand_strength(void) ++{ ++ if (fips_rand_bits) ++ return fips_rand_bits; ++ if (fips_approved_rand_meth == 1) ++ return FIPS_drbg_get_strength(FIPS_get_default_drbg()); ++ else if (fips_approved_rand_meth == 0) { ++ if (FIPS_module_mode()) ++ return 0; ++ else ++ return 256; ++ } ++ return 0; ++} ++ ++void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr) ++{ ++# ifdef OPENSSL_SYS_WIN32 ++ FILETIME ft; ++# elif defined(OPENSSL_SYS_VXWORKS) ++ struct timespec ts; ++# else ++ struct timeval tv; ++# endif ++ ++# ifndef GETPID_IS_MEANINGLESS ++ unsigned long pid; ++# endif ++ ++# ifdef OPENSSL_SYS_WIN32 ++ GetSystemTimeAsFileTime(&ft); ++ buf[0] = (unsigned char)(ft.dwHighDateTime & 0xff); ++ buf[1] = (unsigned char)((ft.dwHighDateTime >> 8) & 0xff); ++ buf[2] = (unsigned char)((ft.dwHighDateTime >> 16) & 0xff); ++ buf[3] = (unsigned char)((ft.dwHighDateTime >> 24) & 0xff); ++ buf[4] = (unsigned char)(ft.dwLowDateTime & 0xff); ++ buf[5] = (unsigned char)((ft.dwLowDateTime >> 8) & 0xff); ++ buf[6] = (unsigned char)((ft.dwLowDateTime >> 16) & 0xff); ++ buf[7] = (unsigned char)((ft.dwLowDateTime >> 24) & 0xff); ++# elif defined(OPENSSL_SYS_VXWORKS) ++ clock_gettime(CLOCK_REALTIME, &ts); ++ buf[0] = (unsigned char)(ts.tv_sec & 0xff); ++ buf[1] = (unsigned char)((ts.tv_sec >> 8) & 0xff); ++ buf[2] = (unsigned char)((ts.tv_sec >> 16) & 0xff); ++ buf[3] = (unsigned char)((ts.tv_sec >> 24) & 0xff); ++ buf[4] = (unsigned char)(ts.tv_nsec & 0xff); ++ buf[5] = (unsigned char)((ts.tv_nsec >> 8) & 0xff); ++ buf[6] = (unsigned char)((ts.tv_nsec >> 16) & 0xff); ++ buf[7] = (unsigned char)((ts.tv_nsec >> 24) & 0xff); ++# else ++ gettimeofday(&tv, NULL); ++ buf[0] = (unsigned char)(tv.tv_sec & 0xff); ++ buf[1] = (unsigned char)((tv.tv_sec >> 8) & 0xff); ++ buf[2] = (unsigned char)((tv.tv_sec >> 16) & 0xff); ++ buf[3] = (unsigned char)((tv.tv_sec >> 24) & 0xff); ++ buf[4] = (unsigned char)(tv.tv_usec & 0xff); ++ buf[5] = (unsigned char)((tv.tv_usec >> 8) & 0xff); ++ buf[6] = (unsigned char)((tv.tv_usec >> 16) & 0xff); ++ buf[7] = (unsigned char)((tv.tv_usec >> 24) & 0xff); ++# endif ++ buf[8] = (unsigned char)(*pctr & 0xff); ++ buf[9] = (unsigned char)((*pctr >> 8) & 0xff); ++ buf[10] = (unsigned char)((*pctr >> 16) & 0xff); ++ buf[11] = (unsigned char)((*pctr >> 24) & 0xff); ++ ++ (*pctr)++; ++ ++# ifndef GETPID_IS_MEANINGLESS ++ pid = (unsigned long)getpid(); ++ buf[12] = (unsigned char)(pid & 0xff); ++ buf[13] = (unsigned char)((pid >> 8) & 0xff); ++ buf[14] = (unsigned char)((pid >> 16) & 0xff); ++ buf[15] = (unsigned char)((pid >> 24) & 0xff); ++# endif ++} ++ +diff -up openssl-1.1.1j/crypto/fips/fips_rsa_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_rsa_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_rsa_selftest.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_rsa_selftest.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,338 @@ ++/* ==================================================================== ++ * Copyright (c) 2003-2007 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++# include "crypto/fips.h" ++#endif ++#include ++#include ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++static int setrsakey(RSA *key) ++{ ++ static const unsigned char keydata_n[] = { ++ 0x00, 0xc9, 0xd5, 0x6d, 0x9d, 0x90, 0xdb, 0x43, 0xd6, 0x02, 0xed, 0x96, 0x88, 0x13, 0x8a, ++ 0xb2, 0xbf, 0x6e, 0xa1, 0x06, 0x10, 0xb2, 0x78, 0x37, 0xa7, 0x14, 0xa8, 0xff, 0xdd, 0x00, ++ 0xdd, 0xb4, 0x93, 0xa0, 0x45, 0xcc, 0x96, 0x90, 0xed, 0xad, 0xa9, 0xdd, 0xc4, 0xd6, 0xca, ++ 0x0c, 0xf0, 0xed, 0x4f, 0x72, 0x5e, 0x21, 0x49, 0x9a, 0x18, 0x12, 0x15, 0x8f, 0x90, 0x5a, ++ 0xdb, 0xb6, 0x33, 0x99, 0xa3, 0xe6, 0xb4, 0xf0, 0xc4, 0x97, 0x21, 0x26, 0xbb, 0xe3, 0xba, ++ 0xf2, 0xff, 0xa0, 0x72, 0xda, 0x89, 0x63, 0x8e, 0x8b, 0x3e, 0x08, 0x9d, 0x92, 0x2a, 0xbe, ++ 0x16, 0xe1, 0x43, 0x15, 0xfc, 0x57, 0xc7, 0x1f, 0x09, 0x11, 0x67, 0x1c, 0xa9, 0x96, 0xd1, ++ 0x8b, 0x3e, 0x80, 0x93, 0xc1, 0x59, 0xd0, 0x6d, 0x39, 0xf2, 0xac, 0x95, 0xcc, 0x10, 0x75, ++ 0xe9, 0x31, 0x24, 0xd1, 0x43, 0xaf, 0x68, 0x52, 0x4b, 0xe7, 0x16, 0xd7, 0x49, 0x65, 0x6f, ++ 0x26, 0xc0, 0x86, 0xad, 0xc0, 0x07, 0x0a, 0xc1, 0xe1, 0x2f, 0x87, 0x85, 0x86, 0x3b, 0xdc, ++ 0x5a, 0x99, 0xbe, 0xe9, 0xf9, 0xb9, 0xe9, 0x82, 0x27, 0x51, 0x04, 0x15, 0xab, 0x06, 0x0e, ++ 0x76, 0x5a, 0x28, 0x8d, 0x92, 0xbd, 0xc5, 0xb5, 0x7b, 0xa8, 0xdf, 0x4e, 0x47, 0xa2, 0xc1, ++ 0xe7, 0x52, 0xbf, 0x47, 0xf7, 0x62, 0xe0, 0x3a, 0x6f, 0x4d, 0x6a, 0x4d, 0x4e, 0xd4, 0xb9, ++ 0x59, 0x69, 0xfa, 0xb2, 0x14, 0xc1, 0xee, 0xe6, 0x2f, 0x95, 0xcd, 0x94, 0x72, 0xae, 0xe4, ++ 0xdb, 0x18, 0x9a, 0xc4, 0xcd, 0x70, 0xbd, 0xee, 0x31, 0x16, 0xb7, 0x49, 0x65, 0xac, 0x40, ++ 0x19, 0x0e, 0xb5, 0x6d, 0x83, 0xf1, 0x36, 0xbb, 0x08, 0x2f, 0x2e, 0x4e, 0x92, 0x62, 0xa4, ++ 0xff, 0x50, 0xdb, 0x20, 0x45, 0xa2, 0xeb, 0x16, 0x7a, 0xf2, 0xd5, 0x28, 0xc1, 0xfd, 0x4e, ++ 0x03, 0x71 ++ }; ++ ++ static const unsigned char keydata_e[] = { 0x01, 0x00, 0x01 }; ++ ++ static const unsigned char keydata_d[] = { ++ 0x36, 0x27, 0x3d, 0xb1, 0xf9, 0x1b, 0xdb, 0xa7, 0xa0, 0x41, 0x7f, 0x12, 0x23, 0xac, 0x23, ++ 0x29, 0x99, 0xd5, 0x3a, 0x7b, 0x60, 0x67, 0x41, 0x07, 0x63, 0x53, 0xb4, 0xd2, 0xe7, 0x58, ++ 0x95, 0x0a, 0xc7, 0x05, 0xf3, 0x4e, 0xb2, 0xb4, 0x12, 0xd4, 0x70, 0xdc, 0x4f, 0x85, 0x06, ++ 0xd3, 0xdd, 0xd8, 0x63, 0x27, 0x3e, 0x67, 0x31, 0x21, 0x24, 0x39, 0x04, 0xbc, 0x06, 0xa4, ++ 0xcc, 0xce, 0x2b, 0x7a, 0xfe, 0x7b, 0xad, 0xde, 0x11, 0x6e, 0xa3, 0xa5, 0xe6, 0x04, 0x53, ++ 0x0e, 0xa3, 0x4e, 0x2d, 0xb4, 0x8f, 0x31, 0xbf, 0xca, 0x75, 0x25, 0x52, 0x02, 0x85, 0xde, ++ 0x3d, 0xb2, 0x72, 0x43, 0xb2, 0x89, 0x8a, 0x9a, 0x34, 0x41, 0x26, 0x3f, 0x9a, 0x67, 0xbe, ++ 0xa4, 0x96, 0x7b, 0x0e, 0x75, 0xba, 0xa6, 0x93, 0xd5, 0xb8, 0xd8, 0xb8, 0x57, 0xf2, 0x4b, ++ 0x0f, 0x14, 0x81, 0xd1, 0x57, 0x4e, 0xf6, 0x45, 0x4c, 0xa6, 0x3b, 0xd0, 0x70, 0xca, 0xd3, ++ 0x9d, 0x55, 0xde, 0x22, 0x05, 0xe7, 0x8e, 0x28, 0x4d, 0xee, 0x11, 0xcf, 0xb6, 0x67, 0x76, ++ 0x09, 0xd3, 0xe3, 0x3c, 0x13, 0xf9, 0x99, 0x34, 0x10, 0x7b, 0xec, 0x81, 0x38, 0xf0, 0xb6, ++ 0x34, 0x9c, 0x9b, 0x50, 0x6f, 0x0b, 0x91, 0x81, 0x4d, 0x89, 0x94, 0x04, 0x7b, 0xf0, 0x3c, ++ 0xf4, 0xb1, 0xb2, 0x00, 0x48, 0x8d, 0x5a, 0x8f, 0x88, 0x9e, 0xc5, 0xab, 0x3a, 0x9e, 0x44, ++ 0x3f, 0x54, 0xe7, 0xd9, 0x6e, 0x47, 0xaa, 0xa1, 0xbd, 0x40, 0x46, 0x31, 0xf9, 0xf0, 0x34, ++ 0xb6, 0x04, 0xe1, 0x2b, 0x5b, 0x73, 0x86, 0xdd, 0x3a, 0x92, 0x1b, 0x71, 0xc7, 0x3f, 0x32, ++ 0xe5, 0xc3, 0xc2, 0xab, 0xa1, 0x7e, 0xbf, 0xa4, 0x52, 0xa0, 0xb0, 0x68, 0x90, 0xd1, 0x20, ++ 0x12, 0x79, 0xe9, 0xd7, 0xc9, 0x40, 0xba, 0xf2, 0x19, 0xc7, 0xa5, 0x00, 0x92, 0x86, 0x0d, ++ 0x01 ++ }; ++ ++ static const unsigned char keydata_p[] = { ++ 0x00, 0xfc, 0x5c, 0x6e, 0x16, 0xce, 0x1f, 0x03, 0x7b, 0xcd, 0xf7, 0xb3, 0x72, 0xb2, 0x8f, ++ 0x16, 0x72, 0xb8, 0x56, 0xae, 0xf7, 0xcd, 0x67, 0xd8, 0x4e, 0x7d, 0x07, 0xaf, 0xd5, 0x43, ++ 0x26, 0xc3, 0x35, 0xbe, 0x43, 0x8f, 0x4e, 0x2f, 0x1c, 0x43, 0x4e, 0x6b, 0xd2, 0xb2, 0xec, ++ 0x52, 0x6d, 0x97, 0x52, 0x2b, 0xcc, 0x5c, 0x3a, 0x6b, 0xf4, 0x14, 0xc6, 0x74, 0xda, 0x66, ++ 0x38, 0x1c, 0x7a, 0x3f, 0x84, 0x2f, 0xe3, 0xf9, 0x5a, 0xb8, 0x65, 0x69, 0x46, 0x06, 0xa3, ++ 0x37, 0x79, 0xb2, 0xa1, 0x5b, 0x58, 0xed, 0x5e, 0xa7, 0x5f, 0x8c, 0x65, 0x66, 0xbb, 0xd1, ++ 0x24, 0x36, 0xe6, 0x37, 0xa7, 0x3d, 0x49, 0x77, 0x8a, 0x8c, 0x34, 0xd8, 0x69, 0x29, 0xf3, ++ 0x4d, 0x58, 0x22, 0xb0, 0x51, 0x24, 0xb6, 0x40, 0xa8, 0x86, 0x59, 0x0a, 0xb7, 0xba, 0x5c, ++ 0x97, 0xda, 0x57, 0xe8, 0x36, 0xda, 0x7a, 0x9c, 0xad ++ }; ++ ++ static const unsigned char keydata_q[] = { ++ 0x00, 0xcc, 0xbe, 0x7b, 0x09, 0x69, 0x06, 0xee, 0x45, 0xbf, 0x88, 0x47, 0x38, 0xa8, 0xf8, ++ 0x17, 0xe5, 0xb6, 0xba, 0x67, 0x55, 0xe3, 0xe8, 0x05, 0x8b, 0xb8, 0xe2, 0x53, 0xd6, 0x8e, ++ 0xef, 0x2c, 0xe7, 0x4f, 0x4a, 0xf7, 0x4e, 0x26, 0x8d, 0x85, 0x0b, 0x3f, 0xec, 0xc3, 0x1c, ++ 0xd4, 0xeb, 0xec, 0x6a, 0xc8, 0x72, 0x2a, 0x25, 0x7d, 0xfd, 0xa6, 0x77, 0x96, 0xf0, 0x1e, ++ 0xcd, 0x28, 0x57, 0xf8, 0x37, 0x30, 0x75, 0x6b, 0xbd, 0xd4, 0x7b, 0x0c, 0x87, 0xc5, 0x6c, ++ 0x87, 0x40, 0xa5, 0xbb, 0x27, 0x2c, 0x78, 0xc9, 0x74, 0x5a, 0x54, 0x5b, 0x0b, 0x30, 0x6f, ++ 0x44, 0x4a, 0xfa, 0x71, 0xe4, 0x21, 0x61, 0x66, 0xf9, 0xee, 0x65, 0xde, 0x7c, 0x04, 0xd7, ++ 0xfd, 0xa9, 0x15, 0x5b, 0x7f, 0xe2, 0x7a, 0xba, 0x69, 0x86, 0x72, 0xa6, 0x06, 0x8d, 0x9b, ++ 0x90, 0x55, 0x60, 0x9e, 0x4c, 0x5d, 0xa9, 0xb6, 0x55 ++ }; ++ ++ static const unsigned char keydata_dmp1[] = { ++ 0x7a, 0xd6, 0x12, 0xd0, 0x0e, 0xec, 0x91, 0xa9, 0x85, 0x8b, 0xf8, 0x50, 0xf0, 0x11, 0x2e, ++ 0x00, 0x11, 0x32, 0x40, 0x60, 0x66, 0x1f, 0x11, 0xee, 0xc2, 0x75, 0x27, 0x65, 0x4b, 0x16, ++ 0x67, 0x16, 0x95, 0xd2, 0x14, 0xc3, 0x1d, 0xb3, 0x48, 0x1f, 0xb7, 0xe4, 0x0b, 0x2b, 0x74, ++ 0xc3, 0xdb, 0x50, 0x27, 0xf9, 0x85, 0x3a, 0xfa, 0xa9, 0x08, 0x23, 0xc1, 0x65, 0x3d, 0x34, ++ 0x3a, 0xc8, 0x56, 0x7a, 0x65, 0x45, 0x36, 0x6e, 0xae, 0x2a, 0xce, 0x9f, 0x43, 0x43, 0xd7, ++ 0x10, 0xe9, 0x9e, 0x18, 0xf4, 0xa4, 0x35, 0xda, 0x8a, 0x6b, 0xb0, 0x3f, 0xdd, 0x53, 0xe3, ++ 0xa8, 0xc5, 0x4e, 0x79, 0x9d, 0x1f, 0x51, 0x8c, 0xa2, 0xca, 0x66, 0x3c, 0x6a, 0x2a, 0xff, ++ 0x8e, 0xd2, 0xf3, 0xb7, 0xcb, 0x82, 0xda, 0xde, 0x2c, 0xe6, 0xd2, 0x8c, 0xb3, 0xad, 0xb6, ++ 0x4c, 0x95, 0x55, 0x76, 0xbd, 0xc9, 0xc8, 0xd1 ++ }; ++ ++ static const unsigned char keydata_dmq1[] = { ++ 0x00, 0x83, 0x23, 0x1d, 0xbb, 0x11, 0x42, 0x17, 0x2b, 0x25, 0x5a, 0x2c, 0x03, 0xe6, 0x75, ++ 0xc1, 0x18, 0xa8, 0xc9, 0x0b, 0x96, 0xbf, 0xba, 0xc4, 0x92, 0x91, 0x80, 0xa5, 0x22, 0x2f, ++ 0xba, 0x91, 0x90, 0x36, 0x01, 0x56, 0x15, 0x00, 0x2c, 0x74, 0xa2, 0x97, 0xf7, 0x15, 0xa1, ++ 0x49, 0xdf, 0x32, 0x35, 0xd2, 0xdd, 0x0c, 0x91, 0xa6, 0xf8, 0xe7, 0xbe, 0x81, 0x36, 0x9b, ++ 0x03, 0xdc, 0x6b, 0x3b, 0xd8, 0x5d, 0x79, 0x57, 0xe0, 0xe6, 0x4f, 0x49, 0xdf, 0x4c, 0x5c, ++ 0x0e, 0xe5, 0x21, 0x41, 0x95, 0xfd, 0xad, 0xff, 0x9a, 0x3e, 0xa0, 0xf9, 0x0f, 0x59, 0x9e, ++ 0x6a, 0xa7, 0x7b, 0x71, 0xa7, 0x24, 0x9a, 0x36, 0x52, 0xae, 0x97, 0x20, 0xc1, 0x5e, 0x78, ++ 0xd9, 0x47, 0x8b, 0x1e, 0x67, 0xf2, 0xaf, 0x98, 0xe6, 0x2d, 0xef, 0x10, 0xd7, 0xf1, 0xab, ++ 0x49, 0xee, 0xe5, 0x4b, 0x7e, 0xae, 0x1f, 0x1d, 0x61 ++ }; ++ ++ static const unsigned char keydata_iqmp[] = { ++ 0x23, 0x96, 0xc1, 0x91, 0x17, 0x5e, 0x0a, 0x83, 0xd2, 0xdc, 0x7b, 0x69, 0xb2, 0x59, 0x1d, ++ 0x33, 0x58, 0x52, 0x3f, 0x18, 0xc7, 0x09, 0x50, 0x1c, 0xb9, 0xa1, 0xbb, 0x4c, 0xa2, 0x38, ++ 0x40, 0x4c, 0x9a, 0x8e, 0xfe, 0x9c, 0x90, 0x92, 0xd0, 0x71, 0x9f, 0x89, 0x99, 0x50, 0x91, ++ 0x1f, 0x34, 0x8b, 0x74, 0x53, 0x11, 0x11, 0x4a, 0x70, 0xe2, 0xf7, 0x30, 0xd8, 0x8c, 0x80, ++ 0xe1, 0xcc, 0x9f, 0xf1, 0x63, 0x17, 0x1a, 0x7d, 0x67, 0x29, 0x4c, 0xcb, 0x4e, 0x74, 0x7b, ++ 0xe0, 0x3e, 0x9e, 0x2f, 0xf4, 0x67, 0x8f, 0xec, 0xb9, 0x5c, 0x00, 0x1e, 0x7e, 0xa2, 0x7b, ++ 0x92, 0xc9, 0x6f, 0x4c, 0xe4, 0x0e, 0xf9, 0x48, 0x63, 0xcd, 0x50, 0x22, 0x5d, 0xbf, 0xb6, ++ 0x9d, 0x01, 0x33, 0x6a, 0xf4, 0x50, 0xbe, 0x86, 0x98, 0x4f, 0xca, 0x3f, 0x3a, 0xfa, 0xcf, ++ 0x07, 0x40, 0xc4, 0xaa, 0xad, 0xae, 0xbe, 0xbf ++ }; ++ ++ int rv = 0; ++ BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ ++ fips_load_key_component(n, keydata); ++ fips_load_key_component(e, keydata); ++ fips_load_key_component(d, keydata); ++ fips_load_key_component(p, keydata); ++ fips_load_key_component(q, keydata); ++ fips_load_key_component(dmp1, keydata); ++ fips_load_key_component(dmq1, keydata); ++ fips_load_key_component(iqmp, keydata); ++ ++ RSA_set0_key(key, n, e, d); ++ RSA_set0_factors(key, p, q); ++ RSA_set0_crt_params(key, dmp1, dmq1, iqmp); ++ ++ rv = 1; ++err: ++ if (!rv) { ++ BN_free(n); ++ BN_free(e); ++ BN_free(d); ++ BN_free(p); ++ BN_free(q); ++ BN_free(dmp1); ++ BN_free(dmq1); ++ BN_free(iqmp); ++ } ++ return rv; ++} ++ ++/* Known Answer Test (KAT) data for the above RSA private key signing ++ * kat_tbs. ++ */ ++ ++static const unsigned char kat_tbs[] = ++ "OpenSSL FIPS 140-2 Public Key RSA KAT"; ++ ++static const unsigned char kat_RSA_PSS_SHA256[] = { ++ 0x38, 0xDA, 0x99, 0x51, 0x26, 0x38, 0xC6, 0x7F, 0xC4, 0x81, 0x57, 0x19, ++ 0x35, 0xC6, 0xF6, 0x1E, 0x90, 0x47, 0x20, 0x55, 0x47, 0x56, 0x26, 0xE9, ++ 0xF2, 0xA8, 0x39, 0x6C, 0xD5, 0xCD, 0xCB, 0x55, 0xFC, 0x0C, 0xC5, 0xCB, ++ 0xF7, 0x40, 0x17, 0x3B, 0xCF, 0xE4, 0x05, 0x03, 0x3B, 0xA0, 0xB2, 0xC9, ++ 0x0D, 0x5E, 0x48, 0x3A, 0xE9, 0xAD, 0x28, 0x71, 0x7D, 0x8F, 0x89, 0x16, ++ 0x59, 0x93, 0x35, 0xDC, 0x4D, 0x7B, 0xDF, 0x84, 0xE4, 0x68, 0xAA, 0x33, ++ 0xAA, 0xDC, 0x66, 0x50, 0xC8, 0xA9, 0x32, 0x12, 0xDC, 0xC6, 0x90, 0x49, ++ 0x0B, 0x75, 0xFF, 0x9B, 0x95, 0x00, 0x9A, 0x90, 0xE0, 0xD4, 0x0E, 0x67, ++ 0xAB, 0x3C, 0x47, 0x36, 0xC5, 0x2E, 0x1C, 0x46, 0xF0, 0x2D, 0xD3, 0x8B, ++ 0x42, 0x08, 0xDE, 0x0D, 0xB6, 0x2C, 0x86, 0xB0, 0x35, 0x71, 0x18, 0x6B, ++ 0x89, 0x67, 0xC0, 0x05, 0xAD, 0xF4, 0x1D, 0x62, 0x4E, 0x75, 0xEC, 0xD6, ++ 0xC2, 0xDB, 0x07, 0xB0, 0xB6, 0x8D, 0x15, 0xAD, 0xCD, 0xBF, 0xF5, 0x60, ++ 0x76, 0xAE, 0x48, 0xB8, 0x77, 0x7F, 0xC5, 0x01, 0xD9, 0x29, 0xBB, 0xD6, ++ 0x17, 0xA2, 0x20, 0x5A, 0xC0, 0x4A, 0x3B, 0x34, 0xC8, 0xB9, 0x39, 0xCF, ++ 0x06, 0x89, 0x95, 0x6F, 0xC7, 0xCA, 0xC4, 0xE4, 0x43, 0xDF, 0x5A, 0x23, ++ 0xE2, 0x89, 0xA3, 0x38, 0x78, 0x31, 0x38, 0xC6, 0xA4, 0x6F, 0x5F, 0x73, ++ 0x5A, 0xE5, 0x9E, 0x09, 0xE7, 0x6F, 0xD4, 0xF8, 0x3E, 0xB7, 0xB0, 0x56, ++ 0x9A, 0xF3, 0x65, 0xF0, 0xC2, 0xA6, 0x8A, 0x08, 0xBA, 0x44, 0xAC, 0x97, ++ 0xDE, 0xB4, 0x16, 0x83, 0xDF, 0xE3, 0xEE, 0x71, 0xFA, 0xF9, 0x51, 0x50, ++ 0x14, 0xDC, 0xFD, 0x6A, 0x82, 0x20, 0x68, 0x64, 0x7D, 0x4E, 0x82, 0x68, ++ 0xD7, 0x45, 0xFA, 0x6A, 0xE4, 0xE5, 0x29, 0x3A, 0x70, 0xFB, 0xE4, 0x62, ++ 0x2B, 0x31, 0xB9, 0x7D ++}; ++ ++static const unsigned char kat_RSA_SHA256[] = { ++ 0xC2, 0xB1, 0x97, 0x00, 0x9A, 0xE5, 0x80, 0x6A, 0xE2, 0x51, 0x68, 0xB9, ++ 0x7A, 0x0C, 0xF2, 0xB4, 0x77, 0xED, 0x15, 0x0C, 0x4E, 0xE1, 0xDC, 0xFF, ++ 0x8E, 0xBC, 0xDE, 0xC7, 0x9A, 0x96, 0xF1, 0x47, 0x45, 0x24, 0x9D, 0x6F, ++ 0xA6, 0xF3, 0x1D, 0x0D, 0x35, 0x4C, 0x1A, 0xF3, 0x58, 0x2C, 0x6C, 0x06, ++ 0xD6, 0x22, 0x37, 0x77, 0x8C, 0x33, 0xE5, 0x07, 0x53, 0x93, 0x28, 0xCF, ++ 0x67, 0xFA, 0xC4, 0x1F, 0x1B, 0x24, 0xDB, 0x4C, 0xC5, 0x2A, 0x51, 0xA2, ++ 0x60, 0x15, 0x8C, 0x54, 0xB4, 0x30, 0xE2, 0x24, 0x47, 0x86, 0xF2, 0xF8, ++ 0x6C, 0xD6, 0x12, 0x59, 0x2C, 0x74, 0x9A, 0x37, 0xF3, 0xC4, 0xA2, 0xD5, ++ 0x4E, 0x1F, 0x77, 0xF0, 0x27, 0xCE, 0x77, 0xF8, 0x4A, 0x79, 0x03, 0xBE, ++ 0xC8, 0x06, 0x2D, 0xA7, 0xA6, 0x46, 0xF5, 0x55, 0x79, 0xD7, 0x5C, 0xC6, ++ 0x5B, 0xB1, 0x00, 0x4E, 0x7C, 0xD9, 0x11, 0x85, 0xE0, 0xB1, 0x4D, 0x2D, ++ 0x13, 0xD7, 0xAC, 0xEA, 0x64, 0xD1, 0xAC, 0x8F, 0x8D, 0x8F, 0xEA, 0x42, ++ 0x7F, 0xF9, 0xB7, 0x7D, 0x2C, 0x68, 0x49, 0x07, 0x7A, 0x74, 0xEF, 0xB4, ++ 0xC9, 0x97, 0x16, 0x5C, 0x6C, 0x6E, 0x5C, 0x09, 0x2E, 0x8E, 0x13, 0x2E, ++ 0x1A, 0x8D, 0xA6, 0x0C, 0x6E, 0x0C, 0x1C, 0x0F, 0xCC, 0xB2, 0x78, 0x8A, ++ 0x07, 0xFC, 0x5C, 0xC2, 0xF5, 0x65, 0xEC, 0xAB, 0x8B, 0x3C, 0xCA, 0x91, ++ 0x6F, 0x84, 0x7C, 0x21, 0x0E, 0xB8, 0xDA, 0x7B, 0x6C, 0xF7, 0xDF, 0xAB, ++ 0x7E, 0x15, 0xFD, 0x85, 0x0B, 0x33, 0x9B, 0x6A, 0x3A, 0xC3, 0xEF, 0x65, ++ 0x04, 0x6E, 0xB2, 0xAC, 0x98, 0xFD, 0xEB, 0x02, 0xF5, 0xC0, 0x0B, 0x5E, ++ 0xCB, 0xD4, 0x83, 0x82, 0x18, 0x1B, 0xDA, 0xB4, 0xCD, 0xE8, 0x71, 0x6B, ++ 0x1D, 0xB5, 0x4F, 0xE9, 0xD6, 0x43, 0xA0, 0x0A, 0x14, 0xA0, 0xE7, 0x5D, ++ 0x47, 0x9D, 0x18, 0xD7 ++}; ++ ++static int fips_rsa_encrypt_test(RSA *rsa, const unsigned char *plaintext, ++ int ptlen) ++{ ++ unsigned char *ctbuf = NULL, *ptbuf = NULL; ++ int ret = 0; ++ int len; ++ ++ ctbuf = OPENSSL_malloc(RSA_size(rsa)); ++ if (!ctbuf) ++ goto err; ++ ++ len = RSA_public_encrypt(ptlen, plaintext, ctbuf, rsa, RSA_PKCS1_PADDING); ++ if (len <= 0) ++ goto err; ++ /* Check ciphertext doesn't match plaintext */ ++ if (len >= ptlen && !memcmp(plaintext, ctbuf, ptlen)) ++ goto err; ++ ++ ptbuf = OPENSSL_malloc(RSA_size(rsa)); ++ if (!ptbuf) ++ goto err; ++ ++ len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); ++ if (len != ptlen) ++ goto err; ++ if (memcmp(ptbuf, plaintext, len)) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ if (ctbuf) ++ OPENSSL_free(ctbuf); ++ if (ptbuf) ++ OPENSSL_free(ptbuf); ++ return ret; ++} ++ ++int FIPS_selftest_rsa() ++{ ++ int ret = 0; ++ RSA *key; ++ EVP_PKEY *pk = NULL; ++ ++ if ((key = RSA_new()) == NULL) ++ goto err; ++ ++ if (!setrsakey(key)) ++ goto err; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_RSA(pk, key); ++ ++ if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, ++ kat_RSA_SHA256, sizeof(kat_RSA_SHA256), ++ EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1, ++ "RSA SHA256 PKCS#1")) ++ goto err; ++ ++ if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, ++ kat_RSA_PSS_SHA256, ++ sizeof(kat_RSA_PSS_SHA256), EVP_sha256(), ++ EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA256 PSS")) ++ goto err; ++ ++ if (!fips_rsa_encrypt_test(key, kat_tbs, sizeof(kat_tbs) - 1)) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ if (pk) ++ EVP_PKEY_free(pk); ++ if (key) ++ RSA_free(key); ++ return ret; ++} ++ ++#endif /* def OPENSSL_FIPS */ +diff -up openssl-1.1.1j/crypto/fips/fips_sha_selftest.c.fips openssl-1.1.1j/crypto/fips/fips_sha_selftest.c +--- openssl-1.1.1j/crypto/fips/fips_sha_selftest.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_sha_selftest.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,223 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++static const char test[][60] = { ++ "", ++ "abc", ++ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ++}; ++ ++static const unsigned char ret[][SHA_DIGEST_LENGTH] = { ++ {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, ++ 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}, ++ {0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, ++ 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d}, ++ {0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, ++ 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1}, ++}; ++ ++int FIPS_selftest_sha1() ++{ ++ int n; ++ ++ for (n = 0; n < sizeof(test) / sizeof(test[0]); ++n) { ++ unsigned char md[SHA_DIGEST_LENGTH]; ++ ++ EVP_Digest(test[n], strlen(test[n]), md, NULL, ++ EVP_sha1(), NULL); ++ if (memcmp(md, ret[n], sizeof md)) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++static const unsigned char msg_sha256[] = ++ { 0xfa, 0x48, 0x59, 0x2a, 0xe1, 0xae, 0x1f, 0x30, ++ 0xfc ++}; ++ ++static const unsigned char dig_sha256[] = ++ { 0xf7, 0x26, 0xd8, 0x98, 0x47, 0x91, 0x68, 0x5b, ++ 0x9e, 0x39, 0xb2, 0x58, 0xbb, 0x75, 0xbf, 0x01, ++ 0x17, 0x0c, 0x84, 0x00, 0x01, 0x7a, 0x94, 0x83, ++ 0xf3, 0x0b, 0x15, 0x84, 0x4b, 0x69, 0x88, 0x8a ++}; ++ ++static const unsigned char msg_sha512[] = ++ { 0x37, 0xd1, 0x35, 0x9d, 0x18, 0x41, 0xe9, 0xb7, ++ 0x6d, 0x9a, 0x13, 0xda, 0x5f, 0xf3, 0xbd ++}; ++ ++static const unsigned char dig_sha512[] = ++ { 0x11, 0x13, 0xc4, 0x19, 0xed, 0x2b, 0x1d, 0x16, ++ 0x11, 0xeb, 0x9b, 0xbe, 0xf0, 0x7f, 0xcf, 0x44, ++ 0x8b, 0xd7, 0x57, 0xbd, 0x8d, 0xa9, 0x25, 0xb0, ++ 0x47, 0x25, 0xd6, 0x6c, 0x9a, 0x54, 0x7f, 0x8f, ++ 0x0b, 0x53, 0x1a, 0x10, 0x68, 0x32, 0x03, 0x38, ++ 0x82, 0xc4, 0x87, 0xc4, 0xea, 0x0e, 0xd1, 0x04, ++ 0xa9, 0x98, 0xc1, 0x05, 0xa3, 0xf3, 0xf8, 0xb1, ++ 0xaf, 0xbc, 0xd9, 0x78, 0x7e, 0xee, 0x3d, 0x43 ++}; ++ ++int FIPS_selftest_sha2(void) ++{ ++ unsigned char md[SHA512_DIGEST_LENGTH]; ++ ++ EVP_Digest(msg_sha256, sizeof(msg_sha256), md, NULL, EVP_sha256(), NULL); ++ if (memcmp(dig_sha256, md, sizeof(dig_sha256))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_SHA2, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ EVP_Digest(msg_sha512, sizeof(msg_sha512), md, NULL, EVP_sha512(), NULL); ++ if (memcmp(dig_sha512, md, sizeof(dig_sha512))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_SHA2, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static const unsigned char msg_sha3_256[] = { ++ 0xa1, 0xd7, 0xce, 0x51, 0x04, 0xeb, 0x25, 0xd6, ++ 0x13, 0x1b, 0xb8, 0xf6, 0x6e, 0x1f, 0xb1, 0x3f, ++ 0x35, 0x23 ++}; ++ ++static const unsigned char dig_sha3_256[] = { ++ 0xee, 0x90, 0x62, 0xf3, 0x97, 0x20, 0xb8, 0x21, ++ 0xb8, 0x8b, 0xe5, 0xe6, 0x46, 0x21, 0xd7, 0xe0, ++ 0xca, 0x02, 0x6a, 0x9f, 0xe7, 0x24, 0x8d, 0x78, ++ 0x15, 0x0b, 0x14, 0xbd, 0xba, 0xa4, 0x0b, 0xed ++}; ++ ++static const unsigned char msg_sha3_512[] = { ++ 0x13, 0x3b, 0x49, 0x7b, 0x00, 0x93, 0x27, 0x73, ++ 0xa5, 0x3b, 0xa9, 0xbf, 0x8e, 0x61, 0xd5, 0x9f, ++ 0x05, 0xf4 ++}; ++ ++static const unsigned char dig_sha3_512[] = { ++ 0x78, 0x39, 0x64, 0xa1, 0xcf, 0x41, 0xd6, 0xd2, ++ 0x10, 0xa8, 0xd7, 0xc8, 0x1c, 0xe6, 0x97, 0x0a, ++ 0xa6, 0x2c, 0x90, 0x53, 0xcb, 0x89, 0xe1, 0x5f, ++ 0x88, 0x05, 0x39, 0x57, 0xec, 0xf6, 0x07, 0xf4, ++ 0x2a, 0xf0, 0x88, 0x04, 0xe7, 0x6f, 0x2f, 0xbd, ++ 0xbb, 0x31, 0x80, 0x9c, 0x9e, 0xef, 0xc6, 0x0e, ++ 0x23, 0x3d, 0x66, 0x24, 0x36, 0x7a, 0x3b, 0x9c, ++ 0x30, 0xf8, 0xee, 0x5f, 0x65, 0xbe, 0x56, 0xac ++}; ++ ++static const unsigned char msg_shake_128[] = { ++ 0x43, 0xbd, 0xb1, 0x1e, 0xac, 0x71, 0x03, 0x1f, ++ 0x02, 0xa1, 0x1c, 0x15, 0xa1, 0x88, 0x5f, 0xa4, ++ 0x28, 0x98 ++}; ++ ++static const unsigned char dig_shake_128[] = { ++ 0xde, 0x68, 0x02, 0x7d, 0xa1, 0x30, 0x66, 0x3a, ++ 0x73, 0x98, 0x0e, 0x35, 0x25, 0xb8, 0x8c, 0x75 ++}; ++ ++static const unsigned char msg_shake_256[] = { ++ 0x8f, 0x84, 0xa3, 0x7d, 0xbd, 0x44, 0xd0, 0xf6, ++ 0x95, 0x36, 0xc5, 0xf4, 0x44, 0x6b, 0xa3, 0x23, ++ 0x9b, 0xfc ++}; ++ ++static const unsigned char dig_shake_256[] = { ++ 0x05, 0xca, 0x83, 0x5e, 0x0c, 0xdb, 0xfa, 0xf5, ++ 0x95, 0xc6, 0x86, 0x7e, 0x2d, 0x9d, 0xb9, 0x3f, ++ 0xca, 0x9c, 0x8b, 0xc6, 0x65, 0x02, 0x2e, 0xdd, ++ 0x6f, 0xe7, 0xb3, 0xda, 0x5e, 0x07, 0xc4, 0xcf ++}; ++ ++int FIPS_selftest_sha3(void) ++{ ++ unsigned char md[SHA512_DIGEST_LENGTH]; ++ ++ EVP_Digest(msg_sha3_256, sizeof(msg_sha3_256), md, NULL, EVP_sha3_256(), NULL); ++ if (memcmp(dig_sha3_256, md, sizeof(dig_sha3_256))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ EVP_Digest(msg_sha3_512, sizeof(msg_sha3_512), md, NULL, EVP_sha3_512(), NULL); ++ if (memcmp(dig_sha3_512, md, sizeof(dig_sha3_512))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ EVP_Digest(msg_shake_128, sizeof(msg_shake_128), md, NULL, EVP_shake128(), NULL); ++ if (memcmp(dig_shake_128, md, sizeof(dig_shake_128))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ EVP_Digest(msg_shake_256, sizeof(msg_shake_256), md, NULL, EVP_shake256(), NULL); ++ if (memcmp(dig_shake_256, md, sizeof(dig_shake_256))) { ++ FIPSerr(FIPS_F_FIPS_SELFTEST, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++#endif +diff -up openssl-1.1.1j/crypto/fips/fips_standalone_hmac.c.fips openssl-1.1.1j/crypto/fips/fips_standalone_hmac.c +--- openssl-1.1.1j/crypto/fips/fips_standalone_hmac.c.fips 2021-03-03 12:57:42.201734542 +0100 ++++ openssl-1.1.1j/crypto/fips/fips_standalone_hmac.c 2021-03-03 12:57:42.201734542 +0100 +@@ -0,0 +1,127 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int main(int argc, char **argv) ++{ ++#ifdef OPENSSL_FIPS ++ static char key[] = "orboDeJITITejsirpADONivirpUkvarP"; ++ int n, binary = 0; ++ ++ if (argc < 2) { ++ fprintf(stderr, "%s []+\n", argv[0]); ++ exit(1); ++ } ++ ++ n = 1; ++ if (!strcmp(argv[n], "-binary")) { ++ n++; ++ binary = 1; /* emit binary fingerprint... */ ++ } ++ ++ for (; n < argc; ++n) { ++ FILE *f = fopen(argv[n], "rb"); ++ HMAC_CTX *hmac_ctx; ++ unsigned char mac[EVP_MAX_MD_SIZE]; ++ unsigned int len; ++ unsigned int i; ++ ++ if (!f) { ++ perror(argv[n]); ++ exit(2); ++ } ++ hmac_ctx = HMAC_CTX_new(); ++ if (!hmac_ctx) ++ exit(3); ++ ++ if (HMAC_Init_ex(hmac_ctx, key, strlen(key), EVP_sha256(), NULL) <= 0) { ++ fprintf(stderr, "HMAC SHA256 initialization failed.\n"); ++ exit(4); ++ } ++ ++ for (;;) { ++ unsigned char buf[1024]; ++ size_t l = fread(buf, 1, sizeof buf, f); ++ ++ if (l == 0) { ++ if (ferror(f)) { ++ perror(argv[n]); ++ exit(3); ++ } else ++ break; ++ } ++ if (HMAC_Update(hmac_ctx, buf, l) <= 0) { ++ fprintf(stderr, "HMAC_Update() failed.\n"); ++ exit(4); ++ } ++ } ++ if (HMAC_Final(hmac_ctx, mac, &len) <= 0) { ++ fprintf(stderr, "HMAC_Final() failed.\n"); ++ exit(4); ++ } ++ ++ if (binary) { ++ fwrite(mac, len, 1, stdout); ++ break; /* ... for single(!) file */ ++ } ++ ++/* printf("HMAC-SHA1(%s)= ",argv[n]); */ ++ for (i = 0; i < len; ++i) ++ printf("%02x", mac[i]); ++ printf("\n"); ++ } ++#endif ++ return 0; ++} +diff -up openssl-1.1.1j/crypto/hmac/hmac.c.fips openssl-1.1.1j/crypto/hmac/hmac.c +--- openssl-1.1.1j/crypto/hmac/hmac.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/hmac/hmac.c 2021-03-03 12:57:42.202734550 +0100 +@@ -44,6 +44,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo + return 0; + + if (key != NULL) { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(EVP_MD_flags(md) & EVP_MD_FLAG_FIPS) ++ && (!EVP_MD_CTX_test_flags(ctx->md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) ++ || !EVP_MD_CTX_test_flags(ctx->i_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) ++ || !EVP_MD_CTX_test_flags(ctx->o_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) ++ goto err; ++#endif + reset = 1; + + j = EVP_MD_block_size(md); +diff -up openssl-1.1.1j/crypto/hmac/hm_pmeth.c.fips openssl-1.1.1j/crypto/hmac/hm_pmeth.c +--- openssl-1.1.1j/crypto/hmac/hm_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/hmac/hm_pmeth.c 2021-03-03 12:57:42.202734550 +0100 +@@ -180,7 +180,7 @@ static int pkey_hmac_ctrl_str(EVP_PKEY_C + + const EVP_PKEY_METHOD hmac_pkey_meth = { + EVP_PKEY_HMAC, +- 0, ++ EVP_PKEY_FLAG_FIPS, + pkey_hmac_init, + pkey_hmac_copy, + pkey_hmac_cleanup, +diff -up openssl-1.1.1j/crypto/o_fips.c.fips openssl-1.1.1j/crypto/o_fips.c +--- openssl-1.1.1j/crypto/o_fips.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/o_fips.c 2021-03-03 12:57:42.202734550 +0100 +@@ -8,17 +8,28 @@ + */ + + #include "internal/cryptlib.h" ++#include "crypto/fips.h" + + int FIPS_mode(void) + { ++#ifdef OPENSSL_FIPS ++ return FIPS_module_mode(); ++#else + /* This version of the library does not support FIPS mode. */ + return 0; ++#endif + } + + int FIPS_mode_set(int r) + { ++#ifdef OPENSSL_FIPS ++ if (r && FIPS_module_mode()) /* can be implicitly initialized by OPENSSL_init() */ ++ return 1; ++ return FIPS_module_mode_set(r); ++#else + if (r == 0) + return 1; + CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); + return 0; ++#endif + } +diff -up openssl-1.1.1j/crypto/o_init.c.fips openssl-1.1.1j/crypto/o_init.c +--- openssl-1.1.1j/crypto/o_init.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/o_init.c 2021-03-03 12:57:42.202734550 +0100 +@@ -7,8 +7,69 @@ + * https://www.openssl.org/source/license.html + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include "e_os.h" + #include ++#ifdef OPENSSL_FIPS ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include "crypto/fips.h" ++ ++# define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" ++ ++static void init_fips_mode(void) ++{ ++ char buf[2] = "0"; ++ int fd; ++ ++ if (secure_getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) { ++ buf[0] = '1'; ++ } else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) { ++ while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR) ; ++ close(fd); ++ } ++ ++ if (buf[0] != '1' && !FIPS_module_installed()) ++ return; ++ ++ /* Ensure the selftests always run */ ++ /* XXX: TO SOLVE - premature initialization due to selftests */ ++ FIPS_mode_set(1); ++ ++ /* Failure reading the fips mode switch file means just not ++ * switching into FIPS mode. We would break too many things ++ * otherwise.. ++ */ ++ ++ if (buf[0] != '1') { ++ /* drop down to non-FIPS mode if it is not requested */ ++ FIPS_mode_set(0); ++ } else { ++ /* abort if selftest failed */ ++ FIPS_selftest_check(); ++ } ++} ++ ++/* ++ * Perform FIPS module power on selftest and automatic FIPS mode switch. ++ */ ++ ++void __attribute__ ((constructor)) OPENSSL_init_library(void) ++{ ++ static int done = 0; ++ if (done) ++ return; ++ done = 1; ++ init_fips_mode(); ++} ++#endif + + /* + * Perform any essential OpenSSL initialization operations. Currently does +diff -up openssl-1.1.1j/crypto/rand/rand_lib.c.fips openssl-1.1.1j/crypto/rand/rand_lib.c +--- openssl-1.1.1j/crypto/rand/rand_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rand/rand_lib.c 2021-03-03 12:57:42.202734550 +0100 +@@ -16,6 +16,10 @@ + #include "internal/thread_once.h" + #include "rand_local.h" + #include "e_os.h" ++#ifdef OPENSSL_FIPS ++# include ++# include ++#endif + + #ifndef OPENSSL_NO_ENGINE + /* non-NULL if default_RAND_meth is ENGINE-provided */ +@@ -959,3 +963,15 @@ int RAND_status(void) + return meth->status(); + return 0; + } ++ ++#ifdef OPENSSL_FIPS ++void RAND_set_fips_drbg_type(int type, int flags) ++{ /* just a stub for ABI compatibility */ ++} ++ ++int RAND_init_fips(void) ++{ ++ /* just a stub for ABI compatibility */ ++ return 1; ++} ++#endif +diff -up openssl-1.1.1j/crypto/rsa/rsa_crpt.c.fips openssl-1.1.1j/crypto/rsa/rsa_crpt.c +--- openssl-1.1.1j/crypto/rsa/rsa_crpt.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_crpt.c 2021-03-03 12:57:42.202734550 +0100 +@@ -27,24 +27,52 @@ int RSA_size(const RSA *r) + int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) ++ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); ++ return -1; ++ } ++#endif + return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding); + } + + int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ++ RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); ++ return -1; ++ } ++#endif + return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding); + } + + int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) ++ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); ++ return -1; ++ } ++#endif + return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding); + } + + int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, ++ RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); ++ return -1; ++ } ++#endif + return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding); + } + +diff -up openssl-1.1.1j/crypto/rsa/rsa_err.c.fips openssl-1.1.1j/crypto/rsa/rsa_err.c +--- openssl-1.1.1j/crypto/rsa/rsa_err.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_err.c 2021-03-03 12:57:42.202734550 +0100 +@@ -16,6 +16,8 @@ + static const ERR_STRING_DATA RSA_str_functs[] = { + {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, 0), "check_padding_md"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_ENCODE_PKCS1, 0), "encode_pkcs1"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_FIPS_RSA_BUILTIN_KEYGEN, 0), ++ "fips_rsa_builtin_keygen"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_INT_RSA_VERIFY, 0), "int_rsa_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, 0), + "old_rsa_priv_decode"}, +@@ -32,6 +34,9 @@ static const ERR_STRING_DATA RSA_str_fun + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_KEY_EX, 0), "RSA_generate_key_ex"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_GENERATE_MULTI_PRIME_KEY, 0), ++ "RSA_generate_multi_prime_key"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_DUP, 0), "RSA_meth_dup"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_NEW, 0), "RSA_meth_new"}, +@@ -90,9 +95,13 @@ static const ERR_STRING_DATA RSA_str_fun + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, 0), "RSA_private_decrypt"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, 0), "RSA_private_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_DECRYPT, 0), "RSA_public_decrypt"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUBLIC_ENCRYPT, 0), "RSA_public_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), +@@ -102,6 +111,8 @@ static const ERR_STRING_DATA RSA_str_fun + "RSA_verify_ASN1_OCTET_STRING"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), + "RSA_verify_PKCS1_PSS_mgf1"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_DEFAULT_METHOD, 0), "RSA_set_default_method"}, ++ {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SET_METHOD, 0), "RSA_set_method"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, + {0, NULL} + }; +@@ -183,6 +194,7 @@ static const ERR_STRING_DATA RSA_str_rea + "mp exponent not congruent to d"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, ++ {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NON_FIPS_RSA_METHOD), "non FIPS rsa method"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), + "null before block missing"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), +@@ -191,6 +203,8 @@ static const ERR_STRING_DATA RSA_str_rea + "n does not equal p q"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), + "oaep decoding error"}, ++ {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), ++ "operation not allowed in FIPS mode"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), +@@ -226,6 +240,8 @@ static const ERR_STRING_DATA RSA_str_rea + "unsupported mask algorithm"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_PARAMETER), + "unsupported mask parameter"}, ++ {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_PARAMETERS), ++ "unsupported parameters"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE), + "unsupported signature type"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_VALUE_MISSING), "value missing"}, +diff -up openssl-1.1.1j/crypto/rsa/rsa_gen.c.fips openssl-1.1.1j/crypto/rsa/rsa_gen.c +--- openssl-1.1.1j/crypto/rsa/rsa_gen.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_gen.c 2021-03-03 12:57:42.202734550 +0100 +@@ -18,6 +18,76 @@ + #include "internal/cryptlib.h" + #include + #include "rsa_local.h" ++#ifdef OPENSSL_FIPS ++# include ++# include "crypto/fips.h" ++ ++int fips_check_rsa(RSA *rsa) ++{ ++ const unsigned char tbs[] = "RSA Pairwise Check Data"; ++ unsigned char *ctbuf = NULL, *ptbuf = NULL; ++ int len, ret = 0; ++ EVP_PKEY *pk; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_RSA(pk, rsa); ++ ++ /* Perform pairwise consistency signature test */ ++ if (!fips_pkey_signature_test(pk, tbs, -1, ++ NULL, 0, EVP_sha256(), ++ EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) ++ || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha256(), ++ EVP_MD_CTX_FLAG_PAD_PSS, NULL)) ++ goto err; ++ /* Now perform pairwise consistency encrypt/decrypt test */ ++ ctbuf = OPENSSL_malloc(RSA_size(rsa)); ++ if (!ctbuf) ++ goto err; ++ ++ len = ++ RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, ++ RSA_PKCS1_PADDING); ++ if (len <= 0) ++ goto err; ++ /* Check ciphertext doesn't match plaintext */ ++ if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) ++ goto err; ++ ptbuf = OPENSSL_malloc(RSA_size(rsa)); ++ ++ if (!ptbuf) ++ goto err; ++ len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); ++ if (len != (sizeof(tbs) - 1)) ++ goto err; ++ if (memcmp(ptbuf, tbs, len)) ++ goto err; ++ ++ ret = 1; ++ ++ if (!ptbuf) ++ goto err; ++ ++ err: ++ if (ret == 0) { ++ fips_set_selftest_fail(); ++ FIPSerr(FIPS_F_FIPS_CHECK_RSA, FIPS_R_PAIRWISE_TEST_FAILED); ++ } ++ ++ if (ctbuf) ++ OPENSSL_free(ctbuf); ++ if (ptbuf) ++ OPENSSL_free(ptbuf); ++ if (pk) ++ EVP_PKEY_free(pk); ++ ++ return ret; ++} ++ ++static int fips_rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, ++ BN_GENCB *cb); ++#endif + + static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, + BN_GENCB *cb); +@@ -31,6 +101,13 @@ static int rsa_builtin_keygen(RSA *rsa, + */ + int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) ++ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); ++ return 0; ++ } ++#endif + if (rsa->meth->rsa_keygen != NULL) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + +@@ -41,6 +118,13 @@ int RSA_generate_key_ex(RSA *rsa, int bi + int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) ++ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_GENERATE_MULTI_PRIME_KEY, RSA_R_NON_FIPS_RSA_METHOD); ++ return 0; ++ } ++#endif + /* multi-prime is only supported with the builtin key generation */ + if (rsa->meth->rsa_multi_prime_keygen != NULL) { + return rsa->meth->rsa_multi_prime_keygen(rsa, bits, primes, +@@ -57,10 +141,285 @@ int RSA_generate_multi_prime_key(RSA *rs + else + return 0; + } +- ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (primes != 2) { ++ RSAerr(RSA_F_RSA_GENERATE_MULTI_PRIME_KEY, RSA_R_UNSUPPORTED_PARAMETERS); ++ return 0; ++ } ++ return fips_rsa_builtin_keygen(rsa, bits, e_value, cb); ++ } ++#endif + return rsa_builtin_keygen(rsa, bits, primes, e_value, cb); + } + ++#ifdef OPENSSL_FIPS ++static int fips_rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, ++ BN_GENCB *cb) ++{ ++ BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; ++ BN_CTX *ctx = NULL; ++ int ok = -1; ++ int i; ++ int n = 0; ++ int test = 0; ++ int pbits = bits / 2; ++ unsigned long error = 0; ++ ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_FIPS_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS ++ || (getenv("OPENSSL_ENFORCE_MODULUS_BITS") && bits < 2048)) { ++ FIPSerr(FIPS_F_FIPS_RSA_BUILTIN_KEYGEN, FIPS_R_KEY_TOO_SHORT); ++ return 0; ++ } ++ if ((pbits & 0xFF) != 0) { ++ FIPSerr(FIPS_F_FIPS_RSA_BUILTIN_KEYGEN, FIPS_R_INVALID_KEY_LENGTH); ++ return 0; ++ } ++ ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ BN_CTX_start(ctx); ++ r0 = BN_CTX_get(ctx); ++ r1 = BN_CTX_get(ctx); ++ r2 = BN_CTX_get(ctx); ++ r3 = BN_CTX_get(ctx); ++ ++ if (r3 == NULL) ++ goto err; ++ ++ /* We need the RSA components non-NULL */ ++ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL)) ++ goto err; ++ if (!rsa->e && ((rsa->e = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL)) ++ goto err; ++ if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL)) ++ goto err; ++ if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL)) ++ goto err; ++ if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL)) ++ goto err; ++ if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL)) ++ goto err; ++ ++ if (!BN_set_word(r0, RSA_F4)) ++ goto err; ++ if (BN_cmp(e_value, r0) < 0 || BN_num_bits(e_value) > 256) { ++ ok = 0; /* we set our own err */ ++ RSAerr(RSA_F_FIPS_RSA_BUILTIN_KEYGEN, RSA_R_BAD_E_VALUE); ++ goto err; ++ } ++ ++ /* prepare approximate minimum p and q */ ++ if (!BN_set_word(r0, 0xB504F334)) ++ goto err; ++ if (!BN_lshift(r0, r0, pbits - 32)) ++ goto err; ++ ++ /* prepare minimum p and q difference */ ++ if (!BN_one(r3)) ++ goto err; ++ if (!BN_lshift(r3, r3, pbits - 100)) ++ goto err; ++ ++ BN_copy(rsa->e, e_value); ++ ++ if (!BN_is_zero(rsa->p) && !BN_is_zero(rsa->q)) ++ test = 1; ++ ++ BN_set_flags(r0, BN_FLG_CONSTTIME); ++ BN_set_flags(r1, BN_FLG_CONSTTIME); ++ BN_set_flags(r2, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->p, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->q, BN_FLG_CONSTTIME); ++ ++ retry: ++ /* generate p and q */ ++ for (i = 0; i < 5 * pbits; i++) { ++ ploop: ++ if (!test) ++ if (!BN_rand(rsa->p, pbits, 0, 1)) ++ goto err; ++ if (BN_cmp(rsa->p, r0) < 0) { ++ if (test) ++ goto err; ++ goto ploop; ++ } ++ ++ if (!BN_sub(r2, rsa->p, BN_value_one())) ++ goto err; ++ ERR_set_mark(); ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ ++ int r; ++ r = BN_is_prime_fasttest_ex(rsa->p, pbits > 1024 ? 4 : 5, ctx, 0, ++ cb); ++ if (r == -1 || (test && r <= 0)) ++ goto err; ++ if (r > 0) ++ break; ++ } else { ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_pop_to_mark(); ++ } else { ++ goto err; ++ } ++ } ++ if (!BN_GENCB_call(cb, 2, n++)) ++ goto err; ++ } ++ ++ if (!BN_GENCB_call(cb, 3, 0)) ++ goto err; ++ ++ if (i >= 5 * pbits) ++ /* prime not found */ ++ goto err; ++ ++ for (i = 0; i < 5 * pbits; i++) { ++ qloop: ++ if (!test) ++ if (!BN_rand(rsa->q, pbits, 0, 1)) ++ goto err; ++ if (BN_cmp(rsa->q, r0) < 0) { ++ if (test) ++ goto err; ++ goto qloop; ++ } ++ if (!BN_sub(r2, rsa->q, rsa->p)) ++ goto err; ++ if (BN_ucmp(r2, r3) <= 0) { ++ if (test) ++ goto err; ++ goto qloop; ++ } ++ ++ if (!BN_sub(r2, rsa->q, BN_value_one())) ++ goto err; ++ ERR_set_mark(); ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ ++ int r; ++ r = BN_is_prime_fasttest_ex(rsa->q, pbits > 1024 ? 4 : 5, ctx, 0, ++ cb); ++ if (r == -1 || (test && r <= 0)) ++ goto err; ++ if (r > 0) ++ break; ++ } else { ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_pop_to_mark(); ++ } else { ++ goto err; ++ } ++ } ++ if (!BN_GENCB_call(cb, 2, n++)) ++ goto err; ++ } ++ ++ if (!BN_GENCB_call(cb, 3, 1)) ++ goto err; ++ ++ if (i >= 5 * pbits) ++ /* prime not found */ ++ goto err; ++ ++ if (test) { ++ /* do not try to calculate the remaining key values */ ++ BN_clear(rsa->n); ++ ok = 1; ++ goto err; ++ } ++ ++ if (BN_cmp(rsa->p, rsa->q) < 0) { ++ tmp = rsa->p; ++ rsa->p = rsa->q; ++ rsa->q = tmp; ++ } ++ ++ /* calculate n */ ++ if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) ++ goto err; ++ ++ /* calculate d */ ++ if (!BN_sub(r1, rsa->p, BN_value_one())) ++ goto err; /* p-1 */ ++ if (!BN_sub(r2, rsa->q, BN_value_one())) ++ goto err; /* q-1 */ ++ ++ /* note that computing gcd is not safe to timing attacks */ ++ if (!BN_gcd(r0, r1, r2, ctx)) ++ goto err; ++ ++ { ++ if (!BN_div(r0, NULL, r1, r0, ctx)) ++ goto err; ++ ++ if (!BN_mul(r0, r0, r2, ctx)) /* lcm(p-1, q-1) */ ++ goto err; ++ ++ if (!BN_mod_inverse(rsa->d, rsa->e, r0, ctx)) /* d */ ++ goto err; ++ } ++ ++ if (BN_num_bits(rsa->d) < pbits) ++ goto retry; /* d is too small */ ++ ++ { ++ BIGNUM *d = BN_new(); ++ ++ if (d == NULL) ++ goto err; ++ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); ++ ++ if (/* calculate d mod (p-1) */ ++ !BN_mod(rsa->dmp1, d, r1, ctx) ++ /* calculate d mod (q-1) */ ++ || !BN_mod(rsa->dmq1, d, r2, ctx)) { ++ BN_free(d); ++ goto err; ++ } ++ /* We MUST free d before any further use of rsa->d */ ++ BN_free(d); ++ } ++ ++ /* calculate inverse of q mod p */ ++ if (!BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) ++ goto err; ++ ++ if (!fips_check_rsa(rsa)) ++ goto err; ++ ++ ok = 1; ++ err: ++ if (ok == -1) { ++ RSAerr(RSA_F_FIPS_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); ++ ok = 0; ++ } ++ if (ctx != NULL) { ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ } ++ ++ return ok; ++} ++#endif ++ + static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, + BN_GENCB *cb) + { +diff -up openssl-1.1.1j/crypto/rsa/rsa_lib.c.fips openssl-1.1.1j/crypto/rsa/rsa_lib.c +--- openssl-1.1.1j/crypto/rsa/rsa_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_lib.c 2021-03-03 12:57:42.203734558 +0100 +@@ -34,6 +34,12 @@ int RSA_set_method(RSA *rsa, const RSA_M + * to deal with which ENGINE it comes from. + */ + const RSA_METHOD *mtmp; ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) { ++ RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_RSA_METHOD); ++ return 0; ++ } ++#endif + mtmp = rsa->meth; + if (mtmp->finish) + mtmp->finish(rsa); +@@ -66,7 +72,6 @@ RSA *RSA_new_method(ENGINE *engine) + + ret->meth = RSA_get_default_method(); + #ifndef OPENSSL_NO_ENGINE +- ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + if (engine) { + if (!ENGINE_init(engine)) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); +@@ -84,8 +89,19 @@ RSA *RSA_new_method(ENGINE *engine) + } + } + #endif ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) { ++ RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_RSA_METHOD); ++# ifndef OPENSSL_NO_ENGINE ++ if (ret->engine) ++ ENGINE_finish(ret->engine); ++# endif ++ OPENSSL_free(ret); ++ return NULL; ++ } ++#endif + +- ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; ++ ret->flags = ret->meth->flags; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { + goto err; + } +diff -up openssl-1.1.1j/crypto/rsa/rsa_ossl.c.fips openssl-1.1.1j/crypto/rsa/rsa_ossl.c +--- openssl-1.1.1j/crypto/rsa/rsa_ossl.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_ossl.c 2021-03-03 12:57:42.203734558 +0100 +@@ -12,6 +12,10 @@ + #include "rsa_local.h" + #include "internal/constant_time.h" + ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ + static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, +@@ -47,6 +51,12 @@ static const RSA_METHOD *default_RSA_met + + void RSA_set_default_method(const RSA_METHOD *meth) + { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) { ++ RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_RSA_METHOD); ++ return; ++ } ++#endif + default_RSA_meth = meth; + } + +@@ -73,6 +83,22 @@ static int rsa_ossl_public_encrypt(int f + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_RSA_OSSL_PUBLIC_ENCRYPT, ++ FIPS_R_FIPS_SELFTEST_FAILED); ++ goto err; ++ } ++ ++ if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { ++ RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); ++ return -1; ++ } ++ } ++# endif ++ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; +@@ -246,6 +272,22 @@ static int rsa_ossl_private_encrypt(int + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_RSA_OSSL_PRIVATE_ENCRYPT, ++ FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++ ++ if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { ++ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); ++ return -1; ++ } ++ } ++# endif ++ + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); +@@ -380,6 +422,22 @@ static int rsa_ossl_private_decrypt(int + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_RSA_OSSL_PRIVATE_DECRYPT, ++ FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++ ++ if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { ++ RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); ++ return -1; ++ } ++ } ++# endif ++ + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); +@@ -507,6 +565,22 @@ static int rsa_ossl_public_decrypt(int f + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + ++# ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_RSA_OSSL_PUBLIC_DECRYPT, ++ FIPS_R_FIPS_SELFTEST_FAILED); ++ goto err; ++ } ++ ++ if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) ++ && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { ++ RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); ++ return -1; ++ } ++ } ++# endif ++ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; +diff -up openssl-1.1.1j/crypto/rsa/rsa_pmeth.c.fips openssl-1.1.1j/crypto/rsa/rsa_pmeth.c +--- openssl-1.1.1j/crypto/rsa/rsa_pmeth.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_pmeth.c 2021-03-03 12:57:42.203734558 +0100 +@@ -756,7 +756,7 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX + + const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, +- EVP_PKEY_FLAG_AUTOARGLEN, ++ EVP_PKEY_FLAG_AUTOARGLEN | EVP_PKEY_FLAG_FIPS, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, +@@ -838,7 +838,7 @@ static int pkey_pss_init(EVP_PKEY_CTX *c + + const EVP_PKEY_METHOD rsa_pss_pkey_meth = { + EVP_PKEY_RSA_PSS, +- EVP_PKEY_FLAG_AUTOARGLEN, ++ EVP_PKEY_FLAG_AUTOARGLEN | EVP_PKEY_FLAG_FIPS, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, +diff -up openssl-1.1.1j/crypto/rsa/rsa_sign.c.fips openssl-1.1.1j/crypto/rsa/rsa_sign.c +--- openssl-1.1.1j/crypto/rsa/rsa_sign.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/rsa/rsa_sign.c 2021-03-03 12:57:42.203734558 +0100 +@@ -73,6 +73,13 @@ int RSA_sign(int type, const unsigned ch + unsigned char *tmps = NULL; + const unsigned char *encoded = NULL; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) ++ && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { ++ RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); ++ return 0; ++ } ++#endif + if (rsa->meth->rsa_sign) { + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); + } +@@ -100,8 +107,9 @@ int RSA_sign(int type, const unsigned ch + RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto err; + } +- encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, +- RSA_PKCS1_PADDING); ++ /* NB: call underlying method directly to avoid FIPS blocking */ ++ encrypt_len = rsa->meth->rsa_priv_enc ? rsa->meth->rsa_priv_enc(encoded_len, encoded, sigret, rsa, ++ RSA_PKCS1_PADDING) : 0; + if (encrypt_len <= 0) + goto err; + +diff -up openssl-1.1.1j/crypto/sha/sha256.c.fips openssl-1.1.1j/crypto/sha/sha256.c +--- openssl-1.1.1j/crypto/sha/sha256.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/sha/sha256.c 2021-03-03 12:57:42.203734558 +0100 +@@ -18,6 +18,9 @@ + + int SHA224_Init(SHA256_CTX *c) + { ++# ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++# endif + memset(c, 0, sizeof(*c)); + c->h[0] = 0xc1059ed8UL; + c->h[1] = 0x367cd507UL; +@@ -33,6 +36,9 @@ int SHA224_Init(SHA256_CTX *c) + + int SHA256_Init(SHA256_CTX *c) + { ++# ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++# endif + memset(c, 0, sizeof(*c)); + c->h[0] = 0x6a09e667UL; + c->h[1] = 0xbb67ae85UL; +diff -up openssl-1.1.1j/crypto/sha/sha512.c.fips openssl-1.1.1j/crypto/sha/sha512.c +--- openssl-1.1.1j/crypto/sha/sha512.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/crypto/sha/sha512.c 2021-03-03 12:57:42.203734558 +0100 +@@ -98,6 +98,9 @@ int sha512_256_init(SHA512_CTX *c) + + int SHA384_Init(SHA512_CTX *c) + { ++# ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++# endif + c->h[0] = U64(0xcbbb9d5dc1059ed8); + c->h[1] = U64(0x629a292a367cd507); + c->h[2] = U64(0x9159015a3070dd17); +@@ -116,6 +119,9 @@ int SHA384_Init(SHA512_CTX *c) + + int SHA512_Init(SHA512_CTX *c) + { ++# ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++# endif + c->h[0] = U64(0x6a09e667f3bcc908); + c->h[1] = U64(0xbb67ae8584caa73b); + c->h[2] = U64(0x3c6ef372fe94f82b); +diff -up openssl-1.1.1j/crypto/sha/sha_local.h.fips openssl-1.1.1j/crypto/sha/sha_local.h +--- openssl-1.1.1j/crypto/sha/sha_local.h.fips 2021-03-03 12:57:41.941732391 +0100 ++++ openssl-1.1.1j/crypto/sha/sha_local.h 2021-03-03 12:57:42.203734558 +0100 +@@ -52,6 +52,9 @@ void sha1_block_data_order(SHA_CTX *c, c + + int HASH_INIT(SHA_CTX *c) + { ++#if defined(OPENSSL_FIPS) ++ FIPS_selftest_check(); ++#endif + memset(c, 0, sizeof(*c)); + c->h0 = INIT_DATA_h0; + c->h1 = INIT_DATA_h1; +diff -up openssl-1.1.1j/doc/man3/DSA_generate_parameters.pod.fips openssl-1.1.1j/doc/man3/DSA_generate_parameters.pod +--- openssl-1.1.1j/doc/man3/DSA_generate_parameters.pod.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/doc/man3/DSA_generate_parameters.pod 2021-03-03 12:57:42.203734558 +0100 +@@ -30,8 +30,10 @@ B is the length of the prime p to + For lengths under 2048 bits, the length of q is 160 bits; for lengths + greater than or equal to 2048 bits, the length of q is set to 256 bits. + +-If B is NULL, the primes will be generated at random. +-If B is less than the length of q, an error is returned. ++If B is NULL, or it does not generate primes, the primes will be ++generated at random. ++If B is less than the length of q, an error is returned ++if old DSA parameter generation method is used as a backend. + + DSA_generate_parameters_ex() places the iteration count in + *B and a counter used for finding a generator in +diff -up openssl-1.1.1j/include/crypto/fips.h.fips openssl-1.1.1j/include/crypto/fips.h +--- openssl-1.1.1j/include/crypto/fips.h.fips 2021-03-03 12:57:42.202734550 +0100 ++++ openssl-1.1.1j/include/crypto/fips.h 2021-03-03 12:57:42.202734550 +0100 +@@ -0,0 +1,98 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++# error FIPS is disabled. ++#endif ++ ++#ifdef OPENSSL_FIPS ++ ++int FIPS_module_mode_set(int onoff); ++int FIPS_module_mode(void); ++int FIPS_module_installed(void); ++int FIPS_selftest_sha1(void); ++int FIPS_selftest_sha2(void); ++int FIPS_selftest_sha3(void); ++int FIPS_selftest_aes_ccm(void); ++int FIPS_selftest_aes_gcm(void); ++int FIPS_selftest_aes_xts(void); ++int FIPS_selftest_aes(void); ++int FIPS_selftest_des(void); ++int FIPS_selftest_rsa(void); ++int FIPS_selftest_dsa(void); ++int FIPS_selftest_ecdsa(void); ++int FIPS_selftest_ecdh(void); ++int FIPS_selftest_dh(void); ++void FIPS_drbg_stick(int onoff); ++int FIPS_selftest_hmac(void); ++int FIPS_selftest_drbg(void); ++int FIPS_selftest_cmac(void); ++ ++int fips_pkey_signature_test(EVP_PKEY *pkey, ++ const unsigned char *tbs, int tbslen, ++ const unsigned char *kat, ++ unsigned int katlen, ++ const EVP_MD *digest, ++ unsigned int md_flags, const char *fail_str); ++ ++int fips_cipher_test(EVP_CIPHER_CTX *ctx, ++ const EVP_CIPHER *cipher, ++ const unsigned char *key, ++ const unsigned char *iv, ++ const unsigned char *plaintext, ++ const unsigned char *ciphertext, int len); ++ ++void fips_set_selftest_fail(void); ++ ++void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr); ++ ++#endif +diff -up openssl-1.1.1j/include/openssl/crypto.h.fips openssl-1.1.1j/include/openssl/crypto.h +--- openssl-1.1.1j/include/openssl/crypto.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/crypto.h 2021-03-03 12:57:42.204734567 +0100 +@@ -331,6 +331,11 @@ int OPENSSL_isservice(void); + int FIPS_mode(void); + int FIPS_mode_set(int r); + ++# ifdef OPENSSL_FIPS ++/* die if FIPS selftest failed */ ++void FIPS_selftest_check(void); ++# endif ++ + void OPENSSL_init(void); + # ifdef OPENSSL_SYS_UNIX + void OPENSSL_fork_prepare(void); +diff -up openssl-1.1.1j/include/openssl/dherr.h.fips openssl-1.1.1j/include/openssl/dherr.h +--- openssl-1.1.1j/include/openssl/dherr.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/dherr.h 2021-03-03 12:57:42.204734567 +0100 +@@ -36,6 +36,9 @@ int ERR_load_DH_strings(void); + # define DH_F_DH_CMS_DECRYPT 114 + # define DH_F_DH_CMS_SET_PEERKEY 115 + # define DH_F_DH_CMS_SET_SHARED_INFO 116 ++# define DH_F_DH_COMPUTE_KEY 203 ++# define DH_F_DH_GENERATE_KEY 202 ++# define DH_F_DH_GENERATE_PARAMETERS_EX 201 + # define DH_F_DH_METH_DUP 117 + # define DH_F_DH_METH_NEW 118 + # define DH_F_DH_METH_SET1_NAME 119 +@@ -73,12 +76,14 @@ int ERR_load_DH_strings(void); + # define DH_R_INVALID_PARAMETER_NID 114 + # define DH_R_INVALID_PUBKEY 102 + # define DH_R_KDF_PARAMETER_ERROR 112 ++# define DH_R_KEY_SIZE_TOO_SMALL 201 + # define DH_R_KEYS_NOT_SET 108 + # define DH_R_MISSING_PUBKEY 125 + # define DH_R_MODULUS_TOO_LARGE 103 + # define DH_R_NOT_SUITABLE_GENERATOR 120 + # define DH_R_NO_PARAMETERS_SET 107 + # define DH_R_NO_PRIVATE_VALUE 100 ++# define DH_R_NON_FIPS_METHOD 202 + # define DH_R_PARAMETER_ENCODING_ERROR 105 + # define DH_R_PEER_KEY_ERROR 111 + # define DH_R_SHARED_INFO_ERROR 113 +diff -up openssl-1.1.1j/include/openssl/dh.h.fips openssl-1.1.1j/include/openssl/dh.h +--- openssl-1.1.1j/include/openssl/dh.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/dh.h 2021-03-03 12:57:42.204734567 +0100 +@@ -31,6 +31,7 @@ extern "C" { + # endif + + # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 ++# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN 2048 + + # define DH_FLAG_CACHE_MONT_P 0x01 + +diff -up openssl-1.1.1j/include/openssl/dsaerr.h.fips openssl-1.1.1j/include/openssl/dsaerr.h +--- openssl-1.1.1j/include/openssl/dsaerr.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/dsaerr.h 2021-03-03 12:57:42.204734567 +0100 +@@ -29,8 +29,11 @@ int ERR_load_DSA_strings(void); + */ + # define DSA_F_DSAPARAMS_PRINT 100 + # define DSA_F_DSAPARAMS_PRINT_FP 101 ++# define DSA_F_DSA_BUILTIN_KEYGEN 202 + # define DSA_F_DSA_BUILTIN_PARAMGEN 125 + # define DSA_F_DSA_BUILTIN_PARAMGEN2 126 ++# define DSA_F_DSA_GENERATE_KEY 201 ++# define DSA_F_DSA_GENERATE_PARAMETERS_EX 200 + # define DSA_F_DSA_DO_SIGN 112 + # define DSA_F_DSA_DO_VERIFY 113 + # define DSA_F_DSA_METH_DUP 127 +@@ -60,10 +63,13 @@ int ERR_load_DSA_strings(void); + # define DSA_R_DECODE_ERROR 104 + # define DSA_R_INVALID_DIGEST_TYPE 106 + # define DSA_R_INVALID_PARAMETERS 112 ++# define DSA_R_KEY_SIZE_INVALID 201 ++# define DSA_R_KEY_SIZE_TOO_SMALL 202 + # define DSA_R_MISSING_PARAMETERS 101 + # define DSA_R_MISSING_PRIVATE_KEY 111 + # define DSA_R_MODULUS_TOO_LARGE 103 + # define DSA_R_NO_PARAMETERS_SET 107 ++# define DSA_R_NON_FIPS_DSA_METHOD 200 + # define DSA_R_PARAMETER_ENCODING_ERROR 105 + # define DSA_R_Q_NOT_PRIME 113 + # define DSA_R_SEED_LEN_SMALL 110 +diff -up openssl-1.1.1j/include/openssl/dsa.h.fips openssl-1.1.1j/include/openssl/dsa.h +--- openssl-1.1.1j/include/openssl/dsa.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/dsa.h 2021-03-03 12:57:42.204734567 +0100 +@@ -31,6 +31,7 @@ extern "C" { + # endif + + # define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 ++# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN 2048 + + # define DSA_FLAG_CACHE_MONT_P 0x01 + # if OPENSSL_API_COMPAT < 0x10100000L +diff -up openssl-1.1.1j/include/openssl/evperr.h.fips openssl-1.1.1j/include/openssl/evperr.h +--- openssl-1.1.1j/include/openssl/evperr.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/evperr.h 2021-03-03 12:57:42.204734567 +0100 +@@ -22,14 +22,15 @@ int ERR_load_EVP_strings(void); + * EVP function codes. + */ + # define EVP_F_AESNI_INIT_KEY 165 +-# define EVP_F_AESNI_XTS_INIT_KEY 207 ++# define EVP_F_AESNI_XTS_INIT_KEY 233 + # define EVP_F_AES_GCM_CTRL 196 + # define EVP_F_AES_INIT_KEY 133 + # define EVP_F_AES_OCB_CIPHER 169 + # define EVP_F_AES_T4_INIT_KEY 178 +-# define EVP_F_AES_T4_XTS_INIT_KEY 208 ++# define EVP_F_AES_T4_XTS_INIT_KEY 234 + # define EVP_F_AES_WRAP_CIPHER 170 +-# define EVP_F_AES_XTS_INIT_KEY 209 ++# define EVP_F_AES_XTS_CIPHER 229 ++# define EVP_F_AES_XTS_INIT_KEY 235 + # define EVP_F_ALG_MODULE_INIT 177 + # define EVP_F_ARIA_CCM_INIT_KEY 175 + # define EVP_F_ARIA_GCM_CTRL 197 +@@ -140,6 +141,7 @@ int ERR_load_EVP_strings(void); + # define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 + # define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 + # define EVP_R_DECODE_ERROR 114 ++# define EVP_R_DISABLED_FOR_FIPS 200 + # define EVP_R_DIFFERENT_KEY_TYPES 101 + # define EVP_R_DIFFERENT_PARAMETERS 153 + # define EVP_R_ERROR_LOADING_SECTION 165 +@@ -184,6 +186,7 @@ int ERR_load_EVP_strings(void); + # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 + # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 + # define EVP_R_PUBLIC_KEY_NOT_RSA 106 ++# define EVP_R_TOO_LARGE 201 + # define EVP_R_UNKNOWN_CIPHER 160 + # define EVP_R_UNKNOWN_DIGEST 161 + # define EVP_R_UNKNOWN_OPTION 169 +@@ -199,6 +202,7 @@ int ERR_load_EVP_strings(void); + # define EVP_R_UNSUPPORTED_SALT_TYPE 126 + # define EVP_R_WRAP_MODE_NOT_ALLOWED 170 + # define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +-# define EVP_R_XTS_DUPLICATED_KEYS 183 ++# define EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE 191 ++# define EVP_R_XTS_DUPLICATED_KEYS 192 + + #endif +diff -up openssl-1.1.1j/include/openssl/evp.h.fips openssl-1.1.1j/include/openssl/evp.h +--- openssl-1.1.1j/include/openssl/evp.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/evp.h 2021-03-03 12:57:42.204734567 +0100 +@@ -1324,6 +1324,9 @@ void EVP_PKEY_asn1_set_security_bits(EVP + */ + # define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + ++/* Downstream modification, large value to avoid conflict */ ++# define EVP_PKEY_FLAG_FIPS 0x4000 ++ + const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); + EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); + void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, +diff -up openssl-1.1.1j/include/openssl/fips.h.fips openssl-1.1.1j/include/openssl/fips.h +--- openssl-1.1.1j/include/openssl/fips.h.fips 2021-03-03 12:57:42.204734567 +0100 ++++ openssl-1.1.1j/include/openssl/fips.h 2021-03-03 12:57:42.204734567 +0100 +@@ -0,0 +1,187 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++# error FIPS is disabled. ++#endif ++ ++#ifdef OPENSSL_FIPS ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ int FIPS_selftest(void); ++ int FIPS_selftest_failed(void); ++ int FIPS_selftest_drbg_all(void); ++ ++ int FIPS_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, ++ const EVP_MD *evpmd, const unsigned char *seed_in, ++ size_t seed_len, int idx, unsigned char *seed_out, ++ int *counter_ret, unsigned long *h_ret, ++ BN_GENCB *cb); ++ int FIPS_dsa_paramgen_check_g(DSA *dsa); ++ ++/* BEGIN ERROR CODES */ ++/* The following lines are auto generated by the script mkerr.pl. Any changes ++ * made after this point may be overwritten when the script is next run. ++ */ ++ int ERR_load_FIPS_strings(void); ++ ++/* Error codes for the FIPS functions. */ ++ ++/* Function codes. */ ++# define FIPS_F_DH_BUILTIN_GENPARAMS 100 ++# define FIPS_F_DRBG_RESEED 121 ++# define FIPS_F_DSA_BUILTIN_PARAMGEN2 107 ++# define FIPS_F_DSA_DO_SIGN 102 ++# define FIPS_F_DSA_DO_VERIFY 103 ++# define FIPS_F_EVP_CIPHER_CTX_NEW 137 ++# define FIPS_F_EVP_CIPHER_CTX_RESET 122 ++# define FIPS_F_ECDH_COMPUTE_KEY 123 ++# define FIPS_F_EVP_CIPHERINIT_EX 124 ++# define FIPS_F_EVP_DIGESTINIT_EX 125 ++# define FIPS_F_FIPS_CHECK_DSA 104 ++# define FIPS_F_FIPS_CHECK_EC 142 ++# define FIPS_F_FIPS_CHECK_RSA 106 ++# define FIPS_F_FIPS_DRBG_BYTES 131 ++# define FIPS_F_FIPS_DRBG_CHECK 146 ++# define FIPS_F_FIPS_DRBG_CPRNG_TEST 132 ++# define FIPS_F_FIPS_DRBG_ERROR_CHECK 136 ++# define FIPS_F_FIPS_DRBG_GENERATE 134 ++# define FIPS_F_FIPS_DRBG_INIT 135 ++# define FIPS_F_FIPS_DRBG_INSTANTIATE 138 ++# define FIPS_F_FIPS_DRBG_NEW 139 ++# define FIPS_F_FIPS_DRBG_RESEED 140 ++# define FIPS_F_FIPS_DRBG_SINGLE_KAT 141 ++# define FIPS_F_FIPS_GET_ENTROPY 147 ++# define FIPS_F_FIPS_MODULE_MODE_SET 108 ++# define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109 ++# define FIPS_F_FIPS_RAND_BYTES 114 ++# define FIPS_F_FIPS_RAND_SEED 128 ++# define FIPS_F_FIPS_RAND_SET_METHOD 126 ++# define FIPS_F_FIPS_RAND_STATUS 127 ++# define FIPS_F_FIPS_RSA_BUILTIN_KEYGEN 101 ++# define FIPS_F_FIPS_SELFTEST 150 ++# define FIPS_F_FIPS_SELFTEST_AES 110 ++# define FIPS_F_FIPS_SELFTEST_AES_CCM 145 ++# define FIPS_F_FIPS_SELFTEST_AES_GCM 129 ++# define FIPS_F_FIPS_SELFTEST_AES_XTS 144 ++# define FIPS_F_FIPS_SELFTEST_CMAC 130 ++# define FIPS_F_FIPS_SELFTEST_DES 111 ++# define FIPS_F_FIPS_SELFTEST_DSA 112 ++# define FIPS_F_FIPS_SELFTEST_ECDSA 133 ++# define FIPS_F_FIPS_SELFTEST_HMAC 113 ++# define FIPS_F_FIPS_SELFTEST_SHA1 115 ++# define FIPS_F_FIPS_SELFTEST_SHA2 105 ++# define FIPS_F_OSSL_ECDSA_SIGN_SIG 143 ++# define FIPS_F_OSSL_ECDSA_VERIFY_SIG 148 ++# define FIPS_F_RSA_BUILTIN_KEYGEN 116 ++# define FIPS_F_RSA_OSSL_INIT 149 ++# define FIPS_F_RSA_OSSL_PRIVATE_DECRYPT 117 ++# define FIPS_F_RSA_OSSL_PRIVATE_ENCRYPT 118 ++# define FIPS_F_RSA_OSSL_PUBLIC_DECRYPT 119 ++# define FIPS_F_RSA_OSSL_PUBLIC_ENCRYPT 120 ++ ++/* Reason codes. */ ++# define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED 150 ++# define FIPS_R_ADDITIONAL_INPUT_TOO_LONG 125 ++# define FIPS_R_ALREADY_INSTANTIATED 134 ++# define FIPS_R_DRBG_NOT_INITIALISED 152 ++# define FIPS_R_DRBG_STUCK 103 ++# define FIPS_R_ENTROPY_ERROR_UNDETECTED 104 ++# define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED 105 ++# define FIPS_R_ENTROPY_SOURCE_STUCK 142 ++# define FIPS_R_ERROR_INITIALISING_DRBG 115 ++# define FIPS_R_ERROR_INSTANTIATING_DRBG 127 ++# define FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 124 ++# define FIPS_R_ERROR_RETRIEVING_ENTROPY 122 ++# define FIPS_R_ERROR_RETRIEVING_NONCE 140 ++# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110 ++# define FIPS_R_FIPS_MODE_ALREADY_SET 102 ++# define FIPS_R_FIPS_SELFTEST_FAILED 106 ++# define FIPS_R_FUNCTION_ERROR 116 ++# define FIPS_R_GENERATE_ERROR 137 ++# define FIPS_R_GENERATE_ERROR_UNDETECTED 118 ++# define FIPS_R_INSTANTIATE_ERROR 119 ++# define FIPS_R_INTERNAL_ERROR 121 ++# define FIPS_R_INVALID_KEY_LENGTH 109 ++# define FIPS_R_IN_ERROR_STATE 123 ++# define FIPS_R_KEY_TOO_SHORT 108 ++# define FIPS_R_NONCE_ERROR_UNDETECTED 149 ++# define FIPS_R_NON_FIPS_METHOD 100 ++# define FIPS_R_NOPR_TEST1_FAILURE 145 ++# define FIPS_R_NOPR_TEST2_FAILURE 146 ++# define FIPS_R_NOT_INSTANTIATED 126 ++# define FIPS_R_PAIRWISE_TEST_FAILED 107 ++# define FIPS_R_PERSONALISATION_ERROR_UNDETECTED 128 ++# define FIPS_R_PERSONALISATION_STRING_TOO_LONG 129 ++# define FIPS_R_PR_TEST1_FAILURE 147 ++# define FIPS_R_PR_TEST2_FAILURE 148 ++# define FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED 130 ++# define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG 131 ++# define FIPS_R_RESEED_COUNTER_ERROR 132 ++# define FIPS_R_RESEED_ERROR 133 ++# define FIPS_R_SELFTEST_FAILED 101 ++# define FIPS_R_SELFTEST_FAILURE 135 ++# define FIPS_R_TEST_FAILURE 117 ++# define FIPS_R_UNINSTANTIATE_ERROR 141 ++# define FIPS_R_UNINSTANTIATE_ZEROISE_ERROR 138 ++# define FIPS_R_UNSUPPORTED_DRBG_TYPE 139 ++# define FIPS_R_UNSUPPORTED_PLATFORM 113 ++ ++# ifdef __cplusplus ++} ++# endif ++#endif +diff -up openssl-1.1.1j/include/openssl/fips_rand.h.fips openssl-1.1.1j/include/openssl/fips_rand.h +--- openssl-1.1.1j/include/openssl/fips_rand.h.fips 2021-03-03 12:57:42.204734567 +0100 ++++ openssl-1.1.1j/include/openssl/fips_rand.h 2021-03-03 12:57:42.204734567 +0100 +@@ -0,0 +1,145 @@ ++/* ==================================================================== ++ * Copyright (c) 2003 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#ifndef HEADER_FIPS_RAND_H ++# define HEADER_FIPS_RAND_H ++ ++# include ++# include ++# include ++# include ++ ++# ifdef OPENSSL_FIPS ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ typedef struct drbg_ctx_st DRBG_CTX; ++/* DRBG external flags */ ++/* Flag for CTR mode only: use derivation function ctr_df */ ++# define DRBG_FLAG_CTR_USE_DF 0x1 ++/* PRNG is in test state */ ++# define DRBG_FLAG_TEST 0x2 ++ ++ DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags); ++ int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags); ++ int FIPS_drbg_instantiate(DRBG_CTX *dctx, ++ const unsigned char *pers, size_t perslen); ++ int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin, ++ size_t adinlen); ++ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, ++ int prediction_resistance, ++ const unsigned char *adin, size_t adinlen); ++ ++ int FIPS_drbg_uninstantiate(DRBG_CTX *dctx); ++ void FIPS_drbg_free(DRBG_CTX *dctx); ++ ++ int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, ++ size_t (*get_entropy) (DRBG_CTX *ctx, ++ unsigned char **pout, ++ int entropy, ++ size_t min_len, ++ size_t max_len), ++ void (*cleanup_entropy) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen), ++ size_t entropy_blocklen, ++ size_t (*get_nonce) (DRBG_CTX *ctx, ++ unsigned char **pout, ++ int entropy, ++ size_t min_len, ++ size_t max_len), ++ void (*cleanup_nonce) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen)); ++ ++ int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, ++ size_t (*get_adin) (DRBG_CTX *ctx, ++ unsigned char ++ **pout), ++ void (*cleanup_adin) (DRBG_CTX *ctx, ++ unsigned char *out, ++ size_t olen), ++ int (*rand_seed_cb) (DRBG_CTX *ctx, ++ const void *buf, ++ int num), ++ int (*rand_add_cb) (DRBG_CTX *ctx, ++ const void *buf, ++ int num, ++ double entropy)); ++ ++ void *FIPS_drbg_get_app_data(DRBG_CTX *ctx); ++ void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data); ++ size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx); ++ int FIPS_drbg_get_strength(DRBG_CTX *dctx); ++ void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval); ++ void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval); ++ ++ int FIPS_drbg_health_check(DRBG_CTX *dctx); ++ ++ DRBG_CTX *FIPS_get_default_drbg(void); ++ const RAND_METHOD *FIPS_drbg_method(void); ++ ++ int FIPS_rand_set_method(const RAND_METHOD *meth); ++ const RAND_METHOD *FIPS_rand_get_method(void); ++ ++ void FIPS_rand_set_bits(int nbits); ++ ++ int FIPS_rand_strength(void); ++ ++/* 1.0.0 compat functions */ ++ int FIPS_rand_seed(const void *buf, int num); ++ int FIPS_rand_bytes(unsigned char *out, int outlen); ++ void FIPS_rand_reset(void); ++ int FIPS_rand_status(void); ++# ifdef __cplusplus ++} ++# endif ++# endif ++#endif +diff -up openssl-1.1.1j/include/openssl/opensslconf.h.in.fips openssl-1.1.1j/include/openssl/opensslconf.h.in +--- openssl-1.1.1j/include/openssl/opensslconf.h.in.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/opensslconf.h.in 2021-03-03 12:57:42.205734575 +0100 +@@ -155,6 +155,11 @@ extern "C" { + + #define RC4_INT {- $config{rc4_int} -} + ++/* Always build FIPS module */ ++#ifndef OPENSSL_FIPS ++# define OPENSSL_FIPS ++#endif ++ + #ifdef __cplusplus + } + #endif +diff -up openssl-1.1.1j/include/openssl/randerr.h.fips openssl-1.1.1j/include/openssl/randerr.h +--- openssl-1.1.1j/include/openssl/randerr.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/randerr.h 2021-03-03 12:57:42.205734575 +0100 +@@ -38,6 +38,7 @@ int ERR_load_RAND_strings(void); + # define RAND_F_RAND_DRBG_SET 104 + # define RAND_F_RAND_DRBG_SET_DEFAULTS 121 + # define RAND_F_RAND_DRBG_UNINSTANTIATE 118 ++# define RAND_F_RAND_INIT_FIPS 200 + # define RAND_F_RAND_LOAD_FILE 111 + # define RAND_F_RAND_POOL_ACQUIRE_ENTROPY 122 + # define RAND_F_RAND_POOL_ADD 103 +diff -up openssl-1.1.1j/include/openssl/rand.h.fips openssl-1.1.1j/include/openssl/rand.h +--- openssl-1.1.1j/include/openssl/rand.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/rand.h 2021-03-03 12:57:42.205734575 +0100 +@@ -69,6 +69,11 @@ DEPRECATEDIN_1_1_0(void RAND_screen(void + DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM)) + # endif + ++# ifdef OPENSSL_FIPS ++/* just stubs for API compatibility */ ++void RAND_set_fips_drbg_type(int type, int flags); ++int RAND_init_fips(void); ++# endif + + #ifdef __cplusplus + } +diff -up openssl-1.1.1j/include/openssl/rsaerr.h.fips openssl-1.1.1j/include/openssl/rsaerr.h +--- openssl-1.1.1j/include/openssl/rsaerr.h.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/include/openssl/rsaerr.h 2021-03-03 12:57:42.205734575 +0100 +@@ -25,6 +25,7 @@ int ERR_load_RSA_strings(void); + */ + # define RSA_F_CHECK_PADDING_MD 140 + # define RSA_F_ENCODE_PKCS1 146 ++# define RSA_F_FIPS_RSA_BUILTIN_KEYGEN 206 + # define RSA_F_INT_RSA_VERIFY 145 + # define RSA_F_OLD_RSA_PRIV_DECODE 147 + # define RSA_F_PKEY_PSS_INIT 165 +@@ -39,6 +40,8 @@ int ERR_load_RSA_strings(void); + # define RSA_F_RSA_CHECK_KEY_EX 160 + # define RSA_F_RSA_CMS_DECRYPT 159 + # define RSA_F_RSA_CMS_VERIFY 158 ++# define RSA_F_RSA_GENERATE_KEY_EX 204 ++# define RSA_F_RSA_GENERATE_MULTI_PRIME_KEY 207 + # define RSA_F_RSA_ITEM_VERIFY 148 + # define RSA_F_RSA_METH_DUP 161 + # define RSA_F_RSA_METH_NEW 162 +@@ -76,10 +79,16 @@ int ERR_load_RSA_strings(void); + # define RSA_F_RSA_PRINT_FP 116 + # define RSA_F_RSA_PRIV_DECODE 150 + # define RSA_F_RSA_PRIV_ENCODE 138 ++# define RSA_F_RSA_PRIVATE_DECRYPT 200 ++# define RSA_F_RSA_PRIVATE_ENCRYPT 201 + # define RSA_F_RSA_PSS_GET_PARAM 151 + # define RSA_F_RSA_PSS_TO_CTX 155 + # define RSA_F_RSA_PUB_DECODE 139 ++# define RSA_F_RSA_PUBLIC_DECRYPT 202 ++# define RSA_F_RSA_PUBLIC_ENCRYPT 203 + # define RSA_F_RSA_SETUP_BLINDING 136 ++# define RSA_F_RSA_SET_DEFAULT_METHOD 205 ++# define RSA_F_RSA_SET_METHOD 204 + # define RSA_F_RSA_SIGN 117 + # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 + # define RSA_F_RSA_VERIFY 119 +@@ -137,10 +146,12 @@ int ERR_load_RSA_strings(void); + # define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 + # define RSA_R_MP_R_NOT_PRIME 170 + # define RSA_R_NO_PUBLIC_EXPONENT 140 ++# define RSA_R_NON_FIPS_RSA_METHOD 200 + # define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 + # define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 + # define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 + # define RSA_R_OAEP_DECODING_ERROR 121 ++# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 201 + # define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 + # define RSA_R_PADDING_CHECK_FAILED 114 + # define RSA_R_PKCS_DECODING_ERROR 159 +@@ -160,6 +171,7 @@ int ERR_load_RSA_strings(void); + # define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 + # define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 + # define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 ++# define RSA_R_UNSUPPORTED_PARAMETERS 202 + # define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 + # define RSA_R_VALUE_MISSING 147 + # define RSA_R_WRONG_SIGNATURE_LENGTH 119 +diff -up openssl-1.1.1j/ssl/s3_lib.c.fips openssl-1.1.1j/ssl/s3_lib.c +--- openssl-1.1.1j/ssl/s3_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/ssl/s3_lib.c 2021-03-03 12:57:42.205734575 +0100 +@@ -43,7 +43,7 @@ static SSL_CIPHER tls13_ciphers[] = { + SSL_AEAD, + TLS1_3_VERSION, TLS1_3_VERSION, + 0, 0, +- SSL_HIGH, ++ SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256, + 128, + 128, +@@ -58,7 +58,7 @@ static SSL_CIPHER tls13_ciphers[] = { + SSL_AEAD, + TLS1_3_VERSION, TLS1_3_VERSION, + 0, 0, +- SSL_HIGH, ++ SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384, + 256, + 256, +@@ -92,7 +92,7 @@ static SSL_CIPHER tls13_ciphers[] = { + SSL_AEAD, + TLS1_3_VERSION, TLS1_3_VERSION, + 0, 0, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256, + 128, + 128, +@@ -634,7 +634,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, +@@ -650,7 +650,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 256, + 256, +@@ -666,7 +666,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, +@@ -682,7 +682,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 256, + 256, +@@ -794,7 +794,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, +@@ -810,7 +810,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 256, + 256, +@@ -890,7 +890,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, +@@ -906,7 +906,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_AEAD, + TLS1_2_VERSION, TLS1_2_VERSION, + DTLS1_2_VERSION, DTLS1_2_VERSION, +- SSL_NOT_DEFAULT | SSL_HIGH, ++ SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 256, + 256, +diff -up openssl-1.1.1j/ssl/ssl_ciph.c.fips openssl-1.1.1j/ssl/ssl_ciph.c +--- openssl-1.1.1j/ssl/ssl_ciph.c.fips 2021-03-03 12:57:42.193734476 +0100 ++++ openssl-1.1.1j/ssl/ssl_ciph.c 2021-03-03 12:57:42.206734583 +0100 +@@ -387,7 +387,7 @@ int ssl_load_ciphers(void) + } + } + /* Make sure we can access MD5 and SHA1 */ +- if (!ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL)) ++ if (!FIPS_mode() && !ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL)) + return 0; + if (!ossl_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL)) + return 0; +@@ -559,6 +559,9 @@ int ssl_cipher_get_evp(const SSL_SESSION + s->ssl_version < TLS1_VERSION) + return 1; + ++ if (FIPS_mode()) ++ return 1; ++ + if (c->algorithm_enc == SSL_RC4 && + c->algorithm_mac == SSL_MD5 && + (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) +@@ -667,6 +670,8 @@ static void ssl_cipher_collect_ciphers(c + /* drop those that use any of that is not available */ + if (c == NULL || !c->valid) + continue; ++ if (FIPS_mode() && !(c->algo_strength & SSL_FIPS)) ++ continue; + if ((c->algorithm_mkey & disabled_mkey) || + (c->algorithm_auth & disabled_auth) || + (c->algorithm_enc & disabled_enc) || +@@ -1671,7 +1676,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ + * to the resulting precedence to the STACK_OF(SSL_CIPHER). + */ + for (curr = head; curr != NULL; curr = curr->next) { +- if (curr->active) { ++ if (curr->active ++ && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { + OPENSSL_free(co_list); + sk_SSL_CIPHER_free(cipherstack); +diff -up openssl-1.1.1j/ssl/ssl_init.c.fips openssl-1.1.1j/ssl/ssl_init.c +--- openssl-1.1.1j/ssl/ssl_init.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/ssl/ssl_init.c 2021-03-03 12:57:42.206734583 +0100 +@@ -27,6 +27,10 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_bas + fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " + "Adding SSL ciphers and digests\n"); + #endif ++#ifdef OPENSSL_FIPS ++ if (!FIPS_mode()) { ++#endif ++ + #ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); +@@ -87,6 +91,31 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_bas + EVP_add_digest(EVP_sha256()); + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); ++#ifdef OPENSSL_FIPS ++ } else { ++# ifndef OPENSSL_NO_DES ++ EVP_add_cipher(EVP_des_ede3_cbc()); ++# endif ++ EVP_add_cipher(EVP_aes_128_cbc()); ++ EVP_add_cipher(EVP_aes_192_cbc()); ++ EVP_add_cipher(EVP_aes_256_cbc()); ++ EVP_add_cipher(EVP_aes_128_gcm()); ++ EVP_add_cipher(EVP_aes_256_gcm()); ++ EVP_add_cipher(EVP_aes_128_ccm()); ++ EVP_add_cipher(EVP_aes_256_ccm()); ++# ifndef OPENSSL_NO_MD5 ++ /* needed even in the FIPS mode for TLS-1.0 */ ++ EVP_add_digest(EVP_md5_sha1()); ++# endif ++ EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ ++ EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); ++ EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); ++ EVP_add_digest(EVP_sha224()); ++ EVP_add_digest(EVP_sha256()); ++ EVP_add_digest(EVP_sha384()); ++ EVP_add_digest(EVP_sha512()); ++ } ++#endif + #ifndef OPENSSL_NO_COMP + # ifdef OPENSSL_INIT_DEBUG + fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " +diff -up openssl-1.1.1j/ssl/ssl_lib.c.fips openssl-1.1.1j/ssl/ssl_lib.c +--- openssl-1.1.1j/ssl/ssl_lib.c.fips 2021-03-03 12:57:42.193734476 +0100 ++++ openssl-1.1.1j/ssl/ssl_lib.c 2021-03-03 12:57:42.206734583 +0100 +@@ -2973,6 +2973,11 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m + if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL)) + return NULL; + ++ if (FIPS_mode() && (meth->version < TLS1_VERSION)) { ++ SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE); ++ return NULL; ++ } ++ + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + goto err; +@@ -3029,13 +3034,17 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m + if (ret->param == NULL) + goto err; + +- if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { +- SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); +- goto err2; +- } +- if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { +- SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); +- goto err2; ++ if (!FIPS_mode()) { ++ if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { ++ SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); ++ goto err2; ++ } ++ if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { ++ SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); ++ goto err2; ++ } ++ } else { ++ ret->min_proto_version = TLS1_VERSION; + } + + if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) +diff -up openssl-1.1.1j/ssl/ssl_local.h.fips openssl-1.1.1j/ssl/ssl_local.h +--- openssl-1.1.1j/ssl/ssl_local.h.fips 2021-03-03 12:57:42.100733706 +0100 ++++ openssl-1.1.1j/ssl/ssl_local.h 2021-03-03 12:57:42.206734583 +0100 +@@ -1515,6 +1515,7 @@ typedef struct tls_group_info_st { + # define TLS_CURVE_PRIME 0x0 + # define TLS_CURVE_CHAR2 0x1 + # define TLS_CURVE_CUSTOM 0x2 ++# define TLS_CURVE_FIPS 0x80 + + typedef struct cert_pkey_st CERT_PKEY; + +diff -up openssl-1.1.1j/ssl/t1_lib.c.fips openssl-1.1.1j/ssl/t1_lib.c +--- openssl-1.1.1j/ssl/t1_lib.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/ssl/t1_lib.c 2021-03-03 12:57:42.207734591 +0100 +@@ -159,11 +159,11 @@ static const TLS_GROUP_INFO nid_list[] = + {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */ + {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */ + {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */ +- {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */ ++ {NID_secp224r1, 112, TLS_CURVE_PRIME | TLS_CURVE_FIPS}, /* secp224r1 (21) */ + {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */ +- {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */ +- {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */ +- {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */ ++ {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME | TLS_CURVE_FIPS}, /* secp256r1 (23) */ ++ {NID_secp384r1, 192, TLS_CURVE_PRIME | TLS_CURVE_FIPS}, /* secp384r1 (24) */ ++ {NID_secp521r1, 256, TLS_CURVE_PRIME | TLS_CURVE_FIPS}, /* secp521r1 (25) */ + {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ + {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ + {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ +@@ -258,6 +258,8 @@ int tls_curve_allowed(SSL *s, uint16_t c + if (cinfo->flags & TLS_CURVE_CHAR2) + return 0; + # endif ++ if (FIPS_mode() && !(cinfo->flags & TLS_CURVE_FIPS)) ++ return 0; + ctmp[0] = curve >> 8; + ctmp[1] = curve & 0xff; + return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); +diff -up openssl-1.1.1j/test/dsatest.c.fips openssl-1.1.1j/test/dsatest.c +--- openssl-1.1.1j/test/dsatest.c.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/test/dsatest.c 2021-03-03 12:57:42.207734591 +0100 +@@ -24,41 +24,42 @@ + #ifndef OPENSSL_NO_DSA + static int dsa_cb(int p, int n, BN_GENCB *arg); + +-/* +- * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS +- * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 +- */ + static unsigned char seed[20] = { +- 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40, +- 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3, ++ 0x02, 0x47, 0x11, 0x92, 0x11, 0x88, 0xC8, 0xFB, 0xAF, 0x48, 0x4C, 0x62, ++ 0xDF, 0xA5, 0xBE, 0xA0, 0xA4, 0x3C, 0x56, 0xE3, + }; + + static unsigned char out_p[] = { +- 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, +- 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, +- 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7, +- 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, +- 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, +- 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac, +- 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2, +- 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91, ++ 0xAC, 0xCB, 0x1E, 0x63, 0x60, 0x69, 0x0C, 0xFB, 0x06, 0x19, 0x68, 0x3E, ++ 0xA5, 0x01, 0x5A, 0xA2, 0x15, 0x5C, 0xE2, 0x99, 0x2D, 0xD5, 0x30, 0x99, ++ 0x7E, 0x5F, 0x8D, 0xE2, 0xF7, 0xC6, 0x2E, 0x8D, 0xA3, 0x9F, 0x58, 0xAD, ++ 0xD6, 0xA9, 0x7D, 0x0E, 0x0D, 0x95, 0x53, 0xA6, 0x71, 0x3A, 0xDE, 0xAB, ++ 0xAC, 0xE9, 0xF4, 0x36, 0x55, 0x9E, 0xB9, 0xD6, 0x93, 0xBF, 0xF3, 0x18, ++ 0x1C, 0x14, 0x7B, 0xA5, 0x42, 0x2E, 0xCD, 0x00, 0xEB, 0x35, 0x3B, 0x1B, ++ 0xA8, 0x51, 0xBB, 0xE1, 0x58, 0x42, 0x85, 0x84, 0x22, 0xA7, 0x97, 0x5E, ++ 0x99, 0x6F, 0x38, 0x20, 0xBD, 0x9D, 0xB6, 0xD9, 0x33, 0x37, 0x2A, 0xFD, ++ 0xBB, 0xD4, 0xBC, 0x0C, 0x2A, 0x67, 0xCB, 0x9F, 0xBB, 0xDF, 0xF9, 0x93, ++ 0xAA, 0xD6, 0xF0, 0xD6, 0x95, 0x0B, 0x5D, 0x65, 0x14, 0xD0, 0x18, 0x9D, ++ 0xC6, 0xAF, 0xF0, 0xC6, 0x37, 0x7C, 0xF3, 0x5F, + }; + + static unsigned char out_q[] = { +- 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, +- 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e, +- 0xda, 0xce, 0x91, 0x5f, ++ 0xE3, 0x8E, 0x5E, 0x6D, 0xBF, 0x2B, 0x79, 0xF8, 0xC5, 0x4B, 0x89, 0x8B, ++ 0xBA, 0x2D, 0x91, 0xC3, 0x6C, 0x80, 0xAC, 0x87, + }; + + static unsigned char out_g[] = { +- 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, +- 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00, +- 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb, +- 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, +- 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, +- 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c, +- 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c, +- 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02, ++ 0x42, 0x4A, 0x04, 0x4E, 0x79, 0xB4, 0x99, 0x7F, 0xFD, 0x58, 0x36, 0x2C, ++ 0x1B, 0x5F, 0x18, 0x7E, 0x0D, 0xCC, 0xAB, 0x81, 0xC9, 0x5D, 0x10, 0xCE, ++ 0x4E, 0x80, 0x7E, 0x58, 0xB4, 0x34, 0x3F, 0xA7, 0x45, 0xC7, 0xAA, 0x36, ++ 0x24, 0x42, 0xA9, 0x3B, 0xE8, 0x0E, 0x04, 0x02, 0x2D, 0xFB, 0xA6, 0x13, ++ 0xB9, 0xB5, 0x15, 0xA5, 0x56, 0x07, 0x35, 0xE4, 0x03, 0xB6, 0x79, 0x7C, ++ 0x62, 0xDD, 0xDF, 0x3F, 0x71, 0x3A, 0x9D, 0x8B, 0xC4, 0xF6, 0xE7, 0x1D, ++ 0x52, 0xA8, 0xA9, 0x43, 0x1D, 0x33, 0x51, 0x88, 0x39, 0xBD, 0x73, 0xE9, ++ 0x5F, 0xBE, 0x82, 0x49, 0x27, 0xE6, 0xB5, 0x53, 0xC1, 0x38, 0xAC, 0x2F, ++ 0x6D, 0x97, 0x6C, 0xEB, 0x67, 0xC1, 0x5F, 0x67, 0xF8, 0x35, 0x05, 0x5E, ++ 0xD5, 0x68, 0x80, 0xAA, 0x96, 0xCA, 0x0B, 0x8A, 0xE6, 0xF1, 0xB1, 0x41, ++ 0xC6, 0x75, 0x94, 0x0A, 0x0A, 0x2A, 0xFA, 0x29, + }; + + static const unsigned char str1[] = "12345678901234567890"; +@@ -79,11 +80,11 @@ static int dsa_test(void) + + BN_GENCB_set(cb, dsa_cb, NULL); + if (!TEST_ptr(dsa = DSA_new()) +- || !TEST_true(DSA_generate_parameters_ex(dsa, 512, seed, 20, ++ || !TEST_true(DSA_generate_parameters_ex(dsa, 1024, seed, 20, + &counter, &h, cb))) + goto end; + +- if (!TEST_int_eq(counter, 105)) ++ if (!TEST_int_eq(counter, 239)) + goto end; + if (!TEST_int_eq(h, 2)) + goto end; +diff -up openssl-1.1.1j/test/recipes/30-test_evp_data/evpciph.txt.fips openssl-1.1.1j/test/recipes/30-test_evp_data/evpciph.txt +--- openssl-1.1.1j/test/recipes/30-test_evp_data/evpciph.txt.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/test/recipes/30-test_evp_data/evpciph.txt 2021-03-03 12:57:42.207734591 +0100 +@@ -1206,6 +1206,7 @@ Key = 0000000000000000000000000000000000 + IV = 00000000000000000000000000000000 + Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 + Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e ++Result = KEY_SET_ERROR + + Cipher = aes-128-xts + Key = 1111111111111111111111111111111122222222222222222222222222222222 +diff -up openssl-1.1.1j/util/libcrypto.num.fips openssl-1.1.1j/util/libcrypto.num +--- openssl-1.1.1j/util/libcrypto.num.fips 2021-02-16 16:24:01.000000000 +0100 ++++ openssl-1.1.1j/util/libcrypto.num 2021-03-03 12:57:42.208734600 +0100 +@@ -4591,3 +4591,38 @@ X509_ALGOR_copy + X509_REQ_set0_signature 4545 1_1_1h EXIST::FUNCTION: + X509_REQ_set1_signature_algo 4546 1_1_1h EXIST::FUNCTION: + EC_KEY_decoded_from_explicit_params 4547 1_1_1h EXIST::FUNCTION:EC ++FIPS_drbg_reseed 6348 1_1_0g EXIST::FUNCTION: ++FIPS_selftest_check 6349 1_1_0g EXIST::FUNCTION: ++FIPS_rand_set_method 6350 1_1_0g EXIST::FUNCTION: ++FIPS_get_default_drbg 6351 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_set_reseed_interval 6352 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_set_app_data 6353 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_method 6354 1_1_0g EXIST::FUNCTION: ++FIPS_rand_status 6355 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_instantiate 6356 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_set_callbacks 6357 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_new 6358 1_1_0g EXIST::FUNCTION: ++FIPS_dsa_paramgen_check_g 6359 1_1_0g EXIST::FUNCTION: ++FIPS_selftest 6360 1_1_0g EXIST::FUNCTION: ++FIPS_rand_set_bits 6361 1_1_0g EXIST::FUNCTION: ++FIPS_rand_bytes 6362 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_get_app_data 6363 1_1_0g EXIST::FUNCTION: ++FIPS_selftest_failed 6364 1_1_0g EXIST::FUNCTION: ++FIPS_dsa_builtin_paramgen2 6365 1_1_0g EXIST::FUNCTION: ++FIPS_rand_reset 6366 1_1_0g EXIST::FUNCTION: ++ERR_load_FIPS_strings 6367 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_generate 6368 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_uninstantiate 6369 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_set_check_interval 6370 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_free 6371 1_1_0g EXIST::FUNCTION: ++FIPS_selftest_drbg_all 6372 1_1_0g EXIST::FUNCTION: ++FIPS_rand_get_method 6373 1_1_0g EXIST::FUNCTION: ++RAND_set_fips_drbg_type 6374 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_health_check 6375 1_1_0g EXIST::FUNCTION: ++RAND_init_fips 6376 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_set_rand_callbacks 6377 1_1_0g EXIST::FUNCTION: ++FIPS_rand_seed 6378 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION: ++FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: ++FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: diff --git a/openssl-1.1.1m.tar.gz b/openssl-1.1.1m.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2db4ee8e8886de8356fa9fdea6d4d99ec5c410e0 Binary files /dev/null and b/openssl-1.1.1m.tar.gz differ diff --git a/openssl.yaml b/openssl.yaml new file mode 100644 index 0000000000000000000000000000000000000000..99a2ced13497657b269602db4233c5daa6395545 --- /dev/null +++ b/openssl.yaml @@ -0,0 +1,5 @@ +version_control: github +src_repo: openssl/openssl +tag_prefix:"^openssl-" +separator: "." +git_url: https://github.com/openssl/openssl.git