diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 8321837cf..58404ba4f 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2640,8 +2640,8 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, /* now find (8+k)G for k=1..7 */ if (err == MP_OKAY) for (j = 9; j < 16; j++) { - err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, - modulus, mp); + err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus, + mp); if (err != MP_OKAY) break; } @@ -2709,7 +2709,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a, - modulus, mp); + modulus, mp); } if (err != MP_OKAY) break; /* empty window and reset */ @@ -2745,8 +2745,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, first = 0; } else { /* then add */ - err = ecc_projective_add_point(R, tG, R, a, modulus, - mp); + err = ecc_projective_add_point(R, tG, R, a, modulus, mp); if (err != MP_OKAY) break; } } @@ -4319,13 +4318,16 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) alt_fp_init(key->pubkey.y); alt_fp_init(key->pubkey.z); ret = mp_init(&key->k); -#else - ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, - NULL, NULL); -#endif /* ALT_ECC_SIZE */ if (ret != MP_OKAY) { return MEMORY_E; } +#else + ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, + NULL, NULL); + if (ret != MP_OKAY) { + return MEMORY_E; + } +#endif /* ALT_ECC_SIZE */ #endif /* WOLFSSL_ATECC508A */ #ifdef WOLFSSL_HEAP_TEST @@ -4679,7 +4681,13 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, } #endif /* !NO_ASN */ -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_STM32_PKA) +int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, + ecc_key* key, mp_int *r, mp_int *s) +{ + return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s); +} +#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) /** Sign a message digest in The message digest to sign @@ -4691,11 +4699,6 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, */ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, ecc_key* key, mp_int *r, mp_int *s) -#if defined(WOLFSSL_STM32_PKA) -{ - return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s); -} -#else { int err = 0; #ifndef WOLFSSL_SP_MATH @@ -4704,11 +4707,16 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, !defined(WOLFSSL_SMALL_STACK) mp_int e_lcl; #endif +#ifndef WOLFSSL_ECDSA_SET_K DECLARE_CURVE_SPECS(curve, 1); +#else + DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); +#endif #endif /* !WOLFSSL_SP_MATH */ - if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) + if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) { return ECC_BAD_ARG_E; + } /* is this a private key? */ if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) { @@ -4721,20 +4729,33 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #ifdef WOLFSSL_SP_MATH - if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) - return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap); - else + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { + #ifndef WOLFSSL_ECDSA_SET_K + return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap); + #else + return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k, + key->heap); + #endif + } + else { return WC_KEY_SIZE_E; + } #else #ifdef WOLFSSL_HAVE_SP_ECC #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) #endif { -#ifndef WOLFSSL_SP_NO_256 + #ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) - return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap); -#endif + #ifndef WOLFSSL_ECDSA_SET_K + return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, + key->heap); + #else + return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k, + key->heap); + #endif + #endif } #endif /* WOLFSSL_HAVE_SP_ECC */ @@ -4785,7 +4806,11 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } /* load curve info */ +#ifndef WOLFSSL_ECDSA_SET_K err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); +#else + err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); +#endif /* load digest into e */ if (err == MP_OKAY) { @@ -4939,8 +4964,25 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, err = RNG_FAILURE_E; break; } - err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, + #ifdef WOLFSSL_ECDSA_SET_K + if (key->sign_k != NULL) { + if (loop_check > 1) { + err = RNG_FAILURE_E; + break; + } + mp_copy(key->sign_k, &pubkey->k); + mp_forcezero(key->sign_k); + mp_free(key->sign_k); + XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); + key->sign_k = NULL; + err = wc_ecc_make_pub_ex(pubkey, curve, NULL); + } + else + #endif + { + err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id); + } if (err != MP_OKAY) break; /* find r = x1 mod n */ @@ -5019,8 +5061,35 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return err; } -#endif /* WOLFSSL_STM32_PKA */ + +#ifdef WOLFSSL_ECDSA_SET_K +int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key) +{ + int ret = 0; + + if (k == NULL || klen <= 0 || key == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + if (key->sign_k == NULL) { + key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, + DYNAMIC_TYPE_ECC); + if (key->sign_k == NULL) { + ret = MEMORY_E; + } + } + } + + if (ret == 0) { + ret = mp_read_unsigned_bin(key->sign_k, k, klen); + } + + return ret; +} +#endif /* WOLFSSL_ECDSA_SET_K */ #endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/ + #endif /* HAVE_ECC_SIGN */ #ifdef WOLFSSL_CUSTOM_CURVES @@ -5055,6 +5124,14 @@ int wc_ecc_free(ecc_key* key) return 0; } +#ifdef WOLFSSL_ECDSA_SET_K + if (key->sign_k != NULL) { + mp_forcezero(key->sign_k); + mp_free(key->sign_k); + XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); + } +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) #ifdef WC_ASYNC_ENABLE_ECC wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); @@ -5255,10 +5332,12 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, /* done with mu */ mp_clear(mu); - #ifdef WOLFSSL_SMALL_STACK - XFREE(mu, heap, DYNAMIC_TYPE_ECC); - #endif } + #ifdef WOLFSSL_SMALL_STACK + if (mu != NULL) { + XFREE(mu, heap, DYNAMIC_TYPE_ECC); + } + #endif } if (err == MP_OKAY) @@ -5347,8 +5426,24 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, if (err == MP_OKAY) err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, a, modulus, mp); - else + if (err != MP_OKAY) break; + if (mp_iszero(C->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(C->x) && mp_iszero(C->y)) { + err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C, + a, modulus, mp); + if (err != MP_OKAY) + break; + } + /* When only Z zero then result is infinity */ + else { + mp_set(C->x, 0); + mp_set(C->y, 0); + mp_set(C->z, 1); + first = 1; + } + } } } } @@ -5861,38 +5956,60 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, err = wc_ecc_point_add(mG, mQ, mG, curve->prime); #else #ifndef ECC_SHAMIR + if (err == MP_OKAY) { mp_digit mp = 0; - /* compute u1*mG + u2*mQ = mG */ - if (err == MP_OKAY) { + if (!mp_iszero(u1)) { + /* compute u1*mG + u2*mQ = mG */ err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap); - } - if (err == MP_OKAY) { - err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, + if (err == MP_OKAY) { + err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); + } + + /* find the montgomery mp */ + if (err == MP_OKAY) + err = mp_montgomery_setup(curve->prime, &mp); + + /* add them */ + if (err == MP_OKAY) + err = ecc_projective_add_point(mQ, mG, mG, curve->Af, + curve->prime, mp); + if (err == MP_OKAY && mp_iszero(mG->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(mG->x) && mp_iszero(mG->y)) { + err = ecc_projective_dbl_point(mQ, mG, curve->Af, + curve->prime, mp); + } + /* When only Z zero then result is infinity */ + else { + mp_set(mG->x, 0); + mp_set(mG->y, 0); + mp_set(mG->z, 1); + } + } + } + else { + /* compute 0*mG + u2*mQ = mG */ + err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0, + key->heap); + /* find the montgomery mp */ + if (err == MP_OKAY) + err = mp_montgomery_setup(curve->prime, &mp); } - - /* find the montgomery mp */ - if (err == MP_OKAY) - err = mp_montgomery_setup(curve->prime, &mp); - - /* add them */ - if (err == MP_OKAY) - err = ecc_projective_add_point(mQ, mG, mG, curve->Af, - curve->prime, mp); /* reduce */ if (err == MP_OKAY) err = ecc_map(mG, curve->prime, mp); } #else - /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ - if (err == MP_OKAY) { - err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime, - key->heap); - } + /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ + if (err == MP_OKAY) { + err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime, + key->heap); + } #endif /* ECC_SHAMIR */ #endif /* FREESCALE_LTC_ECC */ /* v = X_x1 mod n */ @@ -7491,6 +7608,9 @@ int wc_ecc_sig_size(ecc_key* key) extra byte for r and s, so add 2 */ keySz = key->dp->size; orderBits = wc_ecc_get_curve_order_bit_count(key->dp); + if (orderBits > keySz * 8) { + keySz = (orderBits + 7) / 8; + } /* maximum possible signature header size is 7 bytes */ maxSigSz = (keySz * 2) + SIG_HEADER_SZ; if ((orderBits % 8) == 0) { @@ -8414,17 +8534,33 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, /* double if not first */ if (!first) { if ((err = ecc_projective_dbl_point(R, R, a, modulus, - mp)) != MP_OKAY) { + mp)) != MP_OKAY) { break; } } /* add if not first, otherwise copy */ if (!first && z) { - if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, - a, modulus, mp)) != MP_OKAY) { + if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a, + modulus, mp)) != MP_OKAY) { break; } + if (mp_iszero(R->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(R->x) && mp_iszero(R->y)) { + if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z], + R, a, modulus, mp)) != MP_OKAY) { + break; + } + } + /* When only Z zero then result is infinity */ + else { + mp_set(R->x, 0); + mp_set(R->y, 0); + mp_copy(&fp_cache[idx].mu, R->z); + first = 1; + } + } } else if (z) { if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || @@ -8432,7 +8568,7 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, err = GEN_MEM_ERR; break; } - first = 0; + first = 0; } } } @@ -8635,21 +8771,56 @@ static int accel_fp_mul2add(int idx1, int idx2, if (!first) { if (zA) { if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], - R, a, modulus, mp)) != MP_OKAY) { + R, a, modulus, mp)) != MP_OKAY) { break; } + if (mp_iszero(R->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(R->x) && mp_iszero(R->y)) { + if ((err = ecc_projective_dbl_point( + fp_cache[idx1].LUT[zA], R, + a, modulus, mp)) != MP_OKAY) { + break; + } + } + /* When only Z zero then result is infinity */ + else { + mp_set(R->x, 0); + mp_set(R->y, 0); + mp_copy(&fp_cache[idx1].mu, R->z); + first = 1; + } + } } + if (zB) { if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], - R, a, modulus, mp)) != MP_OKAY) { + R, a, modulus, mp)) != MP_OKAY) { break; } + if (mp_iszero(R->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(R->x) && mp_iszero(R->y)) { + if ((err = ecc_projective_dbl_point( + fp_cache[idx2].LUT[zB], R, + a, modulus, mp)) != MP_OKAY) { + break; + } + } + /* When only Z zero then result is infinity */ + else { + mp_set(R->x, 0); + mp_set(R->y, 0); + mp_copy(&fp_cache[idx2].mu, R->z); + first = 1; + } + } } } else { if (zA) { if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || - (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || - (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { + (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || + (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { err = GEN_MEM_ERR; break; } @@ -8658,14 +8829,31 @@ static int accel_fp_mul2add(int idx1, int idx2, if (zB && first == 0) { if (zB) { if ((err = ecc_projective_add_point(R, - fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){ + fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){ break; } + if (mp_iszero(R->z)) { + /* When all zero then should have done an add */ + if (mp_iszero(R->x) && mp_iszero(R->y)) { + if ((err = ecc_projective_dbl_point( + fp_cache[idx2].LUT[zB], R, + a, modulus, mp)) != MP_OKAY) { + break; + } + } + /* When only Z zero then result is infinity */ + else { + mp_set(R->x, 0); + mp_set(R->y, 0); + mp_copy(&fp_cache[idx2].mu, R->z); + first = 1; + } + } } } else if (zB && first == 1) { if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || - (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || - (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { + (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || + (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { err = GEN_MEM_ERR; break; } diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index de6f0fb77..1b2c1a12c 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -26980,7 +26980,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -27046,7 +27046,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 8, priv); /* New random point. */ - err = sp_256_ecc_gen_k_8(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_8(rng, k); + } + else { + sp_256_from_mp(k, 8, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL); } @@ -27205,7 +27211,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); + { sp_256_mul_8(s, s, p256_norm_order); + } err = sp_256_mod_8(s, s, p256_order); } if (err == MP_OKAY) { @@ -27223,7 +27231,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -27253,7 +27280,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 672580068..69a784181 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -30018,7 +30018,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -30084,7 +30084,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 4, priv); /* New random point. */ - err = sp_256_ecc_gen_k_4(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_4(rng, k); + } + else { + sp_256_from_mp(k, 4, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL); } @@ -30243,7 +30249,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 4, pY); sp_256_from_mp(p2->z, 4, pZ); + { sp_256_mul_4(s, s, p256_norm_order); + } err = sp_256_mod_4(s, s, p256_order); } if (err == MP_OKAY) { @@ -30261,7 +30269,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_4(p1, p1, p2, tmp); + if (sp_256_iszero_4(p1->z)) { + if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { + sp_256_proj_point_dbl_4(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -30291,7 +30314,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_4(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_4(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index bbab4605d..b0c885abe 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -16358,7 +16358,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -16424,7 +16424,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 8, priv); /* New random point. */ - err = sp_256_ecc_gen_k_8(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_8(rng, k); + } + else { + sp_256_from_mp(k, 8, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL); } @@ -16583,7 +16589,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); + { sp_256_mul_8(s, s, p256_norm_order); + } err = sp_256_mod_8(s, s, p256_order); } if (err == MP_OKAY) { @@ -16601,7 +16609,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -16631,7 +16658,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index 743b33b93..40c29bcb0 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -8441,13 +8441,11 @@ static const sp_digit p256_mod[10] = { 0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000,0x0000000,0x0000000, 0x0000400,0x3ff0000,0x03fffff }; -#ifndef WOLFSSL_SP_SMALL /* The Montogmery normalizer for modulus of the curve P256. */ static const sp_digit p256_norm_mod[10] = { 0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff, 0x3fffbff,0x000ffff,0x0000000 }; -#endif /* WOLFSSL_SP_SMALL */ /* The Montogmery multiplier for modulus of the curve P256. */ static const sp_digit p256_mp_mod = 0x000001; #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ @@ -12856,7 +12854,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -12922,7 +12920,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 10, priv); /* New random point. */ - err = sp_256_ecc_gen_k_10(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_10(rng, k); + } + else { + sp_256_from_mp(k, 10, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL); } @@ -13081,7 +13085,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 10, pY); sp_256_from_mp(p2->z, 10, pZ); + { sp_256_mul_10(s, s, p256_norm_order); + } err = sp_256_mod_10(s, s, p256_order); } if (err == MP_OKAY) { @@ -13099,7 +13105,28 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_10(p1, p1, p2, tmp); + if (sp_256_iszero_10(p1->z)) { + if (sp_256_iszero_10(p1->x) && sp_256_iszero_10(p1->y)) { + sp_256_proj_point_dbl_10(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -13129,7 +13156,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_10(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_10(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_10(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 1bd086eb9..3702eefa5 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -8011,13 +8011,11 @@ static const sp_digit p256_mod[5] = { 0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L, 0x0ffffffff0000L }; -#ifndef WOLFSSL_SP_SMALL /* The Montogmery normalizer for modulus of the curve P256. */ static const sp_digit p256_norm_mod[5] = { 0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL, 0x000000000ffffL }; -#endif /* WOLFSSL_SP_SMALL */ /* The Montogmery multiplier for modulus of the curve P256. */ static const sp_digit p256_mp_mod = 0x0000000000001; #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ @@ -12201,7 +12199,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -12267,7 +12265,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 5, priv); /* New random point. */ - err = sp_256_ecc_gen_k_5(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_5(rng, k); + } + else { + sp_256_from_mp(k, 5, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL); } @@ -12426,7 +12430,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 5, pY); sp_256_from_mp(p2->z, 5, pZ); + { sp_256_mul_5(s, s, p256_norm_order); + } err = sp_256_mod_5(s, s, p256_order); } if (err == MP_OKAY) { @@ -12444,7 +12450,23 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_5(p1, p1, p2, tmp); + if (sp_256_iszero_5(p1->z)) { + if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) { + sp_256_proj_point_dbl_5(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -12474,7 +12496,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_5(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_5(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index d760cc097..c2925beed 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -16429,7 +16429,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -16495,7 +16495,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 8, priv); /* New random point. */ - err = sp_256_ecc_gen_k_8(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_8(rng, k); + } + else { + sp_256_from_mp(k, 8, km); + mp_zero(km); + } if (err == MP_OKAY) { err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL); } @@ -16654,7 +16660,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); + { sp_256_mul_8(s, s, p256_norm_order); + } err = sp_256_mod_8(s, s, p256_order); } if (err == MP_OKAY) { @@ -16672,7 +16680,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, } if (err == MP_OKAY) { + { sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -16702,7 +16729,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 4b9ab4eb1..063d10c17 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -851,8 +851,14 @@ int sp_add(sp_int* a, sp_int* b, sp_int* r) */ int sp_set_int(sp_int* a, unsigned long b) { - a->used = 1; - a->dp[0] = b; + if (b == 0) { + a->used = 0; + a->dp[0] = 0; + } + else { + a->used = 1; + a->dp[0] = b; + } return MP_OKAY; } diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index 9473b4332..17f630052 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -21130,7 +21130,7 @@ static void sp_256_mont_inv_order_avx2_4(sp_digit* r, const sp_digit* a, * MP_OKAY on success. */ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap) + mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) sp_digit* d = NULL; @@ -21199,7 +21199,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_from_mp(x, 4, priv); /* New random point. */ - err = sp_256_ecc_gen_k_4(rng, k); + if (km == NULL || mp_iszero(km)) { + err = sp_256_ecc_gen_k_4(rng, k); + } + else { + sp_256_from_mp(k, 4, km); + mp_zero(km); + } if (err == MP_OKAY) { #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) @@ -21387,11 +21393,14 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->z, 4, pZ); #ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { sp_256_mul_avx2_4(s, s, p256_norm_order); + } else #endif + { sp_256_mul_4(s, s, p256_norm_order); + } err = sp_256_mod_4(s, s, p256_order); } if (err == MP_OKAY) { @@ -21428,11 +21437,40 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (err == MP_OKAY) { #ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp); + if (sp_256_iszero_4(p1->z)) { + if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { + sp_256_proj_point_dbl_avx2_4(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } else #endif + { sp_256_proj_point_add_4(p1, p1, p2, tmp); + if (sp_256_iszero_4(p1->z)) { + if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { + sp_256_proj_point_dbl_4(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } + } /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ @@ -21462,7 +21500,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* u1 = (r + 1*order).z'.z' mod prime */ sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, p256_mp_mod); - *res = (int)(sp_256_cmp_4(p1->x, u2) == 0); + *res = (int)(sp_256_cmp_4(p1->x, u1) == 0); } } } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6b7397973..4069a85c1 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -16645,6 +16645,85 @@ static int ecc_test_vector(int keySize) return 0; } +#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K) +static int ecc_test_sign_vectors(WC_RNG* rng) +{ + int ret; + ecc_key key; + byte sig[72]; + word32 sigSz; + unsigned char hash[32] = "test wolfSSL deterministic sign"; + const char* dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"; + const char* QIUTx = "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230"; + const char* QIUTy = "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141"; + const byte k[1] = { 0x02 }; + const byte expSig[71] = { + 0x30, 0x45, 0x02, 0x20, 0x7c, 0xf2, 0x7b, 0x18, + 0x8d, 0x03, 0x4f, 0x7e, 0x8a, 0x52, 0x38, 0x03, + 0x04, 0xb5, 0x1a, 0xc3, 0xc0, 0x89, 0x69, 0xe2, + 0x77, 0xf2, 0x1b, 0x35, 0xa6, 0x0b, 0x48, 0xfc, + 0x47, 0x66, 0x99, 0x78, 0x02, 0x21, 0x00, 0xa8, + 0x43, 0xa0, 0xce, 0x6c, 0x5e, 0x17, 0x8a, 0x53, + 0x4d, 0xaf, 0xd2, 0x95, 0x78, 0x9f, 0x84, 0x4f, + 0x94, 0xb8, 0x75, 0xa3, 0x19, 0xa5, 0xd4, 0xdf, + 0xe1, 0xd4, 0x5e, 0x9d, 0x97, 0xfe, 0x81 + }; + + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) { + return ret; + } + ret = wc_ecc_import_raw(&key, QIUTx, QIUTy, dIUT, "SECP256R1"); + if (ret != 0) { + goto done; + } + + ret = wc_ecc_sign_set_k(k, sizeof(k), &key); + if (ret != 0) { + goto done; + } + + sigSz = sizeof(sig); + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret == 0) + ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, &key); + } while (ret == WC_PENDING_E); + if (ret != 0) { + goto done; + } + TEST_SLEEP(); + + if (sigSz != sizeof(expSig)) { + ret = -8350; + goto done; + } + if (XMEMCMP(sig, expSig, sigSz) != 0) { + ret = -8351; + goto done; + } + + sigSz = sizeof(sig); + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret == 0) + ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, &key); + } while (ret == WC_PENDING_E); + if (ret != 0) { + goto done; + } + TEST_SLEEP(); + +done: + wc_ecc_free(&key); + return ret; +} +#endif + #ifdef HAVE_ECC_CDH static int ecc_test_cdh_vectors(void) { @@ -16667,7 +16746,7 @@ static int ecc_test_cdh_vectors(void) ret = wc_ecc_init_ex(&priv_key, HEAP_HINT, devId); if (ret != 0) { wc_ecc_free(&pub_key); - goto done; + return ret; } wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR); wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR); @@ -18494,6 +18573,13 @@ int ecc_test(void) } #endif +#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K) + ret = ecc_test_sign_vectors(&rng); + if (ret != 0) { + printf("ecc_test_sign_vectors failed! %d\n", ret); + goto done; + } +#endif #ifdef HAVE_ECC_CDH ret = ecc_test_cdh_vectors(); if (ret != 0) { diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index ac34e2bd0..41bb8ddf4 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -391,6 +391,10 @@ struct ecc_key { ecc_context_t ctx; #endif +#ifdef WOLFSSL_ECDSA_SET_K + mp_int *sign_k; +#endif + #ifdef WOLFSSL_SMALL_STACK_CACHE mp_int* t1; mp_int* t2; @@ -467,6 +471,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, WOLFSSL_API int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, ecc_key* key, mp_int *r, mp_int *s); +#ifdef WOLFSSL_ECDSA_SET_K +WOLFSSL_API +int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key); +#endif #endif /* HAVE_ECC_SIGN */ #ifdef HAVE_ECC_VERIFY diff --git a/wolfssl/wolfcrypt/sp.h b/wolfssl/wolfcrypt/sp.h index ed1db955c..f6009c9cd 100644 --- a/wolfssl/wolfcrypt/sp.h +++ b/wolfssl/wolfcrypt/sp.h @@ -96,7 +96,7 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap); int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outlen, void* heap); int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, void* heap); + mp_int* rm, mp_int* sm, mp_int* km, void* heap); int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap); int sp_ecc_is_point_256(mp_int* pX, mp_int* pY);