Skip to content

Commit ad49f68

Browse files
committed
Rework ECC param handling for public keys
1 parent e78adc0 commit ad49f68

File tree

4 files changed

+486
-71
lines changed

4 files changed

+486
-71
lines changed

src/wp_ecc_kmgmt.c

Lines changed: 137 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -506,72 +506,84 @@ static const OSSL_PARAM* wp_ecc_settable_params(WOLFPROV_CTX* provCtx)
506506
}
507507

508508
/**
509-
* Set the public key's X and Y ordinates into ECC key object.
509+
* Set the encoded public key parameter into ECC key object.
510510
*
511511
* @param [in, out] ecc ECC key object.
512512
* @param [in] params Array of parameters and values.
513+
* @param [in] key String to look for.
513514
* @return 1 on success.
514515
* @return 0 on failure.
515516
*/
516-
static int wp_ecc_set_params_x_y(wp_Ecc *ecc, const OSSL_PARAM params[])
517+
static int wp_ecc_set_params_enc_pub_key(wp_Ecc *ecc, const OSSL_PARAM params[],
518+
const char* key)
517519
{
518520
int ok = 1;
521+
unsigned char* data = NULL;
522+
size_t len;
519523

520-
if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_X,
521-
ecc->key.pubkey.x)) {
522-
ok = 0;
523-
}
524-
if (ok && mp_iszero(ecc->key.pubkey.x)) {
525-
ok = 0;
526-
}
527-
if (ok && (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y,
528-
ecc->key.pubkey.y))) {
529-
ok = 0;
530-
}
531-
if (ok && mp_iszero(ecc->key.pubkey.x)) {
524+
if (!wp_params_get_octet_string_ptr(params, key, &data, &len)) {
532525
ok = 0;
533526
}
534-
if (ok) {
535-
ok = (mp_set(ecc->key.pubkey.y, 1) == 0);
536-
}
537-
if (ok) {
538-
ecc->key.type = ECC_PUBLICKEY;
539-
ecc->hasPub = 1;
527+
if (ok && (data != NULL)) {
528+
int rc = wc_ecc_import_x963_ex(data, (word32)len, &ecc->key,
529+
ecc->curveId);
530+
if (rc != 0) {
531+
ok = 0;
532+
}
533+
if (ok) {
534+
ecc->hasPub = 1;
535+
}
540536
}
541537

542538
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
543539
return ok;
544540
}
545541

546542
/**
547-
* Set the encoded public key parameter into ECC key object.
543+
* Set the public key values into ECC key object.
548544
*
549545
* @param [in, out] ecc ECC key object.
550546
* @param [in] params Array of parameters and values.
551-
* @param [in] key String to look for.
552547
* @return 1 on success.
553548
* @return 0 on failure.
554549
*/
555-
static int wp_ecc_set_params_enc_pub_key(wp_Ecc *ecc, const OSSL_PARAM params[],
556-
const char* key)
550+
static int wp_ecc_set_params_pub(wp_Ecc *ecc, const OSSL_PARAM params[])
557551
{
558552
int ok = 1;
559-
unsigned char* data = NULL;
560-
size_t len;
553+
const OSSL_PARAM *p = NULL;
561554

562-
if (!wp_params_get_octet_string_ptr(params, key, &data, &len)) {
563-
ok = 0;
564-
}
565-
if (ok && (data != NULL)) {
566-
int rc = wc_ecc_import_x963_ex(data, (word32)len, &ecc->key,
567-
ecc->curveId);
568-
if (rc != 0) {
555+
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_PUB_X);
556+
if (p != NULL) {
557+
if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_X,
558+
ecc->key.pubkey.x)) {
559+
ok = 0;
560+
}
561+
if (ok && mp_iszero(ecc->key.pubkey.x)) {
569562
ok = 0;
570563
}
571564
if (ok) {
565+
ecc->key.type = ECC_PUBLICKEY;
572566
ecc->hasPub = 1;
573567
}
574568
}
569+
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_PUB_Y);
570+
if (p != NULL) {
571+
if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y,
572+
ecc->key.pubkey.y)) {
573+
ok = 0;
574+
}
575+
if (ok && mp_iszero(ecc->key.pubkey.y)) {
576+
ok = 0;
577+
}
578+
}
579+
if (wp_ecc_set_params_enc_pub_key(ecc, params,
580+
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY) != 1) {
581+
ok = 0;
582+
}
583+
if (wp_ecc_set_params_enc_pub_key(ecc, params,
584+
OSSL_PKEY_PARAM_PUB_KEY) != 1) {
585+
ok = 0;
586+
}
575587

576588
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
577589
return ok;
@@ -591,11 +603,8 @@ static int wp_ecc_set_params(wp_Ecc *ecc, const OSSL_PARAM params[])
591603
const OSSL_PARAM *p;
592604

593605
if (params != NULL) {
594-
if (!wp_ecc_set_params_x_y(ecc, params)) {
595-
if (!wp_ecc_set_params_enc_pub_key(ecc, params,
596-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) {
597-
ok = 0;
598-
}
606+
if (!wp_ecc_set_params_pub(ecc, params)) {
607+
ok = 0;
599608
}
600609
if (ok) {
601610
p = OSSL_PARAM_locate_const(params,
@@ -695,22 +704,90 @@ static int wp_ecc_get_params_enc_pub_key(wp_Ecc* ecc, OSSL_PARAM params[],
695704
int rc;
696705
word32 outLen = (word32)p->return_size;
697706

698-
if (p->data == NULL) {
699-
outLen = 1 + 2 * ((ecc->bits + 7) / 8);
707+
if (ecc->hasPub == 0) {
708+
ok = 0;
700709
}
701-
else {
702-
rc = wc_ecc_export_x963_ex(&ecc->key, p->data, &outLen, 0);
703-
if (rc != 0) {
704-
ok = 0;
710+
if (ok) {
711+
if (p->data == NULL) {
712+
outLen = 1 + 2 * ((ecc->bits + 7) / 8);
713+
}
714+
else {
715+
rc = wc_ecc_export_x963_ex(&ecc->key, p->data, &outLen, 0);
716+
if (rc != 0) {
717+
ok = 0;
718+
}
705719
}
720+
p->return_size = outLen;
706721
}
707-
p->return_size = outLen;
708722
}
709723

710724
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
711725
return ok;
712726
}
713727

728+
/**
729+
* Get the public key into parameters.
730+
*
731+
* @param [in] ecc ECC key object.
732+
* @param [in, out] params Array of parameters and values.
733+
* @return 1 on success.
734+
* @return 0 on failure.
735+
*/
736+
static int wp_ecc_get_params_pub(wp_Ecc* ecc, OSSL_PARAM params[])
737+
{
738+
int ok = 1;
739+
OSSL_PARAM* p;
740+
741+
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
742+
if ((p != NULL) && (ecc->hasPub == 0)) {
743+
ok = 0;
744+
}
745+
if (ok && p != NULL) {
746+
size_t outLen = mp_unsigned_bin_size(ecc->key.pubkey.x);
747+
if (p->data != NULL) {
748+
if (p->data_size < outLen) {
749+
ok = 0;
750+
}
751+
if (ok && !wp_mp_to_unsigned_bin_le(ecc->key.pubkey.x,
752+
p->data, outLen)) {
753+
ok = 0;
754+
}
755+
}
756+
p->return_size = outLen;
757+
}
758+
if (ok) {
759+
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
760+
if ((p != NULL) && (ecc->hasPub == 0)) {
761+
ok = 0;
762+
}
763+
}
764+
if (ok && p != NULL) {
765+
size_t outLen = mp_unsigned_bin_size(ecc->key.pubkey.y);
766+
if (p->data != NULL) {
767+
if (p->data_size < outLen) {
768+
ok = 0;
769+
}
770+
if (ok && !wp_mp_to_unsigned_bin_le(ecc->key.pubkey.y,
771+
p->data, outLen)) {
772+
ok = 0;
773+
}
774+
}
775+
p->return_size = outLen;
776+
}
777+
/* Encoded public key. */
778+
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
779+
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))) {
780+
ok = 0;
781+
}
782+
/* Public key. */
783+
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
784+
OSSL_PKEY_PARAM_PUB_KEY))) {
785+
ok = 0;
786+
}
787+
788+
return ok;
789+
}
790+
714791
/**
715792
* Get the ECC key parameters.
716793
*
@@ -767,25 +844,9 @@ static int wp_ecc_get_params(wp_Ecc* ecc, OSSL_PARAM params[])
767844
ok = 0;
768845
}
769846
}
770-
/* X-ordinate of public key. */
771-
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_EC_PUB_X,
772-
ecc->key.pubkey.x))) {
773-
ok = 0;
774-
}
775-
/* Y-ordinate of public key. */
776-
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y,
777-
ecc->key.pubkey.y))) {
778-
ok = 0;
779-
}
780-
/* Encoded public key. */
781-
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
782-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))) {
783-
ok = 0;
784-
}
785-
/* Public key. */
786-
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
787-
OSSL_PKEY_PARAM_PUB_KEY))) {
788-
ok = 0;
847+
/* Public key */
848+
if (ok) {
849+
ok = wp_ecc_get_params_pub(ecc, params);
789850
}
790851
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_PRIV_KEY,
791852
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
@@ -1041,11 +1102,8 @@ static int wp_ecc_import_keypair(wp_Ecc* ecc, const OSSL_PARAM params[],
10411102
{
10421103
int ok = 1;
10431104

1044-
/* This call sets hasPub field in wp_Ecc. */
1045-
if (!wp_ecc_set_params_x_y(ecc, params)) {
1046-
/* Try direct import of encoded public key instead. */
1047-
ok = wp_ecc_set_params_enc_pub_key(ecc, params,
1048-
OSSL_PKEY_PARAM_PUB_KEY);
1105+
if (wp_ecc_set_params_pub(ecc, params) != 1) {
1106+
ok = 0;
10491107
}
10501108
if (ok && priv && (!wp_params_get_mp(params, OSSL_PKEY_PARAM_PRIV_KEY,
10511109
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
@@ -2027,13 +2085,21 @@ static int wp_ecc_decode_pki(wp_Ecc* ecc, unsigned char* data, word32 len)
20272085
#endif
20282086
if (ok) {
20292087
ecc->curveId = ecc->key.dp->id;
2030-
/* ECC_PRIVATEKEY_ONLY when no public key data. */
2031-
ecc->hasPub = ecc->key.type == ECC_PRIVATEKEY;
20322088
ecc->hasPriv = 1;
20332089
/* Needs curveId set. */
20342090
if (!wp_ecc_set_bits(ecc)) {
20352091
ok = 0;
20362092
}
2093+
2094+
/* Keys decoded from pki should always have public key */
2095+
if (ecc->key.type == ECC_PRIVATEKEY_ONLY) {
2096+
#ifdef ECC_TIMING_RESISTANT
2097+
rc = wc_ecc_make_pub_ex(&ecc->key, NULL, &ecc->rng);
2098+
#else
2099+
rc = wc_ecc_make_pub_ex(&ecc->key, NULL, NULL);
2100+
#endif
2101+
}
2102+
ecc->hasPub = 1;
20372103
}
20382104

20392105
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);

0 commit comments

Comments
 (0)