mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-12 11:10:28 +09:00
curve25519: Use mbedTLS curve25519 for ECDH, if available
Signed-off-by: Praneeth Sarode <praneethsarode@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
committed by
Jakub Jelen
parent
84d02e7440
commit
49a355c272
@@ -236,6 +236,20 @@ if (MBEDTLS_FOUND)
|
|||||||
set(CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIR}/mbedtls")
|
set(CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIR}/mbedtls")
|
||||||
check_include_file(chacha20.h HAVE_MBEDTLS_CHACHA20_H)
|
check_include_file(chacha20.h HAVE_MBEDTLS_CHACHA20_H)
|
||||||
check_include_file(poly1305.h HAVE_MBEDTLS_POLY1305_H)
|
check_include_file(poly1305.h HAVE_MBEDTLS_POLY1305_H)
|
||||||
|
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIR}")
|
||||||
|
check_c_source_compiles("
|
||||||
|
#include <mbedtls/ecp.h>
|
||||||
|
int main() {
|
||||||
|
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
#error \"X25519 not supported\"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
" HAVE_MBEDTLS_CURVE25519)
|
||||||
|
|
||||||
if (WITH_BLOWFISH_CIPHER)
|
if (WITH_BLOWFISH_CIPHER)
|
||||||
check_include_file(blowfish.h HAVE_BLOWFISH)
|
check_include_file(blowfish.h HAVE_BLOWFISH)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -87,6 +87,9 @@
|
|||||||
/* Define to 1 if you have elliptic curve cryptography in openssl */
|
/* Define to 1 if you have elliptic curve cryptography in openssl */
|
||||||
#cmakedefine HAVE_OPENSSL_ECC 1
|
#cmakedefine HAVE_OPENSSL_ECC 1
|
||||||
|
|
||||||
|
/* Define to 1 if mbedTLS supports curve25519 */
|
||||||
|
#cmakedefine HAVE_MBEDTLS_CURVE25519 1
|
||||||
|
|
||||||
/* Define to 1 if you have elliptic curve cryptography in gcrypt */
|
/* Define to 1 if you have elliptic curve cryptography in gcrypt */
|
||||||
#cmakedefine HAVE_GCRYPT_ECC 1
|
#cmakedefine HAVE_GCRYPT_ECC 1
|
||||||
|
|
||||||
|
|||||||
225
src/curve25519.c
225
src/curve25519.c
@@ -41,6 +41,10 @@
|
|||||||
|
|
||||||
#ifdef HAVE_LIBCRYPTO
|
#ifdef HAVE_LIBCRYPTO
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#elif defined(HAVE_MBEDTLS_CURVE25519)
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
|
#include <mbedtls/ecdh.h>
|
||||||
|
#include <mbedtls/error.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply);
|
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply);
|
||||||
@@ -108,6 +112,102 @@ int ssh_curve25519_init(ssh_session session)
|
|||||||
|
|
||||||
session->next_crypto->curve25519_privkey = pkey;
|
session->next_crypto->curve25519_privkey = pkey;
|
||||||
pkey = NULL;
|
pkey = NULL;
|
||||||
|
|
||||||
|
#elif defined(HAVE_MBEDTLS_CURVE25519)
|
||||||
|
mbedtls_ecdh_context ecdh_ctx;
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = NULL;
|
||||||
|
ssh_curve25519_pubkey *pubkey_loc = NULL;
|
||||||
|
char error_buf[128];
|
||||||
|
int ret = SSH_ERROR;
|
||||||
|
|
||||||
|
ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
|
||||||
|
mbedtls_ecdh_init(&ecdh_ctx);
|
||||||
|
rc = mbedtls_ecdh_setup(&ecdh_ctx, MBEDTLS_ECP_DP_CURVE25519);
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to setup X25519 context: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_ecdh_gen_public(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(grp),
|
||||||
|
&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(d),
|
||||||
|
&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(Q),
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_ecdh_gen_public(&ecdh_ctx.grp,
|
||||||
|
&ecdh_ctx.d,
|
||||||
|
&ecdh_ctx.Q,
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
|
"Failed to generate X25519 keypair: %s",
|
||||||
|
error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->server) {
|
||||||
|
pubkey_loc = &session->next_crypto->curve25519_server_pubkey;
|
||||||
|
} else {
|
||||||
|
pubkey_loc = &session->next_crypto->curve25519_client_pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(d),
|
||||||
|
session->next_crypto->curve25519_privkey,
|
||||||
|
CURVE25519_PRIVKEY_SIZE);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.d,
|
||||||
|
session->next_crypto->curve25519_privkey,
|
||||||
|
CURVE25519_PRIVKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
|
"Failed to write X25519 private key: %s",
|
||||||
|
error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(Q)
|
||||||
|
.MBEDTLS_PRIVATE(X),
|
||||||
|
*pubkey_loc,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.Q.X,
|
||||||
|
*pubkey_loc,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
|
"Failed to write X25519 public key: %s",
|
||||||
|
error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SSH_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mbedtls_ecdh_free(&ecdh_ctx);
|
||||||
|
return ret;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
rc = ssh_get_random(session->next_crypto->curve25519_privkey,
|
rc = ssh_get_random(session->next_crypto->curve25519_privkey,
|
||||||
CURVE25519_PRIVKEY_SIZE, 1);
|
CURVE25519_PRIVKEY_SIZE, 1);
|
||||||
@@ -234,6 +334,131 @@ out:
|
|||||||
if (ret == SSH_ERROR) {
|
if (ret == SSH_ERROR) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_MBEDTLS_CURVE25519)
|
||||||
|
mbedtls_ecdh_context ecdh_ctx;
|
||||||
|
mbedtls_ctr_drbg_context *ctr_drbg = NULL;
|
||||||
|
ssh_curve25519_pubkey *peer_pubkey_loc = NULL;
|
||||||
|
char error_buf[128];
|
||||||
|
int rc, ret = SSH_ERROR;
|
||||||
|
|
||||||
|
ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
|
|
||||||
|
mbedtls_ecdh_init(&ecdh_ctx);
|
||||||
|
rc = mbedtls_ecdh_setup(&ecdh_ctx, MBEDTLS_ECP_DP_CURVE25519);
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to setup X25519 context: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_read_binary_le(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(d),
|
||||||
|
session->next_crypto->curve25519_privkey,
|
||||||
|
CURVE25519_PRIVKEY_SIZE);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_read_binary_le(&ecdh_ctx.d,
|
||||||
|
session->next_crypto->curve25519_privkey,
|
||||||
|
CURVE25519_PRIVKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to read private key: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->server) {
|
||||||
|
peer_pubkey_loc = &session->next_crypto->curve25519_client_pubkey;
|
||||||
|
} else {
|
||||||
|
peer_pubkey_loc = &session->next_crypto->curve25519_server_pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_read_binary_le(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(Qp)
|
||||||
|
.MBEDTLS_PRIVATE(X),
|
||||||
|
*peer_pubkey_loc,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_read_binary_le(&ecdh_ctx.Qp.X,
|
||||||
|
*peer_pubkey_loc,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to read peer public key: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_lset(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(Qp)
|
||||||
|
.MBEDTLS_PRIVATE(Z),
|
||||||
|
1);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_lset(&ecdh_ctx.Qp.Z, 1);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to set Z coordinate: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_ecdh_compute_shared(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(grp),
|
||||||
|
&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(z),
|
||||||
|
&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(Qp),
|
||||||
|
&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(d),
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_ecdh_compute_shared(&ecdh_ctx.grp,
|
||||||
|
&ecdh_ctx.z,
|
||||||
|
&ecdh_ctx.Qp,
|
||||||
|
&ecdh_ctx.d,
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE,
|
||||||
|
"Failed to compute shared secret: %s",
|
||||||
|
error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.MBEDTLS_PRIVATE(ctx)
|
||||||
|
.MBEDTLS_PRIVATE(mbed_ecdh)
|
||||||
|
.MBEDTLS_PRIVATE(z),
|
||||||
|
k,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
#else
|
||||||
|
rc = mbedtls_mpi_write_binary_le(&ecdh_ctx.z, k, CURVE25519_PUBKEY_SIZE);
|
||||||
|
#endif
|
||||||
|
if (rc != 0) {
|
||||||
|
mbedtls_strerror(rc, error_buf, sizeof(error_buf));
|
||||||
|
SSH_LOG(SSH_LOG_TRACE, "Failed to write shared secret: %s", error_buf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SSH_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mbedtls_ecdh_free(&ecdh_ctx);
|
||||||
|
return ret;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (session->server) {
|
if (session->server) {
|
||||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||||
|
|||||||
@@ -98,8 +98,14 @@ if (WITH_MBEDTLS)
|
|||||||
else ()
|
else ()
|
||||||
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_CHACHAPOLY=1")
|
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_CHACHAPOLY=1")
|
||||||
endif ()
|
endif ()
|
||||||
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_ED25519=1")
|
|
||||||
|
if(HAVE_MBEDTLS_CURVE25519)
|
||||||
|
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_CURVE25519=0")
|
||||||
|
else ()
|
||||||
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_CURVE25519=1")
|
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_CURVE25519=1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_ED25519=1")
|
||||||
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_SNTRUP761=1")
|
list(APPEND OVERRIDE_RESULTS "-DSHOULD_CALL_INTERNAL_SNTRUP761=1")
|
||||||
elseif (WITH_GCRYPT)
|
elseif (WITH_GCRYPT)
|
||||||
if (HAVE_GCRYPT_CHACHA_POLY)
|
if (HAVE_GCRYPT_CHACHA_POLY)
|
||||||
|
|||||||
Reference in New Issue
Block a user