forked from wolfSSL/wolfssl
Merge pull request #782 from dgarske/ecc_mem
Fix to reduce ECC memory usage when async crypt is not enabled
This commit is contained in:
@ -2976,22 +2976,29 @@ int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
|
||||
return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
|
||||
}
|
||||
|
||||
static void wc_ecc_free_rs(ecc_key* key)
|
||||
static INLINE void wc_ecc_free_rs(ecc_key* key, mp_int** r, mp_int** s)
|
||||
{
|
||||
if (key->r) {
|
||||
if (*r) {
|
||||
#ifndef USE_FAST_MATH
|
||||
mp_clear(key->r);
|
||||
mp_clear(*r);
|
||||
#endif
|
||||
XFREE(key->r, key->heap, DYNAMIC_TYPE_BIGINT);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT);
|
||||
key->r = NULL;
|
||||
}
|
||||
if (key->s) {
|
||||
#ifndef USE_FAST_MATH
|
||||
mp_clear(key->s);
|
||||
#endif
|
||||
XFREE(key->s, key->heap, DYNAMIC_TYPE_BIGINT);
|
||||
key->s = NULL;
|
||||
*r = NULL;
|
||||
}
|
||||
if (*s) {
|
||||
#ifndef USE_FAST_MATH
|
||||
mp_clear(*s);
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
XFREE(*s, key->heap, DYNAMIC_TYPE_BIGINT);
|
||||
key->s = NULL;
|
||||
#endif
|
||||
*s = NULL;
|
||||
}
|
||||
(void)key;
|
||||
}
|
||||
|
||||
/* Setup dynamic pointers if using normal math for proper freeing */
|
||||
@ -3081,6 +3088,12 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
WC_RNG* rng, ecc_key* key)
|
||||
{
|
||||
int err;
|
||||
mp_int *r = NULL, *s = NULL;
|
||||
#ifndef WOLFSSL_ASYNC_CRYPT
|
||||
mp_int r_lcl, s_lcl;
|
||||
r = &r_lcl;
|
||||
s = &s_lcl;
|
||||
#endif
|
||||
|
||||
if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
|
||||
rng == NULL) {
|
||||
@ -3111,24 +3124,28 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
case ECC_STATE_NONE:
|
||||
case ECC_STATE_SIGN_DO:
|
||||
key->state = ECC_STATE_SIGN_DO;
|
||||
if (key->r == NULL)
|
||||
key->r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (r == NULL)
|
||||
r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
DYNAMIC_TYPE_BIGINT);
|
||||
if (key->s == NULL)
|
||||
key->s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
if (s == NULL)
|
||||
s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
DYNAMIC_TYPE_BIGINT);
|
||||
if (key->r == NULL || key->s == NULL) {
|
||||
if (r == NULL || s == NULL) {
|
||||
err = MEMORY_E; break;
|
||||
}
|
||||
XMEMSET(key->r, 0, sizeof(mp_int));
|
||||
XMEMSET(key->s, 0, sizeof(mp_int));
|
||||
key->r = r;
|
||||
key->s = s;
|
||||
#endif
|
||||
XMEMSET(r, 0, sizeof(mp_int));
|
||||
XMEMSET(s, 0, sizeof(mp_int));
|
||||
|
||||
if ((err = mp_init_multi(key->r, key->s, NULL, NULL, NULL, NULL))
|
||||
if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL))
|
||||
!= MP_OKAY) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* Check args */
|
||||
if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) {
|
||||
@ -3142,23 +3159,23 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
}
|
||||
|
||||
/* Load R and S */
|
||||
err = mp_read_unsigned_bin(key->r, &out[0], ATECC_KEY_SIZE);
|
||||
err = mp_read_unsigned_bin(r, &out[0], ATECC_KEY_SIZE);
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
err = mp_read_unsigned_bin(key->s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE);
|
||||
err = mp_read_unsigned_bin(s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE);
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Check for zeros */
|
||||
if (mp_iszero(key->r) || mp_iszero(key->s)) {
|
||||
if (mp_iszero(r) || mp_iszero(s)) {
|
||||
return MP_ZERO_E;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, key->r, key->s);
|
||||
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
|
||||
if (err < 0) {
|
||||
break;
|
||||
}
|
||||
@ -3169,8 +3186,13 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
case ECC_STATE_SIGN_ENCODE:
|
||||
key->state = ECC_STATE_SIGN_ENCODE;
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
r = key->r;
|
||||
s = key->s;
|
||||
#endif
|
||||
|
||||
/* encoded with DSA header */
|
||||
err = StoreECC_DSA_Sig(out, outlen, key->r, key->s);
|
||||
err = StoreECC_DSA_Sig(out, outlen, r, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3183,7 +3205,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
return err;
|
||||
}
|
||||
|
||||
wc_ecc_free_rs(key);
|
||||
wc_ecc_free_rs(key, &r, &s);
|
||||
|
||||
key->state = ECC_STATE_NONE;
|
||||
|
||||
@ -3323,8 +3345,8 @@ void wc_ecc_free(ecc_key* key)
|
||||
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
|
||||
wolfAsync_DevCtxFree(&key->asyncDev);
|
||||
}
|
||||
wc_ecc_free_rs(key, &key->r, &key->s);
|
||||
#endif
|
||||
wc_ecc_free_rs(key);
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
atmel_ecc_free(key->slot);
|
||||
@ -3594,6 +3616,12 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||
word32 hashlen, int* stat, ecc_key* key)
|
||||
{
|
||||
int err;
|
||||
mp_int *r = NULL, *s = NULL;
|
||||
#ifndef WOLFSSL_ASYNC_CRYPT
|
||||
mp_int r_lcl, s_lcl;
|
||||
r = &r_lcl;
|
||||
s = &s_lcl;
|
||||
#endif
|
||||
|
||||
if (sig == NULL || hash == NULL || stat == NULL || key == NULL) {
|
||||
return ECC_BAD_ARG_E;
|
||||
@ -3631,20 +3659,24 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||
* If either of those don't allocate correctly, none of
|
||||
* the rest of this function will execute, and everything
|
||||
* gets cleaned up at the end. */
|
||||
if (key->r == NULL)
|
||||
key->r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (r == NULL)
|
||||
r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
DYNAMIC_TYPE_BIGINT);
|
||||
if (key->s == NULL)
|
||||
key->s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
if (s == NULL)
|
||||
s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||
DYNAMIC_TYPE_BIGINT);
|
||||
if (key->r == NULL || key->s == NULL) {
|
||||
if (r == NULL || s == NULL) {
|
||||
err = MEMORY_E; break;
|
||||
}
|
||||
XMEMSET(key->r, 0, sizeof(mp_int));
|
||||
XMEMSET(key->s, 0, sizeof(mp_int));
|
||||
key->r = r;
|
||||
key->s = s;
|
||||
#endif
|
||||
XMEMSET(r, 0, sizeof(mp_int));
|
||||
XMEMSET(s, 0, sizeof(mp_int));
|
||||
|
||||
/* decode DSA header */
|
||||
err = DecodeECC_DSA_Sig(sig, siglen, key->r, key->s);
|
||||
err = DecodeECC_DSA_Sig(sig, siglen, r, s);
|
||||
if (err < 0) {
|
||||
break;
|
||||
}
|
||||
@ -3653,7 +3685,12 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||
case ECC_STATE_VERIFY_DO:
|
||||
key->state = ECC_STATE_VERIFY_DO;
|
||||
|
||||
err = wc_ecc_verify_hash_ex(key->r, key->s, hash, hashlen, stat,
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
r = key->r;
|
||||
s = key->s;
|
||||
#endif
|
||||
|
||||
err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, stat,
|
||||
key);
|
||||
if (err < 0) {
|
||||
break;
|
||||
@ -3675,7 +3712,7 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||
return err;
|
||||
}
|
||||
|
||||
wc_ecc_free_rs(key);
|
||||
wc_ecc_free_rs(key, &r, &s);
|
||||
|
||||
key->state = ECC_STATE_NONE;
|
||||
|
||||
|
@ -274,10 +274,9 @@ typedef struct ecc_key {
|
||||
ecc_point pubkey; /* public key */
|
||||
mp_int k; /* private key */
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
mp_int* r; /* sign/verify temps */
|
||||
mp_int* s;
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
AsyncCryptDev asyncDev;
|
||||
#endif
|
||||
} ecc_key;
|
||||
|
Reference in New Issue
Block a user