Skip to content

Commit 8c58714

Browse files
authored
Merge pull request #115 from ColtonWilley/wp_ecc_pub_params_fix
Rework ECC param handling for public keys
2 parents b896f5b + 151b461 commit 8c58714

File tree

7 files changed

+486
-86
lines changed

7 files changed

+486
-86
lines changed

include/wolfprovider/wp_params.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ void wp_param_set_mp_buf(OSSL_PARAM* p, const char* key, unsigned char* num,
5151

5252
int wp_params_get_digest(const OSSL_PARAM* params, char* name,
5353
OSSL_LIB_CTX* libCtx, enum wc_HashType* type, size_t* len);
54-
int wp_params_get_mp(const OSSL_PARAM* params, const char* key, mp_int* mp);
54+
int wp_params_get_mp(const OSSL_PARAM* params, const char* key, mp_int* mp,
55+
int *set);
5556
int wp_params_get_octet_string(const OSSL_PARAM* params, const char* key,
5657
unsigned char** data, size_t* len, int secure);
5758
int wp_params_get_bn_be(const OSSL_PARAM* params, const char* key,
@@ -70,7 +71,8 @@ int wp_params_get_int(const OSSL_PARAM* params, const char* key, int* val);
7071
int wp_params_get_uint(const OSSL_PARAM* params, const char* key,
7172
unsigned int* val, int* set);
7273

73-
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp);
74+
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp,
75+
int allow);
7476
int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
7577
unsigned char* data, size_t len);
7678

src/wp_dh_kmgmt.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,10 +737,12 @@ static int wp_dh_get_params(wp_Dh* dh, OSSL_PARAM params[])
737737
ok = 0;
738738
}
739739
}
740-
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_FFC_P, &dh->key.p))) {
740+
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_FFC_P,
741+
&dh->key.p, 1))) {
741742
ok = 0;
742743
}
743-
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_FFC_G, &dh->key.g))) {
744+
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_FFC_G,
745+
&dh->key.g, 1))) {
744746
ok = 0;
745747
}
746748
if (ok && (!wp_params_set_octet_string_be(params, OSSL_PKEY_PARAM_PUB_KEY,

src/wp_ecc_kmgmt.c

Lines changed: 105 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -506,72 +506,77 @@ 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+
int set = 0;
561554

562-
if (!wp_params_get_octet_string_ptr(params, key, &data, &len)) {
555+
if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_X,
556+
ecc->key.pubkey.x, &set)) {
563557
ok = 0;
564558
}
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) {
559+
if (ok && (set == 1)) {
560+
if (mp_iszero(ecc->key.pubkey.x)) {
569561
ok = 0;
570562
}
571563
if (ok) {
564+
ecc->key.type = ECC_PUBLICKEY;
572565
ecc->hasPub = 1;
573566
}
574567
}
568+
if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y,
569+
ecc->key.pubkey.y, NULL)) {
570+
ok = 0;
571+
}
572+
if (wp_ecc_set_params_enc_pub_key(ecc, params,
573+
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY) != 1) {
574+
ok = 0;
575+
}
576+
if (wp_ecc_set_params_enc_pub_key(ecc, params,
577+
OSSL_PKEY_PARAM_PUB_KEY) != 1) {
578+
ok = 0;
579+
}
575580

576581
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
577582
return ok;
@@ -591,11 +596,8 @@ static int wp_ecc_set_params(wp_Ecc *ecc, const OSSL_PARAM params[])
591596
const OSSL_PARAM *p;
592597

593598
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-
}
599+
if (!wp_ecc_set_params_pub(ecc, params)) {
600+
ok = 0;
599601
}
600602
if (ok) {
601603
p = OSSL_PARAM_locate_const(params,
@@ -695,22 +697,61 @@ static int wp_ecc_get_params_enc_pub_key(wp_Ecc* ecc, OSSL_PARAM params[],
695697
int rc;
696698
word32 outLen = (word32)p->return_size;
697699

698-
if (p->data == NULL) {
699-
outLen = 1 + 2 * ((ecc->bits + 7) / 8);
700+
if (ecc->hasPub == 0) {
701+
ok = 0;
700702
}
701-
else {
702-
rc = wc_ecc_export_x963_ex(&ecc->key, p->data, &outLen, 0);
703-
if (rc != 0) {
704-
ok = 0;
703+
if (ok) {
704+
if (p->data == NULL) {
705+
outLen = 1 + 2 * ((ecc->bits + 7) / 8);
705706
}
707+
else {
708+
rc = wc_ecc_export_x963_ex(&ecc->key, p->data, &outLen, 0);
709+
if (rc != 0) {
710+
ok = 0;
711+
}
712+
}
713+
p->return_size = outLen;
706714
}
707-
p->return_size = outLen;
708715
}
709716

710717
WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
711718
return ok;
712719
}
713720

721+
/**
722+
* Get the public key into parameters.
723+
*
724+
* @param [in] ecc ECC key object.
725+
* @param [in, out] params Array of parameters and values.
726+
* @return 1 on success.
727+
* @return 0 on failure.
728+
*/
729+
static int wp_ecc_get_params_pub(wp_Ecc* ecc, OSSL_PARAM params[])
730+
{
731+
int ok = 1;
732+
733+
if (!wp_params_set_mp(params, OSSL_PKEY_PARAM_EC_PUB_X, ecc->key.pubkey.x,
734+
(ecc->hasPub == 1))) {
735+
ok = 0;
736+
}
737+
if (!wp_params_set_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y, ecc->key.pubkey.y,
738+
(ecc->hasPub == 1))) {
739+
ok = 0;
740+
}
741+
/* Encoded public key. */
742+
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
743+
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))) {
744+
ok = 0;
745+
}
746+
/* Public key. */
747+
if (ok && (!wp_ecc_get_params_enc_pub_key(ecc, params,
748+
OSSL_PKEY_PARAM_PUB_KEY))) {
749+
ok = 0;
750+
}
751+
752+
return ok;
753+
}
754+
714755
/**
715756
* Get the ECC key parameters.
716757
*
@@ -767,33 +808,17 @@ static int wp_ecc_get_params(wp_Ecc* ecc, OSSL_PARAM params[])
767808
ok = 0;
768809
}
769810
}
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;
811+
/* Public key */
812+
if (ok) {
813+
ok = wp_ecc_get_params_pub(ecc, params);
789814
}
790815
if (ok && (!wp_params_set_mp(params, OSSL_PKEY_PARAM_PRIV_KEY,
791816
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
792-
wc_ecc_key_get_priv(&ecc->key)
817+
wc_ecc_key_get_priv(&ecc->key),
793818
#else
794-
&(ecc->key.k)
819+
&(ecc->key.k),
795820
#endif
796-
))) {
821+
1))) {
797822
ok = 0;
798823
}
799824
/* Private key. */
@@ -1041,19 +1066,16 @@ static int wp_ecc_import_keypair(wp_Ecc* ecc, const OSSL_PARAM params[],
10411066
{
10421067
int ok = 1;
10431068

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);
1069+
if (wp_ecc_set_params_pub(ecc, params) != 1) {
1070+
ok = 0;
10491071
}
10501072
if (ok && priv && (!wp_params_get_mp(params, OSSL_PKEY_PARAM_PRIV_KEY,
10511073
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
1052-
wc_ecc_key_get_priv(&ecc->key)
1074+
wc_ecc_key_get_priv(&ecc->key),
10531075
#else
1054-
&(ecc->key.k)
1076+
&(ecc->key.k),
10551077
#endif
1056-
))) {
1078+
NULL))) {
10571079
ok = 0;
10581080
}
10591081
if (ok &&
@@ -2027,13 +2049,21 @@ static int wp_ecc_decode_pki(wp_Ecc* ecc, unsigned char* data, word32 len)
20272049
#endif
20282050
if (ok) {
20292051
ecc->curveId = ecc->key.dp->id;
2030-
/* ECC_PRIVATEKEY_ONLY when no public key data. */
2031-
ecc->hasPub = ecc->key.type == ECC_PRIVATEKEY;
20322052
ecc->hasPriv = 1;
20332053
/* Needs curveId set. */
20342054
if (!wp_ecc_set_bits(ecc)) {
20352055
ok = 0;
20362056
}
2057+
2058+
/* Keys decoded from pki should always have public key */
2059+
if (ecc->key.type == ECC_PRIVATEKEY_ONLY) {
2060+
#ifdef ECC_TIMING_RESISTANT
2061+
rc = wc_ecc_make_pub_ex(&ecc->key, NULL, &ecc->rng);
2062+
#else
2063+
rc = wc_ecc_make_pub_ex(&ecc->key, NULL, NULL);
2064+
#endif
2065+
}
2066+
ecc->hasPub = 1;
20372067
}
20382068

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

src/wp_params.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,22 +254,34 @@ int wp_params_get_digest(const OSSL_PARAM* params, char* name,
254254
* @param [in] params Array of parameters.
255255
* @param [in] key String key to look for.
256256
* @param [out] mp Multi-precision number.
257+
* @param [out] set Indicates if mp has been set.
257258
* @return 1 on success.
258259
* @return 0 on failure.
259260
*/
260-
int wp_params_get_mp(const OSSL_PARAM* params, const char* key, mp_int* mp)
261+
int wp_params_get_mp(const OSSL_PARAM* params, const char* key, mp_int* mp,
262+
int *set)
261263
{
262264
int ok = 1;
263265
const OSSL_PARAM* p;
264266

267+
if (set != NULL) {
268+
*set = 0;
269+
}
270+
265271
p = OSSL_PARAM_locate_const(params, key);
266272
if ((p != NULL) && (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)) {
267-
ok = 0;
268-
}
269-
if ((p != NULL) && ok && (!wp_mp_read_unsigned_bin_le(mp, p->data,
270-
p->data_size))) {
271273
ok = 0;
272274
}
275+
if (ok && (p != NULL)) {
276+
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
277+
ok = 0;
278+
}
279+
else {
280+
if (set != NULL) {
281+
*set = 1;
282+
}
283+
}
284+
}
273285

274286
WOLFPROV_LEAVE(WP_LOG_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
275287
return ok;
@@ -577,16 +589,21 @@ int wp_params_get_uint(const OSSL_PARAM* params, const char* key,
577589
* @param [in, out] params Array of parameters.
578590
* @param [in] key String key to look for.
579591
* @param [in] mp Multi-precision number.
592+
* @param [in] allow This mp is allowed to be set.
580593
* @return 1 on success.
581594
* @return 0 on failure.
582595
*/
583-
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp)
596+
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp,
597+
int allow)
584598
{
585599
int ok = 1;
586600
OSSL_PARAM* p;
587601

588602
p = OSSL_PARAM_locate(params, key);
589-
if (p != NULL) {
603+
if ((p != NULL) && (allow != 1)) {
604+
ok = 0;
605+
}
606+
if (ok && (p != NULL)) {
590607
size_t outLen = mp_unsigned_bin_size(mp);
591608
if (p->data != NULL) {
592609
if (p->data_size < outLen) {

0 commit comments

Comments
 (0)