ecc: ecc_make_key_ex, ecc_export_x963, accel_fp_mul, accel_fp_mul2add, ecc_encrypt and ecc_decrypt refactory to reduce stack usage: (1350 bytes - pointer sizes) moved to the heap.
--- ecc_make_key_ex: buf variable moved to the heap; (66 bytes) --- ecc_export_x963: buf variable moved to the heap; (256 bytes) --- accel_fp_mul: kb variable moved to the heap; (128 bytes) --- accel_fp_mul2add: kb variable moved to the heap; (256 bytes) --- ecc_encrypt: sharedSecret and keys variables moved to the heap; (66 + 256 bytes) --- ecc_decrypt: sharedSecret and keys variables moved to the heap; (66 + 256 bytes)
This commit is contained in:
parent
fc24dca12d
commit
ce655f61c5
@ -1319,12 +1319,22 @@ int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp)
|
||||
ecc_point* base;
|
||||
mp_int prime;
|
||||
mp_int order;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* buf;
|
||||
#else
|
||||
byte buf[ECC_MAXSIZE];
|
||||
#endif
|
||||
int keysize;
|
||||
|
||||
if (key == NULL || rng == NULL || dp == NULL)
|
||||
return ECC_BAD_ARG_E;
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
buf = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (buf == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
key->idx = -1;
|
||||
key->dp = dp;
|
||||
keysize = dp->size;
|
||||
@ -1334,19 +1344,22 @@ int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp)
|
||||
|
||||
/* make up random string */
|
||||
err = RNG_GenerateBlock(rng, buf, keysize);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
buf[0] |= 0x0c;
|
||||
if (err == 0)
|
||||
buf[0] |= 0x0c;
|
||||
|
||||
/* setup the key variables */
|
||||
if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z,
|
||||
&key->k, &prime, &order)) != MP_OKAY)
|
||||
return MEMORY_E;
|
||||
if (err == 0) {
|
||||
err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z,
|
||||
&key->k, &prime, &order);
|
||||
if (err != MP_OKAY)
|
||||
err = MEMORY_E;
|
||||
}
|
||||
|
||||
base = ecc_new_point();
|
||||
if (base == NULL)
|
||||
err = MEMORY_E;
|
||||
if (err == MP_OKAY) {
|
||||
base = ecc_new_point();
|
||||
if (base == NULL)
|
||||
err = MEMORY_E;
|
||||
}
|
||||
|
||||
/* read in the specs for this key */
|
||||
if (err == MP_OKAY)
|
||||
@ -1384,9 +1397,15 @@ int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp)
|
||||
ecc_del_point(base);
|
||||
mp_clear(&prime);
|
||||
mp_clear(&order);
|
||||
|
||||
#ifdef ECC_CLEAN_STACK
|
||||
XMEMSET(buff, 0, ECC_MAXSIZE);
|
||||
XMEMSET(buf, 0, ECC_MAXSIZE);
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1750,8 +1769,8 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA,
|
||||
}
|
||||
}
|
||||
#ifdef ECC_CLEAN_STACK
|
||||
XMEMSET(tA, 0, ECC_BUF_SIZE);
|
||||
XMEMSET(tB, 0, ECC_BUF_SIZE);
|
||||
XMEMSET(tA, 0, ECC_BUFSIZE);
|
||||
XMEMSET(tB, 0, ECC_BUFSIZE);
|
||||
#endif
|
||||
XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(tB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@ -1955,7 +1974,11 @@ int ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||
/* export public ECC key in ANSI X9.63 format */
|
||||
int ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
|
||||
{
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* buf;
|
||||
#else
|
||||
byte buf[ECC_BUFSIZE];
|
||||
#endif
|
||||
word32 numlen;
|
||||
int ret = MP_OKAY;
|
||||
|
||||
@ -1975,25 +1998,37 @@ int ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
|
||||
/* store byte 0x04 */
|
||||
out[0] = 0x04;
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (buf == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
do {
|
||||
/* pad and store x */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
XMEMSET(buf, 0, ECC_BUFSIZE);
|
||||
ret = mp_to_unsigned_bin(&key->pubkey.x,
|
||||
buf + (numlen - mp_unsigned_bin_size(&key->pubkey.x)));
|
||||
if (ret != MP_OKAY)
|
||||
return ret;
|
||||
break;
|
||||
XMEMCPY(out+1, buf, numlen);
|
||||
|
||||
/* pad and store y */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
XMEMSET(buf, 0, ECC_BUFSIZE);
|
||||
ret = mp_to_unsigned_bin(&key->pubkey.y,
|
||||
buf + (numlen - mp_unsigned_bin_size(&key->pubkey.y)));
|
||||
if (ret != MP_OKAY)
|
||||
return ret;
|
||||
break;
|
||||
XMEMCPY(out+1+numlen, buf, numlen);
|
||||
|
||||
*outLen = 1 + 2*numlen;
|
||||
} while (0);
|
||||
|
||||
return 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -2928,7 +2963,13 @@ static int build_lut(int idx, mp_int* modulus, mp_digit* mp, mp_int* mu)
|
||||
static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus,
|
||||
mp_digit* mp, int map)
|
||||
{
|
||||
#define KB_SIZE 128
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
unsigned char* kb;
|
||||
#else
|
||||
unsigned char kb[128];
|
||||
#endif
|
||||
int x;
|
||||
unsigned y, z, err, bitlen, bitpos, lut_gap, first;
|
||||
mp_int tk;
|
||||
@ -2983,18 +3024,23 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus,
|
||||
lut_gap = bitlen / FP_LUT;
|
||||
|
||||
/* get the k value */
|
||||
if (mp_unsigned_bin_size(&tk) > (int)(sizeof(kb) - 2)) {
|
||||
if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
|
||||
mp_clear(&tk);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* store k */
|
||||
XMEMSET(kb, 0, sizeof(kb));
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (kb == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(kb, 0, KB_SIZE);
|
||||
if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) {
|
||||
mp_clear(&tk);
|
||||
return err;
|
||||
}
|
||||
|
||||
else {
|
||||
/* let's reverse kb so it's little endian */
|
||||
x = 0;
|
||||
y = mp_unsigned_bin_size(&tk) - 1;
|
||||
@ -3020,7 +3066,7 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus,
|
||||
/* double if not first */
|
||||
if (!first) {
|
||||
if ((err = ecc_projective_dbl_point(R, R, modulus, mp)) != MP_OKAY) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3028,25 +3074,36 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus,
|
||||
if (!first && z) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
|
||||
modulus, mp)) != MP_OKAY) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
} 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) ||
|
||||
(mp_copy(&fp_cache[idx].mu, &R->z) != MP_OKAY)) {
|
||||
return GEN_MEM_ERR;
|
||||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err == MP_OKAY) {
|
||||
z = 0;
|
||||
XMEMSET(kb, 0, sizeof(kb));
|
||||
XMEMSET(kb, 0, KB_SIZE);
|
||||
/* map R back from projective space */
|
||||
if (map) {
|
||||
err = ecc_map(R, modulus, mp);
|
||||
} else {
|
||||
err = MP_OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
#undef KB_SIZE
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -3057,7 +3114,13 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
mp_int* kA, mp_int* kB,
|
||||
ecc_point *R, mp_int* modulus, mp_digit* mp)
|
||||
{
|
||||
#define KB_SIZE 128
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
unsigned char* kb[2];
|
||||
#else
|
||||
unsigned char kb[2][128];
|
||||
#endif
|
||||
int x;
|
||||
unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
|
||||
mp_int tka;
|
||||
@ -3154,18 +3217,25 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
lut_gap = bitlen / FP_LUT;
|
||||
|
||||
/* get the k value */
|
||||
if ((mp_unsigned_bin_size(&tka) > (int)(sizeof(kb[0]) - 2)) ||
|
||||
(mp_unsigned_bin_size(&tkb) > (int)(sizeof(kb[0]) - 2)) ) {
|
||||
if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
|
||||
(mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) {
|
||||
mp_clear(&tka);
|
||||
mp_clear(&tkb);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* store k */
|
||||
XMEMSET(kb, 0, sizeof(kb));
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (kb[0] == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(kb[0], 0, KB_SIZE);
|
||||
if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
|
||||
mp_clear(&tka);
|
||||
mp_clear(&tkb);
|
||||
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3179,11 +3249,19 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
}
|
||||
|
||||
/* store b */
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (kb[1] == NULL) {
|
||||
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
XMEMSET(kb[1], 0, KB_SIZE);
|
||||
if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) {
|
||||
mp_clear(&tkb);
|
||||
return err;
|
||||
}
|
||||
|
||||
else {
|
||||
x = 0;
|
||||
y = mp_unsigned_bin_size(&tkb) - 1;
|
||||
mp_clear(&tkb);
|
||||
@ -3208,7 +3286,7 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
/* double if not first */
|
||||
if (!first) {
|
||||
if ((err = ecc_projective_dbl_point(R, R, modulus, mp)) != MP_OKAY) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3217,13 +3295,13 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
if (zA) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
|
||||
R, modulus, mp)) != MP_OKAY) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (zB) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
|
||||
R, modulus, mp)) != MP_OKAY) {
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -3231,7 +3309,8 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
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)) {
|
||||
return GEN_MEM_ERR;
|
||||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
@ -3239,20 +3318,31 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||
if (zB) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
|
||||
R, modulus, mp)) != MP_OKAY){
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} 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)) {
|
||||
return GEN_MEM_ERR;
|
||||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
XMEMSET(kb, 0, sizeof(kb));
|
||||
}
|
||||
}
|
||||
|
||||
XMEMSET(kb[0], 0, KB_SIZE);
|
||||
XMEMSET(kb[1], 0, KB_SIZE);
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
#undef KB_SIZE
|
||||
|
||||
return ecc_map(R, modulus, mp);
|
||||
}
|
||||
@ -3741,9 +3831,14 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 blockSz;
|
||||
word32 digestSz;
|
||||
ecEncCtx localCtx;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* sharedSecret;
|
||||
byte* keys;
|
||||
#else
|
||||
byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
|
||||
byte keys[ECC_BUFSIZE]; /* max size */
|
||||
word32 sharedSz = sizeof(sharedSecret);
|
||||
#endif
|
||||
word32 sharedSz = ECC_MAXSIZE;
|
||||
int keysLen;
|
||||
int encKeySz;
|
||||
int ivSz;
|
||||
@ -3782,7 +3877,7 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
|
||||
}
|
||||
|
||||
if (keysLen > (int)sizeof(keys))
|
||||
if (keysLen > ECC_BUFSIZE) /* keys size */
|
||||
return BUFFER_E;
|
||||
|
||||
if ( (msgSz%blockSz) != 0)
|
||||
@ -3791,23 +3886,34 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
if (*outSz < (msgSz + digestSz))
|
||||
return BUFFER_E;
|
||||
|
||||
ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sharedSecret == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (keys == NULL) {
|
||||
XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
|
||||
|
||||
if (ret == 0) {
|
||||
switch (ctx->kdfAlgo) {
|
||||
case ecHKDF_SHA256 :
|
||||
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
|
||||
ctx->kdfSaltSz, ctx->kdfInfo,
|
||||
ctx->kdfInfoSz, keys, keysLen);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
|
||||
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, keys, keysLen);
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
encKey = keys + offset;
|
||||
encIv = encKey + encKeySz;
|
||||
macKey = encKey + encKeySz + ivSz;
|
||||
@ -3818,43 +3924,50 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
Aes aes;
|
||||
ret = AesSetKey(&aes, encKey,KEY_SIZE_128,encIv,AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = AesCbcEncrypt(&aes, out, msg, msgSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
switch (ctx->macAlgo) {
|
||||
case ecHMAC_SHA256:
|
||||
{
|
||||
Hmac hmac;
|
||||
ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacUpdate(&hmac, out, msgSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacFinal(&hmac, out+msgSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
*outSz = msgSz + digestSz;
|
||||
|
||||
return 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -3868,9 +3981,14 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 blockSz;
|
||||
word32 digestSz;
|
||||
ecEncCtx localCtx;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* sharedSecret;
|
||||
byte* keys;
|
||||
#else
|
||||
byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
|
||||
byte keys[ECC_BUFSIZE]; /* max size */
|
||||
word32 sharedSz = sizeof(sharedSecret);
|
||||
#endif
|
||||
word32 sharedSz = ECC_MAXSIZE;
|
||||
int keysLen;
|
||||
int encKeySz;
|
||||
int ivSz;
|
||||
@ -3909,7 +4027,7 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
|
||||
}
|
||||
|
||||
if (keysLen > (int)sizeof(keys))
|
||||
if (keysLen > ECC_BUFSIZE) /* keys size */
|
||||
return BUFFER_E;
|
||||
|
||||
if ( ((msgSz-digestSz) % blockSz) != 0)
|
||||
@ -3918,23 +4036,34 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
if (*outSz < (msgSz - digestSz))
|
||||
return BUFFER_E;
|
||||
|
||||
ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sharedSecret == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (keys == NULL) {
|
||||
XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
|
||||
|
||||
if (ret == 0) {
|
||||
switch (ctx->kdfAlgo) {
|
||||
case ecHKDF_SHA256 :
|
||||
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
|
||||
ctx->kdfSaltSz, ctx->kdfInfo,
|
||||
ctx->kdfInfoSz, keys, keysLen);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
|
||||
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, keys, keysLen);
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
encKey = keys + offset;
|
||||
encIv = encKey + encKeySz;
|
||||
macKey = encKey + encKeySz + ivSz;
|
||||
@ -3946,47 +4075,54 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
Hmac hmac;
|
||||
ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacUpdate(&hmac, msg, msgSz-digestSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = HmacFinal(&hmac, verify);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0)
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
switch (ctx->encAlgo) {
|
||||
case ecAES_128_CBC:
|
||||
{
|
||||
Aes aes;
|
||||
ret = AesSetKey(&aes, encKey,KEY_SIZE_128,encIv,AES_DECRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
ret = AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
ret = BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
*outSz = msgSz - digestSz;
|
||||
|
||||
return 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user