ECIES: add support for more encryption algorithms

Add support to ECIES for AES-256-CBC, AES-128-CTR, AES-256-CTR.
Added new API wc_ecc_ctx_set_algo() that sets the encryption, KDF and
MAC algorithms.
Cleanup formatting of ECIES code.
pull/4805/head
Sean Parkinson 2022-01-28 16:26:24 +10:00
parent 1465f99b12
commit e50f661639
5 changed files with 505 additions and 256 deletions

View File

@ -1602,6 +1602,38 @@ void wc_ecc_ctx_free(ecEncCtx*);
WOLFSSL_API
int wc_ecc_ctx_reset(ecEncCtx*, WC_RNG*); /* reset for use again w/o alloc/free */
/*!
\ingroup ECC
\brief This function can optionally be called after
wc_ecc_ctx_new. It sets the encryption, KDF, and MAC algorithms
into an ecEncCtx object.
\return 0 Returned upon successfully setting the information
for the ecEncCtx object.
\return BAD_FUNC_ARG Returned if the given ecEncCtx object is
NULL.
\param ctx pointer to the ecEncCtx for which to set the info
\param encAlgo encryption algorithm to use.
\param kdfAlgo KDF algorithm to use.
\param macAlgo MAC algorithm to use.
_Example_
\code
ecEncCtx* ctx;
// initialize ctx
if(wc_ecc_ctx_set_algo(&ctx, ecAES_128_CTR, ecHKDF_SHA256, ecHMAC_SHA256))) {
// error setting info
}
\endcode
\sa wc_ecc_ctx_new
*/
WOLFSSL_API
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo,
byte macAlgo);
/*!
\ingroup ECC

View File

@ -11713,6 +11713,19 @@ struct ecEncCtx {
WC_RNG* rng;
};
/* optional set info, can be called before or after set_peer_salt */
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
ctx->encAlgo = encAlgo;
ctx->kdfAlgo = kdfAlgo;
ctx->macAlgo = macAlgo;
return 0;
}
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
{
@ -11826,7 +11839,21 @@ static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
if (ctx) {
XMEMSET(ctx, 0, sizeof(ecEncCtx));
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
#ifdef WOLFSSL_AES_128
ctx->encAlgo = ecAES_128_CBC;
#else
ctx->encAlgo = ecAES_256_CBC;
#endif
#elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
#ifdef WOLFSSL_AES_256
ctx->encAlgo = ecAES_256_CTR;
#else
ctx->encAlgo = ecAES_128_CTR;
#endif
#else
#error "No valid encryption algorithm for ECIES configured."
#endif
ctx->kdfAlgo = ecHKDF_SHA256;
ctx->macAlgo = ecHMAC_SHA256;
ctx->protocol = (byte)flags;
@ -11895,11 +11922,30 @@ static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
{
if (ctx) {
switch (ctx->encAlgo) {
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
case ecAES_128_CBC:
*encKeySz = KEY_SIZE_128;
*ivSz = IV_SIZE_128;
*blockSz = AES_BLOCK_SIZE;
break;
case ecAES_256_CBC:
*encKeySz = KEY_SIZE_256;
*ivSz = IV_SIZE_128;
*blockSz = AES_BLOCK_SIZE;
break;
#endif
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
case ecAES_128_CTR:
*encKeySz = KEY_SIZE_128;
*ivSz = IV_SIZE_128;
*blockSz = 1;
break;
case ecAES_256_CTR:
*encKeySz = KEY_SIZE_256;
*ivSz = IV_SIZE_128;
*blockSz = 1;
break;
#endif
default:
return BAD_FUNC_ARG;
}
@ -12102,8 +12148,9 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
switch (ctx->encAlgo) {
case ecAES_128_CBC:
case ecAES_256_CBC:
{
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
#ifdef WOLFSSL_SMALL_STACK
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
DYNAMIC_TYPE_AES);
@ -12116,11 +12163,48 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#endif
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, encKey, KEY_SIZE_128, encIv,
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
AES_ENCRYPTION);
if (ret == 0) {
ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
#if defined(WOLFSSL_ASYNC_CRYPT) && \
defined(WC_ASYNC_ENABLE_AES)
ret = wc_AsyncWait(ret, &aes->asyncDev,
WC_ASYNC_FLAG_NONE);
#endif
}
wc_AesFree(aes);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
#else
ret = NOT_COMPILED_IN;
#endif
break;
}
case ecAES_128_CTR:
case ecAES_256_CTR:
{
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
#ifdef WOLFSSL_SMALL_STACK
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
DYNAMIC_TYPE_AES);
if (aes == NULL) {
ret = MEMORY_E;
break;
}
#else
Aes aes[1];
#endif
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
AES_ENCRYPTION);
if (ret == 0) {
ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && \
defined(WC_ASYNC_ENABLE_AES)
ret = wc_AsyncWait(ret, &aes->asyncDev,
WC_ASYNC_FLAG_NONE);
#endif
@ -12157,7 +12241,8 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
WC_SHA256_DIGEST_SIZE);
if (ret == 0)
ret = wc_HmacUpdate(hmac, out, msgSz);
if (ret == 0)
@ -12169,8 +12254,8 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
#endif
}
break;
}
default:
ret = BAD_FUNC_ARG;
@ -12275,8 +12360,8 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
pubKeySz = (pubKeySz / 2) + 1;
}
#endif
#endif
#endif /* HAVE_COMP_KEY */
#endif /* WOLFSSL_ECIES_OLD */
if (ctx->protocol == REQ_RESP_CLIENT) {
offset = keysLen;
@ -12437,15 +12522,16 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
WC_SHA256_DIGEST_SIZE);
if (ret == 0)
ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
if (ret == 0)
ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
if (ret == 0)
ret = wc_HmacFinal(hmac, verify);
if (ret == 0) {
if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
digestSz) != 0)) {
ret = -1;
}
@ -12465,8 +12551,9 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (ret == 0) {
switch (ctx->encAlgo) {
#ifdef HAVE_AES_CBC
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
case ecAES_128_CBC:
case ecAES_256_CBC:
{
#ifdef WOLFSSL_SMALL_STACK
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
@ -12480,12 +12567,12 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#endif
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, encKey, KEY_SIZE_128, encIv,
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
AES_DECRYPTION);
if (ret == 0) {
ret = wc_AesCbcDecrypt(aes, out, msg,
msgSz-digestSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && \
defined(WC_ASYNC_ENABLE_AES)
ret = wc_AsyncWait(ret, &aes->asyncDev,
WC_ASYNC_FLAG_NONE);
#endif
@ -12495,10 +12582,42 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
if (ret != 0)
break;
}
#endif
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
case ecAES_128_CTR:
case ecAES_256_CTR:
{
#ifdef WOLFSSL_SMALL_STACK
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
DYNAMIC_TYPE_AES);
if (aes == NULL) {
ret = MEMORY_E;
break;
}
#else
Aes aes[1];
#endif
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
AES_ENCRYPTION);
if (ret == 0) {
ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && \
defined(WC_ASYNC_ENABLE_AES)
ret = wc_AsyncWait(ret, &aes->asyncDev,
WC_ASYNC_FLAG_NONE);
#endif
}
wc_AesFree(aes);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
break;
}
#endif
default:
ret = BAD_FUNC_ARG;

View File

@ -463,7 +463,7 @@ WOLFSSL_TEST_SUBROUTINE int scrypt_test(void);
#ifdef HAVE_ECC
WOLFSSL_TEST_SUBROUTINE int ecc_test(void);
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
defined(WOLFSSL_AES_128)
(defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_256))
WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void);
#endif
#if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \
@ -1252,7 +1252,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
TEST_PASS("ECC test passed!\n");
PRIVATE_KEY_LOCK();
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
defined(WOLFSSL_AES_128)
(defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_256))
if ( (ret = ecc_encrypt_test()) != 0)
return err_sys("ECC Enc test failed!\n", ret);
else
@ -9421,6 +9421,7 @@ WOLFSSL_TEST_SUBROUTINE int aes256_test(void)
#ifdef HAVE_AESGCM
#ifdef WOLFSSL_AES_128
static int aesgcm_default_test_helper(byte* key, int keySz, byte* iv, int ivSz,
byte* plain, int plainSz, byte* cipher, int cipherSz,
byte* aad, int aadSz, byte* tag, int tagSz)
@ -9517,6 +9518,7 @@ static int aesgcm_default_test_helper(byte* key, int keySz, byte* iv, int ivSz,
return ret;
}
#endif
/* tests that only use 12 byte IV and 16 or less byte AAD
@ -9524,6 +9526,7 @@ static int aesgcm_default_test_helper(byte* key, int keySz, byte* iv, int ivSz,
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES*/
WOLFSSL_TEST_SUBROUTINE int aesgcm_default_test(void)
{
#ifdef WOLFSSL_AES_128
byte key1[] = {
0x29, 0x8e, 0xfa, 0x1c, 0xcf, 0x29, 0xcf, 0x62,
0xae, 0x68, 0x24, 0xbf, 0xc1, 0x95, 0x57, 0xfc
@ -9617,6 +9620,7 @@ WOLFSSL_TEST_SUBROUTINE int aesgcm_default_test(void)
if (ret != 0) {
return ret;
}
#endif
return 0;
}
@ -9648,7 +9652,7 @@ WOLFSSL_TEST_SUBROUTINE int aesgcm_test(void)
0xba, 0x63, 0x7b, 0x39
};
#if defined(WOLFSSL_AES_256)
#if defined(WOLFSSL_AES_256) || defined(WOLFSSL_AES_192)
WOLFSSL_SMALL_STACK_STATIC const byte a[] =
{
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
@ -9671,7 +9675,9 @@ WOLFSSL_TEST_SUBROUTINE int aesgcm_test(void)
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88
};
#endif /* WOLFSSL_AES_256 */
#if defined(WOLFSSL_AES_256) || defined(WOLFSSL_AES_192)
WOLFSSL_SMALL_STACK_STATIC const byte c1[] =
{
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
@ -9683,7 +9689,7 @@ WOLFSSL_TEST_SUBROUTINE int aesgcm_test(void)
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62
};
#endif /* WOLFSSL_AES_256 */
#endif /* WOLFSSL_AES_256 || WOLFSSL_AES_192 */
WOLFSSL_SMALL_STACK_STATIC const byte t1[] =
{
@ -24219,9 +24225,10 @@ done:
}
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
defined(WOLFSSL_AES_128)
(defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_256))
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
ECC_MIN_KEY_SZ <= 256 && defined(WOLFSSL_AES_128)
static int ecc_encrypt_kat(WC_RNG *rng)
{
int ret = 0;
@ -24427,17 +24434,10 @@ static int ecc_encrypt_kat(WC_RNG *rng)
}
#endif
WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
static int ecc_encrypt_e2e_test(WC_RNG* rng, ecc_key* userA, ecc_key* userB,
byte encAlgo, byte kdfAlgo, byte macAlgo)
{
WC_RNG rng;
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
ecc_key *userA = (ecc_key *)XMALLOC(sizeof *userA, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER),
*userB = (ecc_key *)XMALLOC(sizeof *userB, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER),
*tmpKey = (ecc_key *)XMALLOC(sizeof *userB, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#else
ecc_key userA[1], userB[1], tmpKey[1];
#endif
byte msg[48];
byte plain[48];
#ifdef WOLFSSL_ECIES_OLD
@ -24462,67 +24462,26 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
#endif
word32 outSz2 = sizeof(out2);
word32 plainSz2 = sizeof(plain2);
#ifndef HAVE_FIPS
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
#ifdef WOLFSSL_SMALL_STACK
ecc_key *tmpKey = (ecc_key *)XMALLOC(sizeof(ecc_key), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
#else
ret = wc_InitRng(&rng);
ecc_key tmpKey[1];
#endif
if (ret != 0)
return -10400;
#ifdef WOLFSSL_SMALL_STACK
if ((userA == NULL) ||
(userB == NULL))
if (tmpKey == NULL) {
ERROR_OUT(MEMORY_E, done);
}
#endif
XMEMSET(userA, 0, sizeof *userA);
XMEMSET(userB, 0, sizeof *userB);
ret = wc_ecc_init_ex(userA, HEAP_HINT, devId);
if (ret != 0)
goto done;
ret = wc_ecc_init_ex(userB, HEAP_HINT, devId);
if (ret != 0)
goto done;
ret = wc_ecc_init_ex(tmpKey, HEAP_HINT, devId);
if (ret != 0)
goto done;
ret = wc_ecc_make_key(&rng, ECC_KEYGEN_SIZE, userA);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0){
ret = -10401; goto done;
}
ret = wc_ecc_make_key(&rng, ECC_KEYGEN_SIZE, userB);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0){
ret = -10402; goto done;
}
/* set message to incrementing 0,1,2,etc... */
for (i = 0; i < (int)sizeof(msg); i++)
msg[i] = i;
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
!defined(HAVE_SELFTEST)
ret = wc_ecc_set_rng(userA, &rng);
if (ret != 0) {
ret = -10403; goto done;
}
ret = wc_ecc_set_rng(userB, &rng);
if (ret != 0) {
ret = -10404; goto done;
}
#endif
/* encrypt msg to B */
ret = wc_ecc_encrypt(userA, userB, msg, sizeof(msg), out, &outSz, NULL);
if (ret != 0) {
@ -24559,12 +24518,19 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
#endif
/* let's verify message exchange works, A is client, B is server */
cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng);
srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng);
cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, rng);
srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, rng);
if (cliCtx == NULL || srvCtx == NULL) {
ret = -10408; goto done;
}
ret = wc_ecc_ctx_set_algo(cliCtx, encAlgo, kdfAlgo, macAlgo);
if (ret != 0)
goto done;
ret = wc_ecc_ctx_set_algo(srvCtx, encAlgo, kdfAlgo, macAlgo);
if (ret != 0)
goto done;
/* get salt to send to peer */
tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx);
if (tmpSalt == NULL) {
@ -24647,12 +24613,19 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
wc_ecc_ctx_free(srvCtx);
wc_ecc_ctx_free(cliCtx);
/* let's verify message exchange works, A is client, B is server */
cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng);
srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng);
cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, rng);
srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, rng);
if (cliCtx == NULL || srvCtx == NULL) {
ret = -10416; goto done;
}
ret = wc_ecc_ctx_set_algo(cliCtx, encAlgo, kdfAlgo, macAlgo);
if (ret != 0)
goto done;
ret = wc_ecc_ctx_set_algo(srvCtx, encAlgo, kdfAlgo, macAlgo);
if (ret != 0)
goto done;
/* get salt to send to peer */
tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx);
if (tmpSalt == NULL) {
@ -24674,10 +24647,10 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
if (ret != 0)
goto done;
ret = wc_ecc_ctx_set_info(cliCtx, (byte*)"wolfSSL MSGE", 11);
ret = wc_ecc_ctx_set_info(cliCtx, (byte*)"wolfSSL MSGE", 12);
if (ret != 0)
goto done;
ret = wc_ecc_ctx_set_info(srvCtx, (byte*)"wolfSSL MSGE", 11);
ret = wc_ecc_ctx_set_info(srvCtx, (byte*)"wolfSSL MSGE", 12);
if (ret != 0)
goto done;
@ -24702,8 +24675,9 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
}
#endif /* HAVE_COMP_KEY */
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
ret = ecc_encrypt_kat(&rng);
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
(ECC_MIN_KEY_SZ <= 256) && defined(WOLFSSL_AES_128)
ret = ecc_encrypt_kat(rng);
#endif
done:
@ -24712,6 +24686,129 @@ done:
wc_ecc_ctx_free(srvCtx);
wc_ecc_ctx_free(cliCtx);
#ifdef WOLFSSL_SMALL_STACK
if (tmpKey != NULL) {
wc_ecc_free(tmpKey);
XFREE(tmpKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#else
wc_ecc_free(tmpKey);
#endif
return ret;
}
WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
{
WC_RNG rng;
int ret;
#ifdef WOLFSSL_SMALL_STACK
ecc_key *userA;
ecc_key *userB;
#else
ecc_key userA[1];
ecc_key userB[1];
#endif
#ifndef HAVE_FIPS
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
#else
ret = wc_InitRng(&rng);
#endif
if (ret != 0)
return -10400;
#ifdef WOLFSSL_SMALL_STACK
userA = (ecc_key *)XMALLOC(sizeof *userA, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
userB = (ecc_key *)XMALLOC(sizeof *userB, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if ((userA == NULL) || (userB == NULL)) {
ERROR_OUT(MEMORY_E, done);
}
#endif
XMEMSET(userA, 0, sizeof *userA);
XMEMSET(userB, 0, sizeof *userB);
ret = wc_ecc_init_ex(userA, HEAP_HINT, devId);
if (ret != 0)
goto done;
ret = wc_ecc_init_ex(userB, HEAP_HINT, devId);
if (ret != 0)
goto done;
ret = wc_ecc_make_key(&rng, ECC_KEYGEN_SIZE, userA);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0){
ret = -10401; goto done;
}
ret = wc_ecc_make_key(&rng, ECC_KEYGEN_SIZE, userB);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0){
ret = -10402; goto done;
}
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
!defined(HAVE_SELFTEST)
ret = wc_ecc_set_rng(userA, &rng);
if (ret != 0) {
ret = -10403; goto done;
}
ret = wc_ecc_set_rng(userB, &rng);
if (ret != 0) {
ret = -10404; goto done;
}
#endif
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
#ifdef WOLFSSL_AES_128
if (ret == 0) {
ret = ecc_encrypt_e2e_test(&rng, userA, userB, ecAES_128_CBC,
ecHKDF_SHA256, ecHMAC_SHA256);
if (ret != 0) {
printf("ECIES: AES_128_CBC, HKDF_SHA256, HMAC_SHA256\n");
}
}
#endif
#ifdef WOLFSSL_AES_256
if (ret == 0) {
ret = ecc_encrypt_e2e_test(&rng, userA, userB, ecAES_256_CBC,
ecHKDF_SHA256, ecHMAC_SHA256);
if (ret != 0) {
printf("ECIES: AES_256_CBC, HKDF_SHA256, HMAC_SHA256\n");
}
}
#endif
#endif
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
#ifdef WOLFSSL_AES_128
if (ret == 0) {
ret = ecc_encrypt_e2e_test(&rng, userA, userB, ecAES_128_CTR,
ecHKDF_SHA256, ecHMAC_SHA256);
if (ret != 0) {
printf("ECIES: AES_128_CTR, HKDF_SHA256, HMAC_SHA256\n");
}
}
#endif
#ifdef WOLFSSL_AES_256
if (ret == 0) {
ret = ecc_encrypt_e2e_test(&rng, userA, userB, ecAES_256_CTR,
ecHKDF_SHA256, ecHMAC_SHA256);
if (ret != 0) {
printf("ECIES: AES_256_CTR, HKDF_SHA256, HMAC_SHA256\n");
}
}
#endif
#endif
done:
#ifdef WOLFSSL_SMALL_STACK
if (userA != NULL) {
wc_ecc_free(userA);
@ -24721,12 +24818,7 @@ done:
wc_ecc_free(userB);
XFREE(userB, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
if (tmpKey != NULL) {
wc_ecc_free(tmpKey);
XFREE(tmpKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#else
wc_ecc_free(tmpKey);
wc_ecc_free(userB);
wc_ecc_free(userA);
#endif

View File

@ -820,7 +820,9 @@ int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz);
enum ecEncAlgo {
ecAES_128_CBC = 1, /* default */
ecAES_256_CBC = 2
ecAES_256_CBC = 2,
ecAES_128_CTR = 3,
ecAES_256_CTR = 4
};
enum ecKdfAlgo {
@ -860,6 +862,9 @@ void wc_ecc_ctx_free(ecEncCtx* ctx);
WOLFSSL_API
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng); /* reset for use again w/o alloc/free */
WOLFSSL_API
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo,
byte macAlgo);
WOLFSSL_API
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx);
WOLFSSL_API

View File

@ -1997,8 +1997,9 @@ extern void uITRON4_free(void *p) ;
#undef WOLFSSL_AES_256
#define WOLFSSL_AES_256
#endif
#if !defined(WOLFSSL_AES_128) && defined(HAVE_ECC_ENCRYPT)
#warning HAVE_ECC_ENCRYPT uses AES 128 bit keys
#if !defined(WOLFSSL_AES_128) && !defined(WOLFSSL_AES_256) && \
defined(HAVE_ECC_ENCRYPT)
#warning HAVE_ECC_ENCRYPT uses AES 128/256 bit keys
#endif
#ifndef NO_AES_DECRYPT