Fix for SRP leaks with WOLFSSL_SMALL_STACK_CACHE

This commit is contained in:
David Garske
2020-08-26 09:41:09 -07:00
parent d077efcbb3
commit 14e1489365
3 changed files with 67 additions and 23 deletions

View File

@ -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]),

View File

@ -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));

View File

@ -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) */