diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 47c3967e..69f36c59 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -19,7 +19,7 @@ the interesting functions as you go. The libssh library provides: - - Key Exchange Methods: sntrup761x25519-sha512@openssh.com, curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1 + - Key Exchange Methods: sntrup761x25519-sha512, sntrup761x25519-sha512@openssh.com, curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1 - Public Key Algorithms: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256 - Ciphers: aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc - Compression Schemes: zlib, zlib@openssh.com, none diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h index bacfe386..6b8b60ac 100644 --- a/include/libssh/crypto.h +++ b/include/libssh/crypto.h @@ -85,6 +85,8 @@ enum ssh_key_exchange_e { SSH_KEX_DH_GROUP14_SHA256, /* sntrup761x25519-sha512@openssh.com */ SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM, + /* sntrup761x25519-sha512 */ + SSH_KEX_SNTRUP761X25519_SHA512, }; enum ssh_cipher_e { diff --git a/src/client.c b/src/client.c index 7e223da4..8d3374b5 100644 --- a/src/client.c +++ b/src/client.c @@ -291,6 +291,7 @@ int dh_handshake(ssh_session session) break; #endif #ifdef HAVE_SNTRUP761 + case SSH_KEX_SNTRUP761X25519_SHA512: case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: rc = ssh_client_sntrup761x25519_init(session); break; diff --git a/src/kex.c b/src/kex.c index 02f2735f..fa213b74 100644 --- a/src/kex.c +++ b/src/kex.c @@ -97,7 +97,7 @@ #endif /* HAVE_CURVE25519 */ #ifdef HAVE_SNTRUP761 -#define SNTRUP761X25519 "sntrup761x25519-sha512@openssh.com," +#define SNTRUP761X25519 "sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com," #else #define SNTRUP761X25519 "" #endif /* HAVE_SNTRUP761 */ @@ -924,6 +924,8 @@ kex_select_kex_type(const char *kex) return SSH_KEX_CURVE25519_SHA256; } else if (strcmp(kex, "sntrup761x25519-sha512@openssh.com") == 0) { return SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM; + } else if (strcmp(kex, "sntrup761x25519-sha512") == 0) { + return SSH_KEX_SNTRUP761X25519_SHA512; } /* should not happen. We should be getting only valid names at this stage */ return 0; @@ -965,6 +967,7 @@ static void revert_kex_callbacks(ssh_session session) break; #endif #ifdef HAVE_SNTRUP761 + case SSH_KEX_SNTRUP761X25519_SHA512: case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: ssh_client_sntrup761x25519_remove_callbacks(session); break; @@ -1529,6 +1532,7 @@ int ssh_make_sessionid(ssh_session session) break; #endif /* HAVE_CURVE25519 */ #ifdef HAVE_SNTRUP761 + case SSH_KEX_SNTRUP761X25519_SHA512: case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: rc = ssh_buffer_pack(buf, "dPPdPP", @@ -1552,13 +1556,17 @@ int ssh_make_sessionid(ssh_session session) break; #endif /* HAVE_SNTRUP761 */ } - if (session->next_crypto->kex_type == SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM) { + switch (session->next_crypto->kex_type) { + case SSH_KEX_SNTRUP761X25519_SHA512: + case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: rc = ssh_buffer_pack(buf, "F", session->next_crypto->shared_secret, SHA512_DIGEST_LEN); - } else { + break; + default: rc = ssh_buffer_pack(buf, "B", session->next_crypto->shared_secret); + break; } if (rc != SSH_OK) { ssh_set_error(session, SSH_FATAL, "Failed to pack shared secret"); @@ -1618,6 +1626,7 @@ int ssh_make_sessionid(ssh_session session) case SSH_KEX_DH_GROUP16_SHA512: case SSH_KEX_DH_GROUP18_SHA512: case SSH_KEX_ECDH_SHA2_NISTP521: + case SSH_KEX_SNTRUP761X25519_SHA512: case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: session->next_crypto->digest_len = SHA512_DIGEST_LENGTH; session->next_crypto->digest_type = SSH_KDF_SHA512; @@ -1757,11 +1766,15 @@ int ssh_generate_session_keys(ssh_session session) size_t intkey_srv_to_cli_len = 0; int rc = -1; - if (session->next_crypto->kex_type == SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM) { + switch (session->next_crypto->kex_type) { + case SSH_KEX_SNTRUP761X25519_SHA512: + case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: k_string = ssh_make_padded_bignum_string(crypto->shared_secret, SHA512_DIGEST_LEN); - } else { + break; + default: k_string = ssh_make_bignum_string(crypto->shared_secret); + break; } if (k_string == NULL) { ssh_set_error_oom(session); diff --git a/src/session.c b/src/session.c index 78eb2417..6160db74 100644 --- a/src/session.c +++ b/src/session.c @@ -455,6 +455,8 @@ const char* ssh_get_kex_algo(ssh_session session) { return "curve25519-sha256@libssh.org"; case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: return "sntrup761x25519-sha512@openssh.com"; + case SSH_KEX_SNTRUP761X25519_SHA512: + return "sntrup761x25519-sha512"; #ifdef WITH_GEX case SSH_KEX_DH_GEX_SHA1: return "diffie-hellman-group-exchange-sha1"; diff --git a/src/wrapper.c b/src/wrapper.c index cd665c5c..d7a88269 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -594,6 +594,7 @@ int crypt_set_algorithms_server(ssh_session session){ break; #endif #ifdef HAVE_SNTRUP761 + case SSH_KEX_SNTRUP761X25519_SHA512: case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM: ssh_server_sntrup761x25519_init(session); break; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6ee0b688..10012950 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -157,7 +157,7 @@ if (SSH_EXECUTABLE) diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group14-sha256 diffie-hellman-group16-sha512 diffie-hellman-group18-sha512 diffie-hellman-group-exchange-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 - sntrup761x25519-sha512@openssh.com + sntrup761x25519-sha512@openssh.com sntrup761x25519-sha512 curve25519-sha256 curve25519-sha256@libssh.org ssh-ed25519 ssh-ed25519-cert-v01@openssh.com ssh-rsa ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521 diff --git a/tests/client/torture_algorithms.c b/tests/client/torture_algorithms.c index 95dd569e..a2bb60ff 100644 --- a/tests/client/torture_algorithms.c +++ b/tests/client/torture_algorithms.c @@ -735,6 +735,23 @@ torture_algorithms_ecdh_sntrup761x25519_sha512_openssh_com(void **state) } #endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */ +#ifdef OPENSSH_SNTRUP761X25519_SHA512 +static void +torture_algorithms_ecdh_sntrup761x25519_sha512(void **state) +{ + struct torture_state *s = *state; + + if (ssh_fips_mode()) { + skip(); + } + + test_algorithm(s->ssh.session, + "sntrup761x25519-sha512", + NULL /*cipher*/, + NULL /*hmac*/); +} +#endif /* OPENSSH_SNTRUP761X25519_SHA512 */ + static void torture_algorithms_dh_group1(void **state) { struct torture_state *s = *state; @@ -1007,6 +1024,11 @@ int torture_run_tests(void) { session_setup, session_teardown), #endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */ +#ifdef OPENSSH_SNTRUP761X25519_SHA512 + cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_sntrup761x25519_sha512, + session_setup, + session_teardown), +#endif /* OPENSSH_SNTRUP761X25519_SHA512 */ #if defined(HAVE_ECC) cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_sha2_nistp256, session_setup, diff --git a/tests/external_override/torture_override.c b/tests/external_override/torture_override.c index 70ef7e18..9d2eb8aa 100644 --- a/tests/external_override/torture_override.c +++ b/tests/external_override/torture_override.c @@ -290,6 +290,40 @@ torture_override_ecdh_sntrup761x25519_sha512_openssh_com(void **state) } #endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */ +#ifdef OPENSSH_SNTRUP761X25519_SHA512 +static void +torture_override_ecdh_sntrup761x25519_sha512(void **state) +{ + struct torture_state *s = *state; + bool internal_curve25519_called; + bool internal_sntrup761_called; + + if (ssh_fips_mode()) { + skip(); + } + + test_algorithm(s->ssh.session, + "sntrup761x25519-sha512", + NULL, /* cipher */ + NULL /* hostkey */); + + internal_curve25519_called = internal_curve25519_function_called(); + internal_sntrup761_called = internal_sntrup761_function_called(); + +#if SHOULD_CALL_INTERNAL_SNTRUP761 + assert_true(internal_sntrup761_called); +#else + assert_false(internal_sntrup761_called); +#endif + +#if SHOULD_CALL_INTERNAL_CURVE25519 + assert_true(internal_curve25519_called); +#else + assert_false(internal_curve25519_called); +#endif +} +#endif /* OPENSSH_SNTRUP761X25519_SHA512 */ + #ifdef OPENSSH_SSH_ED25519 static void torture_override_ed25519(void **state) { @@ -339,6 +373,11 @@ int torture_run_tests(void) session_setup, session_teardown), #endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */ +#ifdef OPENSSH_SNTRUP761X25519_SHA512 + cmocka_unit_test_setup_teardown(torture_override_ecdh_sntrup761x25519_sha512, + session_setup, + session_teardown), +#endif /* OPENSSH_SNTRUP761X25519_SHA512 */ #ifdef OPENSSH_SSH_ED25519 cmocka_unit_test_setup_teardown(torture_override_ed25519, session_setup, diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c index 6aac2c4a..e43f66ab 100644 --- a/tests/pkd/pkd_hello.c +++ b/tests/pkd/pkd_hello.c @@ -286,11 +286,23 @@ static int torture_pkd_setup_ecdsa_521(void **state) { #endif #ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM +#define SNTRUP_OPENSSH_NAME "sntrup761x25519-sha512@openssh.com" +#define PKDTESTS_KEX_SNTRUP761_OPENSSH(f, client, kexcmd) \ + f(client, rsa_sntrup761x25519_sha512_openssh_com, kexcmd(SNTRUP_OPENSSH_NAME), setup_rsa, teardown) \ + f(client, ecdsa_256_sntrup761x25519_sha512_openssh_com, kexcmd(SNTRUP_OPENSSH_NAME), setup_ecdsa_256, teardown) \ + f(client, ecdsa_384_sntrup761x25519_sha512_openssh_com, kexcmd(SNTRUP_OPENSSH_NAME), setup_ecdsa_384, teardown) \ + f(client, ecdsa_521_sntrup761x25519_sha512_openssh_com, kexcmd(SNTRUP_OPENSSH_NAME), setup_ecdsa_521, teardown) +#else +#define PKDTESTS_KEX_SNTRUP761_OPENSSH(f, client, kexcmd) +#endif + +#ifdef OPENSSH_SNTRUP761X25519_SHA512 +#define SNTRUP_NAME "sntrup761x25519-sha512" #define PKDTESTS_KEX_SNTRUP761(f, client, kexcmd) \ - f(client, rsa_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_rsa, teardown) \ - f(client, ecdsa_256_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_ecdsa_521, teardown) + f(client, rsa_sntrup761x25519_sha512, kexcmd(SNTRUP_NAME), setup_rsa, teardown) \ + f(client, ecdsa_256_sntrup761x25519_sha512, kexcmd(SNTRUP_NAME), setup_ecdsa_256, teardown) \ + f(client, ecdsa_384_sntrup761x25519_sha512, kexcmd(SNTRUP_NAME), setup_ecdsa_384, teardown) \ + f(client, ecdsa_521_sntrup761x25519_sha512, kexcmd(SNTRUP_NAME), setup_ecdsa_521, teardown) #else #define PKDTESTS_KEX_SNTRUP761(f, client, kexcmd) #endif @@ -298,6 +310,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) { #define PKDTESTS_KEX_COMMON(f, client, kexcmd) \ PKDTESTS_KEX_FIPS(f, client, kexcmd) \ PKDTESTS_KEX_SNTRUP761(f, client, kexcmd) \ + PKDTESTS_KEX_SNTRUP761_OPENSSH(f, client, kexcmd) \ f(client, rsa_curve25519_sha256, kexcmd("curve25519-sha256"), setup_rsa, teardown) \ f(client, rsa_curve25519_sha256_libssh_org, kexcmd("curve25519-sha256@libssh.org"), setup_rsa, teardown) \ f(client, rsa_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_rsa, teardown) \ @@ -331,8 +344,15 @@ static int torture_pkd_setup_ecdsa_521(void **state) { #endif #ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM +#define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761_OPENSSH(f, client, kexcmd) \ + f(client, ed25519_sntrup761x25519_sha512_openssh_com, kexcmd(SNTRUP_OPENSSH_NAME), setup_ed25519, teardown) +#else +#define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761_OPENSSH(f, client, kexcmd) +#endif + +#ifdef OPENSSH_SNTRUP761X25519_SHA512 #define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd) \ - f(client, ed25519_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_ed25519, teardown) + f(client, ed25519_sntrup761x25519_sha512, kexcmd(SNTRUP_NAME), setup_ed25519, teardown) #else #define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd) #endif @@ -340,6 +360,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) { #define PKDTESTS_KEX_OPENSSHONLY(f, client, kexcmd) \ /* Kex algorithms. */ \ PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd) \ + PKDTESTS_KEX_OPENSSHONLY_SNTRUP761_OPENSSH(f, client, kexcmd) \ f(client, ed25519_curve25519_sha256, kexcmd("curve25519-sha256"), setup_ed25519, teardown) \ f(client, ed25519_curve25519_sha256_libssh_org, kexcmd("curve25519-sha256@libssh.org"), setup_ed25519, teardown) \ f(client, ed25519_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256"), setup_ed25519, teardown) \ diff --git a/tests/tests_config.h.cmake b/tests/tests_config.h.cmake index 365b0798..3be3bb87 100644 --- a/tests/tests_config.h.cmake +++ b/tests/tests_config.h.cmake @@ -50,6 +50,7 @@ #cmakedefine OPENSSH_ECDH_SHA2_NISTP521 1 #cmakedefine OPENSSH_CURVE25519_SHA256 1 #cmakedefine OPENSSH_CURVE25519_SHA256_LIBSSH_ORG 1 +#cmakedefine OPENSSH_SNTRUP761X25519_SHA512 1 #cmakedefine OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM 1 #cmakedefine OPENSSH_SSH_ED25519 1 #cmakedefine OPENSSH_SSH_ED25519_CERT_V01_OPENSSH_COM 1 diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c index 0b8e047e..f9c4dd58 100644 --- a/tests/unittests/torture_options.c +++ b/tests/unittests/torture_options.c @@ -217,6 +217,7 @@ static void torture_options_set_key_exchange(void **state) /* Test known kexes */ rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, + "sntrup761x25519-sha512," "sntrup761x25519-sha512@openssh.com," "curve25519-sha256,curve25519-sha256@libssh.org," "ecdh-sha2-nistp256,diffie-hellman-group16-sha512," @@ -232,6 +233,7 @@ static void torture_options_set_key_exchange(void **state) "diffie-hellman-group14-sha256"); } else { assert_string_equal(session->opts.wanted_methods[SSH_KEX], + "sntrup761x25519-sha512," "sntrup761x25519-sha512@openssh.com," "curve25519-sha256,curve25519-sha256@libssh.org," "ecdh-sha2-nistp256,diffie-hellman-group16-sha512," @@ -281,6 +283,7 @@ static void torture_options_get_key_exchange(void **state) } else { assert_string_equal(value, "curve25519-sha256,curve25519-sha256@libssh.org," + "sntrup761x25519-sha512," "sntrup761x25519-sha512@openssh.com," "ecdh-sha2-nistp256,ecdh-sha2-nistp384," "ecdh-sha2-nistp521,diffie-hellman-group18-sha512,"