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));
ctx->encAlgo = ecAES_128_CBC;
#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;
}
@ -12006,7 +12052,7 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (keysLen > ECC_BUFSIZE) /* keys size */
return BUFFER_E;
if ( (msgSz%blockSz) != 0)
if ((msgSz % blockSz) != 0)
return BAD_PADDING_E;
#ifdef WOLFSSL_ECIES_OLD
@ -12072,117 +12118,156 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
} while (ret == WC_PENDING_E);
if (ret == 0) {
#ifdef WOLFSSL_ECIES_ISO18033
/* KDF data is encoded public key and secret. */
sharedSz += pubKeySz;
/* KDF data is encoded public key and secret. */
sharedSz += pubKeySz;
#endif
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
keys, keysLen);
break;
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
keys, keysLen);
break;
default:
ret = BAD_FUNC_ARG;
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
#ifdef WOLFSSL_ECIES_OLD
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
#else
XMEMSET(iv, 0, ivSz);
encKey = keys + offset;
encIv = iv;
macKey = encKey + encKeySz;
#endif
#ifdef WOLFSSL_ECIES_OLD
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
#else
XMEMSET(iv, 0, ivSz);
encKey = keys + offset;
encIv = iv;
macKey = encKey + encKeySz;
#endif
switch (ctx->encAlgo) {
case ecAES_128_CBC:
case ecAES_256_CBC:
{
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
#ifdef WOLFSSL_SMALL_STACK
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
#ifdef WOLFSSL_SMALL_STACK
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
DYNAMIC_TYPE_AES);
DYNAMIC_TYPE_AES);
if (aes == NULL) {
ret = MEMORY_E;
break;
}
#else
#else
Aes aes[1];
#endif
#endif
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, encKey, KEY_SIZE_128, encIv,
AES_ENCRYPTION);
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
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
#else
#endif
#else
ret = NOT_COMPILED_IN;
#endif
#endif
break;
}
default:
ret = BAD_FUNC_ARG;
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
}
wc_AesFree(aes);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
#else
ret = NOT_COMPILED_IN;
#endif
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
#ifdef WOLFSSL_SMALL_STACK
Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
DYNAMIC_TYPE_HMAC);
if (hmac == NULL) {
ret = MEMORY_E;
break;
}
#else
Hmac hmac[1];
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
if (ret == 0)
ret = wc_HmacUpdate(hmac, out, msgSz);
if (ret == 0)
ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
if (ret == 0)
ret = wc_HmacFinal(hmac, out+msgSz);
wc_HmacFree(hmac);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
#endif
}
break;
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
#ifdef WOLFSSL_SMALL_STACK
Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
DYNAMIC_TYPE_HMAC);
if (hmac == NULL) {
ret = MEMORY_E;
break;
}
#else
Hmac hmac[1];
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
WC_SHA256_DIGEST_SIZE);
if (ret == 0)
ret = wc_HmacUpdate(hmac, out, msgSz);
if (ret == 0)
ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
if (ret == 0)
ret = wc_HmacFinal(hmac, out+msgSz);
wc_HmacFree(hmac);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
#endif
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
#ifdef WOLFSSL_ECIES_OLD
*outSz = msgSz + digestSz;
*outSz = msgSz + digestSz;
#else
*outSz = pubKeySz + msgSz + digestSz;
*outSz = pubKeySz + msgSz + digestSz;
#endif
}
@ -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;
@ -12298,13 +12383,13 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
return BUFFER_E;
#ifdef WOLFSSL_ECIES_OLD
if ( ((msgSz-digestSz) % blockSz) != 0)
if (((msgSz - digestSz) % blockSz) != 0)
return BAD_PADDING_E;
if (*outSz < (msgSz - digestSz))
return BUFFER_E;
#else
if ( ((msgSz-digestSz-pubKeySz) % blockSz) != 0)
if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
return BAD_PADDING_E;
if (msgSz < pubKeySz + blockSz + digestSz)
@ -12345,7 +12430,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (pubKey == NULL) {
#ifdef WOLFSSL_SMALL_STACK
peerKey = (ecc_key*)XMALLOC(sizeof(*peerKey), ctx->heap,
DYNAMIC_TYPE_ECC_BUFFER);
DYNAMIC_TYPE_ECC_BUFFER);
if (peerKey == NULL)
ret = MEMORY_E;
#endif
@ -12393,117 +12478,151 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
}
if (ret == 0) {
#ifdef WOLFSSL_ECIES_ISO18033
/* KDF data is encoded public key and secret. */
sharedSz += pubKeySz;
/* KDF data is encoded public key and secret. */
sharedSz += pubKeySz;
#endif
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
keys, keysLen);
break;
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
keys, keysLen);
break;
default:
ret = BAD_FUNC_ARG;
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
#ifdef WOLFSSL_ECIES_OLD
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
#else
XMEMSET(iv, 0, ivSz);
encKey = keys + offset;
encIv = iv;
macKey = encKey + encKeySz;
#endif
#ifdef WOLFSSL_ECIES_OLD
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
#else
XMEMSET(iv, 0, ivSz);
encKey = keys + offset;
encIv = iv;
macKey = encKey + encKeySz;
#endif
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
byte verify[WC_SHA256_DIGEST_SIZE];
#ifdef WOLFSSL_SMALL_STACK
Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
DYNAMIC_TYPE_HMAC);
if (hmac == NULL) {
ret = MEMORY_E;
break;
}
#else
Hmac hmac[1];
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
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)
ret = -1;
}
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
byte verify[WC_SHA256_DIGEST_SIZE];
#ifdef WOLFSSL_SMALL_STACK
Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
DYNAMIC_TYPE_HMAC);
if (hmac == NULL) {
ret = MEMORY_E;
break;
}
#else
Hmac hmac[1];
#endif
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) {
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) && (XMEMCMP(verify, msg + msgSz - digestSz,
digestSz) != 0)) {
ret = -1;
}
wc_HmacFree(hmac);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
#endif
break;
}
wc_HmacFree(hmac);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
#endif
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
default:
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
switch (ctx->encAlgo) {
#ifdef HAVE_AES_CBC
case ecAES_128_CBC:
{
#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, KEY_SIZE_128, encIv,
switch (ctx->encAlgo) {
#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,
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_DECRYPTION);
if (ret == 0) {
ret = wc_AesCbcDecrypt(aes, out, msg,
msgSz-digestSz);
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
ret = wc_AsyncWait(ret, &aes->asyncDev,
if (ret == 0) {
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
}
wc_AesFree(aes);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
if (ret != 0)
break;
}
break;
#endif
default:
ret = BAD_FUNC_ARG;
break;
}
#endif
}
wc_AesFree(aes);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
#endif
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;
break;
}
}
if (ret == 0)

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