diff --git a/doc/dox_comments/header_files/ecc.h b/doc/dox_comments/header_files/ecc.h index 97de1641b..446ddaf01 100644 --- a/doc/dox_comments/header_files/ecc.h +++ b/doc/dox_comments/header_files/ecc.h @@ -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 diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 5d6293cc0..9579e0ec3 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 160fb26be..616dd7f66 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -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 diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index a5cc95d62..1a8d44416 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -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 diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 1af36f08c..73503fffb 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -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