mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
add deterministic k generation for ECC sign
This commit is contained in:
@ -127,7 +127,9 @@ ECC Curve Sizes:
|
||||
#include <wolfssl/wolfcrypt/sp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC_ENCRYPT
|
||||
#if defined(HAVE_ECC_ENCRYPT) || defined(WOLFSSL_ECDSA_SET_K) || \
|
||||
defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
|
||||
defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#endif
|
||||
@ -5299,6 +5301,48 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
}
|
||||
#endif /* !NO_ASN */
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
/* returns MP_OKAY on success */
|
||||
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
|
||||
{
|
||||
int err;
|
||||
DECLARE_CURVE_SPECS(curve, 1);
|
||||
ALLOC_CURVE_SPECS(1);
|
||||
|
||||
/* get curve order */
|
||||
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
|
||||
if (err == MP_OKAY) {
|
||||
if (key->sign_k == NULL) {
|
||||
key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
DYNAMIC_TYPE_ECC);
|
||||
if (key->sign_k) {
|
||||
/* currently limiting to SHA256 for auto create */
|
||||
if (mp_init(key->sign_k) != MP_OKAY ||
|
||||
wc_ecc_gen_deterministic_k(in, inlen,
|
||||
WC_HASH_TYPE_SHA256, &key->k, key->sign_k,
|
||||
curve->order, key->heap) != 0) {
|
||||
mp_free(key->sign_k);
|
||||
XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
|
||||
key->sign_k = NULL;
|
||||
wc_ecc_curve_free(curve);
|
||||
FREE_CURVE_SPECS();
|
||||
return ECC_PRIV_KEY_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wc_ecc_curve_free(curve);
|
||||
FREE_CURVE_SPECS();
|
||||
return MEMORY_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wc_ecc_curve_free(curve);
|
||||
FREE_CURVE_SPECS();
|
||||
return err;
|
||||
}
|
||||
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K */
|
||||
|
||||
#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)
|
||||
@ -5356,7 +5400,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
|
||||
err = RNG_FAILURE_E;
|
||||
break;
|
||||
}
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
|
||||
defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
if (key->sign_k != NULL) {
|
||||
if (loop_check > 1) {
|
||||
err = RNG_FAILURE_E;
|
||||
@ -5375,6 +5420,13 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
|
||||
#ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
|
||||
loop_check = 64;
|
||||
#endif
|
||||
#ifdef WOLFSSL_ECDSA_DETERMINISTIC_K
|
||||
if (key->deterministic == 1) {
|
||||
/* sign_k generated earlier in function for SP calls.
|
||||
* Only go through the loop once and fail if error */
|
||||
loop_check = 64;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* compute public key based on provided "k" */
|
||||
err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
|
||||
@ -5474,6 +5526,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
|
||||
defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
|
||||
(defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
|
||||
(defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
|
||||
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
|
||||
@ -5504,13 +5557,24 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
/* generate deterministic 'k' value to be used either with SP or normal */
|
||||
if (key->deterministic == 1) {
|
||||
if (deterministic_sign_helper(in, inlen, key)) {
|
||||
WOLFSSL_MSG("Error generating deterministic k to sign");
|
||||
return ECC_PRIV_KEY_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_HAVE_SP_ECC)
|
||||
if (key->idx != ECC_CUSTOM_IDX
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
||||
&& key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC
|
||||
#endif
|
||||
) {
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
|
||||
|| defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
mp_int* sign_k = key->sign_k;
|
||||
#else
|
||||
mp_int* sign_k = NULL;
|
||||
@ -5611,7 +5675,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||
}
|
||||
|
||||
/* load curve info */
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
|
||||
defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
|
||||
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
|
||||
#else
|
||||
@ -5756,6 +5821,264 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
/* helper function to do HMAC operations
|
||||
* returns 0 on success and updates "out" buffer
|
||||
*/
|
||||
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
|
||||
const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
|
||||
byte* out, enum wc_HashType hashType, void* heap) {
|
||||
Hmac hmac;
|
||||
int ret;
|
||||
|
||||
ret = wc_HmacInit(&hmac, heap, 0);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacSetKey(&hmac, hashType, K, KSz);
|
||||
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(&hmac, V, VSz);
|
||||
|
||||
if (ret == 0 && oct != NULL)
|
||||
ret = wc_HmacUpdate(&hmac, oct, 1);
|
||||
|
||||
if (ret == 0)
|
||||
wc_HmacUpdate(&hmac, x, xSz);
|
||||
|
||||
if (ret == 0)
|
||||
wc_HmacUpdate(&hmac, h1, h1Sz);
|
||||
|
||||
if (ret == 0)
|
||||
wc_HmacFinal(&hmac, out);
|
||||
|
||||
wc_HmacFree(&hmac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Generates a deterministic key based of the message using RFC6967
|
||||
* @param [in] hash Hash value to sign
|
||||
* @param [in] hashSz Size of 'hash' buffer passed in
|
||||
* @param [in] hashType Type of hash to use with deterministic k gen, i.e.
|
||||
* WC_HASH_TYPE_SHA256
|
||||
* @param [in] priv Current ECC private key set
|
||||
* @param [out] k An initialized mp_int to set the k value generated in
|
||||
* @param [in] order ECC order parameter to use with generation
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
|
||||
enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
|
||||
void* heap)
|
||||
{
|
||||
int ret = 0, qbits = 0;
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
byte h1[WC_MAX_DIGEST_SIZE];
|
||||
byte V[WC_MAX_DIGEST_SIZE];
|
||||
byte K[WC_MAX_DIGEST_SIZE];
|
||||
byte x[MAX_ECC_BYTES];
|
||||
#else
|
||||
byte *h1 = NULL;
|
||||
byte *V = NULL;
|
||||
byte *K = NULL;
|
||||
byte *x = NULL;
|
||||
#endif
|
||||
word32 xSz, VSz, KSz, h1len;
|
||||
byte intOct;
|
||||
mp_int z1;
|
||||
|
||||
if (hash == NULL || k == NULL || order == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (hashSz > WC_MAX_DIGEST_SIZE) {
|
||||
WOLFSSL_MSG("hash size was too large!");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((xSz = mp_unsigned_bin_size(priv)) > MAX_ECC_BYTES) {
|
||||
WOLFSSL_MSG("private key larger than max expected!");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
h1 = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_DIGEST);
|
||||
if (h1 == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (V == NULL)
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (K == NULL)
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (x == NULL)
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
/* bail out if any error has been hit at this point */
|
||||
if (ret != 0) {
|
||||
if (x != NULL)
|
||||
XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (K != NULL)
|
||||
XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (V != NULL)
|
||||
XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (h1 != NULL)
|
||||
XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
VSz = KSz = h1len = hashSz;
|
||||
XMEMSET(V, 0x01, VSz);
|
||||
XMEMSET(K, 0x00, KSz);
|
||||
|
||||
ret = mp_to_unsigned_bin(priv, x);
|
||||
|
||||
mp_init(&z1); /* always init z1 and free z1 */
|
||||
if (ret == 0) {
|
||||
qbits = mp_count_bits(order);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = mp_read_unsigned_bin(&z1, hash, hashSz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* right shift by bits in hash minus bits in order */
|
||||
mp_rshb(&z1, (hashSz * WOLFSSL_BIT_SIZE) - qbits);
|
||||
XMEMSET(h1, 0, sizeof(h1));
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* mod reduce by order using conditional subtract */
|
||||
if (mp_cmp(&z1, order) == MP_GT) {
|
||||
mp_sub(&z1, order, &z1);
|
||||
h1len = mp_unsigned_bin_size(&z1);
|
||||
if (h1len < 0 || h1len > WC_MAX_DIGEST_SIZE) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else {
|
||||
ret = mp_to_unsigned_bin(&z1, h1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* use original hash and keep leading 0's */
|
||||
h1len = hashSz;
|
||||
XMEMCPY(h1, hash, hashSz);
|
||||
}
|
||||
}
|
||||
mp_free(&z1);
|
||||
|
||||
/* step d. */
|
||||
if (ret == 0) {
|
||||
intOct = 0x00;
|
||||
ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
|
||||
hashType, heap);
|
||||
}
|
||||
|
||||
/* step e. */
|
||||
if (ret == 0) {
|
||||
ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
|
||||
heap);
|
||||
}
|
||||
|
||||
|
||||
/* step f. */
|
||||
if (ret == 0) {
|
||||
intOct = 0x01;
|
||||
ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
|
||||
heap);
|
||||
}
|
||||
|
||||
/* step g. */
|
||||
if (ret == 0) {
|
||||
ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
|
||||
heap);
|
||||
}
|
||||
|
||||
/* step h. */
|
||||
if (ret == 0 ) {
|
||||
int err;
|
||||
intOct = 0x00;
|
||||
do {
|
||||
err = 0; /* start as good until generated k is tested */
|
||||
|
||||
ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
|
||||
heap);
|
||||
if (ret == 0) {
|
||||
mp_clear(k);
|
||||
ret = mp_read_unsigned_bin(k, V, VSz);
|
||||
}
|
||||
|
||||
if ((ret == 0) && ((int)(VSz * WOLFSSL_BIT_SIZE) != qbits)) {
|
||||
/* handle odd case where shift of 'k' is needed */
|
||||
mp_rshb(k, (VSz * WOLFSSL_BIT_SIZE) - qbits);
|
||||
}
|
||||
|
||||
/* the key should be smaller than the order of base point */
|
||||
if (ret == 0) {
|
||||
if (mp_cmp(k, order) != MP_LT) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* no 0 key's */
|
||||
if (ret == 0) {
|
||||
if (mp_iszero(k) == MP_YES)
|
||||
err = MP_ZERO_E;
|
||||
}
|
||||
|
||||
/* if there was a problem with 'k' generated then try again */
|
||||
if (ret == 0 && err != 0) {
|
||||
ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
|
||||
hashType, heap);
|
||||
if (ret == 0) {
|
||||
ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
|
||||
hashType, heap);
|
||||
}
|
||||
}
|
||||
} while (ret == 0 && err != 0);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (x != NULL)
|
||||
XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (K != NULL)
|
||||
XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (V != NULL)
|
||||
XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (h1 != NULL)
|
||||
XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Sets the deterministic flag for 'k' generation with sign.
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
|
||||
{
|
||||
if (key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
key->deterministic = flag;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
|
||||
{
|
||||
|
@ -20663,6 +20663,95 @@ static int ecc_test_vector(int keySize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
static int ecc_test_deterministic_k(WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
ecc_key key;
|
||||
byte sig[72];
|
||||
word32 sigSz;
|
||||
unsigned char msg[] = "sample";
|
||||
unsigned char hash[32];
|
||||
const char* dIUT =
|
||||
"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
|
||||
const char* QIUTx =
|
||||
"60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6";
|
||||
const char* QIUTy =
|
||||
"7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299";
|
||||
const byte expSig[] = {
|
||||
0x30, 0x46, 0x02, 0x21, 0x00, 0xEF, 0xD4, 0x8B,
|
||||
0x2A, 0xAC, 0xB6, 0xA8, 0xFD, 0x11, 0x40, 0xDD,
|
||||
0x9C, 0xD4, 0x5E, 0x81, 0xD6, 0x9D, 0x2C, 0x87,
|
||||
0x7B, 0x56, 0xAA, 0xF9, 0x91, 0xC3, 0x4D, 0x0E,
|
||||
0xA8, 0x4E, 0xAF, 0x37, 0x16, 0x02, 0x21, 0x00,
|
||||
0xF7, 0xCB, 0x1C, 0x94, 0x2D, 0x65, 0x7C, 0x41,
|
||||
0xD4, 0x36, 0xC7, 0xA1, 0xB6, 0xE2, 0x9F, 0x65,
|
||||
0xF3, 0xE9, 0x00, 0xDB, 0xB9, 0xAF, 0xF4, 0x06,
|
||||
0x4D, 0xC4, 0xAB, 0x2F, 0x84, 0x3A, 0xCD, 0xA8
|
||||
};
|
||||
|
||||
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_Hash(WC_HASH_TYPE_SHA256, msg,
|
||||
(word32)XSTRLEN((const char*)msg), hash, sizeof(hash));
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wc_ecc_set_deterministic(&key, 1);
|
||||
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 = -9830;
|
||||
goto done;
|
||||
}
|
||||
if (XMEMCMP(sig, expSig, sigSz) != 0) {
|
||||
ret = -9831;
|
||||
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
|
||||
|
||||
|
||||
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
|
||||
static int ecc_test_sign_vectors(WC_RNG* rng)
|
||||
{
|
||||
@ -23547,6 +23636,14 @@ WOLFSSL_TEST_SUBROUTINE int ecc_test(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
ret = ecc_test_deterministic_k(&rng);
|
||||
if (ret != 0) {
|
||||
printf("ecc_test_deterministic_k failed! %d\n", ret);
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
|
||||
ret = ecc_test_sign_vectors(&rng);
|
||||
if (ret != 0) {
|
||||
|
@ -456,9 +456,13 @@ struct ecc_key {
|
||||
ecc_context_t ctx;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
|
||||
defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
mp_int *sign_k;
|
||||
#endif
|
||||
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K)
|
||||
byte deterministic:1;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
||||
mp_int* t1;
|
||||
@ -566,6 +570,14 @@ 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_DETERMINISTIC_K
|
||||
WOLFSSL_API
|
||||
int wc_ecc_set_deterministic(ecc_key* key, byte flag);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
|
||||
enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
|
||||
void* heap);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
|
||||
WOLFSSL_API
|
||||
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key);
|
||||
|
Reference in New Issue
Block a user