1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-08 03:42:12 +03:00

curve25519: Avoid reading private curve25519 keys from OpenSSL structures

The previous code created private key curve25519 in OpenSSL, then exported
private key and during key generation, created a new OpenSSL private key object.
This is needless amount of copying potentially sensitive data back and forth and
this will not work when the private key would be backed with external OpenSSL
provider, such as pkcs11 provider or different crypto accelerator handling the
private key operations for us.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
This commit is contained in:
Jakub Jelen
2024-11-05 12:42:14 +01:00
parent d0ecb5388c
commit e2524538f6
3 changed files with 14 additions and 23 deletions

View File

@@ -125,7 +125,11 @@ struct ssh_crypto_struct {
ssh_string ecdh_server_pubkey; ssh_string ecdh_server_pubkey;
#endif #endif
#ifdef HAVE_CURVE25519 #ifdef HAVE_CURVE25519
#ifdef HAVE_LIBCRYPTO
EVP_PKEY *curve25519_privkey;
#else
ssh_curve25519_privkey curve25519_privkey; ssh_curve25519_privkey curve25519_privkey;
#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 #endif

View File

@@ -62,8 +62,8 @@ static int ssh_curve25519_init(ssh_session session)
#ifdef HAVE_LIBCRYPTO #ifdef HAVE_LIBCRYPTO
EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL; EVP_PKEY *pkey = NULL;
ssh_curve25519_pubkey *pubkey_loc = NULL;
size_t pubkey_len = CURVE25519_PUBKEY_SIZE; size_t pubkey_len = CURVE25519_PUBKEY_SIZE;
size_t pkey_len = CURVE25519_PRIVKEY_SIZE;
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
if (pctx == NULL) { if (pctx == NULL) {
@@ -92,15 +92,12 @@ static int ssh_curve25519_init(ssh_session session)
} }
if (session->server) { if (session->server) {
rc = EVP_PKEY_get_raw_public_key(pkey, pubkey_loc = &session->next_crypto->curve25519_server_pubkey;
session->next_crypto->curve25519_server_pubkey,
&pubkey_len);
} else { } else {
rc = EVP_PKEY_get_raw_public_key(pkey, pubkey_loc = &session->next_crypto->curve25519_client_pubkey;
session->next_crypto->curve25519_client_pubkey,
&pubkey_len);
} }
rc = EVP_PKEY_get_raw_public_key(pkey, *pubkey_loc, &pubkey_len);
if (rc != 1) { if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE,
"Failed to get X25519 raw public key: %s", "Failed to get X25519 raw public key: %s",
@@ -109,18 +106,8 @@ static int ssh_curve25519_init(ssh_session session)
return SSH_ERROR; return SSH_ERROR;
} }
rc = EVP_PKEY_get_raw_private_key(pkey, session->next_crypto->curve25519_privkey = pkey;
session->next_crypto->curve25519_privkey, pkey = NULL;
&pkey_len);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to get X25519 raw private key: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
return SSH_ERROR;
}
EVP_PKEY_free(pkey);
#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);
@@ -187,9 +174,7 @@ static int ssh_curve25519_build_k(ssh_session session)
size_t shared_key_len = sizeof(k); size_t shared_key_len = sizeof(k);
int rc, ret = SSH_ERROR; int rc, ret = SSH_ERROR;
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, pkey = session->next_crypto->curve25519_privkey;
session->next_crypto->curve25519_privkey,
CURVE25519_PRIVKEY_SIZE);
if (pkey == NULL) { if (pkey == NULL) {
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE,
"Failed to create X25519 EVP_PKEY: %s", "Failed to create X25519 EVP_PKEY: %s",
@@ -246,7 +231,6 @@ static int ssh_curve25519_build_k(ssh_session session)
} }
ret = SSH_OK; ret = SSH_OK;
out: out:
EVP_PKEY_free(pkey);
EVP_PKEY_free(pubkey); EVP_PKEY_free(pubkey);
EVP_PKEY_CTX_free(pctx); EVP_PKEY_CTX_free(pctx);
if (ret == SSH_ERROR) { if (ret == SSH_ERROR) {

View File

@@ -188,6 +188,9 @@ void crypto_free(struct ssh_crypto_struct *crypto)
#endif #endif
crypto->ecdh_privkey = NULL; crypto->ecdh_privkey = NULL;
} }
#endif
#ifdef HAVE_LIBCRYPTO
EVP_PKEY_free(crypto->curve25519_privkey);
#endif #endif
SAFE_FREE(crypto->dh_server_signature); SAFE_FREE(crypto->dh_server_signature);
if (crypto->session_id != NULL) { if (crypto->session_id != NULL) {