diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e30ca7e..8fa0e5d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -120,7 +120,6 @@ set(libssh_SRCS wrapper.c external/bcrypt_pbkdf.c external/blowfish.c - external/sntrup761.c config_parser.c token.c pki_ed25519_common.c @@ -192,6 +191,7 @@ elseif (WITH_MBEDTLS) external/fe25519.c external/ge25519.c external/sc25519.c + external/sntrup761.c ) if (NOT (HAVE_MBEDTLS_CHACHA20_H AND HAVE_MBEDTLS_POLY1305_H)) set(libssh_SRCS @@ -212,6 +212,7 @@ else (WITH_GCRYPT) md_crypto.c libcrypto.c dh_crypto.c + external/sntrup761.c ) if (NOT HAVE_OPENSSL_EVP_CHACHA20) set(libssh_SRCS diff --git a/src/sntrup761.c b/src/sntrup761.c index ced7cd8a..52623d0c 100644 --- a/src/sntrup761.c +++ b/src/sntrup761.c @@ -44,11 +44,13 @@ void crypto_hash_sha512(unsigned char *out, sha512(in, inlen, out); } +#ifndef HAVE_LIBGCRYPT static void crypto_random(void *ctx, size_t length, uint8_t *dst) { int *err = ctx; *err = ssh_get_random(dst, length, 1); } +#endif /* HAVE_LIBGCRYPT */ static SSH_PACKET_CALLBACK(ssh_packet_client_sntrup761x25519_reply); @@ -74,6 +76,21 @@ static int ssh_sntrup761x25519_init(ssh_session session) } if (!session->server) { +#ifdef HAVE_LIBGCRYPT + gcry_error_t err; + + err = gcry_kem_keypair(GCRY_KEM_SNTRUP761, + session->next_crypto->sntrup761_client_pubkey, + SNTRUP761_PUBLICKEY_SIZE, + session->next_crypto->sntrup761_privkey, + SNTRUP761_SECRETKEY_SIZE); + if (err) { + SSH_LOG(SSH_LOG_TRACE, + "Failed to generate sntrup761 key: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +#else sntrup761_keypair(session->next_crypto->sntrup761_client_pubkey, session->next_crypto->sntrup761_privkey, &rc, @@ -83,6 +100,7 @@ static int ssh_sntrup761x25519_init(ssh_session session) "Failed to generate sntrup761 key: PRNG failure"); return SSH_ERROR; } +#endif /* HAVE_LIBGCRYPT */ } return SSH_OK; @@ -142,6 +160,43 @@ static int ssh_sntrup761x25519_build_k(ssh_session session) ssh_log_hexdump("Curve25519 shared secret", k, CURVE25519_PUBKEY_SIZE); #endif +#ifdef HAVE_LIBGCRYPT + if (session->server) { + gcry_error_t err; + err = gcry_kem_encap(GCRY_KEM_SNTRUP761, + session->next_crypto->sntrup761_client_pubkey, + SNTRUP761_PUBLICKEY_SIZE, + session->next_crypto->sntrup761_ciphertext, + SNTRUP761_CIPHERTEXT_SIZE, + ssk, + SNTRUP761_SIZE, + NULL, + 0); + if (err) { + SSH_LOG(SSH_LOG_TRACE, + "Failed to encapsulate sntrup761 shared secret: %s", + gpg_strerror(err)); + return SSH_ERROR; + } + } else { + gcry_error_t err; + err = gcry_kem_decap(GCRY_KEM_SNTRUP761, + session->next_crypto->sntrup761_privkey, + SNTRUP761_SECRETKEY_SIZE, + session->next_crypto->sntrup761_ciphertext, + SNTRUP761_CIPHERTEXT_SIZE, + ssk, + SNTRUP761_SIZE, + NULL, + 0); + if (err) { + SSH_LOG(SSH_LOG_TRACE, + "Failed to decapsulate sntrup761 shared secret: %s", + gpg_strerror(err)); + return SSH_ERROR; + } + } +#else if (session->server) { sntrup761_enc(session->next_crypto->sntrup761_ciphertext, ssk, @@ -156,6 +211,7 @@ static int ssh_sntrup761x25519_build_k(ssh_session session) session->next_crypto->sntrup761_ciphertext, session->next_crypto->sntrup761_privkey); } +#endif /* HAVE_LIBGCRYPT */ #ifdef DEBUG_CRYPTO ssh_log_hexdump("server cipher text",