diff --git a/oqs_template/generate.py b/oqs_template/generate.py index da6aaa2315..033aed5b9c 100644 --- a/oqs_template/generate.py +++ b/oqs_template/generate.py @@ -49,7 +49,6 @@ def load_config(): config = load_config() # kems -populate('ssl/s3_both.cc', config, '/////') populate('ssl/ssl_key_share.cc', config, '/////') populate('ssl/test/fuzzer.h', config, '/////') populate('ssl/test/test_config.cc', config, '/////') @@ -65,6 +64,10 @@ def load_config(): populate('ssl/ssl_privkey.cc', config, '/////') populate('include/openssl/evp.h', config, '/////') populate('crypto/obj/obj_xref.c', config, '/////') +populate('pki/signature_algorithm.cc', config, '/////') +populate('pki/signature_algorithm.h', config, '/////') +populate('pki/simple_path_builder_delegate.cc', config, '/////') +populate('pki/verify_signed_data.cc', config, '/////') # both populate('crypto/obj/objects.txt', config, '#####') diff --git a/oqs_template/pki/signature_algorithm.cc/list_sig_oids.fragment b/oqs_template/pki/signature_algorithm.cc/list_sig_oids.fragment new file mode 100644 index 0000000000..a2d29bc2c1 --- /dev/null +++ b/oqs_template/pki/signature_algorithm.cc/list_sig_oids.fragment @@ -0,0 +1,4 @@ +{% for sig in config['sigs'] %} +const uint8_t kOid{{ sig['name']|capitalize }}[] = {% raw %}{{% endraw %}{{ sig['oid_encoded']|lower }}{% raw %}}{% endraw %}; +{%- endfor %} + diff --git a/oqs_template/pki/signature_algorithm.cc/pair_sigs_with_digests.fragment b/oqs_template/pki/signature_algorithm.cc/pair_sigs_with_digests.fragment new file mode 100644 index 0000000000..c8dfb245c6 --- /dev/null +++ b/oqs_template/pki/signature_algorithm.cc/pair_sigs_with_digests.fragment @@ -0,0 +1,25 @@ +{%- set Sha256Sigs = [] %} +{%- set Sha384Sigs = [] %} +{%- set Sha512Sigs = [] %} +{%- for sig in config['sigs'] %} +{%- if sig['claimed_security_level'] == '1' or sig['claimed_security_level'] == '2' %} +{%- set _tmp = Sha256Sigs.append( sig['name'] ) %} +{%- elif sig['claimed_security_level'] == '3' or sig['claimed_security_level'] == '4' %} +{%- set _tmp = Sha384Sigs.append( sig['name'] ) %} +{%- else %}{# claimed_security_level == '5' #} +{%- set _tmp = Sha512Sigs.append( sig['name'] ) %} +{%- endif %} +{%- endfor %} +{%- for sig in Sha256Sigs %} + case SignatureAlgorithm::k{{ sig|capitalize }}: +{%- endfor %} + return DigestAlgorithm::Sha256; +{% for sig in Sha384Sigs %} + case SignatureAlgorithm::k{{ sig|capitalize }}: +{%- endfor %} + return DigestAlgorithm::Sha384; +{% for sig in Sha512Sigs %} + case SignatureAlgorithm::k{{ sig|capitalize }}: +{%- endfor %} + return DigestAlgorithm::Sha512; + diff --git a/oqs_template/pki/signature_algorithm.cc/parse_sig_oids.fragment b/oqs_template/pki/signature_algorithm.cc/parse_sig_oids.fragment new file mode 100644 index 0000000000..09eb3adcea --- /dev/null +++ b/oqs_template/pki/signature_algorithm.cc/parse_sig_oids.fragment @@ -0,0 +1,6 @@ +{% for sig in config['sigs'] %} + if (oid == der::Input(kOid{{ sig['name']|capitalize }})) { + return SignatureAlgorithm::k{{ sig['name']|capitalize }}; + } +{%- endfor %} + diff --git a/oqs_template/pki/signature_algorithm.h/list_sigs.fragment b/oqs_template/pki/signature_algorithm.h/list_sigs.fragment new file mode 100644 index 0000000000..3d198d7166 --- /dev/null +++ b/oqs_template/pki/signature_algorithm.h/list_sigs.fragment @@ -0,0 +1,4 @@ +{% for sig in config['sigs'] %} + k{{ sig['name']|capitalize }}, +{%- endfor %} + diff --git a/oqs_template/pki/simple_path_builder_delegate.cc/list_sigs.fragment b/oqs_template/pki/simple_path_builder_delegate.cc/list_sigs.fragment new file mode 100644 index 0000000000..923f5414bd --- /dev/null +++ b/oqs_template/pki/simple_path_builder_delegate.cc/list_sigs.fragment @@ -0,0 +1,4 @@ +{% for sig in config['sigs'] %} + case SignatureAlgorithm::k{{ sig['name']|capitalize }}: +{%- endfor %} + diff --git a/oqs_template/pki/verify_signed_data.cc/list_sigs.fragment b/oqs_template/pki/verify_signed_data.cc/list_sigs.fragment new file mode 100644 index 0000000000..baea72cc22 --- /dev/null +++ b/oqs_template/pki/verify_signed_data.cc/list_sigs.fragment @@ -0,0 +1,14 @@ +{% for sig in config['sigs'] %} + case SignatureAlgorithm::k{{ sig['name']|capitalize }}: + expected_pkey_id = EVP_PKEY_{{ sig['name']|upper }}; + {%- if sig['claimed_security_level'] == '1' or sig['claimed_security_level'] == '2' %} + digest = EVP_sha256(); + {%- elif sig['claimed_security_level'] == '3' or sig['claimed_security_level'] == '4' %} + digest = EVP_sha384(); + {%- else %}{# claimed_security_level == '5' #} + digest = EVP_sha512(); + {%- endif %} + cache_algorithm_name = "{{ sig['name']|capitalize }}"; + break; +{%- endfor %} + diff --git a/pki/signature_algorithm.cc b/pki/signature_algorithm.cc index 73d8bc1bc6..ea50ebbd57 100644 --- a/pki/signature_algorithm.cc +++ b/pki/signature_algorithm.cc @@ -123,6 +123,29 @@ const uint8_t kOidRsaSsaPss[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, const uint8_t kOidMgf1[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08}; +///// OQS_TEMPLATE_FRAGMENT_LIST_SIG_OIDS_START +const uint8_t kOidDilithium2[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x07, 0x04, 0x04}; +const uint8_t kOidDilithium3[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x07, 0x06, 0x05}; +const uint8_t kOidDilithium5[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x07, 0x08, 0x07}; +const uint8_t kOidMldsa44[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x0c, 0x04, 0x04}; +const uint8_t kOidMldsa65[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x0c, 0x06, 0x05}; +const uint8_t kOidMldsa87[] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x82, 0x0b, 0x0c, 0x08, 0x07}; +const uint8_t kOidFalcon512[] = {0x2b, 0xce, 0x0f, 0x03, 0x06}; +const uint8_t kOidFalcon1024[] = {0x2b, 0xce, 0x0f, 0x03, 0x09}; +const uint8_t kOidSphincssha2128fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x04, 0x0d}; +const uint8_t kOidSphincssha2128ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x04, 0x10}; +const uint8_t kOidSphincssha2192fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x05, 0x0a}; +const uint8_t kOidSphincssha2192ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x05, 0x0c}; +const uint8_t kOidSphincssha2256fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x06, 0x0a}; +const uint8_t kOidSphincssha2256ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x06, 0x0c}; +const uint8_t kOidSphincsshake128fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x07, 0x0d}; +const uint8_t kOidSphincsshake128ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x07, 0x10}; +const uint8_t kOidSphincsshake192fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x08, 0x0a}; +const uint8_t kOidSphincsshake192ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x08, 0x0c}; +const uint8_t kOidSphincsshake256fsimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x09, 0x0a}; +const uint8_t kOidSphincsshake256ssimple[] = {0x2b, 0xce, 0x0f, 0x06, 0x09, 0x0c}; +///// OQS_TEMPLATE_FRAGMENT_LIST_SIG_OIDS_END + // Returns true if the entirety of the input is a NULL value. [[nodiscard]] bool IsNull(der::Input input) { der::Parser parser(input); @@ -376,6 +399,69 @@ std::optional ParseSignatureAlgorithm( return SignatureAlgorithm::kEcdsaSha512; } +///// OQS_TEMPLATE_FRAGMENT_PARSE_SIG_OIDS_START + if (oid == der::Input(kOidDilithium2)) { + return SignatureAlgorithm::kDilithium2; + } + if (oid == der::Input(kOidDilithium3)) { + return SignatureAlgorithm::kDilithium3; + } + if (oid == der::Input(kOidDilithium5)) { + return SignatureAlgorithm::kDilithium5; + } + if (oid == der::Input(kOidMldsa44)) { + return SignatureAlgorithm::kMldsa44; + } + if (oid == der::Input(kOidMldsa65)) { + return SignatureAlgorithm::kMldsa65; + } + if (oid == der::Input(kOidMldsa87)) { + return SignatureAlgorithm::kMldsa87; + } + if (oid == der::Input(kOidFalcon512)) { + return SignatureAlgorithm::kFalcon512; + } + if (oid == der::Input(kOidFalcon1024)) { + return SignatureAlgorithm::kFalcon1024; + } + if (oid == der::Input(kOidSphincssha2128fsimple)) { + return SignatureAlgorithm::kSphincssha2128fsimple; + } + if (oid == der::Input(kOidSphincssha2128ssimple)) { + return SignatureAlgorithm::kSphincssha2128ssimple; + } + if (oid == der::Input(kOidSphincssha2192fsimple)) { + return SignatureAlgorithm::kSphincssha2192fsimple; + } + if (oid == der::Input(kOidSphincssha2192ssimple)) { + return SignatureAlgorithm::kSphincssha2192ssimple; + } + if (oid == der::Input(kOidSphincssha2256fsimple)) { + return SignatureAlgorithm::kSphincssha2256fsimple; + } + if (oid == der::Input(kOidSphincssha2256ssimple)) { + return SignatureAlgorithm::kSphincssha2256ssimple; + } + if (oid == der::Input(kOidSphincsshake128fsimple)) { + return SignatureAlgorithm::kSphincsshake128fsimple; + } + if (oid == der::Input(kOidSphincsshake128ssimple)) { + return SignatureAlgorithm::kSphincsshake128ssimple; + } + if (oid == der::Input(kOidSphincsshake192fsimple)) { + return SignatureAlgorithm::kSphincsshake192fsimple; + } + if (oid == der::Input(kOidSphincsshake192ssimple)) { + return SignatureAlgorithm::kSphincsshake192ssimple; + } + if (oid == der::Input(kOidSphincsshake256fsimple)) { + return SignatureAlgorithm::kSphincsshake256fsimple; + } + if (oid == der::Input(kOidSphincsshake256ssimple)) { + return SignatureAlgorithm::kSphincsshake256ssimple; + } +///// OQS_TEMPLATE_FRAGMENT_PARSE_SIG_OIDS_END + if (oid == der::Input(kOidRsaSsaPss)) { return ParseRsaPss(params); } @@ -409,6 +495,34 @@ std::optional GetTlsServerEndpointDigestAlgorithm( case SignatureAlgorithm::kEcdsaSha512: return DigestAlgorithm::Sha512; +///// OQS_TEMPLATE_FRAGMENT_PAIR_SIGS_WITH_DIGESTS_START + case SignatureAlgorithm::kDilithium2: + case SignatureAlgorithm::kMldsa44: + case SignatureAlgorithm::kFalcon512: + case SignatureAlgorithm::kSphincssha2128fsimple: + case SignatureAlgorithm::kSphincssha2128ssimple: + case SignatureAlgorithm::kSphincsshake128fsimple: + case SignatureAlgorithm::kSphincsshake128ssimple: + return DigestAlgorithm::Sha256; + + case SignatureAlgorithm::kDilithium3: + case SignatureAlgorithm::kMldsa65: + case SignatureAlgorithm::kSphincssha2192fsimple: + case SignatureAlgorithm::kSphincssha2192ssimple: + case SignatureAlgorithm::kSphincsshake192fsimple: + case SignatureAlgorithm::kSphincsshake192ssimple: + return DigestAlgorithm::Sha384; + + case SignatureAlgorithm::kDilithium5: + case SignatureAlgorithm::kMldsa87: + case SignatureAlgorithm::kFalcon1024: + case SignatureAlgorithm::kSphincssha2256fsimple: + case SignatureAlgorithm::kSphincssha2256ssimple: + case SignatureAlgorithm::kSphincsshake256fsimple: + case SignatureAlgorithm::kSphincsshake256ssimple: + return DigestAlgorithm::Sha512; +///// OQS_TEMPLATE_FRAGMENT_PAIR_SIGS_WITH_DIGESTS_END + // It is ambiguous whether hash-matching RSASSA-PSS instantiations count as // using one or multiple digests, but the corresponding digest is the only // reasonable interpretation. diff --git a/pki/signature_algorithm.h b/pki/signature_algorithm.h index 2d65be2e24..807b2a2080 100644 --- a/pki/signature_algorithm.h +++ b/pki/signature_algorithm.h @@ -39,6 +39,28 @@ enum class SignatureAlgorithm { kEcdsaSha256, kEcdsaSha384, kEcdsaSha512, +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_START + kDilithium2, + kDilithium3, + kDilithium5, + kMldsa44, + kMldsa65, + kMldsa87, + kFalcon512, + kFalcon1024, + kSphincssha2128fsimple, + kSphincssha2128ssimple, + kSphincssha2192fsimple, + kSphincssha2192ssimple, + kSphincssha2256fsimple, + kSphincssha2256ssimple, + kSphincsshake128fsimple, + kSphincsshake128ssimple, + kSphincsshake192fsimple, + kSphincsshake192ssimple, + kSphincsshake256fsimple, + kSphincsshake256ssimple, +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_END // These RSA-PSS constants match RFC 8446 and refer to RSASSA-PSS with MGF-1, // using the specified hash as both the signature and MGF-1 hash, and the hash // length as the salt length. diff --git a/pki/simple_path_builder_delegate.cc b/pki/simple_path_builder_delegate.cc index 822019b91b..eff355bb8d 100644 --- a/pki/simple_path_builder_delegate.cc +++ b/pki/simple_path_builder_delegate.cc @@ -77,6 +77,28 @@ bool SimplePathBuilderDelegate::IsSignatureAlgorithmAcceptable( case SignatureAlgorithm::kEcdsaSha256: case SignatureAlgorithm::kEcdsaSha384: case SignatureAlgorithm::kEcdsaSha512: +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_START + case SignatureAlgorithm::kDilithium2: + case SignatureAlgorithm::kDilithium3: + case SignatureAlgorithm::kDilithium5: + case SignatureAlgorithm::kMldsa44: + case SignatureAlgorithm::kMldsa65: + case SignatureAlgorithm::kMldsa87: + case SignatureAlgorithm::kFalcon512: + case SignatureAlgorithm::kFalcon1024: + case SignatureAlgorithm::kSphincssha2128fsimple: + case SignatureAlgorithm::kSphincssha2128ssimple: + case SignatureAlgorithm::kSphincssha2192fsimple: + case SignatureAlgorithm::kSphincssha2192ssimple: + case SignatureAlgorithm::kSphincssha2256fsimple: + case SignatureAlgorithm::kSphincssha2256ssimple: + case SignatureAlgorithm::kSphincsshake128fsimple: + case SignatureAlgorithm::kSphincsshake128ssimple: + case SignatureAlgorithm::kSphincsshake192fsimple: + case SignatureAlgorithm::kSphincsshake192ssimple: + case SignatureAlgorithm::kSphincsshake256fsimple: + case SignatureAlgorithm::kSphincsshake256ssimple: +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_END case SignatureAlgorithm::kRsaPssSha256: case SignatureAlgorithm::kRsaPssSha384: case SignatureAlgorithm::kRsaPssSha512: @@ -123,6 +145,10 @@ bool SimplePathBuilderDelegate::IsPublicKeyAcceptable(EVP_PKEY *public_key, return true; } + if (IS_OQS_PKEY(pkey_id)) { + return true; + } + // Unexpected key type. return false; } diff --git a/pki/verify_signed_data.cc b/pki/verify_signed_data.cc index 4502e2de03..bdca1560de 100644 --- a/pki/verify_signed_data.cc +++ b/pki/verify_signed_data.cc @@ -202,6 +202,109 @@ bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data, cache_algorithm_name = "EcdsaSha512"; break; +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_START + case SignatureAlgorithm::kDilithium2: + expected_pkey_id = EVP_PKEY_DILITHIUM2; + digest = EVP_sha256(); + cache_algorithm_name = "Dilithium2"; + break; + case SignatureAlgorithm::kDilithium3: + expected_pkey_id = EVP_PKEY_DILITHIUM3; + digest = EVP_sha384(); + cache_algorithm_name = "Dilithium3"; + break; + case SignatureAlgorithm::kDilithium5: + expected_pkey_id = EVP_PKEY_DILITHIUM5; + digest = EVP_sha512(); + cache_algorithm_name = "Dilithium5"; + break; + case SignatureAlgorithm::kMldsa44: + expected_pkey_id = EVP_PKEY_MLDSA44; + digest = EVP_sha256(); + cache_algorithm_name = "Mldsa44"; + break; + case SignatureAlgorithm::kMldsa65: + expected_pkey_id = EVP_PKEY_MLDSA65; + digest = EVP_sha384(); + cache_algorithm_name = "Mldsa65"; + break; + case SignatureAlgorithm::kMldsa87: + expected_pkey_id = EVP_PKEY_MLDSA87; + digest = EVP_sha512(); + cache_algorithm_name = "Mldsa87"; + break; + case SignatureAlgorithm::kFalcon512: + expected_pkey_id = EVP_PKEY_FALCON512; + digest = EVP_sha256(); + cache_algorithm_name = "Falcon512"; + break; + case SignatureAlgorithm::kFalcon1024: + expected_pkey_id = EVP_PKEY_FALCON1024; + digest = EVP_sha512(); + cache_algorithm_name = "Falcon1024"; + break; + case SignatureAlgorithm::kSphincssha2128fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2128FSIMPLE; + digest = EVP_sha256(); + cache_algorithm_name = "Sphincssha2128fsimple"; + break; + case SignatureAlgorithm::kSphincssha2128ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2128SSIMPLE; + digest = EVP_sha256(); + cache_algorithm_name = "Sphincssha2128ssimple"; + break; + case SignatureAlgorithm::kSphincssha2192fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2192FSIMPLE; + digest = EVP_sha384(); + cache_algorithm_name = "Sphincssha2192fsimple"; + break; + case SignatureAlgorithm::kSphincssha2192ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2192SSIMPLE; + digest = EVP_sha384(); + cache_algorithm_name = "Sphincssha2192ssimple"; + break; + case SignatureAlgorithm::kSphincssha2256fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2256FSIMPLE; + digest = EVP_sha512(); + cache_algorithm_name = "Sphincssha2256fsimple"; + break; + case SignatureAlgorithm::kSphincssha2256ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHA2256SSIMPLE; + digest = EVP_sha512(); + cache_algorithm_name = "Sphincssha2256ssimple"; + break; + case SignatureAlgorithm::kSphincsshake128fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE128FSIMPLE; + digest = EVP_sha256(); + cache_algorithm_name = "Sphincsshake128fsimple"; + break; + case SignatureAlgorithm::kSphincsshake128ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE128SSIMPLE; + digest = EVP_sha256(); + cache_algorithm_name = "Sphincsshake128ssimple"; + break; + case SignatureAlgorithm::kSphincsshake192fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE192FSIMPLE; + digest = EVP_sha384(); + cache_algorithm_name = "Sphincsshake192fsimple"; + break; + case SignatureAlgorithm::kSphincsshake192ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE192SSIMPLE; + digest = EVP_sha384(); + cache_algorithm_name = "Sphincsshake192ssimple"; + break; + case SignatureAlgorithm::kSphincsshake256fsimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE256FSIMPLE; + digest = EVP_sha512(); + cache_algorithm_name = "Sphincsshake256fsimple"; + break; + case SignatureAlgorithm::kSphincsshake256ssimple: + expected_pkey_id = EVP_PKEY_SPHINCSSHAKE256SSIMPLE; + digest = EVP_sha512(); + cache_algorithm_name = "Sphincsshake256ssimple"; + break; +///// OQS_TEMPLATE_FRAGMENT_LIST_SIGS_END + case SignatureAlgorithm::kRsaPssSha256: expected_pkey_id = EVP_PKEY_RSA; digest = EVP_sha256(); @@ -249,6 +352,10 @@ bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data, } } + bool ret; + if (IS_OQS_PKEY(expected_pkey_id)) { + ret = oqs_verify_sig(public_key, signature_value_bytes.data(), signature_value_bytes.size(), signed_data.data(), signed_data.size()) ? true : false; + } else { OpenSSLErrStackTracer err_tracer; bssl::ScopedEVP_MD_CTX ctx; @@ -268,9 +375,10 @@ bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data, } } - bool ret = 1 == EVP_DigestVerify(ctx.get(), signature_value_bytes.data(), - signature_value_bytes.size(), - signed_data.data(), signed_data.size()); + ret = 1 == EVP_DigestVerify(ctx.get(), signature_value_bytes.data(), + signature_value_bytes.size(), + signed_data.data(), signed_data.size()); + } if (!cache_key.empty()) { cache->Store(cache_key, ret ? SignatureVerifyCache::Value::kValid : SignatureVerifyCache::Value::kInvalid);