mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-07-31 00:03:07 +03:00
kex: Add sntrup761x25519-sha512@openssh.com.
All of the initial work was done by Simon. Jakub cleaned up the formatting issues, resolved the padding of bignum to match specs and be interoperable with OpenSSH (and few more minor details). Closes: #194. Signed-off-by: Simon Josefsson <simon@josefsson.org> Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Sahana Prasad <sahana@redhat.com>
This commit is contained in:
committed by
Jakub Jelen
parent
3468cc0dc5
commit
4becc8eb82
@ -19,7 +19,7 @@ the interesting functions as you go.
|
|||||||
|
|
||||||
The libssh library provides:
|
The libssh library provides:
|
||||||
|
|
||||||
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
- <strong>Key Exchange Methods</strong>: <i>sntrup761x25519-sha512@openssh.com, curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
||||||
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256
|
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256
|
||||||
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc
|
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc
|
||||||
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
||||||
|
@ -45,10 +45,11 @@
|
|||||||
#ifdef HAVE_OPENSSL_ECDH_H
|
#ifdef HAVE_OPENSSL_ECDH_H
|
||||||
#include <openssl/ecdh.h>
|
#include <openssl/ecdh.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
#include "libssh/ecdh.h"
|
#include "libssh/ecdh.h"
|
||||||
#include "libssh/kex.h"
|
#include "libssh/kex.h"
|
||||||
#include "libssh/curve25519.h"
|
#include "libssh/sntrup761.h"
|
||||||
|
|
||||||
#define DIGEST_MAX_LEN 64
|
#define DIGEST_MAX_LEN 64
|
||||||
|
|
||||||
@ -82,6 +83,8 @@ enum ssh_key_exchange_e {
|
|||||||
SSH_KEX_DH_GROUP18_SHA512,
|
SSH_KEX_DH_GROUP18_SHA512,
|
||||||
/* diffie-hellman-group14-sha256 */
|
/* diffie-hellman-group14-sha256 */
|
||||||
SSH_KEX_DH_GROUP14_SHA256,
|
SSH_KEX_DH_GROUP14_SHA256,
|
||||||
|
/* sntrup761x25519-sha512@openssh.com */
|
||||||
|
SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssh_cipher_e {
|
enum ssh_cipher_e {
|
||||||
@ -132,6 +135,11 @@ struct ssh_crypto_struct {
|
|||||||
#endif
|
#endif
|
||||||
ssh_curve25519_pubkey curve25519_client_pubkey;
|
ssh_curve25519_pubkey curve25519_client_pubkey;
|
||||||
ssh_curve25519_pubkey curve25519_server_pubkey;
|
ssh_curve25519_pubkey curve25519_server_pubkey;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
ssh_sntrup761_privkey sntrup761_privkey;
|
||||||
|
ssh_sntrup761_pubkey sntrup761_client_pubkey;
|
||||||
|
ssh_sntrup761_ciphertext sntrup761_ciphertext;
|
||||||
#endif
|
#endif
|
||||||
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
||||||
size_t session_id_len;
|
size_t session_id_len;
|
||||||
|
86
include/libssh/sntrup761.h
Normal file
86
include/libssh/sntrup761.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 by Aris Adamantiadis <aris@badcode.be>
|
||||||
|
* Copyright (c) 2023 Simon Josefsson <simon@josefsson.org>
|
||||||
|
* Copyright (c) 2025 Jakub Jelen <jjelen@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation,
|
||||||
|
* version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SNTRUP761_H_
|
||||||
|
#define SNTRUP761_H_
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "curve25519.h"
|
||||||
|
#include "libssh.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
#define HAVE_SNTRUP761 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void crypto_hash_sha512(unsigned char *out,
|
||||||
|
const unsigned char *in,
|
||||||
|
unsigned long long inlen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Derived from public domain source, written by (in alphabetical order):
|
||||||
|
* - Daniel J. Bernstein
|
||||||
|
* - Chitchanok Chuengsatiansup
|
||||||
|
* - Tanja Lange
|
||||||
|
* - Christine van Vredendaal
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SNTRUP761_SECRETKEY_SIZE 1763
|
||||||
|
#define SNTRUP761_PUBLICKEY_SIZE 1158
|
||||||
|
#define SNTRUP761_CIPHERTEXT_SIZE 1039
|
||||||
|
#define SNTRUP761_SIZE 32
|
||||||
|
|
||||||
|
typedef void sntrup761_random_func(void *ctx, size_t length, uint8_t *dst);
|
||||||
|
|
||||||
|
void sntrup761_keypair(uint8_t *pk,
|
||||||
|
uint8_t *sk,
|
||||||
|
void *random_ctx,
|
||||||
|
sntrup761_random_func *random);
|
||||||
|
void sntrup761_enc(uint8_t *c,
|
||||||
|
uint8_t *k,
|
||||||
|
const uint8_t *pk,
|
||||||
|
void *random_ctx,
|
||||||
|
sntrup761_random_func *random);
|
||||||
|
void sntrup761_dec(uint8_t *k, const uint8_t *c, const uint8_t *sk);
|
||||||
|
|
||||||
|
typedef unsigned char ssh_sntrup761_pubkey[SNTRUP761_PUBLICKEY_SIZE];
|
||||||
|
typedef unsigned char ssh_sntrup761_privkey[SNTRUP761_SECRETKEY_SIZE];
|
||||||
|
typedef unsigned char ssh_sntrup761_ciphertext[SNTRUP761_CIPHERTEXT_SIZE];
|
||||||
|
|
||||||
|
int ssh_client_sntrup761x25519_init(ssh_session session);
|
||||||
|
void ssh_client_sntrup761x25519_remove_callbacks(ssh_session session);
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER
|
||||||
|
void ssh_server_sntrup761x25519_init(ssh_session session);
|
||||||
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SNTRUP761_H_ */
|
@ -87,6 +87,7 @@ set(libssh_SRCS
|
|||||||
connector.c
|
connector.c
|
||||||
crypto_common.c
|
crypto_common.c
|
||||||
curve25519.c
|
curve25519.c
|
||||||
|
sntrup761.c
|
||||||
dh.c
|
dh.c
|
||||||
ecdh.c
|
ecdh.c
|
||||||
error.c
|
error.c
|
||||||
@ -119,6 +120,7 @@ set(libssh_SRCS
|
|||||||
wrapper.c
|
wrapper.c
|
||||||
external/bcrypt_pbkdf.c
|
external/bcrypt_pbkdf.c
|
||||||
external/blowfish.c
|
external/blowfish.c
|
||||||
|
external/sntrup761.c
|
||||||
config_parser.c
|
config_parser.c
|
||||||
token.c
|
token.c
|
||||||
pki_ed25519_common.c
|
pki_ed25519_common.c
|
||||||
|
@ -289,6 +289,11 @@ int dh_handshake(ssh_session session)
|
|||||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
rc = ssh_client_curve25519_init(session);
|
rc = ssh_client_curve25519_init(session);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
|
rc = ssh_client_sntrup761x25519_init(session);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
|
1060
src/external/sntrup761.c
vendored
Normal file
1060
src/external/sntrup761.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
src/kex.c
52
src/kex.c
@ -40,6 +40,7 @@
|
|||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
#include "libssh/string.h"
|
#include "libssh/string.h"
|
||||||
#include "libssh/curve25519.h"
|
#include "libssh/curve25519.h"
|
||||||
|
#include "libssh/sntrup761.h"
|
||||||
#include "libssh/knownhosts.h"
|
#include "libssh/knownhosts.h"
|
||||||
#include "libssh/misc.h"
|
#include "libssh/misc.h"
|
||||||
#include "libssh/pki.h"
|
#include "libssh/pki.h"
|
||||||
@ -95,6 +96,12 @@
|
|||||||
#define CURVE25519 ""
|
#define CURVE25519 ""
|
||||||
#endif /* HAVE_CURVE25519 */
|
#endif /* HAVE_CURVE25519 */
|
||||||
|
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
#define SNTRUP761X25519 "sntrup761x25519-sha512@openssh.com,"
|
||||||
|
#else
|
||||||
|
#define SNTRUP761X25519 ""
|
||||||
|
#endif /* HAVE_SNTRUP761 */
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
#define ECDH "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,"
|
#define ECDH "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,"
|
||||||
#define EC_HOSTKEYS "ecdsa-sha2-nistp521," \
|
#define EC_HOSTKEYS "ecdsa-sha2-nistp521," \
|
||||||
@ -159,6 +166,7 @@
|
|||||||
|
|
||||||
#define DEFAULT_KEY_EXCHANGE \
|
#define DEFAULT_KEY_EXCHANGE \
|
||||||
CURVE25519 \
|
CURVE25519 \
|
||||||
|
SNTRUP761X25519 \
|
||||||
ECDH \
|
ECDH \
|
||||||
"diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
|
"diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
|
||||||
GEX_SHA256 \
|
GEX_SHA256 \
|
||||||
@ -894,6 +902,8 @@ kex_select_kex_type(const char *kex)
|
|||||||
return SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
|
return SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
|
||||||
} else if (strcmp(kex, "curve25519-sha256") == 0) {
|
} else if (strcmp(kex, "curve25519-sha256") == 0) {
|
||||||
return SSH_KEX_CURVE25519_SHA256;
|
return SSH_KEX_CURVE25519_SHA256;
|
||||||
|
} else if (strcmp(kex, "sntrup761x25519-sha512@openssh.com") == 0) {
|
||||||
|
return SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM;
|
||||||
}
|
}
|
||||||
/* should not happen. We should be getting only valid names at this stage */
|
/* should not happen. We should be getting only valid names at this stage */
|
||||||
return 0;
|
return 0;
|
||||||
@ -933,6 +943,11 @@ static void revert_kex_callbacks(ssh_session session)
|
|||||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
ssh_client_curve25519_remove_callbacks(session);
|
ssh_client_curve25519_remove_callbacks(session);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
|
ssh_client_sntrup761x25519_remove_callbacks(session);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1475,8 +1490,35 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_CURVE25519 */
|
#endif /* HAVE_CURVE25519 */
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
|
rc = ssh_buffer_pack(buf,
|
||||||
|
"dPPdPP",
|
||||||
|
SNTRUP761_PUBLICKEY_SIZE + CURVE25519_PUBKEY_SIZE,
|
||||||
|
(size_t)SNTRUP761_PUBLICKEY_SIZE,
|
||||||
|
session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
(size_t)CURVE25519_PUBKEY_SIZE,
|
||||||
|
session->next_crypto->curve25519_client_pubkey,
|
||||||
|
SNTRUP761_CIPHERTEXT_SIZE + CURVE25519_PUBKEY_SIZE,
|
||||||
|
(size_t)SNTRUP761_CIPHERTEXT_SIZE,
|
||||||
|
session->next_crypto->sntrup761_ciphertext,
|
||||||
|
(size_t)CURVE25519_PUBKEY_SIZE,
|
||||||
|
session->next_crypto->curve25519_server_pubkey);
|
||||||
|
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_SNTRUP761 */
|
||||||
|
}
|
||||||
|
if (session->next_crypto->kex_type == SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM) {
|
||||||
|
rc = ssh_buffer_pack(buf,
|
||||||
|
"F",
|
||||||
|
session->next_crypto->shared_secret,
|
||||||
|
SHA512_DIGEST_LEN);
|
||||||
|
} else {
|
||||||
|
rc = ssh_buffer_pack(buf, "B", session->next_crypto->shared_secret);
|
||||||
}
|
}
|
||||||
rc = ssh_buffer_pack(buf, "B", session->next_crypto->shared_secret);
|
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1532,6 +1574,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
case SSH_KEX_DH_GROUP16_SHA512:
|
case SSH_KEX_DH_GROUP16_SHA512:
|
||||||
case SSH_KEX_DH_GROUP18_SHA512:
|
case SSH_KEX_DH_GROUP18_SHA512:
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP521:
|
case SSH_KEX_ECDH_SHA2_NISTP521:
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
session->next_crypto->digest_len = SHA512_DIGEST_LENGTH;
|
session->next_crypto->digest_len = SHA512_DIGEST_LENGTH;
|
||||||
session->next_crypto->digest_type = SSH_KDF_SHA512;
|
session->next_crypto->digest_type = SSH_KDF_SHA512;
|
||||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||||
@ -1668,7 +1711,12 @@ int ssh_generate_session_keys(ssh_session session)
|
|||||||
size_t intkey_srv_to_cli_len = 0;
|
size_t intkey_srv_to_cli_len = 0;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
k_string = ssh_make_bignum_string(crypto->shared_secret);
|
if (session->next_crypto->kex_type == SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM) {
|
||||||
|
k_string = ssh_make_padded_bignum_string(crypto->shared_secret,
|
||||||
|
SHA512_DIGEST_LEN);
|
||||||
|
} else {
|
||||||
|
k_string = ssh_make_bignum_string(crypto->shared_secret);
|
||||||
|
}
|
||||||
if (k_string == NULL) {
|
if (k_string == NULL) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -449,6 +449,8 @@ const char* ssh_get_kex_algo(ssh_session session) {
|
|||||||
return "curve25519-sha256";
|
return "curve25519-sha256";
|
||||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
return "curve25519-sha256@libssh.org";
|
return "curve25519-sha256@libssh.org";
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
|
return "sntrup761x25519-sha512@openssh.com";
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
466
src/sntrup761.c
Normal file
466
src/sntrup761.c
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
/*
|
||||||
|
* sntrup761.c - SNTRUP761x25519 ECDH functions for key exchange
|
||||||
|
* sntrup761x25519-sha512@openssh.com - based on curve25519.c.
|
||||||
|
*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 by Aris Adamantiadis <aris@badcode.be>
|
||||||
|
* Copyright (c) 2023 Simon Josefsson <simon@josefsson.org>
|
||||||
|
* Copyright (c) 2025 Jakub Jelen <jjelen@redhat.com>
|
||||||
|
*
|
||||||
|
* The SSH Library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* The SSH Library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the SSH Library; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "libssh/sntrup761.h"
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
|
||||||
|
#include "libssh/bignum.h"
|
||||||
|
#include "libssh/buffer.h"
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/pki.h"
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include "libssh/session.h"
|
||||||
|
#include "libssh/ssh2.h"
|
||||||
|
|
||||||
|
void crypto_hash_sha512(unsigned char *out,
|
||||||
|
const unsigned char *in,
|
||||||
|
unsigned long long inlen)
|
||||||
|
{
|
||||||
|
sha512(in, inlen, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crypto_random(void *ctx, size_t length, uint8_t *dst)
|
||||||
|
{
|
||||||
|
int *err = ctx;
|
||||||
|
*err = ssh_get_random(dst, length, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_sntrup761x25519_reply);
|
||||||
|
|
||||||
|
static ssh_packet_callback dh_client_callbacks[] = {
|
||||||
|
ssh_packet_client_sntrup761x25519_reply,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ssh_packet_callbacks_struct ssh_sntrup761x25519_client_callbacks =
|
||||||
|
{
|
||||||
|
.start = SSH2_MSG_KEX_ECDH_REPLY,
|
||||||
|
.n_callbacks = 1,
|
||||||
|
.callbacks = dh_client_callbacks,
|
||||||
|
.user = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ssh_sntrup761x25519_init(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_curve25519_init(session);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session->server) {
|
||||||
|
sntrup761_keypair(session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
session->next_crypto->sntrup761_privkey,
|
||||||
|
&rc,
|
||||||
|
crypto_random);
|
||||||
|
if (rc != 1) {
|
||||||
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
|
"Failed to generate sntrup761 key: PRNG failure");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief Starts sntrup761x25519-sha512@openssh.com key exchange
|
||||||
|
*/
|
||||||
|
int ssh_client_sntrup761x25519_init(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_sntrup761x25519_init(session);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
|
"bdPP",
|
||||||
|
SSH2_MSG_KEX_ECDH_INIT,
|
||||||
|
CURVE25519_PUBKEY_SIZE + SNTRUP761_PUBLICKEY_SIZE,
|
||||||
|
(size_t)SNTRUP761_PUBLICKEY_SIZE,
|
||||||
|
session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
(size_t)CURVE25519_PUBKEY_SIZE,
|
||||||
|
session->next_crypto->curve25519_client_pubkey);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register the packet callbacks */
|
||||||
|
ssh_packet_set_callbacks(session, &ssh_sntrup761x25519_client_callbacks);
|
||||||
|
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssh_client_sntrup761x25519_remove_callbacks(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_packet_remove_callbacks(session, &ssh_sntrup761x25519_client_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssh_sntrup761x25519_build_k(ssh_session session)
|
||||||
|
{
|
||||||
|
unsigned char ssk[SNTRUP761_SIZE + CURVE25519_PUBKEY_SIZE];
|
||||||
|
unsigned char *k = ssk + SNTRUP761_SIZE;
|
||||||
|
unsigned char hss[SHA512_DIGEST_LEN];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_curve25519_create_k(session, k);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_log_hexdump("Curve25519 shared secret", k, CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (session->server) {
|
||||||
|
sntrup761_enc(session->next_crypto->sntrup761_ciphertext,
|
||||||
|
ssk,
|
||||||
|
session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
&rc,
|
||||||
|
crypto_random);
|
||||||
|
if (rc != 1) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sntrup761_dec(ssk,
|
||||||
|
session->next_crypto->sntrup761_ciphertext,
|
||||||
|
session->next_crypto->sntrup761_privkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_log_hexdump("server cipher text",
|
||||||
|
session->next_crypto->sntrup761_ciphertext,
|
||||||
|
SNTRUP761_CIPHERTEXT_SIZE);
|
||||||
|
ssh_log_hexdump("kem key", ssk, SNTRUP761_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sha512(ssk, sizeof ssk, hss);
|
||||||
|
|
||||||
|
bignum_bin2bn(hss, sizeof hss, &session->next_crypto->shared_secret);
|
||||||
|
if (session->next_crypto->shared_secret == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
|
||||||
|
* a SSH_MSG_NEWKEYS
|
||||||
|
*/
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_sntrup761x25519_reply)
|
||||||
|
{
|
||||||
|
ssh_string q_s_string = NULL;
|
||||||
|
ssh_string pubkey_blob = NULL;
|
||||||
|
ssh_string signature = NULL;
|
||||||
|
int rc;
|
||||||
|
(void)type;
|
||||||
|
(void)user;
|
||||||
|
|
||||||
|
ssh_client_sntrup761x25519_remove_callbacks(session);
|
||||||
|
|
||||||
|
pubkey_blob = ssh_buffer_get_ssh_string(packet);
|
||||||
|
if (pubkey_blob == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No public key in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||||
|
SSH_STRING_FREE(pubkey_blob);
|
||||||
|
if (rc != 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Failed to import next public key");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
q_s_string = ssh_buffer_get_ssh_string(packet);
|
||||||
|
if (q_s_string == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No sntrup761x25519 Q_S in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (ssh_string_len(q_s_string) != (SNTRUP761_CIPHERTEXT_SIZE + CURVE25519_PUBKEY_SIZE)) {
|
||||||
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
|
"Incorrect size for server sntrup761x25519 ciphertext+key: %d",
|
||||||
|
(int)ssh_string_len(q_s_string));
|
||||||
|
SSH_STRING_FREE(q_s_string);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memcpy(session->next_crypto->sntrup761_ciphertext,
|
||||||
|
ssh_string_data(q_s_string),
|
||||||
|
SNTRUP761_CIPHERTEXT_SIZE);
|
||||||
|
memcpy(session->next_crypto->curve25519_server_pubkey,
|
||||||
|
(char *)ssh_string_data(q_s_string) + SNTRUP761_CIPHERTEXT_SIZE,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
SSH_STRING_FREE(q_s_string);
|
||||||
|
|
||||||
|
signature = ssh_buffer_get_ssh_string(packet);
|
||||||
|
if (signature == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No signature in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
session->next_crypto->dh_server_signature = signature;
|
||||||
|
signature = NULL; /* ownership changed */
|
||||||
|
/* TODO: verify signature now instead of waiting for NEWKEYS */
|
||||||
|
if (ssh_sntrup761x25519_build_k(session) < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the MSG_NEWKEYS */
|
||||||
|
if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent");
|
||||||
|
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
|
||||||
|
error:
|
||||||
|
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER
|
||||||
|
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_server_sntrup761x25519_init);
|
||||||
|
|
||||||
|
static ssh_packet_callback dh_server_callbacks[] = {
|
||||||
|
ssh_packet_server_sntrup761x25519_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ssh_packet_callbacks_struct ssh_sntrup761x25519_server_callbacks =
|
||||||
|
{
|
||||||
|
.start = SSH2_MSG_KEX_ECDH_INIT,
|
||||||
|
.n_callbacks = 1,
|
||||||
|
.callbacks = dh_server_callbacks,
|
||||||
|
.user = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief sets up the sntrup761x25519-sha512@openssh.com kex callbacks
|
||||||
|
*/
|
||||||
|
void ssh_server_sntrup761x25519_init(ssh_session session)
|
||||||
|
{
|
||||||
|
/* register the packet callbacks */
|
||||||
|
ssh_packet_set_callbacks(session, &ssh_sntrup761x25519_server_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||||
|
* SSH_MSG_KEXDH_REPLY
|
||||||
|
*/
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_server_sntrup761x25519_init)
|
||||||
|
{
|
||||||
|
/* ECDH/SNTRUP761 keys */
|
||||||
|
ssh_string q_c_string = NULL;
|
||||||
|
ssh_string q_s_string = NULL;
|
||||||
|
ssh_string server_pubkey_blob = NULL;
|
||||||
|
|
||||||
|
/* SSH host keys (rsa, ed25519 and ecdsa) */
|
||||||
|
ssh_key privkey = NULL;
|
||||||
|
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||||
|
ssh_string sig_blob = NULL;
|
||||||
|
int rc;
|
||||||
|
(void)type;
|
||||||
|
(void)user;
|
||||||
|
|
||||||
|
ssh_packet_remove_callbacks(session, &ssh_sntrup761x25519_server_callbacks);
|
||||||
|
|
||||||
|
/* Extract the client pubkey from the init packet */
|
||||||
|
q_c_string = ssh_buffer_get_ssh_string(packet);
|
||||||
|
if (q_c_string == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No sntrup761x25519 Q_C in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (ssh_string_len(q_c_string) != (SNTRUP761_PUBLICKEY_SIZE + CURVE25519_PUBKEY_SIZE)) {
|
||||||
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
|
"Incorrect size for server sntrup761x25519 public key: %zu",
|
||||||
|
ssh_string_len(q_c_string));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
ssh_string_data(q_c_string),
|
||||||
|
SNTRUP761_PUBLICKEY_SIZE);
|
||||||
|
memcpy(session->next_crypto->curve25519_client_pubkey,
|
||||||
|
((char *)ssh_string_data(q_c_string)) + SNTRUP761_PUBLICKEY_SIZE,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
SSH_STRING_FREE(q_c_string);
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_log_hexdump("client public key sntrup761",
|
||||||
|
session->next_crypto->sntrup761_client_pubkey,
|
||||||
|
SNTRUP761_PUBLICKEY_SIZE);
|
||||||
|
ssh_log_hexdump("client public key c25519",
|
||||||
|
session->next_crypto->curve25519_client_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Build server's key pair */
|
||||||
|
rc = ssh_sntrup761x25519_init(session);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Failed to generate sntrup761 keys");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build k and session_id */
|
||||||
|
rc = ssh_sntrup761x25519_build_k(session);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* privkey is not allocated */
|
||||||
|
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_make_sessionid(session);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_dh_get_next_server_publickey_blob(session, &server_pubkey_blob);
|
||||||
|
if (rc != 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not export server public key");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add host's public key */
|
||||||
|
rc = ssh_buffer_add_ssh_string(session->out_buffer, server_pubkey_blob);
|
||||||
|
SSH_STRING_FREE(server_pubkey_blob);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add ecdh public key */
|
||||||
|
rc = ssh_buffer_add_u32(session->out_buffer,
|
||||||
|
ntohl(SNTRUP761_CIPHERTEXT_SIZE
|
||||||
|
+ CURVE25519_PUBKEY_SIZE));
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_buffer_add_data(session->out_buffer,
|
||||||
|
session->next_crypto->sntrup761_ciphertext,
|
||||||
|
SNTRUP761_CIPHERTEXT_SIZE);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_buffer_add_data(session->out_buffer,
|
||||||
|
session->next_crypto->curve25519_server_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_log_hexdump("server public key c25519",
|
||||||
|
session->next_crypto->curve25519_server_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* add signature blob */
|
||||||
|
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||||
|
if (sig_blob == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_buffer_add_ssh_string(session->out_buffer, sig_blob);
|
||||||
|
SSH_STRING_FREE(sig_blob);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_log_hexdump("ECDH_REPLY:",
|
||||||
|
ssh_buffer_get(session->out_buffer),
|
||||||
|
ssh_buffer_get_len(session->out_buffer));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEX_ECDH_REPLY sent");
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the MSG_NEWKEYS */
|
||||||
|
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
|
||||||
|
if (rc < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent");
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
error:
|
||||||
|
SSH_STRING_FREE(q_c_string);
|
||||||
|
SSH_STRING_FREE(q_s_string);
|
||||||
|
ssh_buffer_reinit(session->out_buffer);
|
||||||
|
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
#endif /* HAVE_SNTRUP761 */
|
@ -48,8 +48,9 @@
|
|||||||
#ifdef WITH_GEX
|
#ifdef WITH_GEX
|
||||||
#include "libssh/dh-gex.h"
|
#include "libssh/dh-gex.h"
|
||||||
#endif /* WITH_GEX */
|
#endif /* WITH_GEX */
|
||||||
#include "libssh/ecdh.h"
|
|
||||||
#include "libssh/curve25519.h"
|
#include "libssh/curve25519.h"
|
||||||
|
#include "libssh/ecdh.h"
|
||||||
|
#include "libssh/sntrup761.h"
|
||||||
|
|
||||||
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
||||||
{ "hmac-sha1", SSH_HMAC_SHA1, false },
|
{ "hmac-sha1", SSH_HMAC_SHA1, false },
|
||||||
@ -586,6 +587,11 @@ int crypt_set_algorithms_server(ssh_session session){
|
|||||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
ssh_server_curve25519_init(session);
|
ssh_server_curve25519_init(session);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SNTRUP761
|
||||||
|
case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
|
||||||
|
ssh_server_sntrup761x25519_init(session);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session,
|
ssh_set_error(session,
|
||||||
|
@ -135,6 +135,7 @@ if (SSH_EXECUTABLE)
|
|||||||
diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group14-sha256
|
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-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
|
diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521
|
||||||
|
sntrup761x25519-sha512@openssh.com
|
||||||
curve25519-sha256 curve25519-sha256@libssh.org
|
curve25519-sha256 curve25519-sha256@libssh.org
|
||||||
ssh-ed25519 ssh-ed25519-cert-v01@openssh.com ssh-rsa
|
ssh-ed25519 ssh-ed25519-cert-v01@openssh.com ssh-rsa
|
||||||
ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
|
ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
|
||||||
|
@ -718,6 +718,23 @@ static void torture_algorithms_ecdh_curve25519_sha256_libssh_org(void **state) {
|
|||||||
}
|
}
|
||||||
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
||||||
|
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
static void
|
||||||
|
torture_algorithms_ecdh_sntrup761x25519_sha512_openssh_com(void **state)
|
||||||
|
{
|
||||||
|
struct torture_state *s = *state;
|
||||||
|
|
||||||
|
if (ssh_fips_mode()) {
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
test_algorithm(s->ssh.session,
|
||||||
|
"sntrup761x25519-sha512@openssh.com",
|
||||||
|
NULL /*cipher*/,
|
||||||
|
NULL /*hmac*/);
|
||||||
|
}
|
||||||
|
#endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */
|
||||||
|
|
||||||
static void torture_algorithms_dh_group1(void **state) {
|
static void torture_algorithms_dh_group1(void **state) {
|
||||||
struct torture_state *s = *state;
|
struct torture_state *s = *state;
|
||||||
|
|
||||||
@ -985,6 +1002,11 @@ int torture_run_tests(void) {
|
|||||||
session_setup,
|
session_setup,
|
||||||
session_teardown),
|
session_teardown),
|
||||||
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_sntrup761x25519_sha512_openssh_com,
|
||||||
|
session_setup,
|
||||||
|
session_teardown),
|
||||||
|
#endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */
|
||||||
#if defined(HAVE_ECC)
|
#if defined(HAVE_ECC)
|
||||||
cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_sha2_nistp256,
|
cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_sha2_nistp256,
|
||||||
session_setup,
|
session_setup,
|
||||||
|
@ -255,6 +255,37 @@ static void torture_override_ecdh_curve25519_sha256_libssh_org(void **state)
|
|||||||
}
|
}
|
||||||
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
||||||
|
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
static void
|
||||||
|
torture_override_ecdh_sntrup761x25519_sha512_openssh_com(void **state)
|
||||||
|
{
|
||||||
|
struct torture_state *s = *state;
|
||||||
|
bool internal_curve25519_called;
|
||||||
|
|
||||||
|
if (ssh_fips_mode()) {
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
test_algorithm(s->ssh.session,
|
||||||
|
"sntrup761x25519-sha512@openssh.com",
|
||||||
|
NULL, /* cipher */
|
||||||
|
NULL /* hostkey */);
|
||||||
|
|
||||||
|
internal_curve25519_called = internal_curve25519_function_called();
|
||||||
|
|
||||||
|
/* TODO: when non-internal sntrup761 is supported, this is a good
|
||||||
|
place to add override checks of the sntrup761-related functions
|
||||||
|
too. Currently none of our external crypto libraries supports
|
||||||
|
sntrup761. */
|
||||||
|
|
||||||
|
#if SHOULD_CALL_INTERNAL_CURVE25519
|
||||||
|
assert_true(internal_curve25519_called);
|
||||||
|
#else
|
||||||
|
assert_false(internal_curve25519_called);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */
|
||||||
|
|
||||||
#ifdef OPENSSH_SSH_ED25519
|
#ifdef OPENSSH_SSH_ED25519
|
||||||
static void torture_override_ed25519(void **state)
|
static void torture_override_ed25519(void **state)
|
||||||
{
|
{
|
||||||
@ -299,6 +330,11 @@ int torture_run_tests(void)
|
|||||||
session_setup,
|
session_setup,
|
||||||
session_teardown),
|
session_teardown),
|
||||||
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
#endif /* OPENSSH_CURVE25519_SHA256_LIBSSH_ORG */
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
cmocka_unit_test_setup_teardown(torture_override_ecdh_sntrup761x25519_sha512_openssh_com,
|
||||||
|
session_setup,
|
||||||
|
session_teardown),
|
||||||
|
#endif /* OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM */
|
||||||
#ifdef OPENSSH_SSH_ED25519
|
#ifdef OPENSSH_SSH_ED25519
|
||||||
cmocka_unit_test_setup_teardown(torture_override_ed25519,
|
cmocka_unit_test_setup_teardown(torture_override_ed25519,
|
||||||
session_setup,
|
session_setup,
|
||||||
|
@ -280,8 +280,19 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
|||||||
f(client, ecdsa_521_diffie_hellman_group18_sha512,kexcmd("diffie-hellman-group18-sha512"), setup_ecdsa_521, teardown)
|
f(client, ecdsa_521_diffie_hellman_group18_sha512,kexcmd("diffie-hellman-group18-sha512"), setup_ecdsa_521, teardown)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
#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)
|
||||||
|
#else
|
||||||
|
#define PKDTESTS_KEX_SNTRUP761(f, client, kexcmd)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PKDTESTS_KEX_COMMON(f, client, kexcmd) \
|
#define PKDTESTS_KEX_COMMON(f, client, kexcmd) \
|
||||||
PKDTESTS_KEX_FIPS(f, client, kexcmd) \
|
PKDTESTS_KEX_FIPS(f, client, kexcmd) \
|
||||||
|
PKDTESTS_KEX_SNTRUP761(f, client, kexcmd) \
|
||||||
f(client, rsa_curve25519_sha256, kexcmd("curve25519-sha256"), setup_rsa, teardown) \
|
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_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) \
|
f(client, rsa_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_rsa, teardown) \
|
||||||
@ -314,8 +325,16 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
|||||||
PKDTESTS_KEX_COMMON(f, client, kexcmd)
|
PKDTESTS_KEX_COMMON(f, client, kexcmd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM
|
||||||
|
#define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd) \
|
||||||
|
f(client, ed25519_sntrup761x25519_sha512_openssh_com, kexcmd("sntrup761x25519-sha512@openssh.com"), setup_ed25519, teardown)
|
||||||
|
#else
|
||||||
|
#define PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PKDTESTS_KEX_OPENSSHONLY(f, client, kexcmd) \
|
#define PKDTESTS_KEX_OPENSSHONLY(f, client, kexcmd) \
|
||||||
/* Kex algorithms. */ \
|
/* Kex algorithms. */ \
|
||||||
|
PKDTESTS_KEX_OPENSSHONLY_SNTRUP761(f, client, kexcmd) \
|
||||||
f(client, ed25519_curve25519_sha256, kexcmd("curve25519-sha256"), setup_ed25519, teardown) \
|
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_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) \
|
f(client, ed25519_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256"), setup_ed25519, teardown) \
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#cmakedefine OPENSSH_ECDH_SHA2_NISTP521 1
|
#cmakedefine OPENSSH_ECDH_SHA2_NISTP521 1
|
||||||
#cmakedefine OPENSSH_CURVE25519_SHA256 1
|
#cmakedefine OPENSSH_CURVE25519_SHA256 1
|
||||||
#cmakedefine OPENSSH_CURVE25519_SHA256_LIBSSH_ORG 1
|
#cmakedefine OPENSSH_CURVE25519_SHA256_LIBSSH_ORG 1
|
||||||
|
#cmakedefine OPENSSH_SNTRUP761X25519_SHA512_OPENSSH_COM 1
|
||||||
#cmakedefine OPENSSH_SSH_ED25519 1
|
#cmakedefine OPENSSH_SSH_ED25519 1
|
||||||
#cmakedefine OPENSSH_SSH_ED25519_CERT_V01_OPENSSH_COM 1
|
#cmakedefine OPENSSH_SSH_ED25519_CERT_V01_OPENSSH_COM 1
|
||||||
#cmakedefine OPENSSH_SSH_RSA 1
|
#cmakedefine OPENSSH_SSH_RSA 1
|
||||||
|
@ -216,6 +216,7 @@ static void torture_options_set_key_exchange(void **state)
|
|||||||
/* Test known kexes */
|
/* Test known kexes */
|
||||||
rc = ssh_options_set(session,
|
rc = ssh_options_set(session,
|
||||||
SSH_OPTIONS_KEY_EXCHANGE,
|
SSH_OPTIONS_KEY_EXCHANGE,
|
||||||
|
"sntrup761x25519-sha512@openssh.com,"
|
||||||
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
||||||
"ecdh-sha2-nistp256,diffie-hellman-group16-sha512,"
|
"ecdh-sha2-nistp256,diffie-hellman-group16-sha512,"
|
||||||
"diffie-hellman-group18-sha512,"
|
"diffie-hellman-group18-sha512,"
|
||||||
@ -230,6 +231,7 @@ static void torture_options_set_key_exchange(void **state)
|
|||||||
"diffie-hellman-group14-sha256");
|
"diffie-hellman-group14-sha256");
|
||||||
} else {
|
} else {
|
||||||
assert_string_equal(session->opts.wanted_methods[SSH_KEX],
|
assert_string_equal(session->opts.wanted_methods[SSH_KEX],
|
||||||
|
"sntrup761x25519-sha512@openssh.com,"
|
||||||
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
||||||
"ecdh-sha2-nistp256,diffie-hellman-group16-sha512,"
|
"ecdh-sha2-nistp256,diffie-hellman-group16-sha512,"
|
||||||
"diffie-hellman-group18-sha512,"
|
"diffie-hellman-group18-sha512,"
|
||||||
@ -278,6 +280,7 @@ static void torture_options_get_key_exchange(void **state)
|
|||||||
} else {
|
} else {
|
||||||
assert_string_equal(value,
|
assert_string_equal(value,
|
||||||
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
"curve25519-sha256,curve25519-sha256@libssh.org,"
|
||||||
|
"sntrup761x25519-sha512@openssh.com,"
|
||||||
"ecdh-sha2-nistp256,ecdh-sha2-nistp384,"
|
"ecdh-sha2-nistp256,ecdh-sha2-nistp384,"
|
||||||
"ecdh-sha2-nistp521,diffie-hellman-group18-sha512,"
|
"ecdh-sha2-nistp521,diffie-hellman-group18-sha512,"
|
||||||
"diffie-hellman-group16-sha512,"
|
"diffie-hellman-group16-sha512,"
|
||||||
@ -1312,7 +1315,7 @@ static void torture_options_copy(void **state)
|
|||||||
"BindAddress 127.0.0.2\n"
|
"BindAddress 127.0.0.2\n"
|
||||||
"GlobalKnownHostsFile /etc/ssh/known_hosts2\n"
|
"GlobalKnownHostsFile /etc/ssh/known_hosts2\n"
|
||||||
"UserKnownHostsFile ~/.ssh/known_hosts2\n"
|
"UserKnownHostsFile ~/.ssh/known_hosts2\n"
|
||||||
"KexAlgorithms curve25519-sha256,ecdh-sha2-nistp521\n"
|
"KexAlgorithms curve25519-sha256,sntrup761x25519-sha512@openssh.com,ecdh-sha2-nistp521\n"
|
||||||
"Ciphers aes256-ctr\n"
|
"Ciphers aes256-ctr\n"
|
||||||
"MACs hmac-sha2-256\n"
|
"MACs hmac-sha2-256\n"
|
||||||
"HostKeyAlgorithms ssh-ed25519,ecdsa-sha2-nistp521\n"
|
"HostKeyAlgorithms ssh-ed25519,ecdsa-sha2-nistp521\n"
|
||||||
|
Reference in New Issue
Block a user