Skip to content

Commit

Permalink
SCP11: Code optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
aveenismail committed Dec 3, 2024
1 parent 35fe6e1 commit 4434587
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 129 deletions.
56 changes: 56 additions & 0 deletions lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@

#ifdef USE_CERT_COMPRESS
#include <zlib.h>
#include <openssl/types.h>
#include <openssl/ec.h>
#include <openssl/evp.h>

#endif

#include "internal.h"
Expand Down Expand Up @@ -1860,3 +1864,55 @@ static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data,

return res;
}

ykpiv_rc get_ec_pubkey_from_bytes(int curve_name, uint8_t *point, size_t point_len, EVP_PKEY **pkey) {
ykpiv_rc rc = YKPIV_OK;
EC_POINT *ecpoint = NULL;
EC_KEY *eckey = NULL;
EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_name);
if(group == NULL)
return YKPIV_MEMORY_ERROR;
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
eckey = EC_KEY_new();
if(eckey == NULL) {
rc = YKPIV_MEMORY_ERROR;
goto create_ec_cleanup;
}
if(EC_KEY_set_group(eckey, group) <= 0) {
rc = YKPIV_GENERIC_ERROR;
goto create_ec_cleanup;
}
ecpoint = EC_POINT_new(group);
if(ecpoint == NULL) {
rc = YKPIV_MEMORY_ERROR;
goto create_ec_cleanup;
}
if(EC_POINT_oct2point(group, ecpoint, point, point_len, NULL) <= 0) {
rc = YKPIV_ARGUMENT_ERROR;
goto create_ec_cleanup;
}
if(EC_KEY_set_public_key(eckey, ecpoint) <= 0) {
rc = YKPIV_GENERIC_ERROR;
goto create_ec_cleanup;
}
EVP_PKEY_free(*pkey);
*pkey = EVP_PKEY_new();
if(*pkey == NULL) {
rc = YKPIV_MEMORY_ERROR;
goto create_ec_cleanup;
}
if(EVP_PKEY_assign_EC_KEY(*pkey, eckey) <= 0) {
rc = YKPIV_GENERIC_ERROR;
goto create_ec_cleanup;
}

create_ec_cleanup:
EC_GROUP_clear_free(group);
if(ecpoint != NULL) {
EC_POINT_clear_free(ecpoint);
}
if(rc != YKPIV_OK && eckey != NULL) {
EC_KEY_free(eckey);
}
return rc;
}
64 changes: 7 additions & 57 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,58 +390,7 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) {
return YKPIV_OK;
}

static EVP_PKEY *get_ec_pubkey_from_bytes(uint8_t *pubkey, uint8_t pubkey_len) {
EVP_PKEY *evp_pkey = NULL;
EC_GROUP *ecg = NULL;
EC_POINT *ecp = NULL;
EC_KEY *eckey = NULL;

ecg = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if(!ecg) {
DBG("Failed to create EC_GROUP");
return NULL;
}

ecp = EC_POINT_new(ecg);
if(!ecp) {
DBG("Failed to create EC_POINT");
goto ec_pubkey_cleanup;
}

if (EC_POINT_oct2point(ecg, ecp, pubkey, pubkey_len, NULL) == 0) {
DBG("Failed to parse public key as ec_point");
goto ec_pubkey_cleanup;
}

eckey = EC_KEY_new();
EC_KEY_set_group(eckey, ecg);
if (EC_KEY_set_public_key(eckey, ecp) == 0) {
DBG("Failed to convert sd pubkey point to eckey");
goto ec_pubkey_cleanup;
}

evp_pkey = EVP_PKEY_new();
if (!EVP_PKEY_assign_EC_KEY(evp_pkey, eckey)) {
DBG("Failed to convert sd pubkey eckey to evp_pkey");
goto ec_pubkey_cleanup;
}

return evp_pkey;

ec_pubkey_cleanup:
if(ecg) {
EC_GROUP_free(ecg);
}
if(ecp) {
EC_POINT_free(ecp);
}
if(eckey) {
EC_KEY_free(eckey);
}

return NULL;
}

#if (OPENSSL_VERSION_NUMBER > 0x10100000L)
static ykpiv_rc derive_ecdh(EVP_PKEY *private_key, EVP_PKEY *peer_key, uint8_t *ecdh_key, size_t ecdh_len) {
/* Create the context for the shared secret derivation */
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(private_key, NULL);
Expand Down Expand Up @@ -487,7 +436,7 @@ static ykpiv_rc derive_ecdh(EVP_PKEY *private_key, EVP_PKEY *peer_key, uint8_t *

return rc;
}
#if (OPENSSL_VERSION_NUMBER > 0x10100000L)

static EVP_PKEY* scp11_get_sd_pubkey(ykpiv_state *state) {
ykpiv_rc res;

Expand Down Expand Up @@ -527,10 +476,12 @@ static EVP_PKEY* scp11_get_sd_pubkey(ykpiv_state *state) {
static ykpiv_rc scp11_derive_session_keys(EC_KEY *ekeypair_oce, uint8_t *epubkey_sd_bytes,
size_t epubkey_sd_len, EVP_PKEY *pubkey_sd, uint8_t *session_keys) {

EVP_PKEY *epubkey_sd = get_ec_pubkey_from_bytes(epubkey_sd_bytes, epubkey_sd_len);
if (!epubkey_sd) {
ykpiv_rc rc = YKPIV_OK;
EVP_PKEY *epubkey_sd = NULL;
rc = get_ec_pubkey_from_bytes(NID_X9_62_prime256v1, epubkey_sd_bytes, epubkey_sd_len, &epubkey_sd);
if (rc != YKPIV_OK) {
DBG("Failed to convert sd pubkey bytes to evp_pkey");
return YKPIV_MEMORY_ERROR;
return rc;
}

EVP_PKEY *eprivkey_oce = EVP_PKEY_new();
Expand All @@ -539,7 +490,6 @@ static ykpiv_rc scp11_derive_session_keys(EC_KEY *ekeypair_oce, uint8_t *epubkey
return YKPIV_MEMORY_ERROR;
}

ykpiv_rc rc = YKPIV_OK;
if (!EVP_PKEY_assign_EC_KEY(eprivkey_oce, ekeypair_oce)) {
DBG("Failed to parse OCE ephemeral private key (eSK.OCE.ECKA)");
rc = YKPIV_AUTHENTICATION_ERROR;
Expand Down
2 changes: 2 additions & 0 deletions lib/ykpiv.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <openssl/types.h>

#include "ykpiv-config.h"

Expand Down Expand Up @@ -221,6 +222,7 @@ extern "C"
*/
ykpiv_rc ykpiv_get_serial(ykpiv_state *state, uint32_t* p_serial);

ykpiv_rc get_ec_pubkey_from_bytes(int curve_name, uint8_t *point, size_t point_len, EVP_PKEY **pkey);

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Expand Down
20 changes: 2 additions & 18 deletions tool/yubico-piv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,24 +360,8 @@ static bool generate_key(ykpiv_state *state, enum enum_slot slot,
} else {
nid = NID_secp384r1;
}
eckey = EC_KEY_new();
group = EC_GROUP_new_by_curve_name(nid);
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(eckey, group) != 1) {
fprintf(stderr, "Failed to set EC group.\n");
goto generate_out;
}
ecpoint = EC_POINT_new(group);

if (!EC_POINT_oct2point(group, ecpoint, point, point_len, NULL)) {
fprintf(stderr, "Failed to load public point.\n");
goto generate_out;
}
if (!EC_KEY_set_public_key(eckey, ecpoint)) {
fprintf(stderr, "Failed to set the public key.\n");
goto generate_out;
}
if (EVP_PKEY_set1_EC_KEY(public_key, eckey) != 1) {
res = get_ec_pubkey_from_bytes(nid, point, point_len, &public_key);
if(res != YKPIV_OK) {
fprintf(stderr, "Failed to set EC public key.\n");
goto generate_out;
}
Expand Down
54 changes: 1 addition & 53 deletions ykcs11/openssl_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,58 +164,6 @@ CK_RV do_generate_ec_key(int curve_name, ykcs11_pkey_t **pkey) {
return rv;
}

CK_RV do_create_ec_key(CK_BYTE_PTR point, CK_ULONG point_len, int curve_name, ykcs11_pkey_t **pkey) {
CK_RV rv;
EC_POINT *ecpoint = NULL;
EC_KEY *eckey = NULL;
EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_name);
if(group == NULL)
return CKR_HOST_MEMORY;
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
eckey = EC_KEY_new();
if(eckey == NULL) {
rv = CKR_HOST_MEMORY;
goto create_ec_cleanup;
}
if(EC_KEY_set_group(eckey, group) <= 0) {
rv = CKR_GENERAL_ERROR;
goto create_ec_cleanup;
}
ecpoint = EC_POINT_new(group);
if(ecpoint == NULL) {
rv = CKR_HOST_MEMORY;
goto create_ec_cleanup;
}
if(EC_POINT_oct2point(group, ecpoint, point, point_len, NULL) <= 0) {
rv = CKR_ARGUMENTS_BAD;
goto create_ec_cleanup;
}
if(EC_KEY_set_public_key(eckey, ecpoint) <= 0) {
rv = CKR_GENERAL_ERROR;
goto create_ec_cleanup;
}
EVP_PKEY_free(*pkey);
*pkey = EVP_PKEY_new();
if(*pkey == NULL) {
rv = CKR_HOST_MEMORY;
goto create_ec_cleanup;
}
if(EVP_PKEY_assign_EC_KEY(*pkey, eckey) <= 0) {
rv = CKR_GENERAL_ERROR;
goto create_ec_cleanup;
}
rv = CKR_OK;
create_ec_cleanup:
EC_GROUP_clear_free(group);
if(ecpoint != NULL) {
EC_POINT_clear_free(ecpoint);
}
if(rv != CKR_OK && eckey != NULL) {
EC_KEY_free(eckey);
}
return rv;
}

CK_RV do_create_rsa_key(CK_BYTE_PTR mod, CK_ULONG mod_len, CK_BYTE_PTR exp, CK_ULONG exp_len, ykcs11_pkey_t **pkey) {
CK_RV rv;
RSA *rsa = NULL;
Expand Down Expand Up @@ -306,7 +254,7 @@ CK_RV do_create_public_key(CK_BYTE_PTR in, CK_ULONG in_len, CK_ULONG algorithm,

if (YKPIV_IS_EC(algorithm)) {
int curve_name = get_curve_name(algorithm);
return do_create_ec_key(in, len, curve_name, pkey);
return get_ec_pubkey_from_bytes(curve_name, in, len, pkey);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
} else if (YKPIV_IS_25519(algorithm)) {
if (algorithm == YKPIV_ALGO_ED25519) {
Expand Down
1 change: 0 additions & 1 deletion ykcs11/openssl_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ CK_RV do_rsa_encrypt(ykcs11_pkey_t *key, int padding, const ykcs11_md_t* oaep_md
CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR enc, CK_ULONG_PTR enc_len);
CK_RV do_store_cert(CK_BYTE_PTR data, CK_ULONG len, ykcs11_x509_t **cert);
CK_RV do_generate_ec_key(int curve_name, ykcs11_pkey_t **pkey);
CK_RV do_create_ec_key(CK_BYTE_PTR point, CK_ULONG point_len, int curve_name, ykcs11_pkey_t **pkey);
CK_RV do_create_rsa_key(CK_BYTE_PTR mod, CK_ULONG mod_len, CK_BYTE_PTR exp, CK_ULONG exp_len, ykcs11_pkey_t **pkey);
CK_RV do_create_public_key(CK_BYTE_PTR in, CK_ULONG in_len, CK_ULONG algorithm, ykcs11_pkey_t **pkey);
CK_RV do_sign_empty_cert(const char *cn, ykcs11_pkey_t *pubkey, ykcs11_pkey_t *pvtkey, ykcs11_x509_t **cert);
Expand Down

0 comments on commit 4434587

Please sign in to comment.