From 27fcea99abb5933b47f1e499ead49c5466143770 Mon Sep 17 00:00:00 2001 From: Felipe Ventura Date: Thu, 21 Dec 2023 09:16:46 -0600 Subject: [PATCH] added composite to README.md and ALGORITHMS.md && inverted logic for KEM_ENCODERS=ON to optimize condition checks --- ALGORITHMS.md | 16 +++ README.md | 10 +- oqs-template/ALGORITHMS.md/oids.fragment | 3 + oqs-template/README.md/algs.fragment | 1 + oqsprov/oqsprov_keys.c | 157 ++++++++++++----------- 5 files changed, 105 insertions(+), 82 deletions(-) diff --git a/ALGORITHMS.md b/ALGORITHMS.md index 314ba3cb..b5d668aa 100644 --- a/ALGORITHMS.md +++ b/ALGORITHMS.md @@ -122,13 +122,29 @@ adapting the OIDs of all supported signature algorithms as per the table below. | dilithium2 | 1.3.6.1.4.1.2.267.7.4.4 |Yes| OQS_OID_DILITHIUM2 | p256_dilithium2 | 1.3.9999.2.7.1 |Yes| OQS_OID_P256_DILITHIUM2 | rsa3072_dilithium2 | 1.3.9999.2.7.2 |Yes| OQS_OID_RSA3072_DILITHIUM2 +| dilithium2_pss2048 | 2.16.840.1.114027.80.8.1.1 |Yes| OQS_OID_DILITHIUM2_pss2048 +| dilithium2_rsa2048 | 2.16.840.1.114027.80.8.1.2 |Yes| OQS_OID_DILITHIUM2_rsa2048 +| dilithium2_ed25519 | 2.16.840.1.114027.80.8.1.3 |Yes| OQS_OID_DILITHIUM2_ed25519 +| dilithium2_p256 | 2.16.840.1.114027.80.8.1.4 |Yes| OQS_OID_DILITHIUM2_p256 +| dilithium2_bp256 | 2.16.840.1.114027.80.8.1.5 |Yes| OQS_OID_DILITHIUM2_bp256 | dilithium3 | 1.3.6.1.4.1.2.267.7.6.5 |Yes| OQS_OID_DILITHIUM3 | p384_dilithium3 | 1.3.9999.2.7.3 |Yes| OQS_OID_P384_DILITHIUM3 +| dilithium3_pss3072 | 2.16.840.1.114027.80.8.1.6 |Yes| OQS_OID_DILITHIUM3_pss3072 +| dilithium3_rsa3072 | 2.16.840.1.114027.80.8.1.7 |Yes| OQS_OID_DILITHIUM3_rsa3072 +| dilithium3_p256 | 2.16.840.1.114027.80.8.1.8 |Yes| OQS_OID_DILITHIUM3_p256 +| dilithium3_bp256 | 2.16.840.1.114027.80.8.1.9 |Yes| OQS_OID_DILITHIUM3_bp256 +| dilithium3_ed25519 | 2.16.840.1.114027.80.8.1.10 |Yes| OQS_OID_DILITHIUM3_ed25519 | dilithium5 | 1.3.6.1.4.1.2.267.7.8.7 |Yes| OQS_OID_DILITHIUM5 | p521_dilithium5 | 1.3.9999.2.7.4 |Yes| OQS_OID_P521_DILITHIUM5 +| dilithium5_p384 | 2.16.840.1.114027.80.8.1.11 |Yes| OQS_OID_DILITHIUM5_p384 +| dilithium5_bp384 | 2.16.840.1.114027.80.8.1.12 |Yes| OQS_OID_DILITHIUM5_bp384 +| dilithium5_ed448 | 2.16.840.1.114027.80.8.1.13 |Yes| OQS_OID_DILITHIUM5_ed448 | falcon512 | 1.3.9999.3.6 |Yes| OQS_OID_FALCON512 | p256_falcon512 | 1.3.9999.3.7 |Yes| OQS_OID_P256_FALCON512 | rsa3072_falcon512 | 1.3.9999.3.8 |Yes| OQS_OID_RSA3072_FALCON512 +| falcon512_p256 | 2.16.840.1.114027.80.8.1.14 |Yes| OQS_OID_FALCON512_p256 +| falcon512_bp256 | 2.16.840.1.114027.80.8.1.15 |Yes| OQS_OID_FALCON512_bp256 +| falcon512_ed25519 | 2.16.840.1.114027.80.8.1.16 |Yes| OQS_OID_FALCON512_ed25519 | falcon1024 | 1.3.9999.3.9 |Yes| OQS_OID_FALCON1024 | p521_falcon1024 | 1.3.9999.3.10 |Yes| OQS_OID_P521_FALCON1024 | sphincssha2128fsimple | 1.3.9999.6.4.13 |Yes| OQS_OID_SPHINCSSHA2128FSIMPLE diff --git a/README.md b/README.md index c30af18b..449d3cad 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ This implementation makes available the following quantum safe algorithms: ### Signature algorithms -- **CRYSTALS-Dilithium**:`dilithium2`\*, `p256_dilithium2`\*, `rsa3072_dilithium2`\*, `dilithium3`\*, `p384_dilithium3`\*, `dilithium5`\*, `p521_dilithium5`\* -- **Falcon**:`falcon512`\*, `p256_falcon512`\*, `rsa3072_falcon512`\*, `falcon1024`\*, `p521_falcon1024`\* +- **CRYSTALS-Dilithium**:`dilithium2`\*, `p256_dilithium2`\*, `rsa3072_dilithium2`\*, `dilithium2_pss2048`\*, `dilithium2_rsa2048`\*, `dilithium2_ed25519`\*, `dilithium2_p256`\*, `dilithium2_bp256`\*, `dilithium3`\*, `p384_dilithium3`\*, `dilithium3_pss3072`\*, `dilithium3_rsa3072`\*, `dilithium3_p256`\*, `dilithium3_bp256`\*, `dilithium3_ed25519`\*, `dilithium5`\*, `p521_dilithium5`\*, `dilithium5_p384`\*, `dilithium5_bp384`\*, `dilithium5_ed448`\* +- **Falcon**:`falcon512`\*, `p256_falcon512`\*, `rsa3072_falcon512`\*, `falcon512_p256`\*, `falcon512_bp256`\*, `falcon512_ed25519`\*, `falcon1024`\*, `p521_falcon1024`\* - **SPHINCS-SHA2**:`sphincssha2128fsimple`\*, `p256_sphincssha2128fsimple`\*, `rsa3072_sphincssha2128fsimple`\*, `sphincssha2128ssimple`\*, `p256_sphincssha2128ssimple`\*, `rsa3072_sphincssha2128ssimple`\*, `sphincssha2192fsimple`\*, `p384_sphincssha2192fsimple`\*, `sphincssha2192ssimple`, `p384_sphincssha2192ssimple`, `sphincssha2256fsimple`, `p521_sphincssha2256fsimple`, `sphincssha2256ssimple`, `p521_sphincssha2256ssimple` - **SPHINCS-SHAKE**:`sphincsshake128fsimple`\*, `p256_sphincsshake128fsimple`\*, `rsa3072_sphincsshake128fsimple`\*, `sphincsshake128ssimple`, `p256_sphincsshake128ssimple`, `rsa3072_sphincsshake128ssimple`, `sphincsshake192fsimple`, `p384_sphincsshake192fsimple`, `sphincsshake192ssimple`, `p384_sphincsshake192ssimple`, `sphincsshake256fsimple`, `p521_sphincsshake256fsimple`, `sphincsshake256ssimple`, `p521_sphincsshake256ssimple` @@ -63,9 +63,11 @@ TLS operations. This designation [can be changed by modifying the "enabled" flags in the main algorithm configuration file](CONFIGURE.md#pre-build-configuration). 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 +this provider also provides different hybrid and composite algorithms, combining classic +and quantum-safe methods: For hybrid, these are listed above with a prefix denoting a classic algorithm, e.g., for elliptic curve: "p256_". +For composite, these 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 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/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c index b2ec8f96..ad5e0f6f 100644 --- a/oqsprov/oqsprov_keys.c +++ b/oqsprov/oqsprov_keys.c @@ -824,84 +824,6 @@ 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->keytype != KEY_TYPE_CMP_SIG) - && (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: - 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 - } - } - } if (key->keytype == KEY_TYPE_CMP_SIG) { int i; if (op == KEY_OP_PUBLIC) { @@ -1001,6 +923,85 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) 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: + 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;