From 14e1489365f08502a4616ccae9e69d47e0738f96 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:41:09 -0700 Subject: [PATCH 01/10] Fix for SRP leaks with `WOLFSSL_SMALL_STACK_CACHE` --- src/ssl.c | 39 ++++++++++++++++++----------------- tests/srp.c | 1 + wolfcrypt/src/srp.c | 50 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 11bc08a3c..05e0dc626 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -403,7 +403,7 @@ WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap) #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \ && !defined(NO_SHA256) && !defined(WC_NO_RNG) else { - ctx->srp = (Srp*) XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP); + ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP); if (ctx->srp == NULL){ WOLFSSL_MSG("Init CTX failed"); wolfSSL_CTX_free(ctx); @@ -451,7 +451,7 @@ void wolfSSL_CTX_free(WOLFSSL_CTX* ctx) if (ctx) { #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \ && !defined(NO_SHA256) && !defined(WC_NO_RNG) - if (ctx->srp != NULL){ + if (ctx->srp != NULL) { if (ctx->srp_password != NULL){ XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP); ctx->srp_password = NULL; @@ -14677,10 +14677,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return SSL_FAILURE; } - if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0){ - WOLFSSL_MSG("Init CTX failed"); + if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) { + WOLFSSL_MSG("Init SRP CTX failed"); XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP); - wolfSSL_CTX_free(ctx); + ctx->srp = NULL; return SSL_FAILURE; } r = wc_SrpSetUsername(ctx->srp, (const byte*)username, @@ -14692,23 +14692,24 @@ int wolfSSL_set_compression(WOLFSSL* ssl) /* if wolfSSL_CTX_set_srp_password has already been called, */ /* execute wc_SrpSetPassword here */ - if (ctx->srp_password != NULL){ + if (ctx->srp_password != NULL) { + WC_RNG rng; if (wc_InitRng(&rng) < 0){ WOLFSSL_MSG("wc_InitRng failed"); return SSL_FAILURE; } XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0])); - if (wc_RNG_GenerateBlock(&rng, salt, - sizeof(salt)/sizeof(salt[0])) < 0){ - WOLFSSL_MSG("wc_RNG_GenerateBlock failed"); - wc_FreeRng(&rng); + r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0])); + wc_FreeRng(&rng); + if (r < 0) { + WOLFSSL_MSG("wc_RNG_GenerateBlock failed"); return SSL_FAILURE; } + if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]), srp_g, sizeof(srp_g)/sizeof(srp_g[0]), - salt, sizeof(salt)/sizeof(salt[0])) < 0){ + salt, sizeof(salt)/sizeof(salt[0])) < 0) { WOLFSSL_MSG("wc_SrpSetParam failed"); - wc_FreeRng(&rng); return SSL_FAILURE; } r = wc_SrpSetPassword(ctx->srp, @@ -14718,7 +14719,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_MSG("fail to set srp password."); return SSL_FAILURE; } - wc_FreeRng(&rng); + XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP); ctx->srp_password = NULL; } @@ -14729,23 +14730,23 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password) { int r; - WC_RNG rng; byte salt[SRP_SALT_SIZE]; WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password"); if (ctx == NULL || ctx->srp == NULL || password == NULL) return SSL_FAILURE; - if (ctx->srp->user != NULL){ - if (wc_InitRng(&rng) < 0){ + if (ctx->srp->user != NULL) { + WC_RNG rng; + if (wc_InitRng(&rng) < 0) { WOLFSSL_MSG("wc_InitRng failed"); return SSL_FAILURE; } XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0])); - if (wc_RNG_GenerateBlock(&rng, salt, - sizeof(salt)/sizeof(salt[0])) < 0){ + r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0])); + wc_FreeRng(&rng); + if (r < 0) { WOLFSSL_MSG("wc_RNG_GenerateBlock failed"); - wc_FreeRng(&rng); return SSL_FAILURE; } if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]), diff --git a/tests/srp.c b/tests/srp.c index 504fbfb1c..1132f35b0 100644 --- a/tests/srp.c +++ b/tests/srp.c @@ -449,6 +449,7 @@ static int sha512_key_gen(Srp* srp, byte* secret, word32 size) r = wc_InitSha512(&hash); if (!r) r = wc_Sha512Update(&hash, secret, size); if (!r) r = wc_Sha512Final(&hash, srp->key); + wc_Sha512Free(&hash); XMEMSET(&hash, 0, sizeof(wc_Sha512)); diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 5d5b5ee46..8c16f2e7c 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -188,6 +188,35 @@ static word32 SrpHashSize(SrpType type) } } +static void SrpHashFree(SrpHash* hash) +{ + switch (hash->type) { + case SRP_TYPE_SHA: + #ifndef NO_SHA + wc_ShaFree(&hash->data.sha); + #endif + break; + case SRP_TYPE_SHA256: + #ifndef NO_SHA256 + wc_Sha256Free(&hash->data.sha256); + #endif + break; + case SRP_TYPE_SHA384: + #ifdef WOLFSSL_SHA384 + wc_Sha384Free(&hash->data.sha384); + #endif + break; + case SRP_TYPE_SHA512: + #ifdef WOLFSSL_SHA512 + wc_Sha512Free(&hash->data.sha512); + #endif + break; + default: + break; + } +} + + int wc_SrpInit(Srp* srp, SrpType type, SrpSide side) { int r; @@ -234,18 +263,21 @@ int wc_SrpInit(Srp* srp, SrpType type, SrpSide side) } /* initializing variables */ - XMEMSET(srp, 0, sizeof(Srp)); if ((r = SrpHashInit(&srp->client_proof, type)) != 0) return r; - if ((r = SrpHashInit(&srp->server_proof, type)) != 0) + if ((r = SrpHashInit(&srp->server_proof, type)) != 0) { + SrpHashFree(&srp->client_proof); return r; - + } if ((r = mp_init_multi(&srp->N, &srp->g, &srp->auth, - &srp->priv, 0, 0)) != 0) + &srp->priv, 0, 0)) != 0) { + SrpHashFree(&srp->client_proof); + SrpHashFree(&srp->server_proof); return r; + } srp->side = side; srp->type = type; srp->salt = NULL; srp->saltSz = 0; @@ -282,6 +314,8 @@ void wc_SrpTerm(Srp* srp) XFREE(srp->key, srp->heap, DYNAMIC_TYPE_SRP); } + SrpHashFree(&srp->client_proof); + SrpHashFree(&srp->server_proof); ForceZero(srp, sizeof(Srp)); } } @@ -353,6 +387,7 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, } if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz); if (!r) r = SrpHashFinal(&hash, srp->k); + SrpHashFree(&hash); /* update client proof */ @@ -360,11 +395,13 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, if (!r) r = SrpHashInit(&hash, srp->type); if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz); if (!r) r = SrpHashFinal(&hash, digest1); + SrpHashFree(&hash); /* digest2 = H(g) */ if (!r) r = SrpHashInit(&hash, srp->type); if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz); if (!r) r = SrpHashFinal(&hash, digest2); + SrpHashFree(&hash); /* digest1 = H(N) ^ H(g) */ if (r == 0) { @@ -376,6 +413,7 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, if (!r) r = SrpHashInit(&hash, srp->type); if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz); if (!r) r = SrpHashFinal(&hash, digest2); + SrpHashFree(&hash); /* client proof = H( H(N) ^ H(g) | H(user) | salt) */ if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, j); @@ -406,12 +444,14 @@ int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) if (!r) r = SrpHashUpdate(&hash, (const byte*) ":", 1); if (!r) r = SrpHashUpdate(&hash, password, size); if (!r) r = SrpHashFinal(&hash, digest); + SrpHashFree(&hash); /* digest = H(salt | H(username | ':' | password)) */ if (!r) r = SrpHashInit(&hash, srp->type); if (!r) r = SrpHashUpdate(&hash, srp->salt, srp->saltSz); if (!r) r = SrpHashUpdate(&hash, digest, digestSz); if (!r) r = SrpHashFinal(&hash, digest); + SrpHashFree(&hash); /* Set x (private key) */ if (!r) r = mp_read_unsigned_bin(&srp->auth, digest, digestSz); @@ -579,6 +619,7 @@ static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size) if (!r) r = SrpHashFinal(&hash, srp->key + j); j += digestSz; } + SrpHashFree(&hash); } ForceZero(digest, sizeof(digest)); @@ -641,6 +682,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, /* set u */ if (!r) r = SrpHashFinal(&hash, digest); if (!r) r = mp_read_unsigned_bin(&u, digest, SrpHashSize(srp->type)); + SrpHashFree(&hash); /* building s (secret) */ From 61545df606c95a045fedb64d7d9a21d3a31d3519 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:41:26 -0700 Subject: [PATCH 02/10] Fix to make sure DTLS cookie HMAC free gets called. Note: This does not cover the many error case paths. --- src/internal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal.c b/src/internal.c index dc57df024..8ded80642 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27563,6 +27563,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif #ifdef WOLFSSL_DTLS + wc_HmacFree(&cookieHmac); + if (ret == 0 && ssl->options.dtls) DtlsMsgPoolReset(ssl); #endif From 3878af96cd2acedebbbcaaf1283c2feeb5e179d6 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:42:29 -0700 Subject: [PATCH 03/10] Fix for SP init and free with `HAVE_WOLF_BIGINT`. Fix for sp_free macro typo. Fix to expose `mp_init_copy` with ECC disabled because its used by `mp_test`. --- wolfcrypt/src/sp_int.c | 22 +++++++++++++++++++++- wolfcrypt/src/tfm.c | 13 ++++++------- wolfssl/wolfcrypt/sp_int.h | 2 +- wolfssl/wolfcrypt/tfm.h | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 072801135..b8eb2e339 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -104,7 +104,9 @@ int sp_init(sp_int* a) { a->used = 0; a->size = SP_INT_DIGITS; - +#ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&a->raw); +#endif return MP_OKAY; } @@ -125,26 +127,44 @@ int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, sp_int* e, if (a != NULL) { a->used = 0; a->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&a->raw); + #endif } if (b != NULL) { b->used = 0; b->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&b->raw); + #endif } if (c != NULL) { c->used = 0; c->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&c->raw); + #endif } if (d != NULL) { d->used = 0; d->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&d->raw); + #endif } if (e != NULL) { e->used = 0; e->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&e->raw); + #endif } if (f != NULL) { f->used = 0; f->size = SP_INT_DIGITS; + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&f->raw); + #endif } return MP_OKAY; diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 22e5dea6b..50994c628 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -4300,6 +4300,12 @@ void fp_copy(fp_int *a, fp_int *b) } } +int mp_init_copy(fp_int * a, fp_int * b) +{ + fp_init_copy(a, b); + return MP_OKAY; +} + void fp_init_copy(fp_int *a, fp_int* b) { if (a != b) { @@ -5392,13 +5398,6 @@ int mp_div_2_mod_ct(mp_int *a, mp_int *b, mp_int *c) return fp_div_2_mod_ct(a, b, c); } - -int mp_init_copy(fp_int * a, fp_int * b) -{ - fp_init_copy(a, b); - return MP_OKAY; -} - #ifdef HAVE_COMP_KEY int mp_cnt_lsb(fp_int* a) diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index f616b2471..db8fd4433 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -251,7 +251,7 @@ MP_API int sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r); #define CheckFastMathSettings() 1 -#define mp_free(a) sp_free +#define mp_free sp_free #define mp_isodd sp_isodd #define mp_iseven sp_iseven diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index ae216fa3f..fd112a3cb 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -738,6 +738,7 @@ int fp_sqr_comba64(fp_int *a, fp_int *b); #define mp_tohex(M, S) mp_toradix((M), (S), MP_RADIX_HEX) MP_API int mp_init (mp_int * a); +MP_API int mp_init_copy(fp_int * a, fp_int * b); MP_API void mp_clear (mp_int * a); MP_API void mp_free (mp_int * a); MP_API void mp_forcezero (mp_int * a); @@ -808,7 +809,6 @@ MP_API int mp_radix_size (mp_int * a, int radix, int *size); MP_API int mp_montgomery_setup(fp_int *a, fp_digit *rho); MP_API int mp_div_2(fp_int * a, fp_int * b); MP_API int mp_div_2_mod_ct(mp_int *a, mp_int *b, mp_int *c); - MP_API int mp_init_copy(fp_int * a, fp_int * b); #endif #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DSA) || \ From 5c76afc41c2cbfef63e3515b0719d176b8156db6 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:44:32 -0700 Subject: [PATCH 04/10] Fix for SHA256 missing initialization of small stack cache variable. Fixes issue with Intel ASM and `WOLFSSL_SMALL_STACK_CACHE` --- wolfcrypt/src/sha256.c | 18 ++++++++++-------- wolfcrypt/src/sha512.c | 17 ++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index e9d0a5e2a..3b9d2f169 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -369,6 +369,9 @@ static int InitSha256(wc_Sha256* sha256) #ifdef WOLF_CRYPTO_CB sha256->devId = devId; #endif + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha256->W = NULL; + #endif ret = InitSha256(sha256); if (ret != 0) @@ -697,15 +700,14 @@ static int InitSha256(wc_Sha256* sha256) sha256->devId = devId; sha256->devCtx = NULL; #endif + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha256->W = NULL; + #endif ret = InitSha256(sha256); if (ret != 0) return ret; - #ifdef WOLFSSL_SMALL_STACK_CACHE - sha256->W = NULL; - #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) ret = wolfAsync_DevCtxInit(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId); @@ -1264,6 +1266,7 @@ static int InitSha256(wc_Sha256* sha256) (void)devId; (void)heap; + XMEMSET(sha224, 0, sizeof(wc_Sha224)); wc_Stm32_Hash_Init(&sha224->stmCtx); return 0; } @@ -1362,15 +1365,14 @@ static int InitSha256(wc_Sha256* sha256) return BAD_FUNC_ARG; sha224->heap = heap; + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha224->W = NULL; + #endif ret = InitSha224(sha224); if (ret != 0) return ret; - #ifdef WOLFSSL_SMALL_STACK_CACHE - sha224->W = NULL; - #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) ret = wolfAsync_DevCtxInit(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId); diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index e8a427962..5bceb44b6 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -398,6 +398,9 @@ int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) return BAD_FUNC_ARG; sha512->heap = heap; +#ifdef WOLFSSL_SMALL_STACK_CACHE + sha512->W = NULL; +#endif ret = InitSha512(sha512); if (ret != 0) @@ -407,10 +410,6 @@ int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) Sha512_SetTransform(); #endif -#ifdef WOLFSSL_SMALL_STACK_CACHE - sha512->W = NULL; -#endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) ret = wolfAsync_DevCtxInit(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId); @@ -507,8 +506,7 @@ static int _Transform_Sha512(wc_Sha512* sha512) #ifdef WOLFSSL_SMALL_STACK_CACHE word64* W = sha512->W; if (W == NULL) { - W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, - DYNAMIC_TYPE_TMP_BUFFER); + W = (word64*)XMALLOC(sizeof(word64) * 16, NULL,DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) return MEMORY_E; sha512->W = W; @@ -1019,6 +1017,10 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) } sha384->heap = heap; +#ifdef WOLFSSL_SMALL_STACK_CACHE + sha384->W = NULL; +#endif + ret = InitSha384(sha384); if (ret != 0) return ret; @@ -1026,9 +1028,6 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) Sha512_SetTransform(); #endif -#ifdef WOLFSSL_SMALL_STACK_CACHE - sha384->W = NULL; -#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384, From 6d5731b8e9996d32f3d1ff8a88396503c61b4232 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:45:26 -0700 Subject: [PATCH 05/10] Fixes for HMAC_CTX cleanup not being called to free SHA2 resources with `WOLFSSL_SMALL_STACK_CACHE`. Added return code checking and cleanup for `openssl_test`. --- src/bio.c | 1 + src/ssl.c | 27 ++- tests/api.c | 14 +- wolfcrypt/src/evp.c | 6 +- wolfcrypt/test/test.c | 412 ++++++++++++++++++++++------------------- wolfssl/openssl/hmac.h | 2 + wolfssl/openssl/ssl.h | 1 - 7 files changed, 250 insertions(+), 213 deletions(-) diff --git a/src/bio.c b/src/bio.c index 9de21e45f..657c4040b 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1305,6 +1305,7 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) if (bio->ptr != NULL) { const WOLFSSL_EVP_MD* md = wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr); + wolfSSL_EVP_MD_CTX_cleanup((WOLFSSL_EVP_MD_CTX*)bio->ptr); wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr); wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md); } diff --git a/src/ssl.c b/src/ssl.c index 05e0dc626..c91a7fea6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -14661,7 +14661,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl) { int r = 0; SrpSide srp_side = SRP_CLIENT_SIDE; - WC_RNG rng; byte salt[SRP_SALT_SIZE]; WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username"); @@ -31152,6 +31151,10 @@ int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, } } + /* Make sure and free if needed */ + if (ctx->hmac.macType != WC_HASH_TYPE_NONE) { + wc_HmacFree(&ctx->hmac); + } if (key && keylen) { WOLFSSL_MSG("keying hmac"); @@ -31168,9 +31171,9 @@ int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, WC_HMAC_BLOCK_SIZE); } /* OpenSSL compat, no error */ - } else if(ctx->type >= 0) { /* MD5 == 0 */ + } + else if (ctx->type >= 0) { /* MD5 == 0 */ WOLFSSL_MSG("recover hmac"); - wc_HmacFree(&ctx->hmac); if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) { ctx->hmac.macType = (byte)ctx->type; ctx->hmac.innerHashKeyed = 0; @@ -31289,20 +31292,26 @@ int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx) { WOLFSSL_MSG("wolfSSL_HMAC_cleanup"); - if (ctx) + if (ctx) { wc_HmacFree(&ctx->hmac); + } - return SSL_SUCCESS; + return WOLFSSL_SUCCESS; } +void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx) +{ + if (ctx) { + wolfSSL_HMAC_cleanup(ctx); + } +} void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx) { - if (!ctx) { - return; + if (ctx) { + wolfSSL_HMAC_CTX_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); } - wolfSSL_HMAC_cleanup(ctx); - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); } size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx) diff --git a/tests/api.c b/tests/api.c index 774a33296..9200108fb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30118,18 +30118,17 @@ static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest) AssertIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); AssertIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); - AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); AssertIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); - AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); + AssertIntEQ(digestSz, digestSz2); AssertIntEQ(XMEMCMP(digest, digest2, digestSz), 0); @@ -30141,18 +30140,17 @@ static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest) AssertIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); AssertIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); - AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); AssertIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); - AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); + AssertIntEQ(digestSz, digestSz2); AssertIntEQ(XMEMCMP(digest, digest2, digestSz), 0); @@ -30167,13 +30165,13 @@ static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest) AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); AssertIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - - HMAC_CTX_cleanup(&ctx1); HMAC_CTX_cleanup(&ctx2); + AssertIntEQ(digestSz, digestSz2); AssertIntEQ(XMEMCMP(digest, digest2, digestSz), 0); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index b4bb58971..071f1468d 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3369,9 +3369,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) { if (ctx) { WOLFSSL_ENTER("EVP_MD_CTX_free"); - wolfSSL_EVP_MD_CTX_cleanup(ctx); - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - } + wolfSSL_EVP_MD_CTX_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } } /* returns the NID of message digest used by the ctx */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 40602ac6b..8d07e1e53 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -15692,6 +15692,7 @@ static int openssl_aes_test(void) int openssl_test(void) { + int ret; EVP_MD_CTX md_ctx; testVector a, b, c, d, e, f; byte hash[WC_SHA256_DIGEST_SIZE*2]; /* max size */ @@ -15718,7 +15719,6 @@ int openssl_test(void) } #ifndef NO_MD5 - a.input = "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890"; a.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" @@ -15727,18 +15727,20 @@ int openssl_test(void) a.outLen = WC_MD5_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_md5()); - - EVP_DigestUpdate(&md_ctx, a.input, (unsigned long)a.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE) != 0) - return -8401; - + ret = EVP_DigestInit(&md_ctx, EVP_md5()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, a.input, (unsigned long)a.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE) != 0) { + return -8402; + } #endif /* NO_MD5 */ #ifndef NO_SHA - b.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaa"; @@ -15748,18 +15750,20 @@ int openssl_test(void) b.outLen = WC_SHA_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha1()); - - EVP_DigestUpdate(&md_ctx, b.input, (unsigned long)b.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, b.output, WC_SHA_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha1()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, b.input, (unsigned long)b.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, b.output, WC_SHA_DIGEST_SIZE) != 0) { return -8402; - + } #endif /* NO_SHA */ #ifdef WOLFSSL_SHA224 - e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; e.output = "\xc9\x7c\xa9\xa5\x59\x85\x0c\xe9\x7a\x04\xa9\x6d\xef\x6d\x99" @@ -15768,17 +15772,20 @@ int openssl_test(void) e.outLen = WC_SHA224_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha224()); - - EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, e.output, WC_SHA224_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha224()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, e.output, WC_SHA224_DIGEST_SIZE) != 0) { return -8403; - + } #endif /* WOLFSSL_SHA224 */ - +#ifndef NO_SHA256 d.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; d.output = "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" @@ -15787,16 +15794,20 @@ int openssl_test(void) d.outLen = WC_SHA256_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha256()); - - EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, d.output, WC_SHA256_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha256()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, d.output, WC_SHA256_DIGEST_SIZE) != 0) { return -8404; + } +#endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 - e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; e.output = "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b" @@ -15807,19 +15818,20 @@ int openssl_test(void) e.outLen = WC_SHA384_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha384()); - - EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, e.output, WC_SHA384_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha384()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, e.output, WC_SHA384_DIGEST_SIZE) != 0) { return -8405; - + } #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA512 - f.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; f.output = "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14" @@ -15831,36 +15843,42 @@ int openssl_test(void) f.outLen = WC_SHA512_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha512()); - - EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, f.output, WC_SHA512_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha512()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, f.output, WC_SHA512_DIGEST_SIZE) != 0) { return -8406; - + } #endif /* WOLFSSL_SHA512 */ + #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; - e.output = "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc"; + e.output = "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a" + "\xe5\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc"; e.inLen = XSTRLEN(e.input); e.outLen = WC_SHA3_224_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha3_224()); - - EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, e.output, WC_SHA3_224_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha3_224()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, e.output, WC_SHA3_224_DIGEST_SIZE) != 0) { return -8407; - + } #endif /* WOLFSSL_NOSHA3_224 */ - #ifndef WOLFSSL_NOSHA3_256 d.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; @@ -15871,69 +15889,85 @@ int openssl_test(void) d.outLen = WC_SHA3_256_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha3_256()); - - EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, d.output, WC_SHA3_256_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha3_256()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, d.output, WC_SHA3_256_DIGEST_SIZE) != 0) { return -8408; + } #endif /* WOLFSSL_NOSHA3_256 */ - e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; - e.output = "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7"; + e.output = "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47" + "\x91\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6" + "\x25\xdc\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79" + "\xaa\x7f\xc7"; e.inLen = XSTRLEN(e.input); e.outLen = WC_SHA3_384_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha3_384()); - - EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, e.output, WC_SHA3_384_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha3_384()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, e.output, WC_SHA3_384_DIGEST_SIZE) != 0) { return -8409; - - + } #ifndef WOLFSSL_NOSHA3_512 - f.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; - f.output = "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85"; + f.output = "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78" + "\xf9\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18" + "\xa4\xfa\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8" + "\x2e\x21\x89\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55" + "\xf2\x1d\xd1\x85"; f.inLen = XSTRLEN(f.input); f.outLen = WC_SHA3_512_DIGEST_SIZE; EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit(&md_ctx, EVP_sha3_512()); - - EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); - EVP_DigestFinal(&md_ctx, hash, 0); - - if (XMEMCMP(hash, f.output, WC_SHA3_512_DIGEST_SIZE) != 0) + ret = EVP_DigestInit(&md_ctx, EVP_sha3_512()); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_DigestFinal(&md_ctx, hash, 0); + } + EVP_MD_CTX_cleanup(&md_ctx); + if (ret != WOLFSSL_SUCCESS || + XMEMCMP(hash, f.output, WC_SHA3_512_DIGEST_SIZE) != 0) { return -8410; - + } #endif /* WOLFSSL_NOSHA3_512 */ #endif /* WOLFSSL_SHA3 */ -#ifndef NO_MD5 - if (RAND_bytes(hash, sizeof(hash)) != 1) +#ifndef WC_NO_RNG + if (RAND_bytes(hash, sizeof(hash)) != WOLFSSL_SUCCESS) return -8411; +#endif +#ifndef NO_MD5 c.input = "what do ya want for nothing?"; c.output = "\x55\x78\xe8\x48\x4b\xcc\x93\x80\x93\xec\x53\xaf\x22\xd6\x14" "\x76"; c.inLen = XSTRLEN(c.input); c.outLen = WC_MD5_DIGEST_SIZE; - HMAC(EVP_md5(), - "JefeJefeJefeJefe", 16, (byte*)c.input, (int)c.inLen, hash, 0); - - if (XMEMCMP(hash, c.output, WC_MD5_DIGEST_SIZE) != 0) + if (HMAC(EVP_md5(), "JefeJefeJefeJefe", 16, (byte*)c.input, (int)c.inLen, + hash, 0) == NULL || + XMEMCMP(hash, c.output, WC_MD5_DIGEST_SIZE) != 0) + { return -8412; - + } #endif /* NO_MD5 */ #ifndef NO_DES3 @@ -15943,24 +15977,16 @@ int openssl_test(void) 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; - byte plain[24]; byte cipher[24]; - - const_DES_cblock key = - { + const_DES_cblock key = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; - - DES_cblock iv = - { + DES_cblock iv = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef }; - DES_key_schedule sched; - - const byte verify[] = - { + const byte verify[] = { 0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8, 0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73, 0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b @@ -15985,158 +16011,160 @@ int openssl_test(void) return -8415; } /* end des test */ - #endif /* NO_DES3 */ #if !defined(NO_AES) && !defined(WOLFCRYPT_ONLY) - if (openssl_aes_test() != 0) { - return -8416; - } + if (openssl_aes_test() != 0) { + return -8416; + } #if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC) - { /* evp_cipher test: EVP_aes_128_cbc */ + { /* evp_cipher test: EVP_aes_128_cbc */ EVP_CIPHER_CTX ctx; int idx, cipherSz, plainSz; - const byte msg[] = { /* "Now is the time for all " w/o trailing 0 */ 0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; - - const byte verify[] = - { + const byte verify[] = { 0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53, 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb, 0x3b,0x5d,0x41,0x97,0x94,0x25,0xa4,0xb4, 0xae,0x7b,0x34,0xd0,0x3f,0x0c,0xbc,0x06 }; - - const byte verify2[] = - { + const byte verify2[] = { 0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53, 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb, 0x7d,0x37,0x7b,0x0b,0x44,0xaa,0xb5,0xf0, 0x5f,0x34,0xb4,0xde,0xb5,0xbd,0x2a,0xbb }; - byte key[] = "0123456789abcdef "; /* align */ byte iv[] = "1234567890abcdef "; /* align */ - byte cipher[AES_BLOCK_SIZE * 4]; byte plain [AES_BLOCK_SIZE * 4]; + cipherSz = 0; EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) + ret = EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherUpdate(&ctx, cipher, &idx, (byte*)msg, sizeof(msg)); + if (ret == WOLFSSL_SUCCESS) + cipherSz += idx; + } + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherFinal(&ctx, cipher + cipherSz, &idx); + if (ret == WOLFSSL_SUCCESS) + cipherSz += idx; + } + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) return -8417; - - if (EVP_CipherUpdate(&ctx, cipher, &idx, (byte*)msg, sizeof(msg)) == 0) + if (cipherSz != (int)sizeof(verify) || XMEMCMP(cipher, verify, cipherSz)) return -8418; - cipherSz = idx; - if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) - return -8419; - cipherSz += idx; - - if ((cipherSz != (int)sizeof(verify)) && - XMEMCMP(cipher, verify, cipherSz)) - return -8420; - - EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) - return -8421; - /* check partial decrypt (not enough padding for full block) */ - if (EVP_CipherUpdate(&ctx, plain, &idx, cipher, 1) == 0) + plainSz = 0; + EVP_CIPHER_CTX_init(&ctx); + ret = EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherUpdate(&ctx, plain, &idx, cipher, 1); + if (ret == WOLFSSL_SUCCESS) + plainSz += idx; + } + if (ret == WOLFSSL_SUCCESS) { + /* this test should fail... not enough padding for full block */ + ret = EVP_CipherFinal(&ctx, plain + plainSz, &idx); + if (plainSz == 0 && ret != WOLFSSL_SUCCESS) + ret = WOLFSSL_SUCCESS; + else + ret = -8419; + } + else + ret = -8420; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) + return ret; + + plainSz = 0; + EVP_CIPHER_CTX_init(&ctx); + ret = EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherUpdate(&ctx, plain, &idx, cipher, cipherSz); + if (ret == WOLFSSL_SUCCESS) + plainSz += idx; + } + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherFinal(&ctx, plain + plainSz, &idx); + if (ret == WOLFSSL_SUCCESS) + plainSz += idx; + } + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) + return -8421; + if (plainSz != (int)sizeof(msg) || XMEMCMP(plain, msg, sizeof(msg))) return -8422; - plainSz = idx; - if (EVP_CipherFinal(&ctx, plain + plainSz, &idx) != 0) + cipherSz = 0; + EVP_CIPHER_CTX_init(&ctx); + ret = EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1); + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherUpdate(&ctx, cipher, &idx, msg, AES_BLOCK_SIZE); + if (ret == WOLFSSL_SUCCESS) + cipherSz += idx; + } + if (ret == WOLFSSL_SUCCESS) { + ret = EVP_CipherFinal(&ctx, cipher + cipherSz, &idx); + if (ret == WOLFSSL_SUCCESS) + cipherSz += idx; + } + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) return -8423; - - EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) + if (cipherSz != (int)sizeof(verify2) || XMEMCMP(cipher, verify2, cipherSz)) return -8424; - - if (EVP_CipherUpdate(&ctx, plain, &idx, cipher, cipherSz) == 0) - return -8425; - - plainSz = idx; - if (EVP_CipherFinal(&ctx, plain + plainSz, &idx) == 0) - return -8426; - plainSz += idx; - - if ((plainSz != sizeof(msg)) || XMEMCMP(plain, msg, sizeof(msg))) - return -8427; - - EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) - return -8428; - - if (EVP_CipherUpdate(&ctx, cipher, &idx, msg, AES_BLOCK_SIZE) == 0) - return -8429; - - cipherSz = idx; - if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) - return -8430; - cipherSz += idx; - - if ((cipherSz != (int)sizeof(verify2)) || - XMEMCMP(cipher, verify2, cipherSz)) - return -8431; - } /* end evp_cipher test: EVP_aes_128_cbc*/ #endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */ #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_256) - { /* evp_cipher test: EVP_aes_256_ecb*/ + { /* evp_cipher test: EVP_aes_256_ecb*/ EVP_CIPHER_CTX ctx; - const byte msg[] = - { + const byte msg[] = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a }; - - const byte verify[] = - { + const byte verify[] = { 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 }; - - const byte key[] = - { + const byte key[] = { 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 }; - - byte cipher[AES_BLOCK_SIZE * 4]; byte plain [AES_BLOCK_SIZE * 4]; EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, - NULL, 1) == 0) - return -8432; - - if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -8433; - + ret = EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 1); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_Cipher(&ctx, cipher, (byte*)msg, 16); + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) + return -8430; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -8434; + return -8431; EVP_CIPHER_CTX_init(&ctx); - if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, - NULL, 0) == 0) - return -8435; - - if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) + ret = EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0); + if (ret == WOLFSSL_SUCCESS) + ret = EVP_Cipher(&ctx, plain, cipher, 16); + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WOLFSSL_SUCCESS) return -8436; - if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) return -8437; - } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_128 */ diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h index 6ebd6dca6..d708fe1c6 100644 --- a/wolfssl/openssl/hmac.h +++ b/wolfssl/openssl/hmac.h @@ -72,6 +72,7 @@ WOLFSSL_API int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, WOLFSSL_API int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, unsigned int* len); WOLFSSL_API int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx); @@ -83,6 +84,7 @@ typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; #define HMAC_CTX_init wolfSSL_HMAC_CTX_Init #define HMAC_CTX_copy wolfSSL_HMAC_CTX_copy #define HMAC_CTX_free wolfSSL_HMAC_CTX_free +#define HMAC_CTX_cleanup wolfSSL_HMAC_CTX_cleanup #define HMAC_CTX_reset wolfSSL_HMAC_cleanup #define HMAC_Init_ex wolfSSL_HMAC_Init_ex #define HMAC_Init wolfSSL_HMAC_Init diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index fe1ec4e80..17ce61311 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -861,7 +861,6 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ /*#if OPENSSL_API_COMPAT < 0x10100000L*/ #define CONF_modules_free() #define ENGINE_cleanup() -#define HMAC_CTX_cleanup wolfSSL_HMAC_cleanup #define SSL_CTX_need_tmp_RSA(ctx) 0 #define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 #define SSL_need_tmp_RSA(ssl) 0 From 1b2b3de2c99a36d0162c07a4baccd4276a427931 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 09:48:46 -0700 Subject: [PATCH 06/10] Fixes for missing free calls on hash tests. --- tests/api.c | 8 ++++++++ tests/hash.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/tests/api.c b/tests/api.c index 9200108fb..fccdd650f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -33346,6 +33346,10 @@ static void test_wolfSSL_EVP_PKEY_sign(void) SHA256_Init(&c); SHA256_Update(&c, in, inlen); SHA256_Final(hash, &c); +#ifdef WOLFSSL_SMALL_STACK_CACHE + /* workaround for small stack cache case */ + wc_Sha256Free((wc_Sha256*)&c); +#endif AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); AssertNotNull(pkey = wolfSSL_EVP_PKEY_new()); @@ -35759,6 +35763,10 @@ static void test_wolfSSL_RSA_verify() SHA256_Init(&c); SHA256_Update(&c, text, strlen(text)); SHA256_Final(hash, &c); +#ifdef WOLFSSL_SMALL_STACK_CACHE + /* workaround for small stack cache case */ + wc_Sha256Free((wc_Sha256*)&c); +#endif /* read privete key file */ fp = XFOPEN(svrKeyFile, "r"); diff --git a/tests/hash.c b/tests/hash.c index be9966ac5..c99eb2908 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -320,6 +320,7 @@ int md5_test(void) if (XMEMCMP(hash, test_md5[i].output, WC_MD5_DIGEST_SIZE) != 0) return -5 - i; } + wc_Md5Free(&md5); return 0; } @@ -380,6 +381,7 @@ int sha_test(void) if (XMEMCMP(hash, test_sha[i].output, WC_SHA_DIGEST_SIZE) != 0) return -10 - i; } + wc_ShaFree(&sha); return 0; } @@ -426,6 +428,7 @@ int sha224_test(void) if (XMEMCMP(hash, test_sha[i].output, WC_SHA224_DIGEST_SIZE) != 0) return -10 - i; } + wc_Sha224Free(&sha); return 0; } @@ -475,6 +478,7 @@ int sha256_test(void) if (XMEMCMP(hash, test_sha[i].output, WC_SHA256_DIGEST_SIZE) != 0) return -10 - i; } + wc_Sha256Free(&sha); return 0; } @@ -529,6 +533,7 @@ int sha512_test(void) if (XMEMCMP(hash, test_sha[i].output, WC_SHA512_DIGEST_SIZE) != 0) return -10 - i; } + wc_Sha512Free(&sha); return 0; } @@ -581,6 +586,7 @@ int sha384_test(void) if (XMEMCMP(hash, test_sha[i].output, WC_SHA384_DIGEST_SIZE) != 0) return -10 - i; } + wc_Sha384Free(&sha); return 0; } From 9af0e5528ee32cc5790aacb2be7c0880bfa7f59f Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Aug 2020 10:22:00 -0700 Subject: [PATCH 07/10] New `openssl_test` return code checking requires fix from PR #3243. --- wolfcrypt/src/evp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 071f1468d..7adce50be 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -5505,7 +5505,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; case WC_HASH_TYPE_SHA3_512: #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512) - wolfSSL_SHA3_512_Update((SHA3_512_CTX*)&ctx->hash, data, + ret = wolfSSL_SHA3_512_Update((SHA3_512_CTX*)&ctx->hash, data, (unsigned long)sz); #endif break; From 3e685fdb5b479fff2ff6dbfb0af2ef8371239fe9 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 27 Aug 2020 10:02:15 -0700 Subject: [PATCH 08/10] Fix for DTLS DoClientHello HMAC free (function has another exit point). --- src/internal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/internal.c b/src/internal.c index 8ded80642..eb83f220e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27529,6 +27529,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) { + #ifdef WOLFSSL_DTLS + wc_HmacFree(&cookieHmac); + #endif WOLFSSL_LEAVE("DoClientHello", ret); WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); From 32b46e344db4db28468c967a440733e5c35ab894 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 27 Aug 2020 11:18:55 -0700 Subject: [PATCH 09/10] Fix for ECC curve cache without custom curves enabled. --- wolfcrypt/src/ecc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index da2a629b8..8ab5e7b78 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1304,15 +1304,13 @@ static void wc_ecc_curve_free(ecc_curve_spec* curve) { if (curve) { #ifdef ECC_CACHE_CURVE - /* only free custom curves (reset are globally cached) */ - if (curve->dp #ifdef WOLFSSL_CUSTOM_CURVES - && curve->dp->id == ECC_CURVE_CUSTOM - #endif - ) { + /* only free custom curves (reset are globally cached) */ + if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) { wc_ecc_curve_cache_free_spec(curve); XFREE(curve, NULL, DYNAMIC_TYPE_ECC); } + #endif #else wc_ecc_curve_cache_free_spec(curve); #endif From 21d17b17d0579d18b8768dcc28fd22a59a112513 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 27 Aug 2020 12:01:24 -0700 Subject: [PATCH 10/10] Fix typo in code comment for ECC curve cache. Fix for valgrind report of possible use of uninitialized value with ChaCha/Poly AEAD test. --- wolfcrypt/src/ecc.c | 2 +- wolfcrypt/test/test.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 8ab5e7b78..e6808b338 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1305,7 +1305,7 @@ static void wc_ecc_curve_free(ecc_curve_spec* curve) if (curve) { #ifdef ECC_CACHE_CURVE #ifdef WOLFSSL_CUSTOM_CURVES - /* only free custom curves (reset are globally cached) */ + /* only free custom curves (rest are globally cached) */ if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) { wc_ecc_curve_cache_free_spec(curve); XFREE(curve, NULL, DYNAMIC_TYPE_ECC); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 8d07e1e53..b4d3e605a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5336,7 +5336,7 @@ int chacha20_poly1305_aead_test(void) } - /* AEAD init/update/final */ + /* AEAD init/update/final - bad argument tests */ err = wc_ChaCha20Poly1305_Init(NULL, key1, iv1, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) @@ -5374,7 +5374,12 @@ int chacha20_poly1305_aead_test(void) if (err != BAD_FUNC_ARG) return -4727; - /* AEAD init/update/final - state tests */ + /* AEAD init/update/final - bad state tests */ + /* clear struct - make valgrind happy to resolve + "Conditional jump or move depends on uninitialised value(s)". + The enum is "int" size and aead.state is "byte" */ + /* The wc_ChaCha20Poly1305_Init function does this normally */ + XMEMSET(&aead, 0, sizeof(aead)); aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != BAD_STATE_E)