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);
|
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
|
#ifndef USE_FAST_MATH
|
||||||
mp_clear(key->r);
|
mp_clear(*r);
|
||||||
#endif
|
#endif
|
||||||
XFREE(key->r, key->heap, DYNAMIC_TYPE_BIGINT);
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
|
XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT);
|
||||||
key->r = NULL;
|
key->r = NULL;
|
||||||
}
|
|
||||||
if (key->s) {
|
|
||||||
#ifndef USE_FAST_MATH
|
|
||||||
mp_clear(key->s);
|
|
||||||
#endif
|
#endif
|
||||||
XFREE(key->s, key->heap, DYNAMIC_TYPE_BIGINT);
|
*r = NULL;
|
||||||
key->s = 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 */
|
/* 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)
|
WC_RNG* rng, ecc_key* key)
|
||||||
{
|
{
|
||||||
int err;
|
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 ||
|
if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
|
||||||
rng == 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_NONE:
|
||||||
case ECC_STATE_SIGN_DO:
|
case ECC_STATE_SIGN_DO:
|
||||||
key->state = 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);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (key->s == NULL)
|
if (s == NULL)
|
||||||
key->s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||||
DYNAMIC_TYPE_BIGINT);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (key->r == NULL || key->s == NULL) {
|
if (r == NULL || s == NULL) {
|
||||||
err = MEMORY_E; break;
|
err = MEMORY_E; break;
|
||||||
}
|
}
|
||||||
XMEMSET(key->r, 0, sizeof(mp_int));
|
key->r = r;
|
||||||
XMEMSET(key->s, 0, sizeof(mp_int));
|
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) {
|
!= MP_OKAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_ATECC508A
|
#ifdef WOLFSSL_ATECC508A
|
||||||
/* Check args */
|
/* Check args */
|
||||||
if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) {
|
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 */
|
/* 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) {
|
if (err != MP_OKAY) {
|
||||||
return err;
|
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) {
|
if (err != MP_OKAY) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for zeros */
|
/* Check for zeros */
|
||||||
if (mp_iszero(key->r) || mp_iszero(key->s)) {
|
if (mp_iszero(r) || mp_iszero(s)) {
|
||||||
return MP_ZERO_E;
|
return MP_ZERO_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#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) {
|
if (err < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3169,8 +3186,13 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
|||||||
case ECC_STATE_SIGN_ENCODE:
|
case ECC_STATE_SIGN_ENCODE:
|
||||||
key->state = 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 */
|
/* encoded with DSA header */
|
||||||
err = StoreECC_DSA_Sig(out, outlen, key->r, key->s);
|
err = StoreECC_DSA_Sig(out, outlen, r, s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -3183,7 +3205,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
wc_ecc_free_rs(key);
|
wc_ecc_free_rs(key, &r, &s);
|
||||||
|
|
||||||
key->state = ECC_STATE_NONE;
|
key->state = ECC_STATE_NONE;
|
||||||
|
|
||||||
@ -3323,8 +3345,8 @@ void wc_ecc_free(ecc_key* key)
|
|||||||
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
|
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
|
||||||
wolfAsync_DevCtxFree(&key->asyncDev);
|
wolfAsync_DevCtxFree(&key->asyncDev);
|
||||||
}
|
}
|
||||||
|
wc_ecc_free_rs(key, &key->r, &key->s);
|
||||||
#endif
|
#endif
|
||||||
wc_ecc_free_rs(key);
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_ATECC508A
|
#ifdef WOLFSSL_ATECC508A
|
||||||
atmel_ecc_free(key->slot);
|
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)
|
word32 hashlen, int* stat, ecc_key* key)
|
||||||
{
|
{
|
||||||
int err;
|
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) {
|
if (sig == NULL || hash == NULL || stat == NULL || key == NULL) {
|
||||||
return ECC_BAD_ARG_E;
|
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
|
* If either of those don't allocate correctly, none of
|
||||||
* the rest of this function will execute, and everything
|
* the rest of this function will execute, and everything
|
||||||
* gets cleaned up at the end. */
|
* gets cleaned up at the end. */
|
||||||
if (key->r == NULL)
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
key->r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
if (r == NULL)
|
||||||
|
r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||||
DYNAMIC_TYPE_BIGINT);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (key->s == NULL)
|
if (s == NULL)
|
||||||
key->s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||||
DYNAMIC_TYPE_BIGINT);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (key->r == NULL || key->s == NULL) {
|
if (r == NULL || s == NULL) {
|
||||||
err = MEMORY_E; break;
|
err = MEMORY_E; break;
|
||||||
}
|
}
|
||||||
XMEMSET(key->r, 0, sizeof(mp_int));
|
key->r = r;
|
||||||
XMEMSET(key->s, 0, sizeof(mp_int));
|
key->s = s;
|
||||||
|
#endif
|
||||||
|
XMEMSET(r, 0, sizeof(mp_int));
|
||||||
|
XMEMSET(s, 0, sizeof(mp_int));
|
||||||
|
|
||||||
/* decode DSA header */
|
/* decode DSA header */
|
||||||
err = DecodeECC_DSA_Sig(sig, siglen, key->r, key->s);
|
err = DecodeECC_DSA_Sig(sig, siglen, r, s);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3653,7 +3685,12 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
|||||||
case ECC_STATE_VERIFY_DO:
|
case ECC_STATE_VERIFY_DO:
|
||||||
key->state = 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);
|
key);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
break;
|
break;
|
||||||
@ -3675,7 +3712,7 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
wc_ecc_free_rs(key);
|
wc_ecc_free_rs(key, &r, &s);
|
||||||
|
|
||||||
key->state = ECC_STATE_NONE;
|
key->state = ECC_STATE_NONE;
|
||||||
|
|
||||||
|
@ -274,10 +274,9 @@ typedef struct ecc_key {
|
|||||||
ecc_point pubkey; /* public key */
|
ecc_point pubkey; /* public key */
|
||||||
mp_int k; /* private key */
|
mp_int k; /* private key */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
mp_int* r; /* sign/verify temps */
|
mp_int* r; /* sign/verify temps */
|
||||||
mp_int* s;
|
mp_int* s;
|
||||||
|
|
||||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
||||||
AsyncCryptDev asyncDev;
|
AsyncCryptDev asyncDev;
|
||||||
#endif
|
#endif
|
||||||
} ecc_key;
|
} ecc_key;
|
||||||
|
Reference in New Issue
Block a user