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:
toddouska
2017-03-08 15:35:47 -08:00
committed by GitHub
2 changed files with 74 additions and 38 deletions

View File

@ -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;

View File

@ -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;