mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Fix for SRP leaks with WOLFSSL_SMALL_STACK_CACHE
This commit is contained in:
39
src/ssl.c
39
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]),
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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) */
|
||||
|
||||
|
Reference in New Issue
Block a user