diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9f4b07de..68ef0471 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -145,7 +145,11 @@ jobs: done - name: Run tests - run: ctest --test-dir build --output-on-failure + run: | + ctest --test-dir build \ + --output-on-failure \ + --extra-verbose \ + --repeat until-pass:5 linux_aarch64: name: "aarch64 cross-compilation" diff --git a/ALGORITHMS.md b/ALGORITHMS.md index c45d83ce..da839eef 100644 --- a/ALGORITHMS.md +++ b/ALGORITHMS.md @@ -152,10 +152,23 @@ adapting the OIDs of all supported signature algorithms as per the table below. | mldsa44 | 1.3.6.1.4.1.2.267.12.4.4 |Yes| OQS_OID_MLDSA44 | p256_mldsa44 | 1.3.9999.7.1 |Yes| OQS_OID_P256_MLDSA44 | rsa3072_mldsa44 | 1.3.9999.7.2 |Yes| OQS_OID_RSA3072_MLDSA44 +| mldsa44_pss2048 | 2.16.840.1.114027.80.8.1.1 |Yes| OQS_OID_MLDSA44_pss2048 +| mldsa44_rsa2048 | 2.16.840.1.114027.80.8.1.2 |Yes| OQS_OID_MLDSA44_rsa2048 +| mldsa44_ed25519 | 2.16.840.1.114027.80.8.1.3 |Yes| OQS_OID_MLDSA44_ed25519 +| mldsa44_p256 | 2.16.840.1.114027.80.8.1.4 |Yes| OQS_OID_MLDSA44_p256 +| mldsa44_bp256 | 2.16.840.1.114027.80.8.1.5 |Yes| OQS_OID_MLDSA44_bp256 | mldsa65 | 1.3.6.1.4.1.2.267.12.6.5 |Yes| OQS_OID_MLDSA65 | p384_mldsa65 | 1.3.9999.7.3 |Yes| OQS_OID_P384_MLDSA65 +| mldsa65_pss3072 | 2.16.840.1.114027.80.8.1.6 |Yes| OQS_OID_MLDSA65_pss3072 +| mldsa65_rsa3072 | 2.16.840.1.114027.80.8.1.7 |Yes| OQS_OID_MLDSA65_rsa3072 +| mldsa65_p256 | 2.16.840.1.114027.80.8.1.8 |Yes| OQS_OID_MLDSA65_p256 +| mldsa65_bp256 | 2.16.840.1.114027.80.8.1.9 |Yes| OQS_OID_MLDSA65_bp256 +| mldsa65_ed25519 | 2.16.840.1.114027.80.8.1.10 |Yes| OQS_OID_MLDSA65_ed25519 | mldsa87 | 1.3.6.1.4.1.2.267.12.8.7 |Yes| OQS_OID_MLDSA87 | p521_mldsa87 | 1.3.9999.7.4 |Yes| OQS_OID_P521_MLDSA87 +| mldsa87_p384 | 2.16.840.1.114027.80.8.1.11 |Yes| OQS_OID_MLDSA87_p384 +| mldsa87_bp384 | 2.16.840.1.114027.80.8.1.12 |Yes| OQS_OID_MLDSA87_bp384 +| mldsa87_ed448 | 2.16.840.1.114027.80.8.1.13 |Yes| OQS_OID_MLDSA87_ed448 | falcon512 | 1.3.9999.3.11 |Yes| OQS_OID_FALCON512 | p256_falcon512 | 1.3.9999.3.12 |Yes| OQS_OID_P256_FALCON512 | rsa3072_falcon512 | 1.3.9999.3.13 |Yes| OQS_OID_RSA3072_FALCON512 diff --git a/README.md b/README.md index b6f5b086..b011ad2c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This implementation makes available the following quantum safe algorithms: ### Signature algorithms - **CRYSTALS-Dilithium**:`dilithium2`\*, `p256_dilithium2`\*, `rsa3072_dilithium2`\*, `dilithium3`\*, `p384_dilithium3`\*, `dilithium5`\*, `p521_dilithium5`\* -- **ML-DSA**:`mldsa44`\*, `p256_mldsa44`\*, `rsa3072_mldsa44`\*, `mldsa65`\*, `p384_mldsa65`\*, `mldsa87`\*, `p521_mldsa87`\* +- **ML-DSA**:`mldsa44`\*, `p256_mldsa44`\*, `rsa3072_mldsa44`\*, `mldsa44_pss2048`\*, `mldsa44_rsa2048`\*, `mldsa44_ed25519`\*, `mldsa44_p256`\*, `mldsa44_bp256`\*, `mldsa65`\*, `p384_mldsa65`\*, `mldsa65_pss3072`\*, `mldsa65_rsa3072`\*, `mldsa65_p256`\*, `mldsa65_bp256`\*, `mldsa65_ed25519`\*, `mldsa87`\*, `p521_mldsa87`\*, `mldsa87_p384`\*, `mldsa87_bp384`\*, `mldsa87_ed448`\* - **Falcon**:`falcon512`\*, `p256_falcon512`\*, `rsa3072_falcon512`\*, `falconpadded512`\*, `p256_falconpadded512`\*, `rsa3072_falconpadded512`\*, `falcon1024`\*, `p521_falcon1024`\*, `falconpadded1024`\*, `p521_falconpadded1024`\* - **SPHINCS-SHA2**:`sphincssha2128fsimple`\*, `p256_sphincssha2128fsimple`\*, `rsa3072_sphincssha2128fsimple`\*, `sphincssha2128ssimple`\*, `p256_sphincssha2128ssimple`\*, `rsa3072_sphincssha2128ssimple`\*, `sphincssha2192fsimple`\*, `p384_sphincssha2192fsimple`\*, `sphincssha2192ssimple`, `p384_sphincssha2192ssimple`, `sphincssha2256fsimple`, `p521_sphincssha2256fsimple`, `sphincssha2256ssimple`, `p521_sphincssha2256ssimple` @@ -66,8 +66,11 @@ TLS operations. This designation [can be changed by modifying the In order to support parallel use of classic and quantum-safe cryptography this provider also provides different hybrid algorithms, combining classic -and quantum-safe methods: These are listed above with a prefix denoting a -classic algorithm, e.g., for elliptic curve: "p256_". +and quantum-safe methods. +There are two types of combinations: +The Hybrids are listed above with a prefix denoting a classic algorithm, e.g., for elliptic curve: "p256_". +The [Composite](https://datatracker.ietf.org/doc/draft-ounsworth-pq-composite-sigs/) are listed above with a suffix denoting a +classic algorithm, e.g., for elliptic curve: "_p256". A full list of algorithms, their interoperability code points and OIDs as well as a method to dynamically adapt them, e.g., for interoperability testing are @@ -186,6 +189,7 @@ Contributors to the `oqsprovider` include: - Alex Zaslavsky - Will Childs-Klein - Thomas Bailleux +- Felipe Ventura History ------- diff --git a/oqs-template/ALGORITHMS.md/oids.fragment b/oqs-template/ALGORITHMS.md/oids.fragment index cea8c3c3..0e04d830 100644 --- a/oqs-template/ALGORITHMS.md/oids.fragment +++ b/oqs-template/ALGORITHMS.md/oids.fragment @@ -8,6 +8,9 @@ {%- for classical_alg in variant['mix_with'] %} | {{ classical_alg['name'] }}_{{variant['name']}} | {{ classical_alg['oid'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_OID_{{ classical_alg['name']|upper }}_{{ variant['name']|upper }} {%- endfor %} + {%- for composite_alg in variant['composite'] %} +| {{variant['name']}}_{{ composite_alg['name'] }} | {{ composite_alg['oid'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_OID_{{ variant['name']|upper }}_{{ composite_alg['name'] }} + {%- endfor %} {%- endfor %} {%- endfor %} diff --git a/oqs-template/README.md/algs.fragment b/oqs-template/README.md/algs.fragment index 17e0785c..e13eb0b2 100644 --- a/oqs-template/README.md/algs.fragment +++ b/oqs-template/README.md/algs.fragment @@ -12,6 +12,7 @@ `{{ variant['name'] }}` {%- if variant['enable'] -%} \* {%- endif -%} {%- for classical_alg in variant['mix_with'] -%} , `{{ classical_alg['name']}}_{{ variant['name'] }}`{%- if variant['enable'] -%} \* {%- endif -%}{%- endfor -%} +{%- for composite_alg in variant['composite'] -%} , `{{ variant['name'] }}_{{ composite_alg['name']}}`{%- if variant['enable'] -%} \* {%- endif -%}{%- endfor -%} {%- if not loop.last %}, {% endif -%} {%- endfor -%} {%- endif -%} diff --git a/oqs-template/generate.yml b/oqs-template/generate.yml index e9fcd9bb..1839b970 100644 --- a/oqs-template/generate.yml +++ b/oqs-template/generate.yml @@ -423,7 +423,23 @@ sigs: # 'pretty_name': 'RSA3072', # 'oid': '1.3.9999.1.3', # 'code_point': '0xfe02'}] + # composite:[{'name': 'p256', + # 'pretty_name': 'ECDSA p256', + # 'security': '128', + # 'oid': '2.16.840.1.114027.80.1.8'}] - + # The Composite OIDs are kept up to date by @feventura (Entrust) + # These are prototype OIDs and are in line with draft-ounsworth-pq-composite-sigs-13 + # OID scheme for composite variants: + # joint-iso-itu-t (2) + # country (16) + # us (840) + # organization (1) + # entrust (114027) + # algorithm (80) + # composite (8) + # signature (1) + # - # OID scheme for hybrid variants of Dilithium: # iso (1) # identified-organization (3) @@ -439,6 +455,8 @@ sigs: # IBM (2) # qsc (267) # Dilithium-r3 (7) + + family: 'CRYSTALS-Dilithium' variants: - @@ -548,6 +566,26 @@ sigs: 'pretty_name': 'RSA3072', 'oid': '1.3.9999.7.2', 'code_point': '0xfed4'}] + composite: [{'name': 'pss2048', + 'pretty_name': 'RSA PSS 2048', + 'security': '112', + 'oid': '2.16.840.1.114027.80.8.1.1'}, + {'name': 'rsa2048', + 'pretty_name': 'RSA2028', + 'security': '112', + 'oid': '2.16.840.1.114027.80.8.1.2'}, + {'name': 'ed25519', + 'pretty_name': 'ED25519', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.3'}, + {'name': 'p256', + 'pretty_name': 'ECDSA p256', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.4'}, + {'name': 'bp256', + 'pretty_name': 'ECDSA brainpoolP256r1', + 'security': '256', + 'oid': '2.16.840.1.114027.80.8.1.5'}] - name: 'mldsa65' pretty_name: 'ML-DSA-65' @@ -559,6 +597,26 @@ sigs: 'pretty_name': 'ECDSA p384', 'oid': '1.3.9999.7.3', 'code_point': '0xfed5'}] + composite: [{'name': 'pss3072', + 'pretty_name': 'RSA PSS 3072', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.6'}, + {'name': 'rsa3072', + 'pretty_name': 'RSA 3072', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.7'}, + {'name': 'p256', + 'pretty_name': 'ECDSA p256', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.8'}, + {'name': 'bp256', + 'pretty_name': 'ECDSA brainpoolP256r1', + 'security': '256', + 'oid': '2.16.840.1.114027.80.8.1.9'}, + {'name': 'ed25519', + 'pretty_name': 'ED25519', + 'security': '128', + 'oid': '2.16.840.1.114027.80.8.1.10'}] - name: 'mldsa87' pretty_name: 'ML-DSA-87' @@ -570,6 +628,18 @@ sigs: 'pretty_name': 'ECDSA p521', 'oid': '1.3.9999.7.4', 'code_point': '0xfed6'}] + composite: [{'name': 'p384', + 'pretty_name': 'ECDSA p384', + 'security': '192', + 'oid': '2.16.840.1.114027.80.8.1.11'}, + {'name': 'bp384', + 'pretty_name': 'ECDSA brainpoolP384r1', + 'security': '384', + 'oid': '2.16.840.1.114027.80.8.1.12'}, + {'name': 'ed448', + 'pretty_name': 'ED448', + 'security': '192', + 'oid': '2.16.840.1.114027.80.8.1.13'}] - # iso (1) # identified-organization (3) diff --git a/oqs-template/oqsprov/oqs_decode_der2key.c/decoder_make.fragment b/oqs-template/oqsprov/oqs_decode_der2key.c/decoder_make.fragment index be39a93e..e99a82b2 100644 --- a/oqs-template/oqsprov/oqs_decode_der2key.c/decoder_make.fragment +++ b/oqs-template/oqsprov/oqs_decode_der2key.c/decoder_make.fragment @@ -19,6 +19,10 @@ MAKE_DECODER(, "{{ variant['name'] }}", {{ variant['name'] }}, oqsx, SubjectPubl MAKE_DECODER(, "{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, PrivateKeyInfo); MAKE_DECODER(, "{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectPublicKeyInfo); {%- endfor -%} + {%- for composite_alg in variant['composite'] %} +MAKE_DECODER(, "{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, SubjectPublicKeyInfo); + {%- endfor -%} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_defines.fragment b/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_defines.fragment index e5caab63..9eb193c0 100644 --- a/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_defines.fragment +++ b/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_defines.fragment @@ -19,6 +19,11 @@ # define {{ classical_alg['name'] }}_{{ variant['name'] }}_input_type "{{ classical_alg['name'] }}_{{ variant['name'] }}" # define {{ classical_alg['name'] }}_{{ variant['name'] }}_pem_type "{{ classical_alg['name'] }}_{{ variant['name'] }}" {%- endfor -%} + {%- for composite_alg in variant['composite'] %} +# define {{ variant['name'] }}_{{ composite_alg['name'] }}_evp_type 0 +# define {{ variant['name'] }}_{{ composite_alg['name'] }}_input_type "{{ variant['name'] }}_{{ composite_alg['name'] }}" +# define {{ variant['name'] }}_{{ composite_alg['name'] }}_pem_type "{{ variant['name'] }}_{{ composite_alg['name'] }}" + {%- endfor -%} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_make.fragment b/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_make.fragment index edc87530..f05a36b9 100644 --- a/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_make.fragment +++ b/oqs-template/oqsprov/oqs_encode_key2any.c/encoder_make.fragment @@ -38,6 +38,15 @@ MAKE_ENCODER(, {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectP MAKE_ENCODER(, {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectPublicKeyInfo, pem); MAKE_TEXT_ENCODER(, {{ classical_alg['name'] }}_{{ variant['name'] }}); {%- endfor -%} + {%- for composite_alg in variant['composite'] %} +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, {{ variant['name'] }}_{{ composite_alg['name'] }}); + {%- endfor -%} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment b/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment index df892142..847eff8d 100644 --- a/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment +++ b/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment @@ -24,6 +24,19 @@ static void *{{ classical_alg['name'] }}_{{variant['name']}}_gen_init(void *prov return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, {{variant['security']}}, {{ count.val }}); } + {%- endfor -%} + {%- for composite_alg in variant['composite'] %} + {%- set count.val = count.val + 1 %} +static void *{{ variant['name'] }}_{{ composite_alg['name'] }}_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, NULL, {{composite_alg['security']}}, {{ count.val }}); +} + +static void *{{ variant['name'] }}_{{ composite_alg['name'] }}_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, {{composite_alg['security']}}, {{ count.val }}); +} + {%- endfor -%} {%- endfor %} {% endfor %} diff --git a/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_functions.fragment b/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_functions.fragment index 93e6dbb8..8c0bc153 100644 --- a/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_functions.fragment +++ b/oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_functions.fragment @@ -4,6 +4,9 @@ MAKE_SIG_KEYMGMT_FUNCTIONS({{variant['name']}}) {%- for classical_alg in variant['mix_with'] %} MAKE_SIG_KEYMGMT_FUNCTIONS({{ classical_alg['name'] }}_{{variant['name']}}) {%- endfor -%} + {%- for composite_alg in variant['composite'] %} +MAKE_SIG_KEYMGMT_FUNCTIONS({{variant['name']}}_{{ composite_alg['name'] }}) + {%- endfor -%} {%- endfor %} {%- endfor %} {% for kem in config['kems'] %} diff --git a/oqs-template/oqsprov/oqs_prov.h/alg_functions.fragment b/oqs-template/oqsprov/oqs_prov.h/alg_functions.fragment index e18eb388..acc8e86c 100644 --- a/oqs-template/oqsprov/oqs_prov.h/alg_functions.fragment +++ b/oqs-template/oqsprov/oqs_prov.h/alg_functions.fragment @@ -4,6 +4,9 @@ extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_keymgmt_functions[]; {%- for classical_alg in variant['mix_with'] -%} extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_keymgmt_functions[]; {%- endfor -%} + {%- for composite_alg in variant['composite'] -%} +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_keymgmt_functions[]; + {%- endfor -%} {%- endfor %} {%- endfor %} {% for kem in config['kems'] %} diff --git a/oqs-template/oqsprov/oqs_prov.h/endecoder_functions.fragment b/oqs-template/oqsprov/oqs_prov.h/endecoder_functions.fragment index 43f1c3b0..85a71b8a 100644 --- a/oqs-template/oqsprov/oqs_prov.h/endecoder_functions.fragment +++ b/oqs-template/oqsprov/oqs_prov.h/endecoder_functions.fragment @@ -48,6 +48,17 @@ extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }} extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_{{ classical_alg['name'] }}_{{ variant['name'] }}_decoder_functions[]; extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_{{ classical_alg['name'] }}_{{ variant['name'] }}_decoder_functions[]; {%- endfor -%} + {%- for composite_alg in variant['composite'] -%} +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_{{ composite_alg['name'] }}_to_text_encoder_functions[]; +extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_{{ variant['name'] }}_{{ composite_alg['name'] }}_decoder_functions[]; +extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_{{ variant['name'] }}_{{ composite_alg['name'] }}_decoder_functions[]; + {%- endfor -%} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsdecoders.inc/make.fragment b/oqs-template/oqsprov/oqsdecoders.inc/make.fragment index a2d28c45..8d1c26e7 100644 --- a/oqs-template/oqsprov/oqsdecoders.inc/make.fragment +++ b/oqs-template/oqsprov/oqsdecoders.inc/make.fragment @@ -22,6 +22,10 @@ DECODER_w_structure("{{ variant['name'] }}", der, SubjectPublicKeyInfo, {{ varia DECODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", der, PrivateKeyInfo, {{ classical_alg['name'] }}_{{ variant['name'] }}), DECODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", der, SubjectPublicKeyInfo, {{ classical_alg['name'] }}_{{ variant['name'] }}), {%- endfor %} + {%- for composite_alg in variant['composite'] -%} +DECODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", der, PrivateKeyInfo, {{ variant['name'] }}_{{ composite_alg['name'] }}), +DECODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", der, SubjectPublicKeyInfo, {{ variant['name'] }}_{{ composite_alg['name'] }}), + {%- endfor %} #endif {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsencoders.inc/make.fragment b/oqs-template/oqsprov/oqsencoders.inc/make.fragment index 90464d6d..06509616 100644 --- a/oqs-template/oqsprov/oqsencoders.inc/make.fragment +++ b/oqs-template/oqsprov/oqsencoders.inc/make.fragment @@ -43,6 +43,15 @@ ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ clas ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, pem, SubjectPublicKeyInfo), ENCODER_TEXT("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}), {% endfor -%} +{% for composite_alg in variant['composite'] -%} +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, der, PrivateKeyInfo), +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, pem, PrivateKeyInfo), +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, der, SubjectPublicKeyInfo), +ENCODER_w_structure("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("{{ variant['name'] }}_{{ composite_alg['name'] }}", {{ variant['name'] }}_{{ composite_alg['name'] }}), +{% endfor -%} #endif {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsprov.c/assign_sig_oids.fragment b/oqs-template/oqsprov/oqsprov.c/assign_sig_oids.fragment index bb0c6e00..21af9c85 100644 --- a/oqs-template/oqsprov/oqsprov.c/assign_sig_oids.fragment +++ b/oqs-template/oqsprov/oqsprov.c/assign_sig_oids.fragment @@ -11,6 +11,9 @@ {%- for variant in sig['variants'] %} {%- set count.val = count.val + 1 -%} {%- for classical_alg in variant['mix_with'] %} +{%- set count.val = count.val + 1 -%} + {%- endfor %} + {%- for composite_alg in variant['composite'] %} {%- set count.val = count.val + 1 -%} {%- endfor %} {%- endfor %} @@ -40,6 +43,9 @@ const char* oqs_oid_alg_list[OQS_OID_CNT] = {%- for classical_alg in variant['mix_with'] %} "{{ classical_alg['oid'] }}" , "{{ classical_alg['name'] }}_{{ variant['name'] }}", {%- endfor %} + {%- for composite_alg in variant['composite'] %} +"{{ composite_alg['oid'] }}" , "{{ variant['name'] }}_{{ composite_alg['name'] }}", + {%- endfor %} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsprov.c/encoding_patching.fragment b/oqs-template/oqsprov/oqsprov.c/encoding_patching.fragment index 3531db2f..f629b840 100644 --- a/oqs-template/oqsprov/oqsprov.c/encoding_patching.fragment +++ b/oqs-template/oqsprov/oqsprov.c/encoding_patching.fragment @@ -9,6 +9,11 @@ if (getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}")) oqs_alg_encoding_list[{{ cnt.val }}] = getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}"); if (getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}_ALGNAME")) oqs_alg_encoding_list[{{ cnt.val + 1 }}] = getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}_ALGNAME"); {%- endfor %} + {%- for composite_alg in variant['composite'] %} + {%- set cnt.val = cnt.val + 2 %} + if (getenv("OQS_ENCODING_{{variant['name']|upper}}_{{ composite_alg['name']|upper }}")) oqs_alg_encoding_list[{{ cnt.val }}] = getenv("OQS_ENCODING_{{variant['name']|upper}}_{{ composite_alg['name']|upper }}"); + if (getenv("OQS_ENCODING_{{variant['name']|upper}}_{{ composite_alg['name']|upper }}_ALGNAME")) oqs_alg_encoding_list[{{ cnt.val + 1 }}] = getenv("OQS_ENCODING_{{variant['name']|upper}}_{{ composite_alg['name']|upper }}_ALGNAME"); + {%- endfor %} {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsprov.c/keymgmt_functions.fragment b/oqs-template/oqsprov/oqsprov.c/keymgmt_functions.fragment index ad49db2a..f98a4341 100644 --- a/oqs-template/oqsprov/oqsprov.c/keymgmt_functions.fragment +++ b/oqs-template/oqsprov/oqsprov.c/keymgmt_functions.fragment @@ -7,6 +7,9 @@ {%- for classical_alg in variant['mix_with'] %} SIGALG("{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['security']}}, oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_keymgmt_functions), {%- endfor %} + {%- for composite_alg in variant['composite'] %} + SIGALG("{{variant['name']}}_{{ composite_alg['name'] }}", {{composite_alg['security']}}, oqs_{{variant['name']}}_{{ composite_alg['name'] }}_keymgmt_functions), + {%- endfor %} #endif {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsprov.c/sig_functions.fragment b/oqs-template/oqsprov/oqsprov.c/sig_functions.fragment index 1dbc8be9..92a5c0a4 100644 --- a/oqs-template/oqsprov/oqsprov.c/sig_functions.fragment +++ b/oqs-template/oqsprov/oqsprov.c/sig_functions.fragment @@ -5,6 +5,9 @@ {%- for classical_alg in variant['mix_with'] %} SIGALG("{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['security']}}, oqs_signature_functions), {%- endfor %} + {%- for composite_alg in variant['composite'] %} + SIGALG("{{variant['name']}}_{{ composite_alg['name'] }}", {{composite_alg['security']}}, oqs_signature_functions), + {%- endfor %} #endif {%- endfor %} {%- endfor %} diff --git a/oqs-template/oqsprov/oqsprov_keys.c/oqsnames.fragment b/oqs-template/oqsprov/oqsprov_keys.c/oqsnames.fragment index c452b649..142cb2aa 100644 --- a/oqs-template/oqsprov/oqsprov_keys.c/oqsnames.fragment +++ b/oqs-template/oqsprov/oqsprov_keys.c/oqsnames.fragment @@ -15,6 +15,9 @@ {%- for classical_alg in variant['mix_with'] %} {%- set count.val = count.val + 1 -%} {%- endfor -%} +{%- for composite_alg in variant['composite'] %} +{%- set count.val = count.val + 1 -%} +{%- endfor -%} {%- endfor -%} {%- endfor %} @@ -41,6 +44,9 @@ static oqs_nid_name_t nid_names[NID_TABLE_LEN] = { {%- for classical_alg in variant['mix_with'] %} { 0, "{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['oqs_meth']}}, KEY_TYPE_HYB_SIG, {{variant['security']}} }, {%- endfor %} + {%- for composite_alg in variant['composite'] %} + { 0, "{{variant['name']}}_{{ composite_alg['name'] }}", {{variant['oqs_meth']}}, KEY_TYPE_CMP_SIG, {{composite_alg['security']}} }, + {%- endfor %} {%- endfor %} {%- endfor %} diff --git a/oqs-template/scripts/common.py/sig_algs.fragment b/oqs-template/scripts/common.py/sig_algs.fragment index 2541638a..07706745 100644 --- a/oqs-template/scripts/common.py/sig_algs.fragment +++ b/oqs-template/scripts/common.py/sig_algs.fragment @@ -9,4 +9,11 @@ '{{ classical_alg['name'] }}_{{ variant['name'] }}', {%- endfor -%} {%- endfor %} {%- endfor %} + # post-quantum + classical signatures (COMPOSITE) + {% for sig in config['sigs'] -%} + {%- for variant in sig['variants'] -%} + {%- for composite_alg in variant['composite'] -%} + '{{ variant['name'] }}_{{ composite_alg['name'] }}', + {%- endfor -%} + {%- endfor %} {%- endfor %} diff --git a/oqsprov/oqs_decode_der2key.c b/oqsprov/oqs_decode_der2key.c index ddaf6975..99093ffa 100644 --- a/oqsprov/oqs_decode_der2key.c +++ b/oqsprov/oqs_decode_der2key.c @@ -710,14 +710,40 @@ MAKE_DECODER(, "p256_mldsa44", p256_mldsa44, oqsx, PrivateKeyInfo); MAKE_DECODER(, "p256_mldsa44", p256_mldsa44, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "rsa3072_mldsa44", rsa3072_mldsa44, oqsx, PrivateKeyInfo); MAKE_DECODER(, "rsa3072_mldsa44", rsa3072_mldsa44, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa44_pss2048", mldsa44_pss2048, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa44_pss2048", mldsa44_pss2048, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa44_rsa2048", mldsa44_rsa2048, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa44_rsa2048", mldsa44_rsa2048, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa44_ed25519", mldsa44_ed25519, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa44_ed25519", mldsa44_ed25519, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa44_p256", mldsa44_p256, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa44_p256", mldsa44_p256, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa44_bp256", mldsa44_bp256, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa44_bp256", mldsa44_bp256, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "mldsa65", mldsa65, oqsx, PrivateKeyInfo); MAKE_DECODER(, "mldsa65", mldsa65, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "p384_mldsa65", p384_mldsa65, oqsx, PrivateKeyInfo); MAKE_DECODER(, "p384_mldsa65", p384_mldsa65, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa65_pss3072", mldsa65_pss3072, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa65_pss3072", mldsa65_pss3072, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa65_rsa3072", mldsa65_rsa3072, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa65_rsa3072", mldsa65_rsa3072, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa65_p256", mldsa65_p256, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa65_p256", mldsa65_p256, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa65_bp256", mldsa65_bp256, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa65_bp256", mldsa65_bp256, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa65_ed25519", mldsa65_ed25519, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa65_ed25519", mldsa65_ed25519, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "mldsa87", mldsa87, oqsx, PrivateKeyInfo); MAKE_DECODER(, "mldsa87", mldsa87, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "p521_mldsa87", p521_mldsa87, oqsx, PrivateKeyInfo); MAKE_DECODER(, "p521_mldsa87", p521_mldsa87, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa87_p384", mldsa87_p384, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa87_p384", mldsa87_p384, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa87_bp384", mldsa87_bp384, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa87_bp384", mldsa87_bp384, oqsx, SubjectPublicKeyInfo); +MAKE_DECODER(, "mldsa87_ed448", mldsa87_ed448, oqsx, PrivateKeyInfo); +MAKE_DECODER(, "mldsa87_ed448", mldsa87_ed448, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "falcon512", falcon512, oqsx, PrivateKeyInfo); MAKE_DECODER(, "falcon512", falcon512, oqsx, SubjectPublicKeyInfo); MAKE_DECODER(, "p256_falcon512", p256_falcon512, oqsx, PrivateKeyInfo); diff --git a/oqsprov/oqs_encode_key2any.c b/oqsprov/oqs_encode_key2any.c index b41c0f78..b06e6138 100644 --- a/oqsprov/oqs_encode_key2any.c +++ b/oqsprov/oqs_encode_key2any.c @@ -9,6 +9,7 @@ */ #include "oqs_endecoder_local.h" +#include "oqs_prov.h" #include #include #include @@ -22,6 +23,9 @@ #include #include +#include +#include + #ifdef NDEBUG # define OQS_ENC_PRINTF(a) # define OQS_ENC_PRINTF2(a, b) @@ -283,7 +287,7 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, int key_nid, key_to_paramstring_fn *p2s, i2d_of_void *k2d, struct key2any_ctx_st *ctx) { - int ret = 0; + int ret = 0, cmp_len = 0; void *str = NULL; int strtype = V_ASN1_UNDEF; PKCS8_PRIV_KEY_INFO *p8info; @@ -298,7 +302,6 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, int key_nid, return 0; p8info = key_to_p8info(key, key_nid, str, strtype, k2d); - if (p8info != NULL) ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); else @@ -496,7 +499,10 @@ static int prepare_oqsx_params(const void *oqsxkey, int nid, int save, static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) { const OQSX_KEY *oqsxkey = vxkey; - unsigned char *keyblob; + unsigned char *keyblob, *buf; + int keybloblen, nid, buflen = 0; + ASN1_OCTET_STRING oct; + STACK_OF(ASN1_TYPE) *sk = NULL; int ret = 0; OQS_ENC_PRINTF("OQS ENC provider: oqsx_spki_pub_to_der called\n"); @@ -505,40 +511,106 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER); return 0; } + if (oqsxkey->keytype != KEY_TYPE_CMP_SIG) { +#ifdef USE_ENCODING_LIB + if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL + && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { + unsigned char *buf; + int buflen; + int ret = 0; + const OQSX_ENCODING_CTX *encoding_ctx = &oqsxkey->oqsx_encoding_ctx; + buflen = encoding_ctx->encoding_impl->crypto_publickeybytes; + + buf = OPENSSL_secure_zalloc(buflen); + if (buf == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + return -1; + } + ret = qsc_encode(encoding_ctx->encoding_ctx, + encoding_ctx->encoding_impl, oqsxkey->pubkey, &buf, + 0, 0, 1); + if (ret != QSC_ENC_OK) + return -1; + + *pder = buf; + return buflen; + } else { +#endif + keyblob = OPENSSL_memdup(oqsxkey->pubkey, oqsxkey->pubkeylen); + if (keyblob == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + return 0; + } + *pder = keyblob; + return oqsxkey->pubkeylen; #ifdef USE_ENCODING_LIB - if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL - && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { - unsigned char *buf; - int buflen; - int ret = 0; - const OQSX_ENCODING_CTX *encoding_ctx = &oqsxkey->oqsx_encoding_ctx; - buflen = encoding_ctx->encoding_impl->crypto_publickeybytes; - - buf = OPENSSL_secure_zalloc(buflen); - if (buf == NULL) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - return -1; } - ret = qsc_encode(encoding_ctx->encoding_ctx, - encoding_ctx->encoding_impl, oqsxkey->pubkey, &buf, 0, - 0, 1); - if (ret != QSC_ENC_OK) - return -1; - - *pder = buf; - return buflen; - } else { #endif - keyblob = OPENSSL_memdup(oqsxkey->pubkey, oqsxkey->pubkeylen); - if (keyblob == NULL) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - return 0; + } else { + if ((sk = sk_ASN1_TYPE_new_null()) == NULL) + return -1; + ASN1_TYPE **aType + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_TYPE *)); + ASN1_BIT_STRING **aString + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_BIT_STRING *)); + unsigned char **temp + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(unsigned char *)); + size_t *templen = OPENSSL_malloc(oqsxkey->numkeys * sizeof(size_t)); + int i; + + for (i = 0; i < oqsxkey->numkeys; i++) { + aType[i] = ASN1_TYPE_new(); + aString[i] = ASN1_BIT_STRING_new(); + temp[i] = NULL; + + buflen = oqsxkey->pubkeylen_cmp[i]; + buf = OPENSSL_secure_malloc(buflen); + memcpy(buf, oqsxkey->comp_pubkey[i], buflen); + + oct.data = buf; + oct.length = buflen; + oct.flags = 8; + templen[i] = i2d_ASN1_BIT_STRING(&oct, &temp[i]); + ASN1_STRING_set(aString[i], temp[i], templen[i]); + ASN1_TYPE_set1(aType[i], V_ASN1_SEQUENCE, aString[i]); + + if (!sk_ASN1_TYPE_push(sk, aType[i])) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_BIT_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + OPENSSL_clear_free(temp[j], templen[j]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_secure_clear_free(buf, buflen); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + return -1; + } + OPENSSL_secure_clear_free(buf, buflen); } - *pder = keyblob; - return oqsxkey->pubkeylen; -#ifdef USE_ENCODING_LIB + keybloblen = i2d_ASN1_SEQUENCE_ANY(sk, pder); + + for (i = 0; i < oqsxkey->numkeys; i++) { + OPENSSL_cleanse(aString[i]->data, aString[i]->length); + ASN1_BIT_STRING_free(aString[i]); + OPENSSL_cleanse(aType[i]->value.sequence->data, + aType[i]->value.sequence->length); + OPENSSL_clear_free(temp[i], templen[i]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + + return keybloblen; } -#endif } static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) @@ -547,7 +619,9 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) unsigned char *buf = NULL; int buflen = 0, privkeylen; ASN1_OCTET_STRING oct; - int keybloblen; + int keybloblen, nid; + STACK_OF(ASN1_TYPE) *sk = NULL; + char *name; OQS_ENC_PRINTF("OQS ENC provider: oqsx_pki_priv_to_der called\n"); @@ -566,89 +640,298 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) // only concatenate private classic key (if any) and OQS private and public // key NOT saving public classic key component (if any) - privkeylen = oqsxkey->privkeylen; - if (oqsxkey->numkeys > 1) { // hybrid - int actualprivkeylen; - DECODE_UINT32(actualprivkeylen, oqsxkey->privkey); - if (actualprivkeylen > oqsxkey->evp_info->length_private_key) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - return 0; + if (oqsxkey->keytype != KEY_TYPE_CMP_SIG) { + privkeylen = oqsxkey->privkeylen; + if (oqsxkey->numkeys > 1) { // hybrid + int actualprivkeylen; + DECODE_UINT32(actualprivkeylen, oqsxkey->privkey); + if (actualprivkeylen > oqsxkey->evp_info->length_private_key) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + return 0; + } + privkeylen + -= (oqsxkey->evp_info->length_private_key - actualprivkeylen); } - privkeylen - -= (oqsxkey->evp_info->length_private_key - actualprivkeylen); - } #ifdef USE_ENCODING_LIB - if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL - && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { - const OQSX_ENCODING_CTX *encoding_ctx = &oqsxkey->oqsx_encoding_ctx; - int ret = 0; + if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL + && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) { + const OQSX_ENCODING_CTX *encoding_ctx = &oqsxkey->oqsx_encoding_ctx; + int ret = 0; # ifdef NOPUBKEY_IN_PRIVKEY - int withoptional - = (encoding_ctx->encoding_ctx->raw_private_key_encodes_public_key - ? 1 - : 0); + int withoptional = (encoding_ctx->encoding_ctx + ->raw_private_key_encodes_public_key + ? 1 + : 0); # else - int withoptional = 1; + int withoptional = 1; # endif - buflen - = (withoptional ? encoding_ctx->encoding_impl->crypto_secretkeybytes - : encoding_ctx->encoding_impl - ->crypto_secretkeybytes_nooptional); - buf = OPENSSL_secure_zalloc(buflen); - if (buf == NULL) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - return -1; - } + buflen = (withoptional + ? encoding_ctx->encoding_impl->crypto_secretkeybytes + : encoding_ctx->encoding_impl + ->crypto_secretkeybytes_nooptional); + buf = OPENSSL_secure_zalloc(buflen); + if (buf == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + return -1; + } - ret = qsc_encode(encoding_ctx->encoding_ctx, - encoding_ctx->encoding_impl, - oqsxkey->comp_pubkey[oqsxkey->numkeys - 1], 0, - oqsxkey->privkey, &buf, withoptional); - if (ret != QSC_ENC_OK) - return -1; - } else { + ret = qsc_encode(encoding_ctx->encoding_ctx, + encoding_ctx->encoding_impl, + oqsxkey->comp_pubkey[oqsxkey->numkeys - 1], 0, + oqsxkey->privkey, &buf, withoptional); + if (ret != QSC_ENC_OK) + return -1; + } else { #endif #ifdef NOPUBKEY_IN_PRIVKEY - buflen = privkeylen; + buflen = privkeylen; + buf = OPENSSL_secure_malloc(buflen); + if (buf == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + return -1; + } + OQS_ENC_PRINTF2("OQS ENC provider: saving privkey of length %d\n", + buflen); + memcpy(buf, oqsxkey->privkey, privkeylen); +#else + buflen = privkeylen + oqsx_key_get_oqs_public_key_len(oqsxkey); buf = OPENSSL_secure_malloc(buflen); if (buf == NULL) { ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); return -1; } - OQS_ENC_PRINTF2("OQS ENC provider: saving privkey of length %d\n", + OQS_ENC_PRINTF2("OQS ENC provider: saving priv+pubkey of length %d\n", buflen); memcpy(buf, oqsxkey->privkey, privkeylen); -#else - buflen = privkeylen + oqsx_key_get_oqs_public_key_len(oqsxkey); - buf = OPENSSL_secure_malloc(buflen); - if (buf == NULL) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - return -1; - } - OQS_ENC_PRINTF2("OQS ENC provider: saving priv+pubkey of length %d\n", - buflen); - memcpy(buf, oqsxkey->privkey, privkeylen); - memcpy(buf + privkeylen, oqsxkey->comp_pubkey[oqsxkey->numkeys - 1], - oqsx_key_get_oqs_public_key_len(oqsxkey)); + memcpy(buf + privkeylen, oqsxkey->comp_pubkey[oqsxkey->numkeys - 1], + oqsx_key_get_oqs_public_key_len(oqsxkey)); #endif #ifdef USE_ENCODING_LIB - } + } #endif - oct.data = buf; - oct.length = buflen; - // more logical: - // oct.data = oqsxkey->privkey; - // oct.length = oqsxkey->privkeylen; - oct.flags = 0; + oct.data = buf; + oct.length = buflen; + // more logical: + // oct.data = oqsxkey->privkey; + // oct.length = oqsxkey->privkeylen; + oct.flags = 0; - keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); - if (keybloblen < 0) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - keybloblen = 0; // signal error - } + keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); + if (keybloblen < 0) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + keybloblen = 0; // signal error + } + OPENSSL_secure_clear_free(buf, buflen); + } else { + ASN1_TYPE **aType + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_TYPE *)); + ASN1_OCTET_STRING **aString + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_OCTET_STRING *)); + unsigned char **temp + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(unsigned char *)); + size_t *templen = OPENSSL_malloc(oqsxkey->numkeys * sizeof(size_t)); + PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL; + int i; + + if ((sk = sk_ASN1_TYPE_new_null()) == NULL) + return -1; - OPENSSL_secure_clear_free(buf, buflen); + for (i = 0; i < oqsxkey->numkeys; i++) { + aType[i] = ASN1_TYPE_new(); + aString[i] = ASN1_OCTET_STRING_new(); + p8inf_internal = PKCS8_PRIV_KEY_INFO_new(); + temp[i] = NULL; + int nid, version; + void *pval; + + if ((name = get_cmpname(OBJ_sn2nid(oqsxkey->tls_name), i)) + == NULL) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + if (j < i) + OPENSSL_clear_free(temp[j], templen[j]); + } + + if (sk_ASN1_TYPE_num(sk) != -1) + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + else + ASN1_TYPE_free(aType[i]); + + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + return -1; + } + + if (get_oqsname_fromtls(name) == 0) { + + nid = oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype; + if (nid == EVP_PKEY_RSA) { // get the RSA real key size + unsigned char *enc_len + = OPENSSL_strndup(oqsxkey->comp_privkey[i], 4); + OPENSSL_cleanse(enc_len, 2); + DECODE_UINT32(buflen, enc_len); + buflen += 4; + OPENSSL_free(enc_len); + if (buflen > oqsxkey->privkeylen_cmp[i]) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, + aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + if (j < i) + OPENSSL_clear_free(temp[j], templen[j]); + } + + if (sk_ASN1_TYPE_num(sk) != -1) + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + else + ASN1_TYPE_free(aType[i]); + + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + OPENSSL_free(name); + return -1; + } + } else + buflen = oqsxkey->privkeylen_cmp[i]; + } else { + nid = OBJ_sn2nid(name); + buflen = oqsxkey->privkeylen_cmp[i] + oqsxkey->pubkeylen_cmp[i]; + } + + buf = OPENSSL_secure_malloc(buflen); + if (buf == NULL) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + if (j < i) + OPENSSL_clear_free(temp[j], templen[j]); + } + + if (sk_ASN1_TYPE_num(sk) != -1) + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + else + ASN1_TYPE_free(aType[i]); + + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + OPENSSL_free(name); + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + return -1; + } + if (get_oqsname_fromtls(name) + != 0) { // include pubkey in privkey for PQC + memcpy(buf, oqsxkey->comp_privkey[i], + oqsxkey->privkeylen_cmp[i]); + memcpy(buf + oqsxkey->privkeylen_cmp[i], + oqsxkey->comp_pubkey[i], oqsxkey->pubkeylen_cmp[i]); + } else { + memcpy(buf, oqsxkey->comp_privkey[i], + buflen); // buflen for classical (RSA) might be different + // from oqsxkey->privkeylen_cmp[ + } + + if (nid == EVP_PKEY_EC) { // add the curve OID with the ECPubkey OID + version = V_ASN1_OBJECT; + pval = OBJ_nid2obj( + oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->nid); + } else { + version = V_ASN1_UNDEF; + pval = NULL; + } + if (!PKCS8_pkey_set0(p8inf_internal, OBJ_nid2obj(nid), 0, version, + pval, buf, buflen)) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + OPENSSL_clear_free(temp[j], templen[j]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_free(name); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + OPENSSL_cleanse( + buf, + buflen); // buf is part of p8inf_internal so we cant free + // now, we cleanse it to remove pkey from memory + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); // this also free buf + return -1; + } + + templen[i] = i2d_PKCS8_PRIV_KEY_INFO( + p8inf_internal, + &temp[i]); // create the privkey info for each individual key + ASN1_STRING_set(aString[i], temp[i], + templen[i]); // add privkey info as ASN1_STRING + ASN1_TYPE_set1(aType[i], V_ASN1_SEQUENCE, + aString[i]); // add the ASN1_STRING into a ANS1_TYPE + // so it can be added into the stack + + if (!sk_ASN1_TYPE_push(sk, aType[i])) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + OPENSSL_clear_free(temp[j], templen[j]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_free(name); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + OPENSSL_cleanse( + buf, + buflen); // buf is part of p8inf_internal so we cant free + // now, we cleanse it to remove pkey from memory + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); // this also free buf + return -1; + } + OPENSSL_free(name); + + OPENSSL_cleanse(buf, buflen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + } + keybloblen = i2d_ASN1_SEQUENCE_ANY(sk, pder); + + for (i = 0; i < oqsxkey->numkeys; i++) { + OPENSSL_cleanse(aString[i]->data, aString[i]->length); + ASN1_OCTET_STRING_free(aString[i]); + OPENSSL_cleanse(aType[i]->value.sequence->data, + aType[i]->value.sequence->length); + OPENSSL_clear_free(temp[i], templen[i]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + } return keybloblen; } @@ -873,18 +1156,57 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) #define rsa3072_mldsa44_evp_type 0 #define rsa3072_mldsa44_input_type "rsa3072_mldsa44" #define rsa3072_mldsa44_pem_type "rsa3072_mldsa44" +#define mldsa44_pss2048_evp_type 0 +#define mldsa44_pss2048_input_type "mldsa44_pss2048" +#define mldsa44_pss2048_pem_type "mldsa44_pss2048" +#define mldsa44_rsa2048_evp_type 0 +#define mldsa44_rsa2048_input_type "mldsa44_rsa2048" +#define mldsa44_rsa2048_pem_type "mldsa44_rsa2048" +#define mldsa44_ed25519_evp_type 0 +#define mldsa44_ed25519_input_type "mldsa44_ed25519" +#define mldsa44_ed25519_pem_type "mldsa44_ed25519" +#define mldsa44_p256_evp_type 0 +#define mldsa44_p256_input_type "mldsa44_p256" +#define mldsa44_p256_pem_type "mldsa44_p256" +#define mldsa44_bp256_evp_type 0 +#define mldsa44_bp256_input_type "mldsa44_bp256" +#define mldsa44_bp256_pem_type "mldsa44_bp256" #define mldsa65_evp_type 0 #define mldsa65_input_type "mldsa65" #define mldsa65_pem_type "mldsa65" #define p384_mldsa65_evp_type 0 #define p384_mldsa65_input_type "p384_mldsa65" #define p384_mldsa65_pem_type "p384_mldsa65" +#define mldsa65_pss3072_evp_type 0 +#define mldsa65_pss3072_input_type "mldsa65_pss3072" +#define mldsa65_pss3072_pem_type "mldsa65_pss3072" +#define mldsa65_rsa3072_evp_type 0 +#define mldsa65_rsa3072_input_type "mldsa65_rsa3072" +#define mldsa65_rsa3072_pem_type "mldsa65_rsa3072" +#define mldsa65_p256_evp_type 0 +#define mldsa65_p256_input_type "mldsa65_p256" +#define mldsa65_p256_pem_type "mldsa65_p256" +#define mldsa65_bp256_evp_type 0 +#define mldsa65_bp256_input_type "mldsa65_bp256" +#define mldsa65_bp256_pem_type "mldsa65_bp256" +#define mldsa65_ed25519_evp_type 0 +#define mldsa65_ed25519_input_type "mldsa65_ed25519" +#define mldsa65_ed25519_pem_type "mldsa65_ed25519" #define mldsa87_evp_type 0 #define mldsa87_input_type "mldsa87" #define mldsa87_pem_type "mldsa87" #define p521_mldsa87_evp_type 0 #define p521_mldsa87_input_type "p521_mldsa87" #define p521_mldsa87_pem_type "p521_mldsa87" +#define mldsa87_p384_evp_type 0 +#define mldsa87_p384_input_type "mldsa87_p384" +#define mldsa87_p384_pem_type "mldsa87_p384" +#define mldsa87_bp384_evp_type 0 +#define mldsa87_bp384_input_type "mldsa87_bp384" +#define mldsa87_bp384_pem_type "mldsa87_bp384" +#define mldsa87_ed448_evp_type 0 +#define mldsa87_ed448_input_type "mldsa87_ed448" +#define mldsa87_ed448_pem_type "mldsa87_ed448" #define falcon512_evp_type 0 #define falcon512_input_type "falcon512" #define falcon512_pem_type "falcon512" @@ -1361,6 +1683,11 @@ static int oqsx_to_text(BIO *out, const void *key, int selection) <= 0) return 0; break; + case KEY_TYPE_CMP_SIG: + if (BIO_printf(out, "%s composite private key:\n", okey->tls_name) + <= 0) + return 0; + break; default: ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY); return 0; @@ -1383,6 +1710,11 @@ static int oqsx_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s hybrid public key:\n", okey->tls_name) <= 0) return 0; break; + case KEY_TYPE_CMP_SIG: + if (BIO_printf(out, "%s composite public key:\n", okey->tls_name) + <= 0) + return 0; + break; default: ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY); return 0; @@ -1391,51 +1723,112 @@ static int oqsx_to_text(BIO *out, const void *key, int selection) if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { if (okey->privkey) { - if (okey->numkeys > 1) { // hybrid key - char classic_label[200]; - int classic_key_len = 0; - sprintf(classic_label, - "%s key material:", OBJ_nid2sn(okey->evp_info->nid)); - DECODE_UINT32(classic_key_len, okey->privkey); - if (!print_labeled_buf(out, classic_label, - okey->comp_privkey[0], classic_key_len)) - return 0; - /* finally print pure PQ key */ - if (!print_labeled_buf(out, "PQ key material:", - okey->comp_privkey[okey->numkeys - 1], - okey->privkeylen - classic_key_len - - SIZE_OF_UINT32)) - return 0; - } else { // plain PQ key - if (!print_labeled_buf(out, "PQ key material:", - okey->comp_privkey[okey->numkeys - 1], - okey->privkeylen)) - return 0; + if (okey->keytype == KEY_TYPE_CMP_SIG) { + char *name; + char label[200]; + int i, privlen; + for (i = 0; i < okey->numkeys; i++) { + if ((name = get_cmpname(OBJ_sn2nid(okey->tls_name), i)) + == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY); + return 0; + } + sprintf(label, "%s key material:", name); + + if (get_oqsname_fromtls(name) == 0 // classical key + && okey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype + == EVP_PKEY_RSA) { // get the RSA real key size + unsigned char *enc_len + = OPENSSL_strndup(okey->comp_privkey[i], 4); + OPENSSL_cleanse(enc_len, 2); + DECODE_UINT32(privlen, enc_len); + privlen += 4; + OPENSSL_free(enc_len); + if (privlen > okey->privkeylen_cmp[i]) { + OPENSSL_free(name); + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + return 0; + } + } else + privlen = okey->privkeylen_cmp[i]; + if (!print_labeled_buf(out, label, okey->comp_privkey[i], + privlen)) + return 0; + + OPENSSL_free(name); + } + } else { + if (okey->numkeys > 1) { // hybrid key + char classic_label[200]; + int classic_key_len = 0; + sprintf(classic_label, "%s key material:", + OBJ_nid2sn(okey->evp_info->nid)); + DECODE_UINT32(classic_key_len, okey->privkey); + if (!print_labeled_buf(out, classic_label, + okey->comp_privkey[0], + classic_key_len)) + return 0; + /* finally print pure PQ key */ + if (!print_labeled_buf( + out, "PQ key material:", + okey->comp_privkey[okey->numkeys - 1], + okey->privkeylen - classic_key_len + - SIZE_OF_UINT32)) + return 0; + } else { // plain PQ key + if (!print_labeled_buf( + out, "PQ key material:", + okey->comp_privkey[okey->numkeys - 1], + okey->privkeylen)) + return 0; + } } } } if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { if (okey->pubkey) { - if (okey->numkeys > 1) { // hybrid key - char classic_label[200]; - int classic_key_len = 0; - DECODE_UINT32(classic_key_len, okey->pubkey); - sprintf(classic_label, - "%s key material:", OBJ_nid2sn(okey->evp_info->nid)); - if (!print_labeled_buf(out, classic_label, okey->comp_pubkey[0], - classic_key_len)) - return 0; - /* finally print pure PQ key */ - if (!print_labeled_buf(out, "PQ key material:", - okey->comp_pubkey[okey->numkeys - 1], - okey->pubkeylen - classic_key_len - - SIZE_OF_UINT32)) - return 0; - } else { // PQ key only - if (!print_labeled_buf(out, "PQ key material:", - okey->comp_pubkey[okey->numkeys - 1], - okey->pubkeylen)) - return 0; + if (okey->keytype == KEY_TYPE_CMP_SIG) { + char *name; + char label[200]; + int i; + for (i = 0; i < okey->numkeys; i++) { + if ((name = get_cmpname(OBJ_sn2nid(okey->tls_name), i)) + == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY); + return 0; + } + sprintf(label, "%s key material:", name); + + if (!print_labeled_buf(out, label, okey->comp_pubkey[i], + okey->pubkeylen_cmp[i])) + return 0; + + OPENSSL_free(name); + } + } else { + if (okey->numkeys > 1) { // hybrid key + char classic_label[200]; + int classic_key_len = 0; + DECODE_UINT32(classic_key_len, okey->pubkey); + sprintf(classic_label, "%s key material:", + OBJ_nid2sn(okey->evp_info->nid)); + if (!print_labeled_buf(out, classic_label, + okey->comp_pubkey[0], + classic_key_len)) + return 0; + /* finally print pure PQ key */ + if (!print_labeled_buf(out, "PQ key material:", + okey->comp_pubkey[okey->numkeys - 1], + okey->pubkeylen - classic_key_len + - SIZE_OF_UINT32)) + return 0; + } else { // PQ key only + if (!print_labeled_buf(out, "PQ key material:", + okey->comp_pubkey[okey->numkeys - 1], + okey->pubkeylen)) + return 0; + } } } } @@ -1985,6 +2378,41 @@ MAKE_ENCODER(, rsa3072_mldsa44, oqsx, PrivateKeyInfo, pem); MAKE_ENCODER(, rsa3072_mldsa44, oqsx, SubjectPublicKeyInfo, der); MAKE_ENCODER(, rsa3072_mldsa44, oqsx, SubjectPublicKeyInfo, pem); MAKE_TEXT_ENCODER(, rsa3072_mldsa44); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa44_pss2048, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa44_pss2048); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa44_rsa2048, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa44_rsa2048); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa44_ed25519, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa44_ed25519); +MAKE_ENCODER(, mldsa44_p256, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_p256, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_p256, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_p256, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_p256, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa44_p256, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa44_p256); +MAKE_ENCODER(, mldsa44_bp256, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_bp256, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_bp256, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa44_bp256, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa44_bp256, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa44_bp256, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa44_bp256); MAKE_ENCODER(, mldsa65, oqsx, EncryptedPrivateKeyInfo, der); MAKE_ENCODER(, mldsa65, oqsx, EncryptedPrivateKeyInfo, pem); MAKE_ENCODER(, mldsa65, oqsx, PrivateKeyInfo, der); @@ -1999,6 +2427,41 @@ MAKE_ENCODER(, p384_mldsa65, oqsx, PrivateKeyInfo, pem); MAKE_ENCODER(, p384_mldsa65, oqsx, SubjectPublicKeyInfo, der); MAKE_ENCODER(, p384_mldsa65, oqsx, SubjectPublicKeyInfo, pem); MAKE_TEXT_ENCODER(, p384_mldsa65); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa65_pss3072, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa65_pss3072); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa65_rsa3072, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa65_rsa3072); +MAKE_ENCODER(, mldsa65_p256, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_p256, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_p256, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_p256, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_p256, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa65_p256, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa65_p256); +MAKE_ENCODER(, mldsa65_bp256, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_bp256, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_bp256, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_bp256, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_bp256, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa65_bp256, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa65_bp256); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa65_ed25519, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa65_ed25519); MAKE_ENCODER(, mldsa87, oqsx, EncryptedPrivateKeyInfo, der); MAKE_ENCODER(, mldsa87, oqsx, EncryptedPrivateKeyInfo, pem); MAKE_ENCODER(, mldsa87, oqsx, PrivateKeyInfo, der); @@ -2013,6 +2476,27 @@ MAKE_ENCODER(, p521_mldsa87, oqsx, PrivateKeyInfo, pem); MAKE_ENCODER(, p521_mldsa87, oqsx, SubjectPublicKeyInfo, der); MAKE_ENCODER(, p521_mldsa87, oqsx, SubjectPublicKeyInfo, pem); MAKE_TEXT_ENCODER(, p521_mldsa87); +MAKE_ENCODER(, mldsa87_p384, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_p384, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_p384, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_p384, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_p384, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa87_p384, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa87_p384); +MAKE_ENCODER(, mldsa87_bp384, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_bp384, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_bp384, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_bp384, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_bp384, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa87_bp384, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa87_bp384); +MAKE_ENCODER(, mldsa87_ed448, oqsx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_ed448, oqsx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_ed448, oqsx, PrivateKeyInfo, der); +MAKE_ENCODER(, mldsa87_ed448, oqsx, PrivateKeyInfo, pem); +MAKE_ENCODER(, mldsa87_ed448, oqsx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(, mldsa87_ed448, oqsx, SubjectPublicKeyInfo, pem); +MAKE_TEXT_ENCODER(, mldsa87_ed448); MAKE_ENCODER(, falcon512, oqsx, EncryptedPrivateKeyInfo, der); MAKE_ENCODER(, falcon512, oqsx, EncryptedPrivateKeyInfo, pem); MAKE_ENCODER(, falcon512, oqsx, PrivateKeyInfo, der); diff --git a/oqsprov/oqs_kmgmt.c b/oqsprov/oqs_kmgmt.c index a613a022..7c5f870e 100644 --- a/oqsprov/oqs_kmgmt.c +++ b/oqsprov/oqs_kmgmt.c @@ -73,6 +73,7 @@ struct oqsx_gen_ctx { OSSL_LIB_CTX *libctx; char *propq; char *oqs_name; + char *cmp_name; char *tls_name; int primitive; int selection; @@ -485,6 +486,7 @@ static void *oqsx_gen_init(void *provctx, int selection, char *oqs_name, if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; + gctx->cmp_name = NULL; gctx->oqs_name = OPENSSL_strdup(oqs_name); gctx->tls_name = OPENSSL_strdup(tls_name); gctx->primitive = primitive; @@ -704,198 +706,341 @@ static void *rsa3072_mldsa44_gen_init(void *provctx, int selection) return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, "rsa3072_mldsa44", KEY_TYPE_HYB_SIG, 128, 9); } +static void *mldsa44_pss2048_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_44, + "mldsa44_pss2048", KEY_TYPE_CMP_SIG, NULL, 112, 10); +} + +static void *mldsa44_pss2048_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, + "mldsa44_pss2048", KEY_TYPE_CMP_SIG, 112, 10); +} +static void *mldsa44_rsa2048_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_44, + "mldsa44_rsa2048", KEY_TYPE_CMP_SIG, NULL, 112, 11); +} + +static void *mldsa44_rsa2048_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, + "mldsa44_rsa2048", KEY_TYPE_CMP_SIG, 112, 11); +} +static void *mldsa44_ed25519_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_44, + "mldsa44_ed25519", KEY_TYPE_CMP_SIG, NULL, 128, 12); +} + +static void *mldsa44_ed25519_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, + "mldsa44_ed25519", KEY_TYPE_CMP_SIG, 128, 12); +} +static void *mldsa44_p256_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_44, + "mldsa44_p256", KEY_TYPE_CMP_SIG, NULL, 128, 13); +} + +static void *mldsa44_p256_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, + "mldsa44_p256", KEY_TYPE_CMP_SIG, 128, 13); +} +static void *mldsa44_bp256_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_44, + "mldsa44_bp256", KEY_TYPE_CMP_SIG, NULL, 256, 14); +} + +static void *mldsa44_bp256_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_44, + "mldsa44_bp256", KEY_TYPE_CMP_SIG, 256, 14); +} static void *mldsa65_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, - "mldsa65", KEY_TYPE_SIG, NULL, 192, 10); + "mldsa65", KEY_TYPE_SIG, NULL, 192, 15); } static void *mldsa65_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, "mldsa65", - 0, 192, 10); + 0, 192, 15); } static void *p384_mldsa65_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, - "p384_mldsa65", KEY_TYPE_HYB_SIG, NULL, 192, 11); + "p384_mldsa65", KEY_TYPE_HYB_SIG, NULL, 192, 16); } static void *p384_mldsa65_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, - "p384_mldsa65", KEY_TYPE_HYB_SIG, 192, 11); + "p384_mldsa65", KEY_TYPE_HYB_SIG, 192, 16); +} +static void *mldsa65_pss3072_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, + "mldsa65_pss3072", KEY_TYPE_CMP_SIG, NULL, 128, 17); +} + +static void *mldsa65_pss3072_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, + "mldsa65_pss3072", KEY_TYPE_CMP_SIG, 128, 17); +} +static void *mldsa65_rsa3072_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, + "mldsa65_rsa3072", KEY_TYPE_CMP_SIG, NULL, 128, 18); +} + +static void *mldsa65_rsa3072_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, + "mldsa65_rsa3072", KEY_TYPE_CMP_SIG, 128, 18); +} +static void *mldsa65_p256_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, + "mldsa65_p256", KEY_TYPE_CMP_SIG, NULL, 128, 19); +} + +static void *mldsa65_p256_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, + "mldsa65_p256", KEY_TYPE_CMP_SIG, 128, 19); +} +static void *mldsa65_bp256_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, + "mldsa65_bp256", KEY_TYPE_CMP_SIG, NULL, 256, 20); +} + +static void *mldsa65_bp256_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, + "mldsa65_bp256", KEY_TYPE_CMP_SIG, 256, 20); +} +static void *mldsa65_ed25519_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_65, + "mldsa65_ed25519", KEY_TYPE_CMP_SIG, NULL, 128, 21); +} + +static void *mldsa65_ed25519_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_65, + "mldsa65_ed25519", KEY_TYPE_CMP_SIG, 128, 21); } static void *mldsa87_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_87, - "mldsa87", KEY_TYPE_SIG, NULL, 256, 12); + "mldsa87", KEY_TYPE_SIG, NULL, 256, 22); } static void *mldsa87_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_87, "mldsa87", - 0, 256, 12); + 0, 256, 22); } static void *p521_mldsa87_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_87, - "p521_mldsa87", KEY_TYPE_HYB_SIG, NULL, 256, 13); + "p521_mldsa87", KEY_TYPE_HYB_SIG, NULL, 256, 23); } static void *p521_mldsa87_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_87, - "p521_mldsa87", KEY_TYPE_HYB_SIG, 256, 13); + "p521_mldsa87", KEY_TYPE_HYB_SIG, 256, 23); +} +static void *mldsa87_p384_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_87, + "mldsa87_p384", KEY_TYPE_CMP_SIG, NULL, 192, 24); +} + +static void *mldsa87_p384_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_87, + "mldsa87_p384", KEY_TYPE_CMP_SIG, 192, 24); +} +static void *mldsa87_bp384_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_87, + "mldsa87_bp384", KEY_TYPE_CMP_SIG, NULL, 384, 25); +} + +static void *mldsa87_bp384_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_87, + "mldsa87_bp384", KEY_TYPE_CMP_SIG, 384, 25); +} +static void *mldsa87_ed448_new_key(void *provctx) +{ + return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_ml_dsa_87, + "mldsa87_ed448", KEY_TYPE_CMP_SIG, NULL, 192, 26); +} + +static void *mldsa87_ed448_gen_init(void *provctx, int selection) +{ + return oqsx_gen_init(provctx, selection, OQS_SIG_alg_ml_dsa_87, + "mldsa87_ed448", KEY_TYPE_CMP_SIG, 192, 26); } static void *falcon512_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, - "falcon512", KEY_TYPE_SIG, NULL, 128, 14); + "falcon512", KEY_TYPE_SIG, NULL, 128, 27); } static void *falcon512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, - "falcon512", 0, 128, 14); + "falcon512", 0, 128, 27); } static void *p256_falcon512_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, - "p256_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 15); + "p256_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 28); } static void *p256_falcon512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, - "p256_falcon512", KEY_TYPE_HYB_SIG, 128, 15); + "p256_falcon512", KEY_TYPE_HYB_SIG, 128, 28); } static void *rsa3072_falcon512_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, - "rsa3072_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 16); + "rsa3072_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 29); } static void *rsa3072_falcon512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, - "rsa3072_falcon512", KEY_TYPE_HYB_SIG, 128, 16); + "rsa3072_falcon512", KEY_TYPE_HYB_SIG, 128, 29); } static void *falconpadded512_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_padded_512, "falconpadded512", - KEY_TYPE_SIG, NULL, 128, 17); + KEY_TYPE_SIG, NULL, 128, 30); } static void *falconpadded512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_padded_512, - "falconpadded512", 0, 128, 17); + "falconpadded512", 0, 128, 30); } static void *p256_falconpadded512_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_padded_512, "p256_falconpadded512", - KEY_TYPE_HYB_SIG, NULL, 128, 18); + KEY_TYPE_HYB_SIG, NULL, 128, 31); } static void *p256_falconpadded512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_padded_512, - "p256_falconpadded512", KEY_TYPE_HYB_SIG, 128, 18); + "p256_falconpadded512", KEY_TYPE_HYB_SIG, 128, 31); } static void *rsa3072_falconpadded512_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_padded_512, - "rsa3072_falconpadded512", KEY_TYPE_HYB_SIG, NULL, 128, 19); + "rsa3072_falconpadded512", KEY_TYPE_HYB_SIG, NULL, 128, 32); } static void *rsa3072_falconpadded512_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_padded_512, - "rsa3072_falconpadded512", KEY_TYPE_HYB_SIG, 128, 19); + "rsa3072_falconpadded512", KEY_TYPE_HYB_SIG, 128, 32); } static void *falcon1024_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_1024, - "falcon1024", KEY_TYPE_SIG, NULL, 256, 20); + "falcon1024", KEY_TYPE_SIG, NULL, 256, 33); } static void *falcon1024_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_1024, - "falcon1024", 0, 256, 20); + "falcon1024", 0, 256, 33); } static void *p521_falcon1024_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_1024, - "p521_falcon1024", KEY_TYPE_HYB_SIG, NULL, 256, 21); + "p521_falcon1024", KEY_TYPE_HYB_SIG, NULL, 256, 34); } static void *p521_falcon1024_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_1024, - "p521_falcon1024", KEY_TYPE_HYB_SIG, 256, 21); + "p521_falcon1024", KEY_TYPE_HYB_SIG, 256, 34); } static void *falconpadded1024_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_padded_1024, "falconpadded1024", - KEY_TYPE_SIG, NULL, 256, 22); + KEY_TYPE_SIG, NULL, 256, 35); } static void *falconpadded1024_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_padded_1024, - "falconpadded1024", 0, 256, 22); + "falconpadded1024", 0, 256, 35); } static void *p521_falconpadded1024_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_padded_1024, "p521_falconpadded1024", - KEY_TYPE_HYB_SIG, NULL, 256, 23); + KEY_TYPE_HYB_SIG, NULL, 256, 36); } static void *p521_falconpadded1024_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_padded_1024, - "p521_falconpadded1024", KEY_TYPE_HYB_SIG, 256, 23); + "p521_falconpadded1024", KEY_TYPE_HYB_SIG, 256, 36); } static void *sphincssha2128fsimple_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, - "sphincssha2128fsimple", KEY_TYPE_SIG, NULL, 128, 24); + "sphincssha2128fsimple", KEY_TYPE_SIG, NULL, 128, 37); } static void *sphincssha2128fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, - "sphincssha2128fsimple", 0, 128, 24); + "sphincssha2128fsimple", 0, 128, 37); } static void *p256_sphincssha2128fsimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, - "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 25); + "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 38); } static void *p256_sphincssha2128fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, - "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 25); + "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 38); } static void *rsa3072_sphincssha2128fsimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, - "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 26); + "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 39); } static void *rsa3072_sphincssha2128fsimple_gen_init(void *provctx, @@ -903,39 +1048,39 @@ static void *rsa3072_sphincssha2128fsimple_gen_init(void *provctx, { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, - "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 26); + "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 39); } static void *sphincssha2128ssimple_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, - "sphincssha2128ssimple", KEY_TYPE_SIG, NULL, 128, 27); + "sphincssha2128ssimple", KEY_TYPE_SIG, NULL, 128, 40); } static void *sphincssha2128ssimple_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, - "sphincssha2128ssimple", 0, 128, 27); + "sphincssha2128ssimple", 0, 128, 40); } static void *p256_sphincssha2128ssimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, - "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 28); + "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 41); } static void *p256_sphincssha2128ssimple_gen_init(void *provctx, int selection) { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, - "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 28); + "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 41); } static void *rsa3072_sphincssha2128ssimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, - "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 29); + "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 42); } static void *rsa3072_sphincssha2128ssimple_gen_init(void *provctx, @@ -943,66 +1088,66 @@ static void *rsa3072_sphincssha2128ssimple_gen_init(void *provctx, { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, - "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 29); + "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 42); } static void *sphincssha2192fsimple_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_192f_simple, - "sphincssha2192fsimple", KEY_TYPE_SIG, NULL, 192, 30); + "sphincssha2192fsimple", KEY_TYPE_SIG, NULL, 192, 43); } static void *sphincssha2192fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_192f_simple, - "sphincssha2192fsimple", 0, 192, 30); + "sphincssha2192fsimple", 0, 192, 43); } static void *p384_sphincssha2192fsimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_192f_simple, - "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, NULL, 192, 31); + "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, NULL, 192, 44); } static void *p384_sphincssha2192fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_sha2_192f_simple, - "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, 192, 31); + "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, 192, 44); } static void *sphincsshake128fsimple_new_key(void *provctx) { return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, - "sphincsshake128fsimple", KEY_TYPE_SIG, NULL, 128, 32); + "sphincsshake128fsimple", KEY_TYPE_SIG, NULL, 128, 45); } static void *sphincsshake128fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, - "sphincsshake128fsimple", 0, 128, 32); + "sphincsshake128fsimple", 0, 128, 45); } static void *p256_sphincsshake128fsimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, - "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 33); + "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 46); } static void *p256_sphincsshake128fsimple_gen_init(void *provctx, int selection) { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, - "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 33); + "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 46); } static void *rsa3072_sphincsshake128fsimple_new_key(void *provctx) { return oqsx_key_new( PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, - "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 34); + "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 47); } static void *rsa3072_sphincsshake128fsimple_gen_init(void *provctx, @@ -1010,7 +1155,7 @@ static void *rsa3072_sphincsshake128fsimple_gen_init(void *provctx, { return oqsx_gen_init( provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, - "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 34); + "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 47); } ///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_CONSTRUCTORS_END @@ -1172,10 +1317,23 @@ MAKE_SIG_KEYMGMT_FUNCTIONS(p521_dilithium5) MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44) MAKE_SIG_KEYMGMT_FUNCTIONS(p256_mldsa44) MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_mldsa44) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44_pss2048) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44_rsa2048) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44_ed25519) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44_p256) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa44_bp256) MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65) MAKE_SIG_KEYMGMT_FUNCTIONS(p384_mldsa65) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65_pss3072) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65_rsa3072) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65_p256) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65_bp256) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa65_ed25519) MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa87) MAKE_SIG_KEYMGMT_FUNCTIONS(p521_mldsa87) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa87_p384) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa87_bp384) +MAKE_SIG_KEYMGMT_FUNCTIONS(mldsa87_ed448) MAKE_SIG_KEYMGMT_FUNCTIONS(falcon512) MAKE_SIG_KEYMGMT_FUNCTIONS(p256_falcon512) MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_falcon512) diff --git a/oqsprov/oqs_prov.h b/oqsprov/oqs_prov.h index 847e6f65..3a7faa02 100644 --- a/oqsprov/oqs_prov.h +++ b/oqsprov/oqs_prov.h @@ -142,7 +142,8 @@ enum oqsx_key_type_en { KEY_TYPE_KEM, KEY_TYPE_ECP_HYB_KEM, KEY_TYPE_ECX_HYB_KEM, - KEY_TYPE_HYB_SIG + KEY_TYPE_HYB_SIG, + KEY_TYPE_CMP_SIG }; typedef enum oqsx_key_type_en OQSX_KEY_TYPE; @@ -158,7 +159,7 @@ struct oqsx_key_st { #ifdef USE_ENCODING_LIB OQSX_ENCODING_CTX oqsx_encoding_ctx; #endif - EVP_PKEY *classical_pkey; // for hybrid sigs + EVP_PKEY *classical_pkey; // for hybrid & composite sigs const OQSX_EVP_INFO *evp_info; size_t numkeys; @@ -167,6 +168,8 @@ struct oqsx_key_st { */ size_t privkeylen; size_t pubkeylen; + size_t *privkeylen_cmp; + size_t *pubkeylen_cmp; size_t bit_security; char *tls_name; #ifndef OQS_PROVIDER_NOATOMIC @@ -174,8 +177,10 @@ struct oqsx_key_st { #endif int references; - /* point to actual priv key material -- classic key, if present, first - * i.e., OQS key always at comp_*key[numkeys-1] + /* point to actual priv key material -- if is a hydrid, the classic key will + * be present first, i.e., OQS key always at comp_*key[numkeys-1] - if is a + * composite, the classic key will be presented second, i.e., OQS key always + * at comp_*key[0] */ void **comp_privkey; void **comp_pubkey; @@ -189,6 +194,25 @@ struct oqsx_key_st { typedef struct oqsx_key_st OQSX_KEY; +// composite signature +struct SignatureModel { + ASN1_BIT_STRING *sig1; + ASN1_BIT_STRING *sig2; +}; + +typedef struct SignatureModel CompositeSignature; + +char *get_oqsname_fromtls(char *tlsname); +char *get_oqsname(int nid); +char *get_cmpname(int nid, int index); +int get_oqsalg_idx(int nid); +int get_composite_idx(int idx); + +/* Workaround for not functioning EC PARAM initialization + * TBD, check https://github.com/openssl/openssl/issues/16989 + */ +EVP_PKEY *setECParams(EVP_PKEY *eck, int nid); + /* Register given NID with tlsname in OSSL3 registry */ int oqs_set_nid(char *tlsname, int nid); @@ -1297,6 +1321,91 @@ extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_mldsa44_decoder_functions[]; extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_mldsa44_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_pss2048_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_pss2048_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa44_pss2048_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa44_pss2048_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_rsa2048_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_rsa2048_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa44_rsa2048_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa44_rsa2048_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_ed25519_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_ed25519_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa44_ed25519_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa44_ed25519_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_p256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_p256_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa44_p256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa44_p256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa44_bp256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_bp256_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa44_bp256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa44_bp256_decoder_functions[]; extern const OSSL_DISPATCH oqs_mldsa65_to_PrivateKeyInfo_der_encoder_functions[]; extern const OSSL_DISPATCH @@ -1331,6 +1440,91 @@ extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p384_mldsa65_decoder_functions[]; extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p384_mldsa65_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_pss3072_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_pss3072_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa65_pss3072_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa65_pss3072_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_rsa3072_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_rsa3072_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa65_rsa3072_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa65_rsa3072_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_p256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_p256_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa65_p256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa65_p256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_bp256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_bp256_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa65_bp256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa65_bp256_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa65_ed25519_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_ed25519_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa65_ed25519_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa65_ed25519_decoder_functions[]; extern const OSSL_DISPATCH oqs_mldsa87_to_PrivateKeyInfo_der_encoder_functions[]; extern const OSSL_DISPATCH @@ -1365,6 +1559,57 @@ extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p521_mldsa87_decoder_functions[]; extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p521_mldsa87_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_p384_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_p384_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa87_p384_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa87_p384_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_bp384_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_bp384_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa87_bp384_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa87_bp384_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_mldsa87_ed448_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_ed448_to_text_encoder_functions[]; +extern const OSSL_DISPATCH + oqs_PrivateKeyInfo_der_to_mldsa87_ed448_decoder_functions[]; +extern const OSSL_DISPATCH + oqs_SubjectPublicKeyInfo_der_to_mldsa87_ed448_decoder_functions[]; extern const OSSL_DISPATCH oqs_falcon512_to_PrivateKeyInfo_der_encoder_functions[]; extern const OSSL_DISPATCH @@ -1798,10 +2043,23 @@ extern const OSSL_DISPATCH oqs_p521_dilithium5_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_mldsa44_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_p256_mldsa44_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_rsa3072_mldsa44_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_pss2048_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_rsa2048_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_ed25519_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_p256_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa44_bp256_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_mldsa65_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_p384_mldsa65_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_pss3072_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_rsa3072_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_p256_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_bp256_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa65_ed25519_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_mldsa87_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_p521_mldsa87_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_p384_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_bp384_keymgmt_functions[]; +extern const OSSL_DISPATCH oqs_mldsa87_ed448_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_falcon512_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_p256_falcon512_keymgmt_functions[]; extern const OSSL_DISPATCH oqs_rsa3072_falcon512_keymgmt_functions[]; diff --git a/oqsprov/oqs_sig.c b/oqsprov/oqs_sig.c index 86a4ae3a..ba7e56bf 100644 --- a/oqsprov/oqs_sig.c +++ b/oqsprov/oqs_sig.c @@ -21,9 +21,13 @@ #include #include +#include +#include + // TBD: Review what we really need/want: For now go with OSSL settings: -#define OSSL_MAX_NAME_SIZE 50 -#define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ +#define OSSL_MAX_NAME_SIZE 50 +#define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ +#define COMPOSITE_OID_PREFIX_LEN 26 #ifdef NDEBUG # define OQS_SIG_PRINTF(a) @@ -80,11 +84,21 @@ static int get_aid(unsigned char **oidbuf, const char *tls_name) return (aidlen); } +DECLARE_ASN1_FUNCTIONS(CompositeSignature) + +ASN1_NDEF_SEQUENCE(CompositeSignature) = { + ASN1_SIMPLE(CompositeSignature, sig1, ASN1_BIT_STRING), + ASN1_SIMPLE(CompositeSignature, sig2, ASN1_BIT_STRING), +} ASN1_NDEF_SEQUENCE_END(CompositeSignature) + +IMPLEMENT_ASN1_FUNCTIONS(CompositeSignature) + /* * What's passed as an actual key is defined by the KEYMGMT interface. */ -typedef struct { +typedef struct +{ OSSL_LIB_CTX *libctx; char *propq; OQSX_KEY *sig; @@ -200,6 +214,55 @@ static int oqs_sig_verify_init(void *vpoqs_sigctx, void *voqssig, return oqs_sig_signverify_init(vpoqs_sigctx, voqssig, EVP_PKEY_OP_VERIFY); } +// this list need to be in order of the last number on the OID from the +// composite, the len of each value is COMPOSITE_OID_PREFIX_LEN +static const unsigned char *composite_OID_prefix[] = { + "060B6086480186FA6B50080101", // mldsa44_pss2048 + // id-MLDSA44-RSA2048-PSS-SHA256 + "060B6086480186FA6B50080102", // mldsa44_rsa2048 + // id-MLDSA44-RSA2048-PKCS15-SHA256 + "060B6086480186FA6B50080103", // mldsa44_ed25519 + // id-MLDSA44-Ed25519-SHA512 + "060B6086480186FA6B50080104", // mldsa44_p256 + // id-MLDSA44-ECDSA-P256-SHA256 + "060B6086480186FA6B50080105", // mldsa44_bp256 + // id-MLDSA44-ECDSA-brainpoolP256r1-SHA256 + "060B6086480186FA6B50080106", // mldsa65_pss3072 + // id-MLDSA65-RSA3072-PSS-SHA512 + "060B6086480186FA6B50080107", // mldsa65_rsa3072 + // id-MLDSA65-RSA3072-PKCS15-SHA512 + "060B6086480186FA6B50080108", // mldsa65_p256 + // id-MLDSA65-ECDSA-P256-SHA512 + "060B6086480186FA6B50080109", // mldsa65_bp256 + // id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 + "060B6086480186FA6B5008010A", // mldsa65_ed25519 + // id-MLDSA65-Ed25519-SHA512 + "060B6086480186FA6B5008010B", // mldsa87_p384 + // id-MLDSA87-ECDSA-P384-SHA512 + "060B6086480186FA6B5008010C", // mldsa87_bp384 + // id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 + "060B6086480186FA6B5008010D", // mldsa87_ed448 id-MLDSA87-Ed448-SHA512 + "060B6086480186FA6B5008010E", // falcon512_p256 + // id-Falon512-ECDSA-P256-SHA256 + "060B6086480186FA6B5008010F", // falcon512_bp256 + // id-Falcon512-ECDSA-brainpoolP256r1-SHA256 + "060B6086480186FA6B50080110", // falcon512_ed25519 + // id-Falcon512-Ed25519-SHA512 + +}; + +/*put the chars on in into memory on out*/ +void composite_prefix_conversion(char *out, const unsigned char *in) +{ + int temp; + for (int i = 0; i < COMPOSITE_OID_PREFIX_LEN / 2; i++) { + temp = OPENSSL_hexchar2int(in[2 * i]); + temp = temp * 16; + temp += OPENSSL_hexchar2int(in[2 * i + 1]); + out[i] = (unsigned char)temp; + } +} + /* On entry to this function, data to be signed (tbs) might have been hashed * already: this would be the case if poqs_sigctx->mdctx != NULL; if that is * NULL, we have to hash in case of hybrid signatures @@ -210,23 +273,32 @@ static int oqs_sig_sign(void *vpoqs_sigctx, unsigned char *sig, size_t *siglen, PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx; OQSX_KEY *oqsxkey = poqs_sigctx->sig; OQS_SIG *oqs_key = poqs_sigctx->sig->oqsx_provider_ctx.oqsx_qs_ctx.sig; - EVP_PKEY *evpkey = oqsxkey->classical_pkey; // if this value is not NULL, - // we're running hybrid + EVP_PKEY *oqs_key_classic = NULL; + EVP_PKEY *cmp_key_classic = NULL; + EVP_PKEY *evpkey = oqsxkey->classical_pkey; EVP_PKEY_CTX *classical_ctx_sign = NULL; OQS_SIG_PRINTF2("OQS SIG provider: sign called for %ld bytes\n", tbslen); - int is_hybrid = evpkey != NULL; - size_t max_sig_len = oqs_key->length_signature; + int is_hybrid = (oqsxkey->keytype == KEY_TYPE_HYB_SIG); + int is_composite = (oqsxkey->keytype == KEY_TYPE_CMP_SIG); + size_t max_sig_len = 0; size_t classical_sig_len = 0, oqs_sig_len = 0; size_t actual_classical_sig_len = 0; size_t index = 0; int rv = 0; - if (!oqsxkey || !oqs_key || !oqsxkey->privkey) { + if (!oqsxkey || !(oqs_key || oqs_key_classic) || !oqsxkey->privkey) { ERR_raise(ERR_LIB_USER, OQSPROV_R_NO_PRIVATE_KEY); return rv; } + + if (is_composite) { + max_sig_len = oqsx_key_maxsize(oqsxkey); + } else { + max_sig_len += oqs_key->length_signature; + } + if (is_hybrid) { actual_classical_sig_len = oqsxkey->evp_info->length_signature; max_sig_len += (SIZE_OF_UINT32 + actual_classical_sig_len); @@ -316,12 +388,227 @@ static int oqs_sig_sign(void *vpoqs_sigctx, unsigned char *sig, size_t *siglen, index += classical_sig_len; } - if (OQS_SIG_sign(oqs_key, sig + index, &oqs_sig_len, tbs, tbslen, - oqsxkey->comp_privkey[oqsxkey->numkeys - 1]) - != OQS_SUCCESS) { + if (is_composite) { + unsigned char *buf; + int i; + int nid = OBJ_sn2nid(oqsxkey->tls_name); + int comp_idx = get_composite_idx(get_oqsalg_idx(nid)); + if (comp_idx == -1) + goto endsign; + const unsigned char *oid_prefix = composite_OID_prefix[comp_idx - 1]; + char *final_tbs; + CompositeSignature *compsig = CompositeSignature_new(); + size_t final_tbslen + = COMPOSITE_OID_PREFIX_LEN + / 2; // COMPOSITE_OID_PREFIX_LEN stores the size of the *char, but + // the prefix will be on memory, so each 2 chars will + // translate into one byte + int aux = 0; + unsigned char *tbs_hash; + + // prepare the pre hash + for (i = 0; i < oqsxkey->numkeys; i++) { + char *name; + char *upcase_name; + if ((name = get_cmpname(nid, i)) == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + goto endsign; + } + upcase_name = get_oqsname_fromtls(name); + + if ((upcase_name != 0) + && ((!strcmp(upcase_name, OQS_SIG_alg_ml_dsa_65)) + || (!strcmp(upcase_name, OQS_SIG_alg_ml_dsa_87))) + || (name[0] == 'e')) { + aux = 1; + OPENSSL_free(name); + break; + } + OPENSSL_free(name); + } + switch (aux) { + case 0: + tbs_hash = OPENSSL_malloc(SHA256_DIGEST_LENGTH); + SHA256(tbs, tbslen, tbs_hash); + final_tbslen += SHA256_DIGEST_LENGTH; + break; + case 1: + tbs_hash = OPENSSL_malloc(SHA512_DIGEST_LENGTH); + SHA512(tbs, tbslen, tbs_hash); + final_tbslen += SHA512_DIGEST_LENGTH; + break; + default: + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + goto endsign; + } + final_tbs = OPENSSL_malloc(final_tbslen); + composite_prefix_conversion(final_tbs, oid_prefix); + memcpy(final_tbs + COMPOSITE_OID_PREFIX_LEN / 2, tbs_hash, + final_tbslen - COMPOSITE_OID_PREFIX_LEN / 2); + OPENSSL_free(tbs_hash); + + // sign + for (i = 0; i < oqsxkey->numkeys; i++) { + char *name; + if ((name = get_cmpname(nid, i)) == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endsign; + } + + if (get_oqsname_fromtls(name)) { // PQC signing + oqs_sig_len = oqsxkey->oqsx_provider_ctx.oqsx_qs_ctx.sig + ->length_signature; + buf = OPENSSL_malloc(oqs_sig_len); + if (OQS_SIG_sign(oqs_key, buf, &oqs_sig_len, final_tbs, + final_tbslen, oqsxkey->comp_privkey[i]) + != OQS_SUCCESS) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_SIGNING_FAILED); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + } else { // sign non PQC key on oqs_key + oqs_key_classic = oqsxkey->classical_pkey; + oqs_sig_len = oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->length_signature; + buf = OPENSSL_malloc(oqs_sig_len); + const EVP_MD *classical_md; + int digest_len; + unsigned char + digest[SHA512_DIGEST_LENGTH]; /* init with max length */ + + if (name[0] == 'e') { // ed25519 or ed448 + EVP_MD_CTX *evp_ctx = EVP_MD_CTX_new(); + if ((EVP_DigestSignInit(evp_ctx, NULL, NULL, NULL, + oqs_key_classic) + <= 0) + || (EVP_DigestSign(evp_ctx, buf, &oqs_sig_len, + final_tbs, final_tbslen) + <= 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + EVP_MD_CTX_free(evp_ctx); + OPENSSL_free(buf); + goto endsign; + } + EVP_MD_CTX_free(evp_ctx); + } else { + if ((classical_ctx_sign + = EVP_PKEY_CTX_new(oqs_key_classic, NULL)) + == NULL + || (EVP_PKEY_sign_init(classical_ctx_sign) <= 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + + if (!strncmp(name, "pss", 3)) { + if ((EVP_PKEY_CTX_set_rsa_padding(classical_ctx_sign, + RSA_PKCS1_PSS_PADDING) + <= 0) + || (EVP_PKEY_CTX_set_rsa_pss_saltlen( + classical_ctx_sign, 64) + <= 0) + || (EVP_PKEY_CTX_set_rsa_mgf1_md(classical_ctx_sign, + EVP_sha256()) + <= 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + } else if (oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype + == EVP_PKEY_RSA) { + if (EVP_PKEY_CTX_set_rsa_padding(classical_ctx_sign, + RSA_PKCS1_PADDING) + <= 0) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + } + if (comp_idx < 6) { + classical_md = EVP_sha256(); + digest_len = SHA256_DIGEST_LENGTH; + SHA256(final_tbs, final_tbslen, + (unsigned char *)&digest); + } else { + classical_md = EVP_sha512(); + digest_len = SHA512_DIGEST_LENGTH; + SHA512(final_tbs, final_tbslen, + (unsigned char *)&digest); + } + + if ((EVP_PKEY_CTX_set_signature_md(classical_ctx_sign, + classical_md) + <= 0) + || (EVP_PKEY_sign(classical_ctx_sign, buf, &oqs_sig_len, + digest, digest_len) + <= 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + + if (oqs_sig_len > oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx + ->evp_info->length_signature) { + /* sig is bigger than expected */ + ERR_raise(ERR_LIB_USER, OQSPROV_R_BUFFER_LENGTH_WRONG); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + OPENSSL_free(name); + OPENSSL_free(buf); + goto endsign; + } + } + } + + if (i == 0) { + compsig->sig1->data = OPENSSL_memdup(buf, oqs_sig_len); + compsig->sig1->length = oqs_sig_len; + compsig->sig1->flags + = 8; // set as 8 to not check for unused bits + } else { + compsig->sig2->data = OPENSSL_memdup(buf, oqs_sig_len); + compsig->sig2->length = oqs_sig_len; + compsig->sig2->flags + = 8; // set as 8 to not check for unused bits + } + + OPENSSL_free(buf); + OPENSSL_free(name); + } + oqs_sig_len = i2d_CompositeSignature(compsig, &sig); + + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + } else if (OQS_SIG_sign(oqs_key, sig + index, &oqs_sig_len, tbs, tbslen, + oqsxkey->comp_privkey[oqsxkey->numkeys - 1]) + != OQS_SUCCESS) { ERR_raise(ERR_LIB_USER, OQSPROV_R_SIGNING_FAILED); goto endsign; } + *siglen = classical_sig_len + oqs_sig_len; OQS_SIG_PRINTF2("OQS SIG provider: signing completes with size %ld\n", *siglen); @@ -341,14 +628,15 @@ static int oqs_sig_verify(void *vpoqs_sigctx, const unsigned char *sig, PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx; OQSX_KEY *oqsxkey = poqs_sigctx->sig; OQS_SIG *oqs_key = poqs_sigctx->sig->oqsx_provider_ctx.oqsx_qs_ctx.sig; - EVP_PKEY *evpkey = oqsxkey->classical_pkey; // if this value is not NULL, - // we're running hybrid + EVP_PKEY *evpkey = oqsxkey->classical_pkey; EVP_PKEY_CTX *classical_ctx_sign = NULL; EVP_PKEY_CTX *ctx_verify = NULL; - int is_hybrid = evpkey != NULL; - size_t classical_sig_len = 0; + int is_hybrid = (oqsxkey->keytype == KEY_TYPE_HYB_SIG); + int is_composite = (oqsxkey->keytype == KEY_TYPE_CMP_SIG); + size_t classical_sig_len = 0, oqs_sig_len = 0; size_t index = 0; int rv = 0; + ASN1_BIT_STRING *comp_sig; OQS_SIG_PRINTF3( "OQS SIG provider: verify called with siglen %ld bytes and tbslen %ld\n", @@ -426,17 +714,202 @@ static int oqs_sig_verify(void *vpoqs_sigctx, const unsigned char *sig, classical_sig_len = SIZE_OF_UINT32 + actual_classical_sig_len; index += classical_sig_len; } + if (is_composite) { + CompositeSignature *compsig; + int i; + int nid = OBJ_sn2nid(oqsxkey->tls_name); + int comp_idx = get_composite_idx(get_oqsalg_idx(nid)); + if (comp_idx == -1) + goto endverify; + unsigned char *buf; + size_t buf_len; + const unsigned char *oid_prefix = composite_OID_prefix[comp_idx - 1]; + char *final_tbs; + size_t final_tbslen = COMPOSITE_OID_PREFIX_LEN / 2; + int aux = 0; + unsigned char *tbs_hash; + + if ((compsig = d2i_CompositeSignature(NULL, &sig, siglen)) == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + CompositeSignature_free(compsig); + goto endverify; + } - if (!oqsxkey->comp_pubkey[oqsxkey->numkeys - 1]) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS); - goto endverify; - } - if (OQS_SIG_verify(oqs_key, tbs, tbslen, sig + index, - siglen - classical_sig_len, - oqsxkey->comp_pubkey[oqsxkey->numkeys - 1]) - != OQS_SUCCESS) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); - goto endverify; + // prepare the pre hash + for (i = 0; i < oqsxkey->numkeys; i++) { + char *name; + char *upcase_name; + if ((name = get_cmpname(nid, i)) == NULL) { + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + goto endverify; + } + upcase_name = get_oqsname_fromtls(name); + + if ((upcase_name != 0) + && ((!strcmp(upcase_name, OQS_SIG_alg_ml_dsa_65)) + || (!strcmp(upcase_name, OQS_SIG_alg_ml_dsa_87))) + || (name[0] == 'e')) { + aux = 1; + OPENSSL_free(name); + break; + } + OPENSSL_free(name); + } + switch (aux) { + case 0: + tbs_hash = OPENSSL_malloc(SHA256_DIGEST_LENGTH); + SHA256(tbs, tbslen, tbs_hash); + final_tbslen += SHA256_DIGEST_LENGTH; + break; + case 1: + tbs_hash = OPENSSL_malloc(SHA512_DIGEST_LENGTH); + SHA512(tbs, tbslen, tbs_hash); + final_tbslen += SHA512_DIGEST_LENGTH; + break; + default: + ERR_raise(ERR_LIB_USER, ERR_R_FATAL); + CompositeSignature_free(compsig); + goto endverify; + } + final_tbs = OPENSSL_malloc(final_tbslen); + composite_prefix_conversion(final_tbs, oid_prefix); + memcpy(final_tbs + COMPOSITE_OID_PREFIX_LEN / 2, tbs_hash, + final_tbslen - COMPOSITE_OID_PREFIX_LEN / 2); + OPENSSL_free(tbs_hash); + + // verify + for (i = 0; i < oqsxkey->numkeys; i++) { + if (i == 0) { + buf = compsig->sig1->data; + buf_len = compsig->sig1->length; + } else { + buf = compsig->sig2->data; + buf_len = compsig->sig2->length; + } + + char *name; + if ((name = get_cmpname(nid, i)) == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + + if (get_oqsname_fromtls(name)) { + if (OQS_SIG_verify(oqs_key, final_tbs, final_tbslen, buf, + buf_len, oqsxkey->comp_pubkey[i]) + != OQS_SUCCESS) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + OPENSSL_free(name); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + } else { + const EVP_MD *classical_md; + int digest_len; + int aux; + unsigned char + digest[SHA512_DIGEST_LENGTH]; /* init with max length */ + + if (name[0] == 'e') { // ed25519 or ed448 + EVP_MD_CTX *evp_ctx = EVP_MD_CTX_new(); + if ((EVP_DigestVerifyInit(evp_ctx, NULL, NULL, NULL, + oqsxkey->classical_pkey) + <= 0) + || (EVP_DigestVerify(evp_ctx, buf, buf_len, final_tbs, + final_tbslen) + <= 0)) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + OPENSSL_free(name); + EVP_MD_CTX_free(evp_ctx); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + EVP_MD_CTX_free(evp_ctx); + } else { + if (((ctx_verify + = EVP_PKEY_CTX_new(oqsxkey->classical_pkey, NULL)) + == NULL) + || (EVP_PKEY_verify_init(ctx_verify) <= 0)) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + OPENSSL_free(name); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + if (!strncmp(name, "pss", 3)) { + if ((EVP_PKEY_CTX_set_rsa_padding(ctx_verify, + RSA_PKCS1_PSS_PADDING) + <= 0) + || (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx_verify, 64) + <= 0) + || (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx_verify, + EVP_sha256()) + <= 0)) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS); + OPENSSL_free(name); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + } else if (oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype + == EVP_PKEY_RSA) { + if (EVP_PKEY_CTX_set_rsa_padding(ctx_verify, + RSA_PKCS1_PADDING) + <= 0) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS); + OPENSSL_free(name); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + } + if (comp_idx < 6) { + classical_md = EVP_sha256(); + digest_len = SHA256_DIGEST_LENGTH; + SHA256(final_tbs, final_tbslen, + (unsigned char *)&digest); + } else { + classical_md = EVP_sha512(); + digest_len = SHA512_DIGEST_LENGTH; + SHA512(final_tbs, final_tbslen, + (unsigned char *)&digest); + } + + if ((EVP_PKEY_CTX_set_signature_md(ctx_verify, classical_md) + <= 0) + || (EVP_PKEY_verify(ctx_verify, buf, buf_len, digest, + digest_len) + <= 0)) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + OPENSSL_free(name); + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + goto endverify; + } + } + } + + OPENSSL_free(name); + } + CompositeSignature_free(compsig); + OPENSSL_free(final_tbs); + } else { + if (!oqsxkey->comp_pubkey[oqsxkey->numkeys - 1]) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS); + goto endverify; + } + if (OQS_SIG_verify(oqs_key, tbs, tbslen, sig + index, + siglen - classical_sig_len, + oqsxkey->comp_pubkey[oqsxkey->numkeys - 1]) + != OQS_SUCCESS) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR); + goto endverify; + } } rv = 1; diff --git a/oqsprov/oqsdecoders.inc b/oqsprov/oqsdecoders.inc index 2f6bc610..f9d9fc4d 100644 --- a/oqsprov/oqsdecoders.inc +++ b/oqsprov/oqsdecoders.inc @@ -264,6 +264,24 @@ DECODER_w_structure("frodo640aes", der, PrivateKeyInfo, frodo640aes), rsa3072_mldsa44), DECODER_w_structure("rsa3072_mldsa44", der, SubjectPublicKeyInfo, rsa3072_mldsa44), + DECODER_w_structure("mldsa44_pss2048", der, PrivateKeyInfo, + mldsa44_pss2048), + DECODER_w_structure("mldsa44_pss2048", der, SubjectPublicKeyInfo, + mldsa44_pss2048), + DECODER_w_structure("mldsa44_rsa2048", der, PrivateKeyInfo, + mldsa44_rsa2048), + DECODER_w_structure("mldsa44_rsa2048", der, SubjectPublicKeyInfo, + mldsa44_rsa2048), + DECODER_w_structure("mldsa44_ed25519", der, PrivateKeyInfo, + mldsa44_ed25519), + DECODER_w_structure("mldsa44_ed25519", der, SubjectPublicKeyInfo, + mldsa44_ed25519), + DECODER_w_structure("mldsa44_p256", der, PrivateKeyInfo, mldsa44_p256), + DECODER_w_structure("mldsa44_p256", der, SubjectPublicKeyInfo, + mldsa44_p256), + DECODER_w_structure("mldsa44_bp256", der, PrivateKeyInfo, mldsa44_bp256), + DECODER_w_structure("mldsa44_bp256", der, SubjectPublicKeyInfo, + mldsa44_bp256), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_65 DECODER_w_structure("mldsa65", der, PrivateKeyInfo, mldsa65), @@ -271,6 +289,24 @@ DECODER_w_structure("frodo640aes", der, PrivateKeyInfo, frodo640aes), DECODER_w_structure("p384_mldsa65", der, PrivateKeyInfo, p384_mldsa65), DECODER_w_structure("p384_mldsa65", der, SubjectPublicKeyInfo, p384_mldsa65), + DECODER_w_structure("mldsa65_pss3072", der, PrivateKeyInfo, + mldsa65_pss3072), + DECODER_w_structure("mldsa65_pss3072", der, SubjectPublicKeyInfo, + mldsa65_pss3072), + DECODER_w_structure("mldsa65_rsa3072", der, PrivateKeyInfo, + mldsa65_rsa3072), + DECODER_w_structure("mldsa65_rsa3072", der, SubjectPublicKeyInfo, + mldsa65_rsa3072), + DECODER_w_structure("mldsa65_p256", der, PrivateKeyInfo, mldsa65_p256), + DECODER_w_structure("mldsa65_p256", der, SubjectPublicKeyInfo, + mldsa65_p256), + DECODER_w_structure("mldsa65_bp256", der, PrivateKeyInfo, mldsa65_bp256), + DECODER_w_structure("mldsa65_bp256", der, SubjectPublicKeyInfo, + mldsa65_bp256), + DECODER_w_structure("mldsa65_ed25519", der, PrivateKeyInfo, + mldsa65_ed25519), + DECODER_w_structure("mldsa65_ed25519", der, SubjectPublicKeyInfo, + mldsa65_ed25519), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_87 DECODER_w_structure("mldsa87", der, PrivateKeyInfo, mldsa87), @@ -278,6 +314,15 @@ DECODER_w_structure("frodo640aes", der, PrivateKeyInfo, frodo640aes), DECODER_w_structure("p521_mldsa87", der, PrivateKeyInfo, p521_mldsa87), DECODER_w_structure("p521_mldsa87", der, SubjectPublicKeyInfo, p521_mldsa87), + DECODER_w_structure("mldsa87_p384", der, PrivateKeyInfo, mldsa87_p384), + DECODER_w_structure("mldsa87_p384", der, SubjectPublicKeyInfo, + mldsa87_p384), + DECODER_w_structure("mldsa87_bp384", der, PrivateKeyInfo, mldsa87_bp384), + DECODER_w_structure("mldsa87_bp384", der, SubjectPublicKeyInfo, + mldsa87_bp384), + DECODER_w_structure("mldsa87_ed448", der, PrivateKeyInfo, mldsa87_ed448), + DECODER_w_structure("mldsa87_ed448", der, SubjectPublicKeyInfo, + mldsa87_ed448), #endif #ifdef OQS_ENABLE_SIG_falcon_512 DECODER_w_structure("falcon512", der, PrivateKeyInfo, falcon512), diff --git a/oqsprov/oqsencoders.inc b/oqsprov/oqsencoders.inc index e60f81e3..34537f51 100644 --- a/oqsprov/oqsencoders.inc +++ b/oqsprov/oqsencoders.inc @@ -774,6 +774,67 @@ ENCODER_w_structure("frodo640aes", frodo640aes, der, PrivateKeyInfo), ENCODER_w_structure("rsa3072_mldsa44", rsa3072_mldsa44, pem, SubjectPublicKeyInfo), ENCODER_TEXT("rsa3072_mldsa44", rsa3072_mldsa44), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa44_pss2048", mldsa44_pss2048, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa44_pss2048", mldsa44_pss2048), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa44_rsa2048", mldsa44_rsa2048, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa44_rsa2048", mldsa44_rsa2048), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa44_ed25519", mldsa44_ed25519, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa44_ed25519", mldsa44_ed25519), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa44_p256", mldsa44_p256, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa44_p256", mldsa44_p256), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa44_bp256", mldsa44_bp256, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa44_bp256", mldsa44_bp256), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_65 ENCODER_w_structure("mldsa65", mldsa65, der, PrivateKeyInfo), @@ -794,6 +855,67 @@ ENCODER_w_structure("frodo640aes", frodo640aes, der, PrivateKeyInfo), ENCODER_w_structure("p384_mldsa65", p384_mldsa65, pem, SubjectPublicKeyInfo), ENCODER_TEXT("p384_mldsa65", p384_mldsa65), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa65_pss3072", mldsa65_pss3072, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa65_pss3072", mldsa65_pss3072), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa65_rsa3072", mldsa65_rsa3072, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa65_rsa3072", mldsa65_rsa3072), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa65_p256", mldsa65_p256, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa65_p256", mldsa65_p256), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa65_bp256", mldsa65_bp256, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa65_bp256", mldsa65_bp256), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, der, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, pem, + PrivateKeyInfo), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa65_ed25519", mldsa65_ed25519, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa65_ed25519", mldsa65_ed25519), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_87 ENCODER_w_structure("mldsa87", mldsa87, der, PrivateKeyInfo), @@ -814,6 +936,39 @@ ENCODER_w_structure("frodo640aes", frodo640aes, der, PrivateKeyInfo), ENCODER_w_structure("p521_mldsa87", p521_mldsa87, pem, SubjectPublicKeyInfo), ENCODER_TEXT("p521_mldsa87", p521_mldsa87), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa87_p384", mldsa87_p384, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa87_p384", mldsa87_p384), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa87_bp384", mldsa87_bp384, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa87_bp384", mldsa87_bp384), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, der, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, pem, PrivateKeyInfo), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, der, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, pem, + EncryptedPrivateKeyInfo), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, der, + SubjectPublicKeyInfo), + ENCODER_w_structure("mldsa87_ed448", mldsa87_ed448, pem, + SubjectPublicKeyInfo), + ENCODER_TEXT("mldsa87_ed448", mldsa87_ed448), #endif #ifdef OQS_ENABLE_SIG_falcon_512 ENCODER_w_structure("falcon512", falcon512, der, PrivateKeyInfo), diff --git a/oqsprov/oqsprov.c b/oqsprov/oqsprov.c index 64ca0256..ef494b93 100644 --- a/oqsprov/oqsprov.c +++ b/oqsprov/oqsprov.c @@ -8,6 +8,7 @@ */ #include "oqs_prov.h" +#include #include #include #include @@ -49,9 +50,9 @@ extern OSSL_FUNC_provider_get_capabilities_fn oqs_provider_get_capabilities; ///// OQS_TEMPLATE_FRAGMENT_ASSIGN_SIG_OIDS_START #ifdef OQS_KEM_ENCODERS -# define OQS_OID_CNT 176 +# define OQS_OID_CNT 202 #else -# define OQS_OID_CNT 70 +# define OQS_OID_CNT 96 #endif const char *oqs_oid_alg_list[OQS_OID_CNT] = { @@ -186,14 +187,40 @@ const char *oqs_oid_alg_list[OQS_OID_CNT] = { "p256_mldsa44", "1.3.9999.7.2", "rsa3072_mldsa44", + "2.16.840.1.114027.80.8.1.1", + "mldsa44_pss2048", + "2.16.840.1.114027.80.8.1.2", + "mldsa44_rsa2048", + "2.16.840.1.114027.80.8.1.3", + "mldsa44_ed25519", + "2.16.840.1.114027.80.8.1.4", + "mldsa44_p256", + "2.16.840.1.114027.80.8.1.5", + "mldsa44_bp256", "1.3.6.1.4.1.2.267.12.6.5", "mldsa65", "1.3.9999.7.3", "p384_mldsa65", + "2.16.840.1.114027.80.8.1.6", + "mldsa65_pss3072", + "2.16.840.1.114027.80.8.1.7", + "mldsa65_rsa3072", + "2.16.840.1.114027.80.8.1.8", + "mldsa65_p256", + "2.16.840.1.114027.80.8.1.9", + "mldsa65_bp256", + "2.16.840.1.114027.80.8.1.10", + "mldsa65_ed25519", "1.3.6.1.4.1.2.267.12.8.7", "mldsa87", "1.3.9999.7.4", "p521_mldsa87", + "2.16.840.1.114027.80.8.1.11", + "mldsa87_p384", + "2.16.840.1.114027.80.8.1.12", + "mldsa87_bp384", + "2.16.840.1.114027.80.8.1.13", + "mldsa87_ed448", "1.3.9999.3.11", "falcon512", "1.3.9999.3.12", @@ -523,137 +550,199 @@ int oqs_patch_encodings(void) if (getenv("OQS_ENCODING_RSA3072_MLDSA44_ALGNAME")) oqs_alg_encoding_list[19] = getenv("OQS_ENCODING_RSA3072_MLDSA44_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA44_PSS2048")) + oqs_alg_encoding_list[20] = getenv("OQS_ENCODING_MLDSA44_PSS2048"); + if (getenv("OQS_ENCODING_MLDSA44_PSS2048_ALGNAME")) + oqs_alg_encoding_list[21] + = getenv("OQS_ENCODING_MLDSA44_PSS2048_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA44_RSA2048")) + oqs_alg_encoding_list[22] = getenv("OQS_ENCODING_MLDSA44_RSA2048"); + if (getenv("OQS_ENCODING_MLDSA44_RSA2048_ALGNAME")) + oqs_alg_encoding_list[23] + = getenv("OQS_ENCODING_MLDSA44_RSA2048_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA44_ED25519")) + oqs_alg_encoding_list[24] = getenv("OQS_ENCODING_MLDSA44_ED25519"); + if (getenv("OQS_ENCODING_MLDSA44_ED25519_ALGNAME")) + oqs_alg_encoding_list[25] + = getenv("OQS_ENCODING_MLDSA44_ED25519_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA44_P256")) + oqs_alg_encoding_list[26] = getenv("OQS_ENCODING_MLDSA44_P256"); + if (getenv("OQS_ENCODING_MLDSA44_P256_ALGNAME")) + oqs_alg_encoding_list[27] = getenv("OQS_ENCODING_MLDSA44_P256_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA44_BP256")) + oqs_alg_encoding_list[28] = getenv("OQS_ENCODING_MLDSA44_BP256"); + if (getenv("OQS_ENCODING_MLDSA44_BP256_ALGNAME")) + oqs_alg_encoding_list[29] + = getenv("OQS_ENCODING_MLDSA44_BP256_ALGNAME"); if (getenv("OQS_ENCODING_MLDSA65")) - oqs_alg_encoding_list[20] = getenv("OQS_ENCODING_MLDSA65"); + oqs_alg_encoding_list[30] = getenv("OQS_ENCODING_MLDSA65"); if (getenv("OQS_ENCODING_MLDSA65_ALGNAME")) - oqs_alg_encoding_list[21] = getenv("OQS_ENCODING_MLDSA65_ALGNAME"); + oqs_alg_encoding_list[31] = getenv("OQS_ENCODING_MLDSA65_ALGNAME"); if (getenv("OQS_ENCODING_P384_MLDSA65")) - oqs_alg_encoding_list[22] = getenv("OQS_ENCODING_P384_MLDSA65"); + oqs_alg_encoding_list[32] = getenv("OQS_ENCODING_P384_MLDSA65"); if (getenv("OQS_ENCODING_P384_MLDSA65_ALGNAME")) - oqs_alg_encoding_list[23] = getenv("OQS_ENCODING_P384_MLDSA65_ALGNAME"); + oqs_alg_encoding_list[33] = getenv("OQS_ENCODING_P384_MLDSA65_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA65_PSS3072")) + oqs_alg_encoding_list[34] = getenv("OQS_ENCODING_MLDSA65_PSS3072"); + if (getenv("OQS_ENCODING_MLDSA65_PSS3072_ALGNAME")) + oqs_alg_encoding_list[35] + = getenv("OQS_ENCODING_MLDSA65_PSS3072_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA65_RSA3072")) + oqs_alg_encoding_list[36] = getenv("OQS_ENCODING_MLDSA65_RSA3072"); + if (getenv("OQS_ENCODING_MLDSA65_RSA3072_ALGNAME")) + oqs_alg_encoding_list[37] + = getenv("OQS_ENCODING_MLDSA65_RSA3072_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA65_P256")) + oqs_alg_encoding_list[38] = getenv("OQS_ENCODING_MLDSA65_P256"); + if (getenv("OQS_ENCODING_MLDSA65_P256_ALGNAME")) + oqs_alg_encoding_list[39] = getenv("OQS_ENCODING_MLDSA65_P256_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA65_BP256")) + oqs_alg_encoding_list[40] = getenv("OQS_ENCODING_MLDSA65_BP256"); + if (getenv("OQS_ENCODING_MLDSA65_BP256_ALGNAME")) + oqs_alg_encoding_list[41] + = getenv("OQS_ENCODING_MLDSA65_BP256_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA65_ED25519")) + oqs_alg_encoding_list[42] = getenv("OQS_ENCODING_MLDSA65_ED25519"); + if (getenv("OQS_ENCODING_MLDSA65_ED25519_ALGNAME")) + oqs_alg_encoding_list[43] + = getenv("OQS_ENCODING_MLDSA65_ED25519_ALGNAME"); if (getenv("OQS_ENCODING_MLDSA87")) - oqs_alg_encoding_list[24] = getenv("OQS_ENCODING_MLDSA87"); + oqs_alg_encoding_list[44] = getenv("OQS_ENCODING_MLDSA87"); if (getenv("OQS_ENCODING_MLDSA87_ALGNAME")) - oqs_alg_encoding_list[25] = getenv("OQS_ENCODING_MLDSA87_ALGNAME"); + oqs_alg_encoding_list[45] = getenv("OQS_ENCODING_MLDSA87_ALGNAME"); if (getenv("OQS_ENCODING_P521_MLDSA87")) - oqs_alg_encoding_list[26] = getenv("OQS_ENCODING_P521_MLDSA87"); + oqs_alg_encoding_list[46] = getenv("OQS_ENCODING_P521_MLDSA87"); if (getenv("OQS_ENCODING_P521_MLDSA87_ALGNAME")) - oqs_alg_encoding_list[27] = getenv("OQS_ENCODING_P521_MLDSA87_ALGNAME"); + oqs_alg_encoding_list[47] = getenv("OQS_ENCODING_P521_MLDSA87_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA87_P384")) + oqs_alg_encoding_list[48] = getenv("OQS_ENCODING_MLDSA87_P384"); + if (getenv("OQS_ENCODING_MLDSA87_P384_ALGNAME")) + oqs_alg_encoding_list[49] = getenv("OQS_ENCODING_MLDSA87_P384_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA87_BP384")) + oqs_alg_encoding_list[50] = getenv("OQS_ENCODING_MLDSA87_BP384"); + if (getenv("OQS_ENCODING_MLDSA87_BP384_ALGNAME")) + oqs_alg_encoding_list[51] + = getenv("OQS_ENCODING_MLDSA87_BP384_ALGNAME"); + if (getenv("OQS_ENCODING_MLDSA87_ED448")) + oqs_alg_encoding_list[52] = getenv("OQS_ENCODING_MLDSA87_ED448"); + if (getenv("OQS_ENCODING_MLDSA87_ED448_ALGNAME")) + oqs_alg_encoding_list[53] + = getenv("OQS_ENCODING_MLDSA87_ED448_ALGNAME"); if (getenv("OQS_ENCODING_FALCON512")) - oqs_alg_encoding_list[28] = getenv("OQS_ENCODING_FALCON512"); + oqs_alg_encoding_list[54] = getenv("OQS_ENCODING_FALCON512"); if (getenv("OQS_ENCODING_FALCON512_ALGNAME")) - oqs_alg_encoding_list[29] = getenv("OQS_ENCODING_FALCON512_ALGNAME"); + oqs_alg_encoding_list[55] = getenv("OQS_ENCODING_FALCON512_ALGNAME"); if (getenv("OQS_ENCODING_P256_FALCON512")) - oqs_alg_encoding_list[30] = getenv("OQS_ENCODING_P256_FALCON512"); + oqs_alg_encoding_list[56] = getenv("OQS_ENCODING_P256_FALCON512"); if (getenv("OQS_ENCODING_P256_FALCON512_ALGNAME")) - oqs_alg_encoding_list[31] + oqs_alg_encoding_list[57] = getenv("OQS_ENCODING_P256_FALCON512_ALGNAME"); if (getenv("OQS_ENCODING_RSA3072_FALCON512")) - oqs_alg_encoding_list[32] = getenv("OQS_ENCODING_RSA3072_FALCON512"); + oqs_alg_encoding_list[58] = getenv("OQS_ENCODING_RSA3072_FALCON512"); if (getenv("OQS_ENCODING_RSA3072_FALCON512_ALGNAME")) - oqs_alg_encoding_list[33] + oqs_alg_encoding_list[59] = getenv("OQS_ENCODING_RSA3072_FALCON512_ALGNAME"); if (getenv("OQS_ENCODING_FALCONPADDED512")) - oqs_alg_encoding_list[34] = getenv("OQS_ENCODING_FALCONPADDED512"); + oqs_alg_encoding_list[60] = getenv("OQS_ENCODING_FALCONPADDED512"); if (getenv("OQS_ENCODING_FALCONPADDED512_ALGNAME")) - oqs_alg_encoding_list[35] + oqs_alg_encoding_list[61] = getenv("OQS_ENCODING_FALCONPADDED512_ALGNAME"); if (getenv("OQS_ENCODING_P256_FALCONPADDED512")) - oqs_alg_encoding_list[36] = getenv("OQS_ENCODING_P256_FALCONPADDED512"); + oqs_alg_encoding_list[62] = getenv("OQS_ENCODING_P256_FALCONPADDED512"); if (getenv("OQS_ENCODING_P256_FALCONPADDED512_ALGNAME")) - oqs_alg_encoding_list[37] + oqs_alg_encoding_list[63] = getenv("OQS_ENCODING_P256_FALCONPADDED512_ALGNAME"); if (getenv("OQS_ENCODING_RSA3072_FALCONPADDED512")) - oqs_alg_encoding_list[38] + oqs_alg_encoding_list[64] = getenv("OQS_ENCODING_RSA3072_FALCONPADDED512"); if (getenv("OQS_ENCODING_RSA3072_FALCONPADDED512_ALGNAME")) - oqs_alg_encoding_list[39] + oqs_alg_encoding_list[65] = getenv("OQS_ENCODING_RSA3072_FALCONPADDED512_ALGNAME"); if (getenv("OQS_ENCODING_FALCON1024")) - oqs_alg_encoding_list[40] = getenv("OQS_ENCODING_FALCON1024"); + oqs_alg_encoding_list[66] = getenv("OQS_ENCODING_FALCON1024"); if (getenv("OQS_ENCODING_FALCON1024_ALGNAME")) - oqs_alg_encoding_list[41] = getenv("OQS_ENCODING_FALCON1024_ALGNAME"); + oqs_alg_encoding_list[67] = getenv("OQS_ENCODING_FALCON1024_ALGNAME"); if (getenv("OQS_ENCODING_P521_FALCON1024")) - oqs_alg_encoding_list[42] = getenv("OQS_ENCODING_P521_FALCON1024"); + oqs_alg_encoding_list[68] = getenv("OQS_ENCODING_P521_FALCON1024"); if (getenv("OQS_ENCODING_P521_FALCON1024_ALGNAME")) - oqs_alg_encoding_list[43] + oqs_alg_encoding_list[69] = getenv("OQS_ENCODING_P521_FALCON1024_ALGNAME"); if (getenv("OQS_ENCODING_FALCONPADDED1024")) - oqs_alg_encoding_list[44] = getenv("OQS_ENCODING_FALCONPADDED1024"); + oqs_alg_encoding_list[70] = getenv("OQS_ENCODING_FALCONPADDED1024"); if (getenv("OQS_ENCODING_FALCONPADDED1024_ALGNAME")) - oqs_alg_encoding_list[45] + oqs_alg_encoding_list[71] = getenv("OQS_ENCODING_FALCONPADDED1024_ALGNAME"); if (getenv("OQS_ENCODING_P521_FALCONPADDED1024")) - oqs_alg_encoding_list[46] + oqs_alg_encoding_list[72] = getenv("OQS_ENCODING_P521_FALCONPADDED1024"); if (getenv("OQS_ENCODING_P521_FALCONPADDED1024_ALGNAME")) - oqs_alg_encoding_list[47] + oqs_alg_encoding_list[73] = getenv("OQS_ENCODING_P521_FALCONPADDED1024_ALGNAME"); if (getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE")) - oqs_alg_encoding_list[48] + oqs_alg_encoding_list[74] = getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE"); if (getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[49] + oqs_alg_encoding_list[75] = getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE")) - oqs_alg_encoding_list[50] + oqs_alg_encoding_list[76] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE"); if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[51] + oqs_alg_encoding_list[77] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE")) - oqs_alg_encoding_list[52] + oqs_alg_encoding_list[78] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[53] + oqs_alg_encoding_list[79] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE")) - oqs_alg_encoding_list[54] + oqs_alg_encoding_list[80] = getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE"); if (getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE_ALGNAME")) - oqs_alg_encoding_list[55] + oqs_alg_encoding_list[81] = getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE")) - oqs_alg_encoding_list[56] + oqs_alg_encoding_list[82] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE"); if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE_ALGNAME")) - oqs_alg_encoding_list[57] + oqs_alg_encoding_list[83] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE")) - oqs_alg_encoding_list[58] + oqs_alg_encoding_list[84] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE_ALGNAME")) - oqs_alg_encoding_list[59] + oqs_alg_encoding_list[85] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE")) - oqs_alg_encoding_list[60] + oqs_alg_encoding_list[86] = getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE"); if (getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[61] + oqs_alg_encoding_list[87] = getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE")) - oqs_alg_encoding_list[62] + oqs_alg_encoding_list[88] = getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE"); if (getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[63] + oqs_alg_encoding_list[89] = getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE")) - oqs_alg_encoding_list[64] + oqs_alg_encoding_list[90] = getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE"); if (getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[65] + oqs_alg_encoding_list[91] = getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE")) - oqs_alg_encoding_list[66] + oqs_alg_encoding_list[92] = getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE"); if (getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[67] + oqs_alg_encoding_list[93] = getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE_ALGNAME"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE")) - oqs_alg_encoding_list[68] + oqs_alg_encoding_list[94] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE"); if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE_ALGNAME")) - oqs_alg_encoding_list[69] + oqs_alg_encoding_list[95] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE_ALGNAME"); ///// OQS_TEMPLATE_FRAGMENT_ENCODING_PATCHING_END return 1; @@ -716,14 +805,27 @@ static const OSSL_ALGORITHM oqsprovider_signatures[] = { SIGALG("mldsa44", 128, oqs_signature_functions), SIGALG("p256_mldsa44", 128, oqs_signature_functions), SIGALG("rsa3072_mldsa44", 128, oqs_signature_functions), + SIGALG("mldsa44_pss2048", 112, oqs_signature_functions), + SIGALG("mldsa44_rsa2048", 112, oqs_signature_functions), + SIGALG("mldsa44_ed25519", 128, oqs_signature_functions), + SIGALG("mldsa44_p256", 128, oqs_signature_functions), + SIGALG("mldsa44_bp256", 256, oqs_signature_functions), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_65 SIGALG("mldsa65", 192, oqs_signature_functions), SIGALG("p384_mldsa65", 192, oqs_signature_functions), + SIGALG("mldsa65_pss3072", 128, oqs_signature_functions), + SIGALG("mldsa65_rsa3072", 128, oqs_signature_functions), + SIGALG("mldsa65_p256", 128, oqs_signature_functions), + SIGALG("mldsa65_bp256", 256, oqs_signature_functions), + SIGALG("mldsa65_ed25519", 128, oqs_signature_functions), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_87 SIGALG("mldsa87", 256, oqs_signature_functions), SIGALG("p521_mldsa87", 256, oqs_signature_functions), + SIGALG("mldsa87_p384", 192, oqs_signature_functions), + SIGALG("mldsa87_bp384", 384, oqs_signature_functions), + SIGALG("mldsa87_ed448", 192, oqs_signature_functions), #endif #ifdef OQS_ENABLE_SIG_falcon_512 SIGALG("falcon512", 128, oqs_signature_functions), @@ -883,14 +985,27 @@ static const OSSL_ALGORITHM oqsprovider_keymgmt[] SIGALG("mldsa44", 128, oqs_mldsa44_keymgmt_functions), SIGALG("p256_mldsa44", 128, oqs_p256_mldsa44_keymgmt_functions), SIGALG("rsa3072_mldsa44", 128, oqs_rsa3072_mldsa44_keymgmt_functions), + SIGALG("mldsa44_pss2048", 112, oqs_mldsa44_pss2048_keymgmt_functions), + SIGALG("mldsa44_rsa2048", 112, oqs_mldsa44_rsa2048_keymgmt_functions), + SIGALG("mldsa44_ed25519", 128, oqs_mldsa44_ed25519_keymgmt_functions), + SIGALG("mldsa44_p256", 128, oqs_mldsa44_p256_keymgmt_functions), + SIGALG("mldsa44_bp256", 256, oqs_mldsa44_bp256_keymgmt_functions), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_65 SIGALG("mldsa65", 192, oqs_mldsa65_keymgmt_functions), SIGALG("p384_mldsa65", 192, oqs_p384_mldsa65_keymgmt_functions), + SIGALG("mldsa65_pss3072", 128, oqs_mldsa65_pss3072_keymgmt_functions), + SIGALG("mldsa65_rsa3072", 128, oqs_mldsa65_rsa3072_keymgmt_functions), + SIGALG("mldsa65_p256", 128, oqs_mldsa65_p256_keymgmt_functions), + SIGALG("mldsa65_bp256", 256, oqs_mldsa65_bp256_keymgmt_functions), + SIGALG("mldsa65_ed25519", 128, oqs_mldsa65_ed25519_keymgmt_functions), #endif #ifdef OQS_ENABLE_SIG_ml_dsa_87 SIGALG("mldsa87", 256, oqs_mldsa87_keymgmt_functions), SIGALG("p521_mldsa87", 256, oqs_p521_mldsa87_keymgmt_functions), + SIGALG("mldsa87_p384", 192, oqs_mldsa87_p384_keymgmt_functions), + SIGALG("mldsa87_bp384", 384, oqs_mldsa87_bp384_keymgmt_functions), + SIGALG("mldsa87_ed448", 192, oqs_mldsa87_ed448_keymgmt_functions), #endif #ifdef OQS_ENABLE_SIG_falcon_512 SIGALG("falcon512", 128, oqs_falcon512_keymgmt_functions), @@ -1055,6 +1170,32 @@ static const OSSL_ALGORITHM oqsprovider_decoder[] = { #undef DECODER_PROVIDER }; +// get the last number on the composite OID +int get_composite_idx(int idx) +{ + char *s; + int i, len, ret = -1, count = 0; + + if (2 * idx > OQS_OID_CNT) + return 0; + s = (char *)oqs_oid_alg_list[idx * 2]; + len = strlen(s); + + for (i = 0; i < len; i++) { + if (s[i] == '.') { + count += 1; + } + if (count == 8) { // 8 dots in composite OID + errno = 0; + ret = strtol(s + i + 1, NULL, 10); + if (errno == ERANGE) + ret = -1; + break; + } + } + return ret; +} + static const OSSL_PARAM *oqsprovider_gettable_params(void *provctx) { return oqsprovider_param_types; diff --git a/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c index 53e96a07..23e95267 100644 --- a/oqsprov/oqsprov_keys.c +++ b/oqsprov/oqsprov_keys.c @@ -54,9 +54,9 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op); ///// OQS_TEMPLATE_FRAGMENT_OQSNAMES_START #ifdef OQS_KEM_ENCODERS -# define NID_TABLE_LEN 88 +# define NID_TABLE_LEN 101 #else -# define NID_TABLE_LEN 35 +# define NID_TABLE_LEN 48 #endif static oqs_nid_name_t nid_names[NID_TABLE_LEN] = { @@ -137,10 +137,23 @@ static oqs_nid_name_t nid_names[NID_TABLE_LEN] = { {0, "mldsa44", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_SIG, 128}, {0, "p256_mldsa44", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_HYB_SIG, 128}, {0, "rsa3072_mldsa44", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_HYB_SIG, 128}, + {0, "mldsa44_pss2048", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_CMP_SIG, 112}, + {0, "mldsa44_rsa2048", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_CMP_SIG, 112}, + {0, "mldsa44_ed25519", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_CMP_SIG, 128}, + {0, "mldsa44_p256", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_CMP_SIG, 128}, + {0, "mldsa44_bp256", OQS_SIG_alg_ml_dsa_44, KEY_TYPE_CMP_SIG, 256}, {0, "mldsa65", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_SIG, 192}, {0, "p384_mldsa65", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_HYB_SIG, 192}, + {0, "mldsa65_pss3072", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_CMP_SIG, 128}, + {0, "mldsa65_rsa3072", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_CMP_SIG, 128}, + {0, "mldsa65_p256", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_CMP_SIG, 128}, + {0, "mldsa65_bp256", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_CMP_SIG, 256}, + {0, "mldsa65_ed25519", OQS_SIG_alg_ml_dsa_65, KEY_TYPE_CMP_SIG, 128}, {0, "mldsa87", OQS_SIG_alg_ml_dsa_87, KEY_TYPE_SIG, 256}, {0, "p521_mldsa87", OQS_SIG_alg_ml_dsa_87, KEY_TYPE_HYB_SIG, 256}, + {0, "mldsa87_p384", OQS_SIG_alg_ml_dsa_87, KEY_TYPE_CMP_SIG, 192}, + {0, "mldsa87_bp384", OQS_SIG_alg_ml_dsa_87, KEY_TYPE_CMP_SIG, 384}, + {0, "mldsa87_ed448", OQS_SIG_alg_ml_dsa_87, KEY_TYPE_CMP_SIG, 192}, {0, "falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_SIG, 128}, {0, "p256_falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_HYB_SIG, 128}, {0, "rsa3072_falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_HYB_SIG, 128}, @@ -211,7 +224,20 @@ static int get_keytype(int nid) return 0; } -static char *get_oqsname(int nid) +char *get_oqsname_fromtls(char *tlsname) +{ + int i; + for (i = 0; i < NID_TABLE_LEN; i++) { + if (nid_names[i].keytype == KEY_TYPE_SIG) { + if (!strcmp(nid_names[i].oqsname, tlsname) + || !strcmp(nid_names[i].tlsname, tlsname)) + return nid_names[i].oqsname; + } + } + return 0; // classical +} + +char *get_oqsname(int nid) { int i; for (i = 0; i < NID_TABLE_LEN; i++) { @@ -221,7 +247,35 @@ static char *get_oqsname(int nid) return 0; } -static int get_oqsalg_idx(int nid) +char *get_cmpname(int nid, int index) +{ + int i, len; + char *name, *s; + if ((i = get_oqsalg_idx(nid)) == -1) + return NULL; + s = nid_names[i].tlsname; + len = strlen(s); + for (i = 0; i < len; i++) { + if (s[i] == '_') { + break; + } + } + switch (index) { + case 0: + name = OPENSSL_strndup(s, i); + break; + case 1: + i += 1; + name = OPENSSL_strndup(s + i, len - i); + break; + default: + name = NULL; + } + + return name; +} + +int get_oqsalg_idx(int nid) { int i; for (i = 0; i < NID_TABLE_LEN; i++) { @@ -241,29 +295,50 @@ static int oqsx_key_set_composites(OQSX_KEY *key) if (key->numkeys == 1) { key->comp_privkey[0] = key->privkey; key->comp_pubkey[0] = key->pubkey; - } else { // TBD: extend for more than 1 classic key: - int classic_pubkey_len, classic_privkey_len; - - if (key->privkey) { - key->comp_privkey[0] = (char *)key->privkey + SIZE_OF_UINT32; - DECODE_UINT32(classic_privkey_len, key->privkey); - key->comp_privkey[1] - = (char *)key->privkey + classic_privkey_len + SIZE_OF_UINT32; - } else { - key->comp_privkey[0] = NULL; - key->comp_privkey[1] = NULL; - } - if (key->pubkey) { - key->comp_pubkey[0] = (char *)key->pubkey + SIZE_OF_UINT32; - DECODE_UINT32(classic_pubkey_len, key->pubkey); - key->comp_pubkey[1] - = (char *)key->pubkey + classic_pubkey_len + SIZE_OF_UINT32; + } else { // TBD: extend for more than 1 classic key or first OQS for + // composite: + if (key->keytype == KEY_TYPE_CMP_SIG) { + int i; + int privlen = 0; + int publen = 0; + for (i = 0; i < key->numkeys; i++) { + if (key->privkey) { + key->comp_privkey[i] = (char *)key->privkey + privlen; + privlen += key->privkeylen_cmp[i]; + } else { + key->comp_privkey[i] = NULL; + } + if (key->pubkey) { + key->comp_pubkey[i] = (char *)key->pubkey + publen; + publen += key->pubkeylen_cmp[i]; + } else { + key->comp_pubkey[i] = NULL; + } + } } else { + int classic_pubkey_len, classic_privkey_len; - key->comp_pubkey[0] = NULL; - key->comp_pubkey[1] = NULL; + if (key->privkey) { + key->comp_privkey[0] = (char *)key->privkey + SIZE_OF_UINT32; + DECODE_UINT32(classic_privkey_len, key->privkey); + key->comp_privkey[1] = (char *)key->privkey + + classic_privkey_len + SIZE_OF_UINT32; + } else { + key->comp_privkey[0] = NULL; + key->comp_privkey[1] = NULL; + } + if (key->pubkey) { + key->comp_pubkey[0] = (char *)key->pubkey + SIZE_OF_UINT32; + DECODE_UINT32(classic_pubkey_len, key->pubkey); + key->comp_pubkey[1] + = (char *)key->pubkey + classic_pubkey_len + SIZE_OF_UINT32; + } else { + key->comp_pubkey[0] = NULL; + key->comp_pubkey[1] = NULL; + } } } +err: return ret; } @@ -320,6 +395,10 @@ EVP_PKEY *setECParams(EVP_PKEY *eck, int nid) = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22}; const unsigned char p521params[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23}; + const char bp256params[] + = {0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}; + const char bp384params[] + = {0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b}; const unsigned char *params; switch (nid) { @@ -332,11 +411,171 @@ EVP_PKEY *setECParams(EVP_PKEY *eck, int nid) case NID_secp521r1: params = p521params; return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(p521params)); + case NID_brainpoolP256r1: + params = bp256params; + return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(bp256params)); + case NID_brainpoolP384r1: + params = bp384params; + return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(bp384params)); default: return NULL; } } +/* Key codes */ + +static const OQSX_EVP_INFO nids_sig[] = { + {EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65, 121, 32, 72}, // 128 bit + {EVP_PKEY_EC, NID_secp384r1, 0, 97, 167, 48, 104}, // 192 bit + {EVP_PKEY_EC, NID_secp521r1, 0, 133, 223, 66, 141}, // 256 bit + {EVP_PKEY_EC, NID_brainpoolP256r1, 0, 65, 122, 32, 72}, // 256 bit + {EVP_PKEY_EC, NID_brainpoolP384r1, 0, 97, 171, 48, 104}, // 384 bit + {EVP_PKEY_RSA, NID_rsaEncryption, 0, 398, 1770, 0, 384}, // 128 bit + {EVP_PKEY_RSA, NID_rsaEncryption, 0, 270, 1193, 0, 256}, // 112 bit + {EVP_PKEY_ED25519, NID_ED25519, 1, 32, 32, 32, 72}, // 128 bit + {EVP_PKEY_ED448, NID_ED448, 1, 57, 57, 57, 122}, // 192 bit + +}; +// These two array need to stay synced: +// note only leading 4 chars of alg name are checked +static const char *OQSX_ECP_NAMES[] = {"p256", "p384", "p521", 0}; +static const OQSX_EVP_INFO nids_ecp[] = { + {EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65, 121, 32, 0}, // 128 bit + {EVP_PKEY_EC, NID_secp384r1, 0, 97, 167, 48, 0}, // 192 bit + {EVP_PKEY_EC, NID_secp521r1, 0, 133, 223, 66, 0} // 256 bit +}; + +// These two array need to stay synced: +// note only leading 4 chars of alg name are checked +static const char *OQSX_ECX_NAMES[] = {"x25519", "x448", 0}; +static const OQSX_EVP_INFO nids_ecx[] = { + {EVP_PKEY_X25519, 0, 1, 32, 32, 32, 0}, // 128 bit + {EVP_PKEY_X448, 0, 1, 56, 56, 56, 0}, // 192 bit + {0, 0, 0, 0, 0, 0, 0} // 256 bit +}; + +static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx, + char *algname) +{ + int ret = 1; + int idx = (bit_security - 128) / 64; + ON_ERR_GOTO(idx < 0 || idx > 5, err_init); + + if (!strncmp(algname, "rsa", 3) || !strncmp(algname, "pss", 3)) { + idx += 5; + if (bit_security == 112) + idx += 1; + } else if (algname[0] != 'p' && algname[0] != 'e') { + if (algname[0] == 'b') { // bp + if (algname[2] == '2') // bp256 + idx += 1; + } else { + OQS_KEY_PRINTF2("OQS KEY: Incorrect hybrid name: %s\n", algname); + ret = 0; + goto err_init; + } + } + + ON_ERR_GOTO(idx < 0 || idx > 6, err_init); + + if (algname[0] == 'e') // ED25519 or ED448 + { + evp_ctx->evp_info = &nids_sig[idx + 7]; + + evp_ctx->keyParam = EVP_PKEY_new(); + ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err_init); + + ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype); + ON_ERR_SET_GOTO(ret <= 0, ret, -1, err_init); + + evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL); + ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err_init); + } else { + evp_ctx->evp_info = &nids_sig[idx]; + + evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL); + ON_ERR_GOTO(!evp_ctx->ctx, err_init); + + if (idx < 5) { // EC + ret = EVP_PKEY_paramgen_init(evp_ctx->ctx); + ON_ERR_GOTO(ret <= 0, err_init); + + ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid( + evp_ctx->ctx, evp_ctx->evp_info->nid); + ON_ERR_GOTO(ret <= 0, free_evp_ctx); + + ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam); + ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, free_evp_ctx); + } + } + // RSA bit length set only during keygen + goto err_init; + +free_evp_ctx: + EVP_PKEY_CTX_free(evp_ctx->ctx); + evp_ctx->ctx = NULL; + +err_init: + return ret; +} + +static const int oqshybkem_init_ecp(char *tls_name, OQSX_EVP_CTX *evp_ctx) +{ + int ret = 1; + int idx = 0; + while (idx < OSSL_NELEM(OQSX_ECP_NAMES)) { + if (!strncmp(tls_name, OQSX_ECP_NAMES[idx], 4)) + break; + idx++; + } + ON_ERR_GOTO(idx < 0 || idx > 2, err_init_ecp); + + evp_ctx->evp_info = &nids_ecp[idx]; + + evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL); + ON_ERR_GOTO(!evp_ctx->ctx, err_init_ecp); + + ret = EVP_PKEY_paramgen_init(evp_ctx->ctx); + ON_ERR_GOTO(ret <= 0, err_init_ecp); + + ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx, + evp_ctx->evp_info->nid); + ON_ERR_GOTO(ret <= 0, err_init_ecp); + + ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam); + ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, err_init_ecp); + +err_init_ecp: + return ret; +} + +static const int oqshybkem_init_ecx(char *tls_name, OQSX_EVP_CTX *evp_ctx) +{ + int ret = 1; + int idx = 0; + + while (idx < OSSL_NELEM(OQSX_ECX_NAMES)) { + if (!strncmp(tls_name, OQSX_ECX_NAMES[idx], 4)) + break; + idx++; + } + ON_ERR_GOTO(idx < 0 || idx > 2, err_init_ecx); + + evp_ctx->evp_info = &nids_ecx[idx]; + + evp_ctx->keyParam = EVP_PKEY_new(); + ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err_init_ecx); + + ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype); + ON_ERR_SET_GOTO(ret <= 0, ret, -1, err_init_ecx); + + evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL); + ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err_init_ecx); + +err_init_ecx: + return ret; +} + /* Re-create OQSX_KEY from encoding(s): Same end-state as after ken-gen */ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p, int plen, oqsx_key_op_t op, OSSL_LIB_CTX *libctx, @@ -414,95 +653,204 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p, size_t actualprivkeylen = key->privkeylen; // for hybrid keys, we expect classic priv key||OQS priv key||OQS pub // key classic pub key must/can be re-created from classic private key - if (key->numkeys == 2) { - DECODE_UINT32(classical_privatekey_len, - p); // actual classic key len - // adjust expected size - if (classical_privatekey_len > key->evp_info->length_private_key) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + if (key->keytype == KEY_TYPE_CMP_SIG) { + size_t privlen = 0; + size_t publen = 0; + size_t previous_privlen = 0; + size_t previous_publen = 0; + size_t temp_pub_len, temp_priv_len; + char *temp_priv, *temp_pub; + int pqc_pub_enc = 0; + int i; + + // check if key is the right size + for (i = 0; i < key->numkeys; i++) { + char *name; + if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) + == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + privlen = key->privkeylen_cmp[i]; + if (get_oqsname_fromtls(name) == 0) { // classical key + publen = 0; + } else { // PQC key + publen = key->pubkeylen_cmp[i]; // pubkey in PQC privkey is + // OPTIONAL + } + previous_privlen += privlen; + previous_publen += publen; + OPENSSL_free(name); + } + if (previous_privlen != plen) { + // is ok, PQC pubkey might be in privkey + pqc_pub_enc = 1; + if (previous_privlen + previous_publen != plen) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + if (oqsx_key_allocate_keymaterial(key, 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + goto err_key_op; + } + } + if (oqsx_key_allocate_keymaterial(key, 1)) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); goto err_key_op; } - actualprivkeylen -= (key->evp_info->length_private_key - - classical_privatekey_len); - } + temp_priv_len = previous_privlen; + temp_pub_len = previous_publen; + temp_priv = OPENSSL_secure_zalloc(temp_priv_len); + temp_pub = OPENSSL_secure_zalloc(temp_pub_len); + previous_privlen = 0; + previous_publen = 0; + for (i = 0; i < key->numkeys; i++) { + size_t classic_publen = 0; + char *name; + if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) + == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + OPENSSL_secure_clear_free(temp_priv, temp_priv_len); + OPENSSL_secure_clear_free(temp_pub, temp_pub_len); + goto err_key_op; + } + if (get_oqsname_fromtls(name) == 0) { // classical key + publen = 0; // no pubkey encoded with privkey on classical + // keys. will recreate the pubkey later + if (key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->keytype + == EVP_PKEY_RSA) { // get the RSA real key size + unsigned char *enc_len = OPENSSL_strndup( + p + previous_privlen + previous_publen, 4); + OPENSSL_cleanse(enc_len, 2); + DECODE_UINT32(privlen, enc_len); + privlen += 4; + OPENSSL_free(enc_len); + if (privlen > key->privkeylen_cmp[i]) { + OPENSSL_free(name); + OPENSSL_secure_clear_free(temp_priv, temp_priv_len); + OPENSSL_secure_clear_free(temp_pub, temp_pub_len); + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + key->privkeylen_cmp[i] = privlen; + } else + privlen = key->privkeylen_cmp[i]; + } else { // PQC key + privlen = key->privkeylen_cmp[i]; + if (pqc_pub_enc) + publen = key->pubkeylen_cmp[i]; + else + publen = 0; + } + memcpy(temp_priv + previous_privlen, + p + previous_privlen + previous_publen, privlen); + memcpy(temp_pub + previous_publen, + p + privlen + previous_privlen + previous_publen, + publen); + previous_privlen += privlen; + previous_publen += publen; + OPENSSL_free(name); + } + memcpy(key->privkey, temp_priv, previous_privlen); + memcpy(key->pubkey, temp_pub, previous_publen); + OPENSSL_secure_clear_free(temp_priv, temp_priv_len); + OPENSSL_secure_clear_free(temp_pub, temp_pub_len); + } else { + if (key->numkeys == 2) { + DECODE_UINT32(classical_privatekey_len, + p); // actual classic key len + // adjust expected size + if (classical_privatekey_len + > key->evp_info->length_private_key) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + actualprivkeylen -= (key->evp_info->length_private_key + - classical_privatekey_len); + } #ifdef USE_ENCODING_LIB - if (key->oqsx_encoding_ctx.encoding_ctx - && key->oqsx_encoding_ctx.encoding_impl) { - const qsc_encoding_t *encoding_ctx - = key->oqsx_encoding_ctx.encoding_ctx; + if (key->oqsx_encoding_ctx.encoding_ctx + && key->oqsx_encoding_ctx.encoding_impl) { + const qsc_encoding_t *encoding_ctx + = key->oqsx_encoding_ctx.encoding_ctx; # ifdef NOPUBKEY_IN_PRIVKEY - // if the raw private key includes the public key, the optional part - // is needed, otherwise not. - int withoptional - = (encoding_ctx->raw_private_key_encodes_public_key ? 1 : 0); + // if the raw private key includes the public key, the optional + // part is needed, otherwise not. + int withoptional + = (encoding_ctx->raw_private_key_encodes_public_key ? 1 + : 0); # else - int withoptional = 1; + int withoptional = 1; # endif - int pubkey_available = withoptional; - if (oqsx_key_allocate_keymaterial(key, 1)) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - goto err_key_op; - } - if (pubkey_available) { - if (oqsx_key_allocate_keymaterial(key, 0)) { + int pubkey_available = withoptional; + if (oqsx_key_allocate_keymaterial(key, 1)) { ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); goto err_key_op; } - } + if (pubkey_available) { + if (oqsx_key_allocate_keymaterial(key, 0)) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + goto err_key_op; + } + } - if (qsc_decode( - encoding_ctx, key->oqsx_encoding_ctx.encoding_impl, 0, - (pubkey_available ? (unsigned char **)&key->pubkey : 0), p, - (unsigned char **)&key->privkey, withoptional) - != QSC_ENC_OK) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto err_key_op; - } + if (qsc_decode( + encoding_ctx, key->oqsx_encoding_ctx.encoding_impl, 0, + (pubkey_available ? (unsigned char **)&key->pubkey : 0), + p, (unsigned char **)&key->privkey, withoptional) + != QSC_ENC_OK) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } - } else { + } else { #endif #ifdef NOPUBKEY_IN_PRIVKEY - if (actualprivkeylen != plen) { + if (actualprivkeylen != plen) { + OQS_KEY_PRINTF3( + "OQSX KEY: private key with unexpected length %d vs %d\n", + plen, (int)(actualprivkeylen)); +#else + if (actualprivkeylen + oqsx_key_get_oqs_public_key_len(key) + != plen) { OQS_KEY_PRINTF3( "OQSX KEY: private key with unexpected length %d vs %d\n", - plen, (int)(actualprivkeylen)); -#else - if (actualprivkeylen + oqsx_key_get_oqs_public_key_len(key) != plen) { - OQS_KEY_PRINTF3( - "OQSX KEY: private key with unexpected length %d vs %d\n", plen, - (int)(actualprivkeylen + oqsx_key_get_oqs_public_key_len(key))); + plen, + (int)(actualprivkeylen + + oqsx_key_get_oqs_public_key_len(key))); #endif - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto err_key_op; - } - if (oqsx_key_allocate_keymaterial(key, 1) + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + if (oqsx_key_allocate_keymaterial(key, 1) #ifndef NOPUBKEY_IN_PRIVKEY - || oqsx_key_allocate_keymaterial(key, 0) + || oqsx_key_allocate_keymaterial(key, 0) #endif - ) { - ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); - goto err_key_op; - } - // first populate private key data - memcpy(key->privkey, p, actualprivkeylen); + ) { + ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); + goto err_key_op; + } + // first populate private key data + memcpy(key->privkey, p, actualprivkeylen); #ifndef NOPUBKEY_IN_PRIVKEY - // only enough data to fill public OQS key component - if (oqsx_key_get_oqs_public_key_len(key) - != plen - actualprivkeylen) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto err_key_op; - } - // populate OQS public key structure - if (key->numkeys == 2) { - unsigned char *pubkey = (unsigned char *)key->pubkey; - ENCODE_UINT32(pubkey, key->evp_info->length_public_key); - memcpy(pubkey + SIZE_OF_UINT32 - + key->evp_info->length_public_key, - p + actualprivkeylen, plen - actualprivkeylen); - } else - memcpy(key->pubkey, p + key->privkeylen, - plen - key->privkeylen); + // only enough data to fill public OQS key component + if (oqsx_key_get_oqs_public_key_len(key) + != plen - actualprivkeylen) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err_key_op; + } + // populate OQS public key structure + if (key->numkeys == 2) { + unsigned char *pubkey = (unsigned char *)key->pubkey; + ENCODE_UINT32(pubkey, key->evp_info->length_public_key); + memcpy(pubkey + SIZE_OF_UINT32 + + key->evp_info->length_public_key, + p + actualprivkeylen, plen - actualprivkeylen); + } else + memcpy(key->pubkey, p + key->privkeylen, + plen - key->privkeylen); #endif + } } #ifdef USE_ENCODING_LIB } @@ -520,84 +868,188 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p, /* Recreate EVP data structure after import. RetVal 0 is error. */ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) { - if (key->numkeys == 2) { // hybrid key - int classical_pubkey_len, classical_privkey_len; - if (!key->evp_info) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_EVPINFO_MISSING); - goto rec_err; - } + if (key->keytype == KEY_TYPE_CMP_SIG) { + int i; if (op == KEY_OP_PUBLIC) { - const unsigned char *enc_pubkey = key->comp_pubkey[0]; - DECODE_UINT32(classical_pubkey_len, key->pubkey); - if (key->evp_info->raw_key_support) { - key->classical_pkey = EVP_PKEY_new_raw_public_key( - key->evp_info->keytype, NULL, enc_pubkey, - classical_pubkey_len); - if (!key->classical_pkey) { + + for (i = 0; i < key->numkeys; i++) { + char *name; + if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) + == NULL) { ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); goto rec_err; } - } else { - EVP_PKEY *npk = EVP_PKEY_new(); - if (key->evp_info->keytype != EVP_PKEY_RSA) { - npk = setECParams(npk, key->evp_info->nid); - } - key->classical_pkey - = d2i_PublicKey(key->evp_info->keytype, &npk, &enc_pubkey, - classical_pubkey_len); - if (!key->classical_pkey) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - EVP_PKEY_free(npk); - goto rec_err; + const unsigned char *enc_pubkey = key->comp_pubkey[i]; + + if (get_oqsname_fromtls(name) == 0) { + if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->raw_key_support) { + EVP_PKEY *npk = EVP_PKEY_new(); + if (key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype + != EVP_PKEY_RSA) { + npk = setECParams(npk, + key->oqsx_provider_ctx + .oqsx_evp_ctx->evp_info->nid); + } + key->classical_pkey = d2i_PublicKey( + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype, + &npk, &enc_pubkey, key->pubkeylen_cmp[i]); + } else + key->classical_pkey = EVP_PKEY_new_raw_public_key( + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype, + NULL, enc_pubkey, key->pubkeylen_cmp[i]); + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + OPENSSL_free(name); + goto rec_err; + } } + OPENSSL_free(name); } } + if (op == KEY_OP_PRIVATE) { - DECODE_UINT32(classical_privkey_len, key->privkey); - const unsigned char *enc_privkey = key->comp_privkey[0]; - unsigned char *enc_pubkey = key->comp_pubkey[0]; - if (key->evp_info->raw_key_support) { - key->classical_pkey = EVP_PKEY_new_raw_private_key( - key->evp_info->keytype, NULL, enc_privkey, - classical_privkey_len); - if (!key->classical_pkey) { + + for (i = 0; i < key->numkeys; i++) { + char *name; + if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) + == NULL) { ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); goto rec_err; } -#ifndef NOPUBKEY_IN_PRIVKEY - // re-create classic public key part from private key: - size_t pubkeylen; - - EVP_PKEY_get_raw_public_key(key->classical_pkey, NULL, - &pubkeylen); - if (pubkeylen != key->evp_info->length_public_key - || EVP_PKEY_get_raw_public_key(key->classical_pkey, - enc_pubkey, &pubkeylen) - != 1) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto rec_err; + if (get_oqsname_fromtls(name) == 0) { + const unsigned char *enc_privkey = key->comp_privkey[i]; + if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->raw_key_support) { + EVP_PKEY *npk; + key->classical_pkey = d2i_PrivateKey( + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype, + NULL, &enc_privkey, key->privkeylen_cmp[i]); + } else { + key->classical_pkey = EVP_PKEY_new_raw_private_key( + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype, + NULL, enc_privkey, key->privkeylen_cmp[i]); + } + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + OPENSSL_free(name); + goto rec_err; + } + if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->raw_key_support) { + unsigned char *comp_pubkey = key->comp_pubkey[i]; + int pubkeylen + = i2d_PublicKey(key->classical_pkey, &comp_pubkey); + if (pubkeylen + != key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->length_public_key) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + OPENSSL_free(name); + goto rec_err; + } + } else { + size_t pubkeylen = key->pubkeylen_cmp[i]; + int ret = EVP_PKEY_get_raw_public_key( + key->classical_pkey, key->comp_pubkey[i], + &pubkeylen); + if (ret <= 0) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + OPENSSL_free(name); + goto rec_err; + } + } } -#endif - } else { - key->classical_pkey - = d2i_PrivateKey(key->evp_info->keytype, NULL, &enc_privkey, - classical_privkey_len); - if (!key->classical_pkey) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto rec_err; + OPENSSL_free(name); + } + } + } else { + if ((key->numkeys == 2)) { // hybrid key + int classical_pubkey_len, classical_privkey_len; + if (!key->evp_info) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_EVPINFO_MISSING); + goto rec_err; + } + if (op == KEY_OP_PUBLIC) { + const unsigned char *enc_pubkey = key->comp_pubkey[0]; + DECODE_UINT32(classical_pubkey_len, key->pubkey); + if (key->evp_info->raw_key_support) { + key->classical_pkey = EVP_PKEY_new_raw_public_key( + key->evp_info->keytype, NULL, enc_pubkey, + classical_pubkey_len); + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto rec_err; + } + } else { + EVP_PKEY *npk = EVP_PKEY_new(); + if (key->evp_info->keytype != EVP_PKEY_RSA) { + npk = setECParams(npk, key->evp_info->nid); + } + key->classical_pkey + = d2i_PublicKey(key->evp_info->keytype, &npk, + &enc_pubkey, classical_pubkey_len); + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + EVP_PKEY_free(npk); + goto rec_err; + } } + } + if (op == KEY_OP_PRIVATE) { + DECODE_UINT32(classical_privkey_len, key->privkey); + const unsigned char *enc_privkey = key->comp_privkey[0]; + unsigned char *enc_pubkey = key->comp_pubkey[0]; + if (key->evp_info->raw_key_support) { + key->classical_pkey = EVP_PKEY_new_raw_private_key( + key->evp_info->keytype, NULL, enc_privkey, + classical_privkey_len); + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto rec_err; + } #ifndef NOPUBKEY_IN_PRIVKEY - // re-create classic public key part from private key: - int pubkeylen = i2d_PublicKey(key->classical_pkey, &enc_pubkey); - if (pubkeylen != key->evp_info->length_public_key) { - ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); - goto rec_err; - } + // re-create classic public key part from private key: + size_t pubkeylen; + + EVP_PKEY_get_raw_public_key(key->classical_pkey, NULL, + &pubkeylen); + if (pubkeylen != key->evp_info->length_public_key + || EVP_PKEY_get_raw_public_key(key->classical_pkey, + enc_pubkey, &pubkeylen) + != 1) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto rec_err; + } #endif + } else { + key->classical_pkey + = d2i_PrivateKey(key->evp_info->keytype, NULL, + &enc_privkey, classical_privkey_len); + if (!key->classical_pkey) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto rec_err; + } +#ifndef NOPUBKEY_IN_PRIVKEY + // re-create classic public key part from private key: + int pubkeylen + = i2d_PublicKey(key->classical_pkey, &enc_pubkey); + if (pubkeylen != key->evp_info->length_public_key) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto rec_err; + } +#endif + } } } } + return 1; + rec_err: return 0; } @@ -609,11 +1061,51 @@ OQSX_KEY *oqsx_key_from_x509pubkey(const X509_PUBKEY *xpk, OSSL_LIB_CTX *libctx, int plen; X509_ALGOR *palg; OQSX_KEY *oqsx = NULL; + STACK_OF(ASN1_TYPE) *sk = NULL; + ASN1_TYPE *aType = NULL; + ASN1_OCTET_STRING *oct = NULL; + const unsigned char *buf; + unsigned char *concat_key; + int count, aux, i, buflen; if (!xpk || (!X509_PUBKEY_get0_param(NULL, &p, &plen, &palg, xpk))) { return NULL; } + if (get_keytype(OBJ_obj2nid(palg->algorithm)) == KEY_TYPE_CMP_SIG) { + sk = d2i_ASN1_SEQUENCE_ANY(NULL, &p, plen); + if (sk == NULL) { + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + return NULL; + } else { + count = sk_ASN1_TYPE_num(sk); + concat_key + = OPENSSL_zalloc(plen); // concat_key is allocated with plen, + // which is the max value for pubkey + + aux = 0; + for (i = 0; i < count; i++) { + aType + = sk_ASN1_TYPE_pop(sk); // this remove in FILO order, but we + // need this in the opposite order + buf = aType->value.sequence->data; + buflen = aType->value.sequence->length; + aux += buflen; + memcpy(concat_key + plen - 1 - aux, buf, + buflen); // fill concat_key starting at the end + ASN1_TYPE_free(aType); + } + + p = OPENSSL_memdup(concat_key + plen - 1 - aux, + aux); // copy used memory on concat_key to p + OPENSSL_clear_free(concat_key, plen); + plen = aux; // update plen value + sk_ASN1_TYPE_free(sk); + } + } oqsx = oqsx_key_op(palg, p, plen, KEY_OP_PUBLIC, libctx, propq); + if (get_keytype(OBJ_obj2nid(palg->algorithm)) == KEY_TYPE_CMP_SIG) + OPENSSL_clear_free((unsigned char *)p, plen); return oqsx; } @@ -625,150 +1117,177 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, int plen; ASN1_OCTET_STRING *oct = NULL; const X509_ALGOR *palg; + STACK_OF(ASN1_TYPE) *sk = NULL; + ASN1_TYPE *aType = NULL; + unsigned char *concat_key; + const unsigned char *buf; + int count, aux, i, buflen, key_diff = 0; if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) return 0; - oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); - if (oct == NULL) { - p = NULL; - plen = 0; + if (get_keytype(OBJ_obj2nid(palg->algorithm)) != KEY_TYPE_CMP_SIG) { + oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); + if (oct == NULL) { + p = NULL; + plen = 0; + } else { + p = ASN1_STRING_get0_data(oct); + plen = ASN1_STRING_length(oct); + } } else { - p = ASN1_STRING_get0_data(oct); - plen = ASN1_STRING_length(oct); - } - - oqsx = oqsx_key_op(palg, p, plen, KEY_OP_PRIVATE, libctx, propq); - ASN1_OCTET_STRING_free(oct); - return oqsx; -} - -/* Key codes */ - -static const OQSX_EVP_INFO nids_sig[] = { - {EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65, 121, 32, 72}, // 128 bit - {EVP_PKEY_EC, NID_secp384r1, 0, 97, 167, 48, 104}, // 192 bit - {EVP_PKEY_EC, NID_secp521r1, 0, 133, 223, 66, 141}, // 256 bit - {EVP_PKEY_RSA, NID_rsaEncryption, 0, 398, 1770, 0, 384}, // 128 bit -}; - -// These two arrays need to stay synced: -// note only leading 4 chars of alg name are checked -static const char *OQSX_ECP_NAMES[] = {"p256", "p384", "p521", 0}; -static const OQSX_EVP_INFO nids_ecp[] = { - {EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65, 121, 32, 0}, // 128 bit - {EVP_PKEY_EC, NID_secp384r1, 0, 97, 167, 48, 0}, // 192 bit - {EVP_PKEY_EC, NID_secp521r1, 0, 133, 223, 66, 0} // 256 bit -}; - -// These two arrays need to stay synced: -// note only leading 4 chars of alg name are checked -static const char *OQSX_ECX_NAMES[] = {"x25519", "x448", 0}; -static const OQSX_EVP_INFO nids_ecx[] = { - {EVP_PKEY_X25519, 0, 1, 32, 32, 32, 0}, // 128 bit - {EVP_PKEY_X448, 0, 1, 56, 56, 56, 0}, // 192 bit - {0, 0, 0, 0, 0, 0, 0} // 256 bit -}; - -static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx, - char *algname) -{ - int ret = 1; - int idx = (bit_security - 128) / 64; - ON_ERR_GOTO(idx < 0 || idx > 2, err_init); - - if (!strncmp(algname, "rsa3072_", 8)) - idx += 3; - else if (algname[0] != 'p') { - OQS_KEY_PRINTF2("OQS KEY: Incorrect hybrid name: %s\n", algname); - ret = 0; - goto err_init; - } - - ON_ERR_GOTO(idx < 0 || idx > 3, err_init); - - evp_ctx->evp_info = &nids_sig[idx]; - - evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL); - ON_ERR_GOTO(!evp_ctx->ctx, err_init); - - if (idx < 3) { // EC - ret = EVP_PKEY_paramgen_init(evp_ctx->ctx); - ON_ERR_GOTO(ret <= 0, free_evp_ctx); + sk = d2i_ASN1_SEQUENCE_ANY(NULL, &p, plen); + if (sk == NULL) { + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + return NULL; + } else { + count = sk_ASN1_TYPE_num(sk); + plen = 2 * plen; // get more than necessary in case its needed + concat_key = OPENSSL_zalloc(plen); + PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL; + const X509_ALGOR *palg_internal; + int keytype, nid; + + aux = 0; + for (i = 0; i < count; i++) { + aType + = sk_ASN1_TYPE_pop(sk); // this remove in FILO order, but we + // need this in the opposite order + p8inf_internal = PKCS8_PRIV_KEY_INFO_new(); + nid = 0; + char *name; + if ((name + = get_cmpname(OBJ_obj2nid(palg->algorithm), count - 1 - i)) + == NULL) { + ASN1_TYPE_free(aType); + OPENSSL_clear_free(concat_key, plen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + sk_ASN1_TYPE_free(sk); + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + return NULL; + } + buflen = aType->value.sequence->length; + const unsigned char *buf2 = aType->value.sequence->data; + + p8inf_internal + = d2i_PKCS8_PRIV_KEY_INFO(&p8inf_internal, &buf2, buflen); + if (!PKCS8_pkey_get0(NULL, &buf, &buflen, &palg_internal, + p8inf_internal)) { + OPENSSL_free(name); + ASN1_TYPE_free(aType); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + OPENSSL_clear_free(concat_key, plen); + sk_ASN1_TYPE_free(sk); + return NULL; + } - ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx, - evp_ctx->evp_info->nid); - ON_ERR_GOTO(ret <= 0, free_evp_ctx); + keytype = OBJ_obj2nid(palg_internal->algorithm); + + // Checking OPTIONAL params on EC + if (keytype == EVP_PKEY_EC) { + int j; + nid = OBJ_obj2nid(palg_internal->parameter->value.object); + for (j = 0; j < OSSL_NELEM(nids_sig); j++) { + if ((nids_sig[j].nid == nid) + && (nids_sig[j].length_private_key + > buflen)) { // check if the curve is the same + // and if the key len is smaller + // than the max key size + EVP_PKEY *ec_pkey; + OSSL_PARAM params[3]; + int include_pub = 1; + const unsigned char *buf3 + = aType->value.sequence->data; + unsigned char *buf4, *buf5; + + if (buflen + != nids_sig[j].kex_length_secret + + 7) { // no OPTIONAL ECParameter and no + // OPTIONAL Pubkey + OPENSSL_free(name); + ASN1_TYPE_free(aType); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + OPENSSL_clear_free(concat_key, plen); + sk_ASN1_TYPE_free(sk); + return NULL; + } + ec_pkey = EVP_PKEY_new(); + d2i_PrivateKey( + EVP_PKEY_EC, &ec_pkey, &buf3, + aType->value.sequence + ->length); // create a new EVP_PKEY using ec + // priv key + + // set parameters for the new priv key format + params[0] = OSSL_PARAM_construct_int( + OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, + &include_pub); // add pubkey to priv key + params[1] = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_EC_ENCODING, + OSSL_PKEY_EC_ENCODING_GROUP, + 0); // add ECParam to the priv key + params[2] = OSSL_PARAM_construct_end(); + EVP_PKEY_set_params(ec_pkey, params); + + buf4 = OPENSSL_malloc( + nids_sig[j].length_private_key); + buf5 = buf4; + buflen = i2d_PrivateKey( + ec_pkey, + &buf5); // encode priv key including parameters + + aux += buflen; + memcpy( + concat_key + plen - 1 - aux, buf4, + buflen); // fill concat_key starting at the end + + EVP_PKEY_free(ec_pkey); + OPENSSL_clear_free(buf4, buflen); + break; + } + } + if (j == OSSL_NELEM(nids_sig)) + nid = 0; // buflen is already with the correct size, + // changing nid to memcpy at the end + } - ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam); - ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, free_evp_ctx); - } - // RSA bit length set only during keygen - goto err_init; + // if is a RSA key the actual encoding size might be different + // from max size we calculate that difference for to facilitate + // the key reconstruction + if (keytype == EVP_PKEY_RSA) { + if (name[3] == '3') // 3072 + key_diff = nids_sig[5].length_private_key - buflen; + else // 2048 + key_diff = nids_sig[6].length_private_key - buflen; + } -free_evp_ctx: - EVP_PKEY_CTX_free(evp_ctx->ctx); - evp_ctx->ctx = NULL; + if (!nid) { + aux += buflen; + memcpy(concat_key + plen - 1 - aux, buf, + buflen); // fill concat_key starting at the end + } -err_init: - return ret; -} + OPENSSL_free(name); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + ASN1_TYPE_free(aType); + } -static const int oqshybkem_init_ecp(char *tls_name, OQSX_EVP_CTX *evp_ctx) -{ - int ret = 1; - int idx = 0; - while (idx < OSSL_NELEM(OQSX_ECP_NAMES)) { - if (!strncmp(tls_name, OQSX_ECP_NAMES[idx], 4)) - break; - idx++; + p = OPENSSL_memdup(concat_key + plen - 1 - aux, aux); + OPENSSL_clear_free(concat_key, plen); + plen = aux; // update plen to correct size + sk_ASN1_TYPE_free(sk); + } } - ON_ERR_GOTO(idx < 0 || idx > 2, err_init_ecp); - - evp_ctx->evp_info = &nids_ecp[idx]; - - evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL); - ON_ERR_GOTO(!evp_ctx->ctx, err_init_ecp); - - ret = EVP_PKEY_paramgen_init(evp_ctx->ctx); - ON_ERR_GOTO(ret <= 0, err_init_ecp); - ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx, - evp_ctx->evp_info->nid); - ON_ERR_GOTO(ret <= 0, err_init_ecp); - - ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam); - ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, err_init_ecp); - -err_init_ecp: - return ret; -} - -static const int oqshybkem_init_ecx(char *tls_name, OQSX_EVP_CTX *evp_ctx) -{ - int ret = 1; - int idx = 0; - - while (idx < OSSL_NELEM(OQSX_ECX_NAMES)) { - if (!strncmp(tls_name, OQSX_ECX_NAMES[idx], 4)) - break; - idx++; + oqsx = oqsx_key_op(palg, p, plen + key_diff, KEY_OP_PRIVATE, libctx, propq); + if (get_keytype(OBJ_obj2nid(palg->algorithm)) != KEY_TYPE_CMP_SIG) { + ASN1_OCTET_STRING_free(oct); + } else { + OPENSSL_clear_free((unsigned char *)p, + plen); // for COMPOSITE p include both privkey } - ON_ERR_GOTO(idx < 0 || idx > 2, err_init_ecx); - - evp_ctx->evp_info = &nids_ecx[idx]; - - evp_ctx->keyParam = EVP_PKEY_new(); - ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err_init_ecx); - - ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype); - ON_ERR_SET_GOTO(ret <= 0, ret, -1, err_init_ecx); - - evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL); - ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err_init_ecx); - -err_init_ecx: - return ret; + return oqsx; } static const int (*init_kex_fun[])(char *, OQSX_EVP_CTX *) @@ -785,7 +1304,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, OQSX_KEY *ret = OPENSSL_zalloc( sizeof(*ret)); // ensure all component pointers are NULL OQSX_EVP_CTX *evp_ctx = NULL; - int ret2 = 0; + int ret2 = 0, i; if (ret == NULL) goto err; @@ -811,6 +1330,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, ret->comp_privkey = OPENSSL_malloc(sizeof(void *)); ret->comp_pubkey = OPENSSL_malloc(sizeof(void *)); ON_ERR_GOTO(!ret->comp_privkey || !ret->comp_pubkey, err); + ret->oqsx_provider_ctx.oqsx_evp_ctx = NULL; ret->oqsx_provider_ctx.oqsx_qs_ctx.sig = OQS_SIG_new(oqs_name); if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) { fprintf( @@ -850,6 +1370,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, ret->comp_privkey = OPENSSL_malloc(sizeof(void *)); ret->comp_pubkey = OPENSSL_malloc(sizeof(void *)); ON_ERR_GOTO(!ret->comp_privkey || !ret->comp_pubkey, err); + ret->oqsx_provider_ctx.oqsx_evp_ctx = NULL; ret->oqsx_provider_ctx.oqsx_qs_ctx.kem = OQS_KEM_new(oqs_name); if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.kem) { fprintf( @@ -927,6 +1448,54 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, ret->oqsx_provider_ctx.oqsx_evp_ctx = evp_ctx; ret->keytype = primitive; ret->evp_info = evp_ctx->evp_info; + break; + case KEY_TYPE_CMP_SIG: + ret->numkeys = 2; + ret->privkeylen = 0; + ret->pubkeylen = 0; + ret->privkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(size_t)); + ret->pubkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(size_t)); + ret->comp_privkey = OPENSSL_malloc(ret->numkeys * sizeof(void *)); + ret->comp_pubkey = OPENSSL_malloc(ret->numkeys * sizeof(void *)); + + for (i = 0; i < ret->numkeys; i++) { + char *name; + if ((name = get_cmpname(OBJ_sn2nid(tls_name), i)) == NULL) { + ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); + goto err; + } + if (get_oqsname_fromtls(name) != 0) { + ret->oqsx_provider_ctx.oqsx_qs_ctx.sig + = OQS_SIG_new(get_oqsname_fromtls(name)); + if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) { + fprintf( + stderr, + "Could not create OQS signature algorithm %s. Enabled in liboqs?A\n", + name); + goto err; + } + ret->privkeylen_cmp[i] + = ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_secret_key; + ret->pubkeylen_cmp[i] + = ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key; + } else { + evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX)); + ON_ERR_GOTO(!evp_ctx, err); + + ret2 = oqsx_hybsig_init(bit_security, evp_ctx, name); + ON_ERR_GOTO(ret2 <= 0 || !evp_ctx->ctx, err); + ret->oqsx_provider_ctx.oqsx_evp_ctx = evp_ctx; + ret->privkeylen_cmp[i] = ret->oqsx_provider_ctx.oqsx_evp_ctx + ->evp_info->length_private_key; + ret->pubkeylen_cmp[i] = ret->oqsx_provider_ctx.oqsx_evp_ctx + ->evp_info->length_public_key; + } + ret->privkeylen += ret->privkeylen_cmp[i]; + ret->pubkeylen += ret->pubkeylen_cmp[i]; + OPENSSL_free(name); + } + ret->keytype = primitive; + break; default: OQS_KEY_PRINTF2("OQSX_KEY: Unknown key type encountered: %d\n", @@ -966,7 +1535,6 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, void oqsx_key_free(OQSX_KEY *key) { int refcnt; - if (key == NULL) return; @@ -993,6 +1561,10 @@ void oqsx_key_free(OQSX_KEY *key) OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen); OPENSSL_free(key->comp_pubkey); OPENSSL_free(key->comp_privkey); + if (key->keytype == KEY_TYPE_CMP_SIG) { + OPENSSL_free(key->privkeylen_cmp); + OPENSSL_free(key->pubkeylen_cmp); + } if (key->keytype == KEY_TYPE_KEM) OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem); else if (key->keytype == KEY_TYPE_ECP_HYB_KEM @@ -1006,6 +1578,7 @@ void oqsx_key_free(OQSX_KEY *key) EVP_PKEY_free(key->oqsx_provider_ctx.oqsx_evp_ctx->keyParam); OPENSSL_free(key->oqsx_provider_ctx.oqsx_evp_ctx); } + #ifdef OQS_PROVIDER_NOATOMIC CRYPTO_THREAD_lock_free(key->lock); #endif @@ -1033,10 +1606,13 @@ int oqsx_key_up_ref(OQSX_KEY *key) int oqsx_key_allocate_keymaterial(OQSX_KEY *key, int include_private) { - int ret = 0; + int ret = 0, aux = 0; + + if (key->keytype != KEY_TYPE_CMP_SIG) + aux = SIZE_OF_UINT32; if (!key->privkey && include_private) { - key->privkey = OPENSSL_secure_zalloc(key->privkeylen); + key->privkey = OPENSSL_secure_zalloc(key->privkeylen + aux); ON_ERR_SET_GOTO(!key->privkey, ret, 1, err_alloc); } if (!key->pubkey && !include_private) { @@ -1108,19 +1684,20 @@ static int oqsx_key_gen_oqs(OQSX_KEY *key, int gen_kem) return OQS_KEM_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.kem, key->comp_pubkey[key->numkeys - 1], key->comp_privkey[key->numkeys - 1]); - else + else { return OQS_SIG_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.sig, key->comp_pubkey[key->numkeys - 1], key->comp_privkey[key->numkeys - 1]); + } } /* Generate classic keys, store length in leading SIZE_OF_UINT32 bytes of * pubkey/privkey buffers; returned EVP_PKEY must be freed if not used */ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, - unsigned char *privkey) + unsigned char *privkey, int encode) { - int ret = 0, ret2 = 0; + int ret = 0, ret2 = 0, aux = 0; // Free at errhyb: EVP_PKEY_CTX *kgctx = NULL; @@ -1129,6 +1706,10 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, size_t pubkeylen = 0, privkeylen = 0; + if (encode) { // hybrid + aux = SIZE_OF_UINT32; + } + if (ctx->keyParam) kgctx = EVP_PKEY_CTX_new(ctx->keyParam, NULL); else @@ -1138,34 +1719,47 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, ret2 = EVP_PKEY_keygen_init(kgctx); ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, errhyb); if (ctx->evp_info->keytype == EVP_PKEY_RSA) { - ret2 = EVP_PKEY_CTX_set_rsa_keygen_bits(kgctx, 3072); + if (ctx->evp_info->length_public_key > 270) { + ret2 = EVP_PKEY_CTX_set_rsa_keygen_bits(kgctx, 3072); + } else { + ret2 = EVP_PKEY_CTX_set_rsa_keygen_bits(kgctx, 2048); + } ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, errhyb); } + ret2 = EVP_PKEY_keygen(kgctx, &pkey); ON_ERR_SET_GOTO(ret2 <= 0, ret, -2, errhyb); if (ctx->evp_info->raw_key_support) { // TODO: If available, use preallocated memory - pubkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &pubkey_encoded); - ON_ERR_SET_GOTO(pubkeylen != ctx->evp_info->length_public_key - || !pubkey_encoded, - ret, -3, errhyb); - memcpy(pubkey + SIZE_OF_UINT32, pubkey_encoded, pubkeylen); + if (ctx->evp_info->nid != NID_ED25519 + && ctx->evp_info->nid != NID_ED448) { + pubkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &pubkey_encoded); + ON_ERR_SET_GOTO(pubkeylen != ctx->evp_info->length_public_key + || !pubkey_encoded, + ret, -3, errhyb); + memcpy(pubkey + aux, pubkey_encoded, pubkeylen); + } else { + pubkeylen = ctx->evp_info->length_public_key; + ret2 = EVP_PKEY_get_raw_public_key(pkey, pubkey + aux, &pubkeylen); + ON_ERR_SET_GOTO( + ret2 <= 0 || pubkeylen != ctx->evp_info->length_public_key, ret, + -3, errhyb); + } privkeylen = ctx->evp_info->length_private_key; - ret2 = EVP_PKEY_get_raw_private_key(pkey, privkey + SIZE_OF_UINT32, - &privkeylen); + ret2 = EVP_PKEY_get_raw_private_key(pkey, privkey + aux, &privkeylen); ON_ERR_SET_GOTO(ret2 <= 0 || privkeylen != ctx->evp_info->length_private_key, ret, -4, errhyb); } else { - unsigned char *pubkey_enc = pubkey + SIZE_OF_UINT32; - const unsigned char *pubkey_enc2 = pubkey + SIZE_OF_UINT32; + unsigned char *pubkey_enc = pubkey + aux; + const unsigned char *pubkey_enc2 = pubkey + aux; pubkeylen = i2d_PublicKey(pkey, &pubkey_enc); ON_ERR_SET_GOTO( !pubkey_enc || pubkeylen > (int)ctx->evp_info->length_public_key, ret, -11, errhyb); - unsigned char *privkey_enc = privkey + SIZE_OF_UINT32; - const unsigned char *privkey_enc2 = privkey + SIZE_OF_UINT32; + unsigned char *privkey_enc = privkey + aux; + const unsigned char *privkey_enc2 = privkey + aux; privkeylen = i2d_PrivateKey(pkey, &privkey_enc); ON_ERR_SET_GOTO( !privkey_enc || privkeylen > (int)ctx->evp_info->length_private_key, @@ -1176,8 +1770,10 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, ON_ERR_SET_GOTO(!ck2, ret, -14, errhyb); EVP_PKEY_free(ck2); } - ENCODE_UINT32(pubkey, pubkeylen); - ENCODE_UINT32(privkey, privkeylen); + if (encode) { + ENCODE_UINT32(pubkey, pubkeylen); + ENCODE_UINT32(privkey, privkeylen); + } OQS_KEY_PRINTF3( "OQSKM: Storing classical privkeylen: %ld & pubkeylen: %ld\n", privkeylen, pubkeylen); @@ -1213,7 +1809,7 @@ int oqsx_key_gen(OQSX_KEY *key) || key->keytype == KEY_TYPE_ECX_HYB_KEM || key->keytype == KEY_TYPE_HYB_SIG) { pkey = oqsx_key_gen_evp_key(key->oqsx_provider_ctx.oqsx_evp_ctx, - key->pubkey, key->privkey); + key->pubkey, key->privkey, 1); ON_ERR_GOTO(pkey == NULL, err_gen); ret = !oqsx_key_set_composites(key); ON_ERR_GOTO(ret, err_gen); @@ -1222,6 +1818,30 @@ int oqsx_key_gen(OQSX_KEY *key) key->classical_pkey = pkey; ret = oqsx_key_gen_oqs(key, key->keytype != KEY_TYPE_HYB_SIG); + } else if (key->keytype == KEY_TYPE_CMP_SIG) { + int i; + ret = oqsx_key_set_composites(key); + for (i = 0; i < key->numkeys; i++) { + char *name; + if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) == NULL) { + ON_ERR_GOTO(ret, err_gen); + } + if (get_oqsname_fromtls(name) == 0) { + pkey = oqsx_key_gen_evp_key(key->oqsx_provider_ctx.oqsx_evp_ctx, + key->comp_pubkey[i], + key->comp_privkey[i], 0); + OPENSSL_free(name); + ON_ERR_GOTO(pkey == NULL, err_gen); + key->classical_pkey = pkey; + } else { + ret = OQS_SIG_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.sig, + key->comp_pubkey[i], + key->comp_privkey[i]); + OPENSSL_free(name); + ON_ERR_GOTO(ret, err_gen); + } + } + } else if (key->keytype == KEY_TYPE_SIG) { ret = !oqsx_key_set_composites(key); ON_ERR_GOTO(ret, err_gen); @@ -1257,6 +1877,11 @@ int oqsx_key_maxsize(OQSX_KEY *key) return key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->length_signature + SIZE_OF_UINT32; + case KEY_TYPE_CMP_SIG: + return sizeof(CompositeSignature) + + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->length_signature + + key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature; + default: OQS_KEY_PRINTF("OQSX KEY: Wrong key type\n"); return 0; diff --git a/scripts/common.py b/scripts/common.py index 70e66d2d..98716939 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -19,6 +19,8 @@ 'dilithium2','dilithium3','dilithium5','mldsa44','mldsa65','mldsa87','falcon512','falconpadded512','falcon1024','falconpadded1024','sphincssha2128fsimple','sphincssha2128ssimple','sphincssha2192fsimple','sphincsshake128fsimple', # post-quantum + classical signatures 'p256_dilithium2','rsa3072_dilithium2','p384_dilithium3','p521_dilithium5','p256_mldsa44','rsa3072_mldsa44','p384_mldsa65','p521_mldsa87','p256_falcon512','rsa3072_falcon512','p256_falconpadded512','rsa3072_falconpadded512','p521_falcon1024','p521_falconpadded1024','p256_sphincssha2128fsimple','rsa3072_sphincssha2128fsimple','p256_sphincssha2128ssimple','rsa3072_sphincssha2128ssimple','p384_sphincssha2192fsimple','p256_sphincsshake128fsimple','rsa3072_sphincsshake128fsimple', + # post-quantum + classical signatures (COMPOSITE) + 'mldsa44_pss2048','mldsa44_rsa2048','mldsa44_ed25519','mldsa44_p256','mldsa44_bp256','mldsa65_pss3072','mldsa65_rsa3072','mldsa65_p256','mldsa65_bp256','mldsa65_ed25519','mldsa87_p384','mldsa87_bp384','mldsa87_ed448', ##### OQS_TEMPLATE_FRAGMENT_SIG_ALGS_END ]