forked from wolfSSL/wolfssl
async: fix overwrite of keylen params between calls
The `kse->pubKeyLen` parameter is used as an input parameter to `DhGenKeyPair` to provide the size of the `pubKey` buffer (the same size as the prime p). After that, `kse->pubKeyLen` is used to check that the public key generated is of the same length as the prime p. If this is not the case, the public key is padded. If the key generation is asynchronous, then `TLSX_KeyShare_GenDhKey` may be invoked twice. The second time, the `kse->pubKeyLen` value, updated asynchronously by the async code, is overwritten with the prime size at the beginning of the function. When this happens, a wrong public key value is used, and the shared secret computed is incorrect. Similar reasoning can be applied to `kse->keyLen`
This commit is contained in:
25
src/tls.c
25
src/tls.c
@ -6724,31 +6724,31 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
#ifdef HAVE_FFDHE_2048
|
#ifdef HAVE_FFDHE_2048
|
||||||
case WOLFSSL_FFDHE_2048:
|
case WOLFSSL_FFDHE_2048:
|
||||||
params = wc_Dh_ffdhe2048_Get();
|
params = wc_Dh_ffdhe2048_Get();
|
||||||
kse->keyLen = 29;
|
pvtSz = 29;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FFDHE_3072
|
#ifdef HAVE_FFDHE_3072
|
||||||
case WOLFSSL_FFDHE_3072:
|
case WOLFSSL_FFDHE_3072:
|
||||||
params = wc_Dh_ffdhe3072_Get();
|
params = wc_Dh_ffdhe3072_Get();
|
||||||
kse->keyLen = 34;
|
pvtSz = 34;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FFDHE_4096
|
#ifdef HAVE_FFDHE_4096
|
||||||
case WOLFSSL_FFDHE_4096:
|
case WOLFSSL_FFDHE_4096:
|
||||||
params = wc_Dh_ffdhe4096_Get();
|
params = wc_Dh_ffdhe4096_Get();
|
||||||
kse->keyLen = 39;
|
pvtSz = 39;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FFDHE_6144
|
#ifdef HAVE_FFDHE_6144
|
||||||
case WOLFSSL_FFDHE_6144:
|
case WOLFSSL_FFDHE_6144:
|
||||||
params = wc_Dh_ffdhe6144_Get();
|
params = wc_Dh_ffdhe6144_Get();
|
||||||
kse->keyLen = 46;
|
pvtSz = 46;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FFDHE_8192
|
#ifdef HAVE_FFDHE_8192
|
||||||
case WOLFSSL_FFDHE_8192:
|
case WOLFSSL_FFDHE_8192:
|
||||||
params = wc_Dh_ffdhe8192_Get();
|
params = wc_Dh_ffdhe8192_Get();
|
||||||
kse->keyLen = 52;
|
pvtSz = 52;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@ -6757,19 +6757,16 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
if (params == NULL)
|
if (params == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
pSz = params->p_len;
|
pSz = params->p_len;
|
||||||
pvtSz = kse->keyLen;
|
|
||||||
#else
|
#else
|
||||||
kse->keyLen = wc_DhGetNamedKeyMinSize(kse->group);
|
pvtSz = wc_DhGetNamedKeyMinSize(kse->group);
|
||||||
if (kse->keyLen == 0) {
|
if (pvtSz == 0) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
ret = wc_DhGetNamedKeyParamSize(kse->group, &pSz, NULL, NULL);
|
ret = wc_DhGetNamedKeyParamSize(kse->group, &pSz, NULL, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
pvtSz = kse->keyLen;
|
|
||||||
#endif
|
#endif
|
||||||
kse->pubKeyLen = pSz;
|
|
||||||
|
|
||||||
/* Trigger Key Generation */
|
/* Trigger Key Generation */
|
||||||
if (kse->pubKey == NULL || kse->privKey == NULL) {
|
if (kse->pubKey == NULL || kse->privKey == NULL) {
|
||||||
@ -6794,14 +6791,14 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
|
|
||||||
/* Allocate space for the private and public key */
|
/* Allocate space for the private and public key */
|
||||||
if (ret == 0 && kse->pubKey == NULL) {
|
if (ret == 0 && kse->pubKey == NULL) {
|
||||||
kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap,
|
kse->pubKey = (byte*)XMALLOC(pSz, ssl->heap,
|
||||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||||
if (kse->pubKey == NULL)
|
if (kse->pubKey == NULL)
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 && kse->privKey == NULL) {
|
if (ret == 0 && kse->privKey == NULL) {
|
||||||
kse->privKey = (byte*)XMALLOC(kse->keyLen, ssl->heap,
|
kse->privKey = (byte*)XMALLOC(pvtSz, ssl->heap,
|
||||||
DYNAMIC_TYPE_PRIVATE_KEY);
|
DYNAMIC_TYPE_PRIVATE_KEY);
|
||||||
if (kse->privKey == NULL)
|
if (kse->privKey == NULL)
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
@ -6810,6 +6807,8 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
|
||||||
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key);
|
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key);
|
||||||
|
kse->pubKeyLen = pSz;
|
||||||
|
kse->keyLen = pvtSz;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_DhExportKeyPair(dhKey,
|
ret = wc_DhExportKeyPair(dhKey,
|
||||||
(byte*)kse->privKey, &kse->keyLen, /* private */
|
(byte*)kse->privKey, &kse->keyLen, /* private */
|
||||||
@ -6823,6 +6822,8 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
/* For async this is called once and when event is done, the
|
/* For async this is called once and when event is done, the
|
||||||
* provided buffers will be populated.
|
* provided buffers will be populated.
|
||||||
* Final processing is zero pad below. */
|
* Final processing is zero pad below. */
|
||||||
|
kse->pubKeyLen = pSz;
|
||||||
|
kse->keyLen = pvtSz;
|
||||||
ret = DhGenKeyPair(ssl, dhKey,
|
ret = DhGenKeyPair(ssl, dhKey,
|
||||||
(byte*)kse->privKey, &kse->keyLen, /* private */
|
(byte*)kse->privKey, &kse->keyLen, /* private */
|
||||||
kse->pubKey, &kse->pubKeyLen /* public */
|
kse->pubKey, &kse->pubKeyLen /* public */
|
||||||
|
Reference in New Issue
Block a user