Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Hybrid SSH Keys #161

Merged
merged 1 commit into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 %}

Original file line number Diff line number Diff line change
@@ -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 %}

4 changes: 2 additions & 2 deletions oqs-template/ssh-keygen.c/define_key_types.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
59 changes: 46 additions & 13 deletions oqs-template/ssh-oqs.c/define_sig_functions.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -74,13 +75,12 @@ const struct sshkey_impl sshkey_{{ symbol_base_name }}_impl = {
/* .nid = */ 0,
/* .cert = */ 0,
/* .sigonly = */ 0,
/* .keybits = */ 256, // TODO - What should be here?
/* .keybits = */ 0,
/* .funcs = */ &sshkey_{{ symbol_base_name }}_funcs,
};
{%- 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('_','') %}
Expand All @@ -93,24 +93,57 @@ 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,
/* .keybits = */ 256, // TODO - What should be here?
/* .keybits = */ 0,
/* .funcs = */ &sshkey_{{ symbol_base_name }}_funcs,
};
{%- 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 = */ "{{ alg['name']|upper + '_' + sig['name']|replace('_','')|upper }}",
/* .sigalg = */ NULL,
/* .type = */ KEY_{{ alg['name']|upper }}_{{ sig['name']|upper }},
/* .nid = */ {{ alg['openssl_nid'] }},
/* .cert = */ 0,
/* .sigonly = */ 0,
/* .keybits = */ 0,
/* .funcs = */ &sshkey_{{ symbol_base_name }}_funcs,
};
{%- endfor %}
{%- endfor %}
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */

9 changes: 9 additions & 0 deletions oqs-template/ssh-oqs.c/impl_lookup_cases.fragment
Original file line number Diff line number Diff line change
@@ -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 %}

3 changes: 1 addition & 2 deletions oqs-template/sshkey.c/define_keytypes.fragment
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
3 changes: 1 addition & 2 deletions oqs-template/sshkey.c/extern_key_impls.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
80 changes: 42 additions & 38 deletions oqs-test/try_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -13,75 +14,75 @@
kexs = [
##### OQS_TEMPLATE_FRAGMENT_LIST_ALL_KEXS_START
"frodokem-640-aes-sha256",
# "[email protected]",
"[email protected]",
"frodokem-976-aes-sha384",
# "[email protected]",
"[email protected]",
"frodokem-1344-aes-sha512",
# "[email protected]",
"[email protected]",
"frodokem-640-shake-sha256",
# "[email protected]",
"[email protected]",
"frodokem-976-shake-sha384",
# "[email protected]",
"[email protected]",
"frodokem-1344-shake-sha512",
# "[email protected]",
"[email protected]",
"kyber-512-sha256",
# "[email protected]",
"[email protected]",
"kyber-768-sha384",
# "[email protected]",
"[email protected]",
"kyber-1024-sha512",
# "[email protected]",
"[email protected]",
"bike-l1-sha512",
# "[email protected]",
"[email protected]",
"bike-l3-sha512",
# "[email protected]",
"[email protected]",
"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",
# "[email protected]",
"[email protected]",
"hqc-192-sha384",
# "[email protected]",
"[email protected]",
"hqc-256-sha512",
# "[email protected]",
"[email protected]",
##### 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
]

Expand Down Expand Up @@ -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)

4 changes: 2 additions & 2 deletions ssh-ecdsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ ssh_ecdsa_verify(const struct sshkey *key,
char *ktype = NULL;

if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA &&
!oqs_utils_is_ecdsa_hybrid(sshkey_type_plain(key->type)) ||
(sshkey_type_plain(key->type) != KEY_ECDSA &&
!oqs_utils_is_ecdsa_hybrid(sshkey_type_plain(key->type))) ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;

Expand Down
20 changes: 10 additions & 10 deletions ssh-keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,17 +1170,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
Expand Down
Loading