diff --git a/oqs-template/oqs-test/try_connection.py/list_all_kexs.fragment b/oqs-template/oqs-test/try_connection.py/list_all_kexs.fragment index ac70cab70a93..e59f9dc47acc 100644 --- a/oqs-template/oqs-test/try_connection.py/list_all_kexs.fragment +++ b/oqs-template/oqs-test/try_connection.py/list_all_kexs.fragment @@ -1,7 +1,7 @@ {%- for kex in config['kexs'] %} "{{ kex['pretty_name'] }}", {%- for curve in kex['mix_with'] %} - # "{{ curve['pretty_name'] }}", + "{{ curve['pretty_name'] }}", {%- endfor -%} {%- endfor %} diff --git a/oqs-template/oqs-test/try_connection.py/list_all_sigs.fragment b/oqs-template/oqs-test/try_connection.py/list_all_sigs.fragment index 63f0e3338200..b8f64005742a 100644 --- a/oqs-template/oqs-test/try_connection.py/list_all_sigs.fragment +++ b/oqs-template/oqs-test/try_connection.py/list_all_sigs.fragment @@ -1,7 +1,7 @@ {%- for sig in config['sigs'] %} "ssh-{{ sig['name']|replace('_','') }}", {%- for alg in sig['mix_with'] %} - # "ssh-{{ alg['name']|replace('_','-') }}-{{ sig['name']|replace('_','') }}", + "ssh-{{ alg['name']|replace('_','-') }}-{{ sig['name']|replace('_','') }}", {%- endfor -%} {%- endfor %} diff --git a/oqs-template/ssh-keygen.c/define_key_types.fragment b/oqs-template/ssh-keygen.c/define_key_types.fragment index 0cbad36601a7..f524ca24fa05 100644 --- a/oqs-template/ssh-keygen.c/define_key_types.fragment +++ b/oqs-template/ssh-keygen.c/define_key_types.fragment @@ -4,13 +4,13 @@ #ifdef WITH_OPENSSL {%- for sig in config['sigs'] %} {%- for alg in sig['mix_with'] if alg['rsa'] %} - // { "{{ alg['name'] }}_{{ sig['name']|replace('_','') }}", "{{ alg['name']|upper }}_{{ sig['name']|upper }}", _PATH_HOST_{{ alg['name']|upper }}_{{ sig['name']|upper }}_KEY_FILE }, + { "{{ alg['name'] }}_{{ sig['name']|replace('_','') }}", "{{ alg['name']|upper }}_{{ sig['name']|upper }}", _PATH_HOST_{{ alg['name']|upper }}_{{ sig['name']|upper }}_KEY_FILE }, {%- endfor %} {%- endfor %} #ifdef OPENSSL_HAS_ECC {%- for sig in config['sigs'] %} {%- for alg in sig['mix_with'] if not alg['rsa'] %} - // { "{{ alg['name'] }}_{{ sig['name']|replace('_','') }}", "{{ alg['name']|upper }}_{{ sig['name']|upper }}", _PATH_HOST_{{ alg['name']|upper }}_{{ sig['name']|upper }}_KEY_FILE }, + { "{{ alg['name'] }}_{{ sig['name']|replace('_','') }}", "{{ alg['name']|upper }}_{{ sig['name']|upper }}", _PATH_HOST_{{ alg['name']|upper }}_{{ sig['name']|upper }}_KEY_FILE }, {%- endfor %} {%- endfor %} #endif /* OPENSSL_HAS_ECC */ diff --git a/oqs-template/ssh-keygen.c/handle_ecdsa_hybrids.fragment b/oqs-template/ssh-keygen.c/handle_ecdsa_hybrids.fragment deleted file mode 100644 index ad3e0e085fa8..000000000000 --- a/oqs-template/ssh-keygen.c/handle_ecdsa_hybrids.fragment +++ /dev/null @@ -1,12 +0,0 @@ -{%- for sig in config['sigs'] if sig['level'] != 1 -%} - {%- for alg in sig['mix_with'] %} - case KEY_{{ alg['name']|upper }}_{{ sig['name']|upper }}: - {%- if sig['level'] == 3 %} - *bitsp = 384; - {%- elif sig['level'] == 5 %} - *bitsp = 521; - {%- endif %} - break; - {%- endfor %} -{%- endfor %} - diff --git a/oqs-template/ssh-oqs.c/define_sig_functions.fragment b/oqs-template/ssh-oqs.c/define_sig_functions.fragment index 18cb6d37c7d5..c995e9a359be 100644 --- a/oqs-template/ssh-oqs.c/define_sig_functions.fragment +++ b/oqs-template/ssh-oqs.c/define_sig_functions.fragment @@ -15,7 +15,7 @@ static int ssh_{{ symbol_base_name }}_generate(struct sshkey *k, int bits) return OQS_SIG_{{ sig['name'] }}_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_{{ symbol_base_name }}_sign(const struct sshkey *key, +int ssh_{{ symbol_base_name }}_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -29,7 +29,7 @@ int ssh_{{ symbol_base_name }}_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "{{ symbol_base_name }}", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "{{ symbol_base_name }}", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -40,13 +40,14 @@ int ssh_{{ symbol_base_name }}_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_{{ sig['name'] }}); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "{{ symbol_base_name }}", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "{{ symbol_base_name }}", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -79,8 +80,7 @@ const struct sshkey_impl sshkey_{{ symbol_base_name }}_impl = { }; {%- endfor %} -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL {%- for sig in config['sigs'] %} {%- for alg in sig['mix_with'] if alg['rsa'] %} {%- set symbol_base_name = alg['name']|replace('_','') + '_' + sig['name']|replace('_','') %} @@ -93,17 +93,17 @@ static const struct sshkey_impl_funcs sshkey_{{ symbol_base_name }}_funcs = { /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, /* .ssh_serialize_private = */ ssh_generic_serialize_private, /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, - /* .generate = */ ssh_{{ symbol_base_name }}_generate, + /* .generate = */ ssh_generic_generate, /* .copy_public = */ ssh_generic_copy_public, - /* .sign = */ ssh_{{ symbol_base_name }}_sign, - /* .verify = */ ssh_{{ symbol_base_name }}_verify, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, }; const struct sshkey_impl sshkey_{{ symbol_base_name }}_impl = { - /* .name = */ "ssh-{{ symbol_base_name }}", + /* .name = */ "ssh-{{ alg['name']|replace('_','') + '-' + sig['name']|replace('_','') }}", /* .shortname = */ "{{ symbol_base_name|upper }}", /* .sigalg = */ NULL, - /* .type = */ KEY_{{ sig['name']|upper }}, + /* .type = */ KEY_{{ alg['name']|upper }}_{{ sig['name']|upper }}, /* .nid = */ 0, /* .cert = */ 0, /* .sigonly = */ 0, @@ -112,5 +112,38 @@ const struct sshkey_impl sshkey_{{ symbol_base_name }}_impl = { }; {%- endfor %} {%- endfor %} +#ifdef OPENSSL_HAS_ECC +{%- for sig in config['sigs'] %} +{%- for alg in sig['mix_with'] if not alg['rsa'] %} +{%- set symbol_base_name = alg['name']|replace('_','') + '_' + sig['name']|replace('_','') %} +static const struct sshkey_impl_funcs sshkey_{{ symbol_base_name }}_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_{{ symbol_base_name }}_impl = { + /* .name = */ "ssh-{{ alg['name']|replace('_','-') + '-' + sig['name']|replace('_','') }}", + /* .shortname = */ "{{ symbol_base_name|upper }}", + /* .sigalg = */ NULL, + /* .type = */ KEY_{{ alg['name']|upper }}_{{ sig['name']|upper }}, + /* .nid = */ {{ alg['openssl_nid'] }}, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_{{ symbol_base_name }}_funcs, +}; +{%- endfor %} +{%- endfor %} +#endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ diff --git a/oqs-template/ssh-oqs.c/impl_lookup_cases.fragment b/oqs-template/ssh-oqs.c/impl_lookup_cases.fragment new file mode 100644 index 000000000000..2c17a5334e9d --- /dev/null +++ b/oqs-template/ssh-oqs.c/impl_lookup_cases.fragment @@ -0,0 +1,9 @@ +{% for sig in config['sigs'] %} + case KEY_{{ sig['name']|upper }}: + {%- for alg in sig['mix_with'] %} + case KEY_{{ alg['name']|upper }}_{{ sig['name']|upper }}: + {%- endfor %} + impl = &sshkey_{{ sig['name']|replace('_','') }}_impl; + break; +{%- endfor %} + diff --git a/oqs-template/sshkey.c/define_keytypes.fragment b/oqs-template/sshkey.c/define_keytypes.fragment index 2bf9d9345b99..3bbd36d32953 100644 --- a/oqs-template/sshkey.c/define_keytypes.fragment +++ b/oqs-template/sshkey.c/define_keytypes.fragment @@ -1,8 +1,7 @@ {%- for sig in config['sigs'] %} &sshkey_{{ sig['name']|replace('_','') }}_impl, {%- endfor %} -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL {%- for sig in config['sigs'] %} {%- for alg in sig['mix_with'] if alg['rsa'] %} &sshkey_{{ alg['name']|replace('_','') }}_{{ sig['name']|replace('_','') }}_impl, diff --git a/oqs-template/sshkey.c/extern_key_impls.fragment b/oqs-template/sshkey.c/extern_key_impls.fragment index 6cb7e3c1acc8..9f5858a8ba95 100644 --- a/oqs-template/sshkey.c/extern_key_impls.fragment +++ b/oqs-template/sshkey.c/extern_key_impls.fragment @@ -2,8 +2,7 @@ extern const struct sshkey_impl sshkey_{{ sig['name']|replace('_','') }}_impl; {%- endfor %} -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL {%- for sig in config['sigs'] %} {%- for alg in sig['mix_with'] if alg['rsa'] %} extern const struct sshkey_impl sshkey_{{ alg['name']|replace('_','') }}_{{ sig['name']|replace('_','') }}_impl; diff --git a/oqs-test/try_connection.py b/oqs-test/try_connection.py index 512873e5cb0d..3f4ce9175c63 100644 --- a/oqs-test/try_connection.py +++ b/oqs-test/try_connection.py @@ -2,6 +2,7 @@ # and signature algorithm, and checks whether the stock BoringSSL # client and server can establish a handshake with the choices. +import argparse import os import random import subprocess @@ -13,75 +14,75 @@ kexs = [ ##### OQS_TEMPLATE_FRAGMENT_LIST_ALL_KEXS_START "frodokem-640-aes-sha256", - # "ecdh-nistp256-frodokem-640-aesr2-sha256@openquantumsafe.org", + "ecdh-nistp256-frodokem-640-aesr2-sha256@openquantumsafe.org", "frodokem-976-aes-sha384", - # "ecdh-nistp384-frodokem-976-aesr2-sha384@openquantumsafe.org", + "ecdh-nistp384-frodokem-976-aesr2-sha384@openquantumsafe.org", "frodokem-1344-aes-sha512", - # "ecdh-nistp521-frodokem-1344-aesr2-sha512@openquantumsafe.org", + "ecdh-nistp521-frodokem-1344-aesr2-sha512@openquantumsafe.org", "frodokem-640-shake-sha256", - # "ecdh-nistp256-frodokem-640-shaker2-sha256@openquantumsafe.org", + "ecdh-nistp256-frodokem-640-shaker2-sha256@openquantumsafe.org", "frodokem-976-shake-sha384", - # "ecdh-nistp384-frodokem-976-shaker2-sha384@openquantumsafe.org", + "ecdh-nistp384-frodokem-976-shaker2-sha384@openquantumsafe.org", "frodokem-1344-shake-sha512", - # "ecdh-nistp521-frodokem-1344-shaker2-sha512@openquantumsafe.org", + "ecdh-nistp521-frodokem-1344-shaker2-sha512@openquantumsafe.org", "kyber-512-sha256", - # "ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org", + "ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org", "kyber-768-sha384", - # "ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org", + "ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org", "kyber-1024-sha512", - # "ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org", + "ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org", "bike-l1-sha512", - # "ecdh-nistp256-bike-l1r3-sha512@openquantumsafe.org", + "ecdh-nistp256-bike-l1r3-sha512@openquantumsafe.org", "bike-l3-sha512", - # "ecdh-nistp384-bike-l3r3-sha512@openquantumsafe.org", + "ecdh-nistp384-bike-l3r3-sha512@openquantumsafe.org", "classic-mceliece-348864-sha256", - # "ecdh-nistp256-classic-mceliece-348864r4-sha256@openquantumsafe.org", + "ecdh-nistp256-classic-mceliece-348864r4-sha256@openquantumsafe.org", "classic-mceliece-348864f-sha256", - # "ecdh-nistp256-classic-mceliece-348864fr4-sha256@openquantumsafe.org", + "ecdh-nistp256-classic-mceliece-348864fr4-sha256@openquantumsafe.org", "classic-mceliece-460896-sha512", - # "ecdh-nistp384-classic-mceliece-460896r4-sha512@openquantumsafe.org", + "ecdh-nistp384-classic-mceliece-460896r4-sha512@openquantumsafe.org", "classic-mceliece-460896f-sha512", - # "ecdh-nistp384-classic-mceliece-460896fr4-sha512@openquantumsafe.org", + "ecdh-nistp384-classic-mceliece-460896fr4-sha512@openquantumsafe.org", "classic-mceliece-6688128-sha512", - # "ecdh-nistp521-classic-mceliece-6688128r4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-6688128r4-sha512@openquantumsafe.org", "classic-mceliece-6688128f-sha512", - # "ecdh-nistp521-classic-mceliece-6688128fr4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-6688128fr4-sha512@openquantumsafe.org", "classic-mceliece-6960119-sha512", - # "ecdh-nistp521-classic-mceliece-6960119r4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-6960119r4-sha512@openquantumsafe.org", "classic-mceliece-6960119f-sha512", - # "ecdh-nistp521-classic-mceliece-6960119fr4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-6960119fr4-sha512@openquantumsafe.org", "classic-mceliece-8192128-sha512", - # "ecdh-nistp521-classic-mceliece-8192128r4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-8192128r4-sha512@openquantumsafe.org", "classic-mceliece-8192128f-sha512", - # "ecdh-nistp521-classic-mceliece-8192128fr4-sha512@openquantumsafe.org", + "ecdh-nistp521-classic-mceliece-8192128fr4-sha512@openquantumsafe.org", "hqc-128-sha256", - # "ecdh-nistp256-hqc-128r3-sha256@openquantumsafe.org", + "ecdh-nistp256-hqc-128r3-sha256@openquantumsafe.org", "hqc-192-sha384", - # "ecdh-nistp384-hqc-192r3-sha384@openquantumsafe.org", + "ecdh-nistp384-hqc-192r3-sha384@openquantumsafe.org", "hqc-256-sha512", - # "ecdh-nistp521-hqc-256r3-sha512@openquantumsafe.org", + "ecdh-nistp521-hqc-256r3-sha512@openquantumsafe.org", ##### OQS_TEMPLATE_FRAGMENT_LIST_ALL_KEXS_END ] sigs = [ ##### OQS_TEMPLATE_FRAGMENT_LIST_ALL_SIGS_START "ssh-falcon512", - # "ssh-rsa3072-falcon512", - # "ssh-ecdsa-nistp256-falcon512", + "ssh-rsa3072-falcon512", + "ssh-ecdsa-nistp256-falcon512", "ssh-falcon1024", - # "ssh-ecdsa-nistp521-falcon1024", + "ssh-ecdsa-nistp521-falcon1024", "ssh-dilithium2", - # "ssh-rsa3072-dilithium2", - # "ssh-ecdsa-nistp256-dilithium2", + "ssh-rsa3072-dilithium2", + "ssh-ecdsa-nistp256-dilithium2", "ssh-dilithium3", - # "ssh-ecdsa-nistp384-dilithium3", + "ssh-ecdsa-nistp384-dilithium3", "ssh-dilithium5", - # "ssh-ecdsa-nistp521-dilithium5", + "ssh-ecdsa-nistp521-dilithium5", "ssh-sphincssha2128fsimple", - # "ssh-rsa3072-sphincssha2128fsimple", - # "ssh-ecdsa-nistp256-sphincssha2128fsimple", + "ssh-rsa3072-sphincssha2128fsimple", + "ssh-ecdsa-nistp256-sphincssha2128fsimple", "ssh-sphincssha2256fsimple", - # "ssh-ecdsa-nistp521-sphincssha2256fsimple", + "ssh-ecdsa-nistp521-sphincssha2256fsimple", ##### OQS_TEMPLATE_FRAGMENT_LIST_ALL_SIGS_END ] @@ -131,8 +132,11 @@ def try_handshake(ssh, sshd, dorandom="random"): do_handshake(ssh, sshd, test_sig, test_kex) if __name__ == '__main__': - if len(sys.argv)==1: - try_handshake(os.path.abspath('ssh'), os.path.abspath('sshd')) - else: - try_handshake(os.path.abspath('ssh'), os.path.abspath('sshd'), dorandom=sys.argv[1]) + parser = argparse.ArgumentParser(description="Test connections between ssh and sshd using PQ algorithms.") + parser.add_argument("--ssh", default=os.path.abspath('ssh'), type=str, help="Override the ssh binary.") + parser.add_argument("--sshd", default=os.path.abspath('sshd'), type=str, help="Override the sshd binary.") + parser.add_argument("dorandom", type=str, default="random", choices=["doall", "doone", "random"], + help="Slice of test cases to run.") + args = parser.parse_args() + try_handshake(args.ssh, args.sshd, args.dorandom) diff --git a/ssh-keygen.c b/ssh-keygen.c index 8d2dbb27609b..134af7ed027c 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -206,32 +206,6 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) break; } #endif - /* OQS note: different parameter sets for one PQ scheme are identified - * by different types (unlike ECDSA which uses one key type and a 2nd - * 'nid' value to identify the curve. We need this special processing - * for ECDSA hybrid of levels 3+ to avoid defaulting to P256 when - * name is NULL (like when called from do_gen_all_hostkeys) or when the - * -t parameter is provided with a shortname, which sshkey_ecdsa_nid_from_name - * doesn't check. - */ - if (oqs_utils_is_ecdsa_hybrid(type)) { - switch (type) { -///// OQS_TEMPLATE_FRAGMENT_HANDLE_ECDSA_HYBRIDS_START - case KEY_ECDSA_NISTP521_FALCON_1024: - *bitsp = 521; - break; - case KEY_ECDSA_NISTP384_DILITHIUM_3: - *bitsp = 384; - break; - case KEY_ECDSA_NISTP521_DILITHIUM_5: - *bitsp = 521; - break; - case KEY_ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE: - *bitsp = 521; - break; -///// OQS_TEMPLATE_FRAGMENT_HANDLE_ECDSA_HYBRIDS_END - } - } } #ifdef WITH_OPENSSL switch (type) { @@ -1170,17 +1144,17 @@ do_gen_all_hostkeys(struct passwd *pw) { "sphincssha2128fsimple", "SPHINCS_SHA2_128F_SIMPLE", _PATH_HOST_SPHINCS_SHA2_128F_SIMPLE_KEY_FILE }, { "sphincssha2256fsimple", "SPHINCS_SHA2_256F_SIMPLE", _PATH_HOST_SPHINCS_SHA2_256F_SIMPLE_KEY_FILE }, #ifdef WITH_OPENSSL - // { "rsa3072_falcon512", "RSA3072_FALCON_512", _PATH_HOST_RSA3072_FALCON_512_KEY_FILE }, - // { "rsa3072_dilithium2", "RSA3072_DILITHIUM_2", _PATH_HOST_RSA3072_DILITHIUM_2_KEY_FILE }, - // { "rsa3072_sphincssha2128fsimple", "RSA3072_SPHINCS_SHA2_128F_SIMPLE", _PATH_HOST_RSA3072_SPHINCS_SHA2_128F_SIMPLE_KEY_FILE }, + { "rsa3072_falcon512", "RSA3072_FALCON_512", _PATH_HOST_RSA3072_FALCON_512_KEY_FILE }, + { "rsa3072_dilithium2", "RSA3072_DILITHIUM_2", _PATH_HOST_RSA3072_DILITHIUM_2_KEY_FILE }, + { "rsa3072_sphincssha2128fsimple", "RSA3072_SPHINCS_SHA2_128F_SIMPLE", _PATH_HOST_RSA3072_SPHINCS_SHA2_128F_SIMPLE_KEY_FILE }, #ifdef OPENSSL_HAS_ECC - // { "ecdsa_nistp256_falcon512", "ECDSA_NISTP256_FALCON_512", _PATH_HOST_ECDSA_NISTP256_FALCON_512_KEY_FILE }, - // { "ecdsa_nistp521_falcon1024", "ECDSA_NISTP521_FALCON_1024", _PATH_HOST_ECDSA_NISTP521_FALCON_1024_KEY_FILE }, - // { "ecdsa_nistp256_dilithium2", "ECDSA_NISTP256_DILITHIUM_2", _PATH_HOST_ECDSA_NISTP256_DILITHIUM_2_KEY_FILE }, - // { "ecdsa_nistp384_dilithium3", "ECDSA_NISTP384_DILITHIUM_3", _PATH_HOST_ECDSA_NISTP384_DILITHIUM_3_KEY_FILE }, - // { "ecdsa_nistp521_dilithium5", "ECDSA_NISTP521_DILITHIUM_5", _PATH_HOST_ECDSA_NISTP521_DILITHIUM_5_KEY_FILE }, - // { "ecdsa_nistp256_sphincssha2128fsimple", "ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE", _PATH_HOST_ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE_KEY_FILE }, - // { "ecdsa_nistp521_sphincssha2256fsimple", "ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE", _PATH_HOST_ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE_KEY_FILE }, + { "ecdsa_nistp256_falcon512", "ECDSA_NISTP256_FALCON_512", _PATH_HOST_ECDSA_NISTP256_FALCON_512_KEY_FILE }, + { "ecdsa_nistp521_falcon1024", "ECDSA_NISTP521_FALCON_1024", _PATH_HOST_ECDSA_NISTP521_FALCON_1024_KEY_FILE }, + { "ecdsa_nistp256_dilithium2", "ECDSA_NISTP256_DILITHIUM_2", _PATH_HOST_ECDSA_NISTP256_DILITHIUM_2_KEY_FILE }, + { "ecdsa_nistp384_dilithium3", "ECDSA_NISTP384_DILITHIUM_3", _PATH_HOST_ECDSA_NISTP384_DILITHIUM_3_KEY_FILE }, + { "ecdsa_nistp521_dilithium5", "ECDSA_NISTP521_DILITHIUM_5", _PATH_HOST_ECDSA_NISTP521_DILITHIUM_5_KEY_FILE }, + { "ecdsa_nistp256_sphincssha2128fsimple", "ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE", _PATH_HOST_ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE_KEY_FILE }, + { "ecdsa_nistp521_sphincssha2256fsimple", "ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE", _PATH_HOST_ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE_KEY_FILE }, #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ ///// OQS_TEMPLATE_FRAGMENT_DEFINE_KEY_TYPES_END diff --git a/ssh-oqs.c b/ssh-oqs.c index ad290511e8e7..e05d76ede96f 100644 --- a/ssh-oqs.c +++ b/ssh-oqs.c @@ -19,6 +19,9 @@ #include #include +#ifdef WITH_OPENSSL +#include +#endif #include "crypto_api.h" @@ -26,6 +29,7 @@ #include #include "log.h" +#include "oqs-utils.h" #include "sshbuf.h" #define SSHKEY_INTERNAL #include "sshkey.h" @@ -34,6 +38,12 @@ #include "oqs/oqs.h" +extern const struct sshkey_impl sshkey_rsa_impl; +extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl; + +const struct sshkey_impl *oqs_pq_sshkey_impl(const struct sshkey *k); +const struct sshkey_impl *oqs_classical_sshkey_impl(const struct sshkey *k); + /* returns the size of an oqs public key */ static size_t oqs_sig_pk_len(int type) { @@ -95,30 +105,49 @@ static size_t oqs_sig_sk_len(int type) return 0; } -static int ssh_generic_size(struct sshkey *k) +static unsigned int ssh_generic_size(const struct sshkey *k) { - return k->oqs_pk_len; + int size; + const struct sshkey_impl *classical; + size = k->oqs_pk_len; + classical = oqs_classical_sshkey_impl(k); + if ((classical != NULL) && (classical->funcs->size != NULL)) { + size += classical->funcs->size(k); + } + return size; } static int ssh_generic_alloc(struct sshkey *k) { + const struct sshkey_impl *classical; k->oqs_sk = NULL; k->oqs_pk = NULL; k->oqs_pk_len = oqs_sig_pk_len(k->type); k->oqs_sk_len = oqs_sig_sk_len(k->type); + classical = oqs_classical_sshkey_impl(k); + if ((classical != NULL) && (classical->funcs->alloc != NULL)) { + classical->funcs->alloc(k); + } return 0; } static void ssh_generic_cleanup(struct sshkey *k) { + const struct sshkey_impl *classical; freezero(k->oqs_sk, k->oqs_sk_len); k->oqs_sk = NULL; freezero(k->oqs_pk, k->oqs_pk_len); k->oqs_pk = NULL; + classical = oqs_classical_sshkey_impl(k); + if ((classical != NULL) && (classical->funcs->cleanup != NULL)) { + classical->funcs->cleanup(k); + } + return; } static int ssh_generic_equal(const struct sshkey *a, const struct sshkey *b) { + const struct sshkey_impl *classical; if (a->oqs_pk == NULL || b->oqs_pk == NULL) { return 0; } @@ -128,13 +157,24 @@ static int ssh_generic_equal(const struct sshkey *a, const struct sshkey *b) if (memcmp(a->oqs_pk, b->oqs_pk, a->oqs_pk_len) != 0) { return 0; } + classical = oqs_classical_sshkey_impl(a); + if (classical) { + return classical->funcs->equal(a, b); + } return 1; } static int ssh_generic_serialize_public(const struct sshkey *key, struct sshbuf *b, enum sshkey_serialize_rep opts) { + const struct sshkey_impl *classical; int r; + classical = oqs_classical_sshkey_impl(key); + if (classical) { + if((r = classical->funcs->serialize_public(key, b, opts)) != 0) { + return r; + } + } if (key->oqs_pk == NULL) { return SSH_ERR_INVALID_ARGUMENT; } @@ -147,10 +187,17 @@ static int ssh_generic_serialize_public(const struct sshkey *key, static int ssh_generic_deserialize_public(const char *ktype, struct sshbuf *b, struct sshkey *key) { + const struct sshkey_impl *classical; u_char *pk = NULL; size_t len = 0; int r; + classical = oqs_classical_sshkey_impl(key); + if (classical) { + if ((r = classical->funcs->deserialize_public(ktype, b, key)) != 0) { + return r; + } + } if ((r = sshbuf_get_string(b, &pk, &len)) != 0) { return r; } @@ -165,7 +212,14 @@ static int ssh_generic_deserialize_public(const char *ktype, struct sshbuf *b, static int ssh_generic_serialize_private(const struct sshkey *key, struct sshbuf *b, enum sshkey_serialize_rep opts) { + const struct sshkey_impl *classical; int r; + classical = oqs_classical_sshkey_impl(key); + if (classical) { + if ((r = classical->funcs->serialize_private(key, b, opts)) != 0) { + return r; + } + } if ((r = sshbuf_put_string(b, key->oqs_pk, key->oqs_pk_len)) != 0 || (r = sshbuf_put_string(b, key->oqs_sk, key->oqs_sk_len)) != 0) { return r; @@ -176,11 +230,18 @@ static int ssh_generic_serialize_private(const struct sshkey *key, static int ssh_generic_deserialize_private(const char *ktype, struct sshbuf *b, struct sshkey *key) { + const struct sshkey_impl *classical; int r; size_t pklen = 0; size_t sklen = 0; u_char *oqs_pk = NULL; u_char *oqs_sk = NULL; + classical = oqs_classical_sshkey_impl(key); + if (classical) { + if ((r = classical->funcs->deserialize_private(ktype, b, key)) != 0) { + return r; + } + } if ((r = sshbuf_get_string(b, &oqs_pk, &pklen)) != 0 || (r = sshbuf_get_string(b, &oqs_sk, &sklen)) != 0) { goto out; @@ -202,6 +263,14 @@ static int ssh_generic_deserialize_private(const char *ktype, struct sshbuf *b, static int ssh_generic_copy_public(const struct sshkey *from, struct sshkey *to) { + const struct sshkey_impl *classical; + int r; + classical = oqs_classical_sshkey_impl(from); + if (classical) { + if ((r = classical->funcs->copy_public(from, to)) != 0) { + return r; + } + } if (from->oqs_pk != NULL) { if ((to->oqs_pk = malloc(from->oqs_pk_len)) == NULL) { return SSH_ERR_ALLOC_FAIL; @@ -211,7 +280,124 @@ static int ssh_generic_copy_public(const struct sshkey *from, struct sshkey *to) return 0; } -static int ssh_generic_sign(OQS_SIG *oqs_sig, +static int ssh_generic_generate(struct sshkey *k, int bits) +{ + const struct sshkey_impl *impl; + int r; + impl = oqs_classical_sshkey_impl(k); + if ((impl != NULL) && (impl->funcs->generate != NULL)) { + if ((r = impl->funcs->generate(k, bits)) != 0) { + return r; + } + } + impl = oqs_pq_sshkey_impl(k); + if ((r = impl->funcs->generate(k, bits)) != 0) { + return r; + } + return 0; +} + +static int ssh_generic_sign(struct sshkey *key, u_char **sigp, + size_t *lenp, const u_char *data, size_t datalen, const char *alg, + const char *sk_provider, const char *sk_pin, u_int compat) +{ + u_char *sig_classical = NULL, *sig_pq = NULL; + size_t len_classical = 0, len_pq = 0; + int index = 0; + int r; + const struct sshkey_impl *impl; + if (lenp != NULL) { + *lenp = 0; + } + if (sigp != NULL) { + *sigp = NULL; + } + impl = oqs_pq_sshkey_impl(key); + if ((r = impl->funcs->sign(key, &sig_pq, &len_pq, data, datalen, alg, + sk_provider, sk_pin, compat)) != 0) { + free(sig_pq); + return r; + } + + impl = oqs_classical_sshkey_impl(key); + if ((impl != NULL) && (impl->funcs->sign != NULL)) { + if ((r = impl->funcs->sign(key, &sig_classical, &len_classical, data, + datalen, alg, sk_provider, sk_pin, compat)) + != 0) { + free(sig_classical); + free(sig_pq); + return r; + } + *lenp = 4 + len_classical + 4 + len_pq; + if ((*sigp = malloc(*lenp)) == NULL) { + free(sig_classical); + free(sig_pq); + return SSH_ERR_ALLOC_FAIL; + } + /* encode the classical sig length */ + POKE_U32(*sigp + index, (size_t) len_classical); + index += 4; + /* encode the classical sig */ + memcpy(*sigp + index, sig_classical, (size_t) len_classical); + index += len_classical; + free(sig_classical); + /* encode the PQ sig length */ + POKE_U32(*sigp + index, len_pq); + index += 4; + /* encode the PQ sig */ + memcpy(*sigp + index, sig_pq, len_pq); + index += len_pq; + free(sig_pq); + } else { + *sigp = sig_pq; + *lenp = len_pq; + } +} + +static int ssh_generic_verify(const struct sshkey *key, + const u_char *sig, size_t siglen, const u_char *data, size_t dlen, + const char *alg, u_int compat, struct sshkey_sig_details **detailsp) +{ + const struct sshkey_impl *impl; + const u_char *sig_classical = NULL; + size_t siglen_classical = 0; + int index = 0; + const u_char *sig_pq = NULL; + size_t siglen_pq = 0; + int r; + impl = oqs_classical_sshkey_impl(key); + if (impl) { + /* classical-PQ hybrid: we separate the signatures */ + /* decode the classical sig length */ + siglen_classical = (size_t) PEEK_U32(sig + index); + index += 4; + /* point to the classical sig */ + sig_classical = sig + index; + index += siglen_classical; + /* decode the PQ sig length */ + siglen_pq = (size_t) PEEK_U32(sig + index); + index += 4; + /* point to the PQ sig */ + sig_pq = sig + index; + index += siglen_pq; + if ((r = impl->funcs->verify(key, sig_classical, siglen_classical, data, + dlen, alg, compat, detailsp)) != 0) { + return r; + } + } else { + /* PQ signature */ + sig_pq = sig; + siglen_pq = siglen; + } + impl = oqs_pq_sshkey_impl(key); + if ((r = impl->funcs->verify(key, sig_pq, siglen_pq, data, + dlen, alg, compat, detailsp)) != 0) { + return r; + } + return 0; +} + +static int oqs_sign(OQS_SIG *oqs_sig, const char *alg_pretty_name, const struct sshkey *key, u_char **sigp, @@ -287,7 +473,7 @@ static int ssh_generic_sign(OQS_SIG *oqs_sig, return r; } -static int ssh_generic_verify(OQS_SIG *oqs_sig, +static int oqs_verify(OQS_SIG *oqs_sig, const char *alg_pretty_name, const struct sshkey *key, const u_char *signature, @@ -370,7 +556,7 @@ static int ssh_falcon512_generate(struct sshkey *k, int bits) return OQS_SIG_falcon_512_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_falcon512_sign(const struct sshkey *key, +int ssh_falcon512_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -384,7 +570,7 @@ int ssh_falcon512_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "falcon512", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "falcon512", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -395,13 +581,14 @@ int ssh_falcon512_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_falcon_512); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "falcon512", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "falcon512", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -447,7 +634,7 @@ static int ssh_falcon1024_generate(struct sshkey *k, int bits) return OQS_SIG_falcon_1024_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_falcon1024_sign(const struct sshkey *key, +int ssh_falcon1024_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -461,7 +648,7 @@ int ssh_falcon1024_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "falcon1024", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "falcon1024", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -472,13 +659,14 @@ int ssh_falcon1024_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_falcon_1024); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "falcon1024", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "falcon1024", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -524,7 +712,7 @@ static int ssh_dilithium2_generate(struct sshkey *k, int bits) return OQS_SIG_dilithium_2_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_dilithium2_sign(const struct sshkey *key, +int ssh_dilithium2_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -538,7 +726,7 @@ int ssh_dilithium2_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "dilithium2", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "dilithium2", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -549,13 +737,14 @@ int ssh_dilithium2_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_dilithium_2); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "dilithium2", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "dilithium2", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -601,7 +790,7 @@ static int ssh_dilithium3_generate(struct sshkey *k, int bits) return OQS_SIG_dilithium_3_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_dilithium3_sign(const struct sshkey *key, +int ssh_dilithium3_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -615,7 +804,7 @@ int ssh_dilithium3_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "dilithium3", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "dilithium3", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -626,13 +815,14 @@ int ssh_dilithium3_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_dilithium_3); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "dilithium3", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "dilithium3", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -678,7 +868,7 @@ static int ssh_dilithium5_generate(struct sshkey *k, int bits) return OQS_SIG_dilithium_5_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_dilithium5_sign(const struct sshkey *key, +int ssh_dilithium5_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -692,7 +882,7 @@ int ssh_dilithium5_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "dilithium5", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "dilithium5", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -703,13 +893,14 @@ int ssh_dilithium5_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_dilithium_5); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "dilithium5", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "dilithium5", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -755,7 +946,7 @@ static int ssh_sphincssha2128fsimple_generate(struct sshkey *k, int bits) return OQS_SIG_sphincs_sha2_128f_simple_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_sphincssha2128fsimple_sign(const struct sshkey *key, +int ssh_sphincssha2128fsimple_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -769,7 +960,7 @@ int ssh_sphincssha2128fsimple_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "sphincssha2128fsimple", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "sphincssha2128fsimple", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -780,13 +971,14 @@ int ssh_sphincssha2128fsimple_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_sphincs_sha2_128f_simple); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "sphincssha2128fsimple", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "sphincssha2128fsimple", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -832,7 +1024,7 @@ static int ssh_sphincssha2256fsimple_generate(struct sshkey *k, int bits) return OQS_SIG_sphincs_sha2_256f_simple_keypair(k->oqs_pk, k->oqs_sk); } -int ssh_sphincssha2256fsimple_sign(const struct sshkey *key, +int ssh_sphincssha2256fsimple_sign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, @@ -846,7 +1038,7 @@ int ssh_sphincssha2256fsimple_sign(const struct sshkey *key, if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_sign(sig, "sphincssha2256fsimple", key, sigp, lenp, data, datalen, compat); + int r = oqs_sign(sig, "sphincssha2256fsimple", key, sigp, lenp, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -857,13 +1049,14 @@ int ssh_sphincssha2256fsimple_verify(const struct sshkey *key, const u_char *data, size_t datalen, const char *alg, - u_int compat) + u_int compat, + struct sshkey_sig_details **detailsp) { OQS_SIG *sig = OQS_SIG_new(OQS_SIG_alg_sphincs_sha2_256f_simple); if (sig == NULL) { return SSH_ERR_ALLOC_FAIL; } - int r = ssh_generic_verify(sig, "sphincssha2256fsimple", key, signature, signaturelen, data, datalen, compat); + int r = oqs_verify(sig, "sphincssha2256fsimple", key, signature, signaturelen, data, datalen, compat); OQS_SIG_free(sig); return r; } @@ -895,8 +1088,7 @@ const struct sshkey_impl sshkey_sphincssha2256fsimple_impl = { /* .funcs = */ &sshkey_sphincssha2256fsimple_funcs, }; -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL static const struct sshkey_impl_funcs sshkey_rsa3072_falcon512_funcs = { /* .size = */ ssh_generic_size, /* .alloc = */ ssh_generic_alloc, @@ -906,17 +1098,17 @@ static const struct sshkey_impl_funcs sshkey_rsa3072_falcon512_funcs = { /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, /* .ssh_serialize_private = */ ssh_generic_serialize_private, /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, - /* .generate = */ ssh_rsa3072_falcon512_generate, + /* .generate = */ ssh_generic_generate, /* .copy_public = */ ssh_generic_copy_public, - /* .sign = */ ssh_rsa3072_falcon512_sign, - /* .verify = */ ssh_rsa3072_falcon512_verify, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, }; const struct sshkey_impl sshkey_rsa3072_falcon512_impl = { - /* .name = */ "ssh-rsa3072_falcon512", + /* .name = */ "ssh-rsa3072-falcon512", /* .shortname = */ "RSA3072_FALCON512", /* .sigalg = */ NULL, - /* .type = */ KEY_FALCON_512, + /* .type = */ KEY_RSA3072_FALCON_512, /* .nid = */ 0, /* .cert = */ 0, /* .sigonly = */ 0, @@ -932,17 +1124,17 @@ static const struct sshkey_impl_funcs sshkey_rsa3072_dilithium2_funcs = { /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, /* .ssh_serialize_private = */ ssh_generic_serialize_private, /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, - /* .generate = */ ssh_rsa3072_dilithium2_generate, + /* .generate = */ ssh_generic_generate, /* .copy_public = */ ssh_generic_copy_public, - /* .sign = */ ssh_rsa3072_dilithium2_sign, - /* .verify = */ ssh_rsa3072_dilithium2_verify, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, }; const struct sshkey_impl sshkey_rsa3072_dilithium2_impl = { - /* .name = */ "ssh-rsa3072_dilithium2", + /* .name = */ "ssh-rsa3072-dilithium2", /* .shortname = */ "RSA3072_DILITHIUM2", /* .sigalg = */ NULL, - /* .type = */ KEY_DILITHIUM_2, + /* .type = */ KEY_RSA3072_DILITHIUM_2, /* .nid = */ 0, /* .cert = */ 0, /* .sigonly = */ 0, @@ -958,22 +1150,267 @@ static const struct sshkey_impl_funcs sshkey_rsa3072_sphincssha2128fsimple_funcs /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, /* .ssh_serialize_private = */ ssh_generic_serialize_private, /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, - /* .generate = */ ssh_rsa3072_sphincssha2128fsimple_generate, + /* .generate = */ ssh_generic_generate, /* .copy_public = */ ssh_generic_copy_public, - /* .sign = */ ssh_rsa3072_sphincssha2128fsimple_sign, - /* .verify = */ ssh_rsa3072_sphincssha2128fsimple_verify, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, }; const struct sshkey_impl sshkey_rsa3072_sphincssha2128fsimple_impl = { - /* .name = */ "ssh-rsa3072_sphincssha2128fsimple", + /* .name = */ "ssh-rsa3072-sphincssha2128fsimple", /* .shortname = */ "RSA3072_SPHINCSSHA2128FSIMPLE", /* .sigalg = */ NULL, - /* .type = */ KEY_SPHINCS_SHA2_128F_SIMPLE, + /* .type = */ KEY_RSA3072_SPHINCS_SHA2_128F_SIMPLE, /* .nid = */ 0, /* .cert = */ 0, /* .sigonly = */ 0, /* .keybits = */ 256, // TODO - What should be here? /* .funcs = */ &sshkey_rsa3072_sphincssha2128fsimple_funcs, }; +#ifdef OPENSSL_HAS_ECC +static const struct sshkey_impl_funcs sshkey_ecdsanistp256_falcon512_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp256_falcon512_impl = { + /* .name = */ "ssh-ecdsa-nistp256-falcon512", + /* .shortname = */ "ECDSANISTP256_FALCON512", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP256_FALCON_512, + /* .nid = */ NID_X9_62_prime256v1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp256_falcon512_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp521_falcon1024_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp521_falcon1024_impl = { + /* .name = */ "ssh-ecdsa-nistp521-falcon1024", + /* .shortname = */ "ECDSANISTP521_FALCON1024", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP521_FALCON_1024, + /* .nid = */ NID_secp521r1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp521_falcon1024_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp256_dilithium2_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp256_dilithium2_impl = { + /* .name = */ "ssh-ecdsa-nistp256-dilithium2", + /* .shortname = */ "ECDSANISTP256_DILITHIUM2", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP256_DILITHIUM_2, + /* .nid = */ NID_X9_62_prime256v1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp256_dilithium2_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp384_dilithium3_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp384_dilithium3_impl = { + /* .name = */ "ssh-ecdsa-nistp384-dilithium3", + /* .shortname = */ "ECDSANISTP384_DILITHIUM3", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP384_DILITHIUM_3, + /* .nid = */ NID_secp384r1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp384_dilithium3_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp521_dilithium5_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp521_dilithium5_impl = { + /* .name = */ "ssh-ecdsa-nistp521-dilithium5", + /* .shortname = */ "ECDSANISTP521_DILITHIUM5", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP521_DILITHIUM_5, + /* .nid = */ NID_secp521r1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp521_dilithium5_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp256_sphincssha2128fsimple_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp256_sphincssha2128fsimple_impl = { + /* .name = */ "ssh-ecdsa-nistp256-sphincssha2128fsimple", + /* .shortname = */ "ECDSANISTP256_SPHINCSSHA2128FSIMPLE", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE, + /* .nid = */ NID_X9_62_prime256v1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp256_sphincssha2128fsimple_funcs, +}; +static const struct sshkey_impl_funcs sshkey_ecdsanistp521_sphincssha2256fsimple_funcs = { + /* .size = */ ssh_generic_size, + /* .alloc = */ ssh_generic_alloc, + /* .cleanup = */ ssh_generic_cleanup, + /* .equal = */ ssh_generic_equal, + /* .ssh_serialize_public = */ ssh_generic_serialize_public, + /* .ssh_deserialize_public = */ ssh_generic_deserialize_public, + /* .ssh_serialize_private = */ ssh_generic_serialize_private, + /* .ssh_deserialize_private = */ ssh_generic_deserialize_private, + /* .generate = */ ssh_generic_generate, + /* .copy_public = */ ssh_generic_copy_public, + /* .sign = */ ssh_generic_sign, + /* .verify = */ ssh_generic_verify, +}; + +const struct sshkey_impl sshkey_ecdsanistp521_sphincssha2256fsimple_impl = { + /* .name = */ "ssh-ecdsa-nistp521-sphincssha2256fsimple", + /* .shortname = */ "ECDSANISTP521_SPHINCSSHA2256FSIMPLE", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE, + /* .nid = */ NID_secp521r1, + /* .cert = */ 0, + /* .sigonly = */ 0, + /* .keybits = */ 256, // TODO - What should be here? + /* .funcs = */ &sshkey_ecdsanistp521_sphincssha2256fsimple_funcs, +}; +#endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ ///// OQS_TEMPLATE_FRAGMENT_DEFINE_SIG_FUNCTIONS_END + + +const struct sshkey_impl *oqs_classical_sshkey_impl(const struct sshkey *k) +{ + const struct sshkey_impl *impl = NULL; + switch(k->type) { + CASE_KEY_RSA_HYBRID: + impl = &sshkey_rsa_impl; + break; + CASE_KEY_ECDSA_HYBRID: + // Behind the P-256 impl struct is a generic ECDSA implementation which + // multiplexes off of either the bits or key->nid parameters passed into + // the interface. This behavior is in-line with the "normal" ECDSA code. + impl = &sshkey_ecdsa_nistp256_impl; + break; + } + return impl; +} + +const struct sshkey_impl *oqs_pq_sshkey_impl(const struct sshkey *k) +{ + const struct sshkey_impl *impl = NULL; + switch(k->type) { +///// OQS_TEMPLATE_FRAGMENT_IMPL_LOOKUP_CASES_START + case KEY_FALCON_512: + case KEY_RSA3072_FALCON_512: + case KEY_ECDSA_NISTP256_FALCON_512: + impl = &sshkey_falcon512_impl; + break; + case KEY_FALCON_1024: + case KEY_ECDSA_NISTP521_FALCON_1024: + impl = &sshkey_falcon1024_impl; + break; + case KEY_DILITHIUM_2: + case KEY_RSA3072_DILITHIUM_2: + case KEY_ECDSA_NISTP256_DILITHIUM_2: + impl = &sshkey_dilithium2_impl; + break; + case KEY_DILITHIUM_3: + case KEY_ECDSA_NISTP384_DILITHIUM_3: + impl = &sshkey_dilithium3_impl; + break; + case KEY_DILITHIUM_5: + case KEY_ECDSA_NISTP521_DILITHIUM_5: + impl = &sshkey_dilithium5_impl; + break; + case KEY_SPHINCS_SHA2_128F_SIMPLE: + case KEY_RSA3072_SPHINCS_SHA2_128F_SIMPLE: + case KEY_ECDSA_NISTP256_SPHINCS_SHA2_128F_SIMPLE: + impl = &sshkey_sphincssha2128fsimple_impl; + break; + case KEY_SPHINCS_SHA2_256F_SIMPLE: + case KEY_ECDSA_NISTP521_SPHINCS_SHA2_256F_SIMPLE: + impl = &sshkey_sphincssha2256fsimple_impl; + break; +///// OQS_TEMPLATE_FRAGMENT_IMPL_LOOKUP_CASES_END + default: + break; + } + return impl; +} diff --git a/sshkey.c b/sshkey.c index d81c956462b0..14b3e9732654 100644 --- a/sshkey.c +++ b/sshkey.c @@ -142,8 +142,7 @@ extern const struct sshkey_impl sshkey_dilithium5_impl; extern const struct sshkey_impl sshkey_sphincssha2128fsimple_impl; extern const struct sshkey_impl sshkey_sphincssha2256fsimple_impl; -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL extern const struct sshkey_impl sshkey_rsa3072_falcon512_impl; extern const struct sshkey_impl sshkey_rsa3072_dilithium2_impl; extern const struct sshkey_impl sshkey_rsa3072_sphincssha2128fsimple_impl; @@ -205,8 +204,7 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_dilithium5_impl, &sshkey_sphincssha2128fsimple_impl, &sshkey_sphincssha2256fsimple_impl, -#ifdef HYBRID_IMPLEMENTATION_EXISTS -// #ifdef WITH_OPENSSL +#ifdef WITH_OPENSSL &sshkey_rsa3072_falcon512_impl, &sshkey_rsa3072_dilithium2_impl, &sshkey_rsa3072_sphincssha2128fsimple_impl,