diff --git a/src/internal.c b/src/internal.c index 249277a37..9de8836ee 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2400,16 +2400,19 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #endif #ifdef WOLFSSL_STATIC_EPHEMERAL #ifndef NO_DH - if (ctx->staticKE.dhKey && ctx->staticKE.weOwnDH) - FreeDer(&ctx->staticKE.dhKey); + FreeDer(&ctx->staticKE.dhKey); #endif #ifdef HAVE_ECC - if (ctx->staticKE.ecKey && ctx->staticKE.weOwnEC) - FreeDer(&ctx->staticKE.ecKey); + FreeDer(&ctx->staticKE.ecKey); #endif #ifdef HAVE_CURVE25519 - if (ctx->staticKE.x25519Key && ctx->staticKE.weOwnX25519) - FreeDer(&ctx->staticKE.x25519Key); + FreeDer(&ctx->staticKE.x25519Key); + #endif + #ifndef SINGLE_THREADED + if (ctx->staticKELockInit) { + wc_FreeMutex(&ctx->staticKELock); + ctx->staticKELockInit = 0; + } #endif #endif (void)heapAtCTXInit; @@ -6381,19 +6384,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.useClientOrder = ctx->useClientOrder; ssl->options.mutualAuth = ctx->mutualAuth; -#ifdef WOLFSSL_STATIC_EPHEMERAL - XMEMCPY(&ssl->staticKE, &ctx->staticKE, sizeof(StaticKeyExchangeInfo_t)); - #ifdef HAVE_ECC - ssl->staticKE.weOwnEC = 0; - #endif - #ifndef NO_DH - ssl->staticKE.weOwnDH = 0; - #endif - #ifdef HAVE_CURVE25519 - ssl->staticKE.weOwnX25519 = 0; - #endif -#endif - #ifdef WOLFSSL_TLS13 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) ssl->options.maxTicketTls13 = ctx->maxTicketTls13; @@ -7207,16 +7197,13 @@ void SSL_ResourceFree(WOLFSSL* ssl) #endif #ifdef WOLFSSL_STATIC_EPHEMERAL #ifndef NO_DH - if (ssl->staticKE.dhKey && ssl->staticKE.weOwnDH) - FreeDer(&ssl->staticKE.dhKey); + FreeDer(&ssl->staticKE.dhKey); #endif #ifdef HAVE_ECC - if (ssl->staticKE.ecKey && ssl->staticKE.weOwnEC) - FreeDer(&ssl->staticKE.ecKey); + FreeDer(&ssl->staticKE.ecKey); #endif #ifdef HAVE_CURVE25519 - if (ssl->staticKE.x25519Key && ssl->staticKE.weOwnX25519) - FreeDer(&ssl->staticKE.x25519Key); + FreeDer(&ssl->staticKE.x25519Key); #endif #endif diff --git a/src/sniffer.c b/src/sniffer.c index 6112b018c..defcf0194 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -2158,32 +2158,19 @@ static void ShowTlsSecrets(SnifferSession* session) /* Process Keys */ -/* contains static ephemeral keys */ -typedef struct { -#ifndef NO_DH - DerBuffer* dhKey; -#endif -#ifdef HAVE_ECC - DerBuffer* ecKey; -#endif -#ifdef HAVE_CURVE25519 - DerBuffer* x25519Key; -#endif -#if !defined(NO_RSA) && defined(WOLFSSL_STATIC_RSA) - DerBuffer* rsaKey; -#endif -} KeyBuffers_t; - static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, - char* error, KeyShareInfo* ksInfo, KeyBuffers_t* keys) + char* error, KeyShareInfo* ksInfo) { word32 idx = 0; int ret; - DerBuffer* keyBuf; + DerBuffer* keyBuf = NULL; + int keyBufFree = 0; #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) int useCurveId = 0; #endif int devId = INVALID_DEVID; + WOLFSSL_CTX* ctx = session->context->ctx; + WOLFSSL* ssl = session->sslServer; #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) if (ksInfo && ksInfo->curve_id != 0) @@ -2201,15 +2188,18 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, #ifndef NO_RSA /* Static RSA */ - if (ksInfo == NULL && keys->rsaKey) { + if (ksInfo == NULL && ssl->buffers.key) { RsaKey key; int length; - - keyBuf = keys->rsaKey; + int keyInit = 0; ret = wc_InitRsaKey_ex(&key, NULL, devId); if (ret == 0) { - ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length); + keyInit = 1; + keyBuf = ssl->buffers.key; + + ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key, + keyBuf->length); if (ret != 0) { #ifndef HAVE_ECC #ifdef WOLFSSL_SNIFFER_STATS @@ -2217,18 +2207,12 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, #endif SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE); #else - /* If we can do ECC, this isn't fatal. Not loading an ECC - * key will be fatal, though. */ + /* If we can do ECC, this isn't fatal. Not loading a key later + * will be fatal, though. */ SetError(RSA_DECODE_STR, error, session, 0); - if (keys->ecKey == NULL) - keys->ecKey = session->sslServer->buffers.key; /* try ECC */ + keyBuf = NULL; #endif } - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) - else { - useCurveId = -1; /* don't try loading further */ - } - #endif } if (ret == 0) { @@ -2243,14 +2227,14 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } } - #ifdef WC_RSA_BLINDING + #ifdef WC_RSA_BLINDING if (ret == 0) { ret = wc_RsaSetRNG(&key, session->sslServer->rng); if (ret != 0) { SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); } } - #endif + #endif if (ret == 0) { session->keySz = length * WOLFSSL_BIT_SIZE; @@ -2264,8 +2248,8 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, #endif if (ret >= 0) { ret = wc_RsaPrivateDecrypt(input, length, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz, &key); + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz, &key); } } while (ret == WC_PENDING_E); @@ -2274,100 +2258,137 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } } - wc_FreeRsaKey(&key); + if (keyInit) { + wc_FreeRsaKey(&key); + } } #endif /* !NO_RSA */ #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) /* Static DH Key */ - if (ksInfo && ksInfo->dh_key_bits != 0 && keys->dhKey) { + if (ksInfo && ksInfo->dh_key_bits != 0 && keyBuf == NULL) { DhKey dhKey; -#ifdef HAVE_PUBLIC_FFDHE + #ifdef HAVE_PUBLIC_FFDHE const DhParams* params; - word32 privKeySz; -#else + #endif word32 privKeySz = 0, p_len = 0; -#endif byte privKey[52]; /* max for TLS */ + int keyInit = 0; - keyBuf = keys->dhKey; + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + #ifndef SINGLE_THREADED + int keyLocked = 0; + if (ctx->staticKELockInit && + wc_LockMutex(&ctx->staticKELock) == 0) + #endif + { + #ifndef SINGLE_THREADED + keyLocked = 1; + #endif + keyBuf = ssl->staticKE.dhKey; + if (keyBuf == NULL) + keyBuf = ctx->staticKE.dhKey; + } + #endif -#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK if (KeyCb != NULL) { + if (keyBuf == NULL) { + ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); + if (ret == 0) + keyBufFree = 1; + } ret = KeyCb(session, ksInfo->named_group, session->srvKs.key, session->srvKs.key_len, session->cliKs.key, session->cliKs.key_len, keyBuf, KeyCbCtx, error); if (ret != 0) { SetError(-1, error, session, FATAL_ERROR_STATE); - return ret; } } -#endif - -#ifdef HAVE_PUBLIC_FFDHE - /* get DH params */ - switch (ksInfo->named_group) { - #ifdef HAVE_FFDHE_2048 - case WOLFSSL_FFDHE_2048: - params = wc_Dh_ffdhe2048_Get(); - privKeySz = 29; - break; - #endif - #ifdef HAVE_FFDHE_3072 - case WOLFSSL_FFDHE_3072: - params = wc_Dh_ffdhe3072_Get(); - privKeySz = 34; - break; - #endif - #ifdef HAVE_FFDHE_4096 - case WOLFSSL_FFDHE_4096: - params = wc_Dh_ffdhe4096_Get(); - privKeySz = 39; - break; - #endif - #ifdef HAVE_FFDHE_6144 - case WOLFSSL_FFDHE_6144: - params = wc_Dh_ffdhe6144_Get(); - privKeySz = 46; - break; - #endif - #ifdef HAVE_FFDHE_8192 - case WOLFSSL_FFDHE_8192: - params = wc_Dh_ffdhe8192_Get(); - privKeySz = 52; - break; - #endif - default: - return BAD_FUNC_ARG; + #endif + if (ret == 0 && keyBuf == NULL) { + ret = BUFFER_E; } -#endif - ret = wc_InitDhKey_ex(&dhKey, NULL, devId); + #ifdef HAVE_PUBLIC_FFDHE if (ret == 0) { -#ifdef HAVE_PUBLIC_FFDHE + /* get DH params */ + switch (ksInfo->named_group) { + #ifdef HAVE_FFDHE_2048 + case WOLFSSL_FFDHE_2048: + params = wc_Dh_ffdhe2048_Get(); + privKeySz = 29; + break; + #endif + #ifdef HAVE_FFDHE_3072 + case WOLFSSL_FFDHE_3072: + params = wc_Dh_ffdhe3072_Get(); + privKeySz = 34; + break; + #endif + #ifdef HAVE_FFDHE_4096 + case WOLFSSL_FFDHE_4096: + params = wc_Dh_ffdhe4096_Get(); + privKeySz = 39; + break; + #endif + #ifdef HAVE_FFDHE_6144 + case WOLFSSL_FFDHE_6144: + params = wc_Dh_ffdhe6144_Get(); + privKeySz = 46; + break; + #endif + #ifdef HAVE_FFDHE_8192 + case WOLFSSL_FFDHE_8192: + params = wc_Dh_ffdhe8192_Get(); + privKeySz = 52; + break; + #endif + default: + ret = BAD_FUNC_ARG; + } + } + #endif + + if (ret == 0) { + ret = wc_InitDhKey_ex(&dhKey, NULL, devId); + if (ret == 0) + keyInit = 1; + } + if (ret == 0) { + #ifdef HAVE_PUBLIC_FFDHE ret = wc_DhSetKey(&dhKey, (byte*)params->p, params->p_len, (byte*)params->g, params->g_len); -#else + p_len = params->p_len; + #else ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group); -#endif - if (ret == 0) { - ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey, - keyBuf->length); - } -#ifndef HAVE_PUBLIC_FFDHE if (ret == 0) { privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group); ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group, &p_len, NULL, NULL); } -#endif - if (ret == 0) { - ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL, - NULL); - } + #endif + } + if (ret == 0) { + ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey, + keyBuf->length); + } + if (ret == 0) { + ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL, + NULL); + } + #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + if (keyLocked) { + wc_UnLockMutex(&ctx->staticKELock); + } + #endif + + if (ret == 0) { /* Derive secret from private key and peer's public key */ do { #ifdef WOLFSSL_ASYNC_CRYPT @@ -2384,71 +2405,86 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, PRIVATE_KEY_LOCK(); } } while (ret == WC_PENDING_E); + } + if (keyInit) wc_FreeDhKey(&dhKey); - #ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); - #endif + #ifdef WOLFSSL_SNIFFER_STATS + if (ret != 0) + INC_STAT(SnifferStats.sslKeyFails); + #endif - /* left-padded with zeros up to the size of the prime */ -#ifdef HAVE_PUBLIC_FFDHE - if (ret == 0 && params->p_len > session->sslServer->arrays->preMasterSz) { - word32 diff = params->p_len - session->sslServer->arrays->preMasterSz; - XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz); - XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); - session->sslServer->arrays->preMasterSz = params->p_len; - } -#else /* HAVE_PUBLIC_FFDHE */ - if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) { - word32 diff = p_len - session->sslServer->arrays->preMasterSz; - XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz); - XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); - session->sslServer->arrays->preMasterSz = p_len; - } -#endif /* HAVE_PUBLIC_FFDHE */ + /* left-padded with zeros up to the size of the prime */ + if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) { + word32 diff = p_len - session->sslServer->arrays->preMasterSz; + XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz); + XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); + session->sslServer->arrays->preMasterSz = p_len; } } #endif /* !NO_DH && WOLFSSL_DH_EXTRA */ #ifdef HAVE_ECC /* Static ECC Key */ - if (useCurveId >= 0 && keys->ecKey + if (useCurveId >= 0 && keyBuf == NULL #ifdef HAVE_CURVE25519 && useCurveId != ECC_X25519 #endif ) { - ecc_key key; - ecc_key pubKey; + ecc_key key, pubKey; int length, keyInit = 0, pubKeyInit = 0; - keyBuf = keys->ecKey; + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + #ifndef SINGLE_THREADED + int keyLocked = 0; + if (ctx->staticKELockInit && + wc_LockMutex(&ctx->staticKELock) == 0) + #endif + { + #ifndef SINGLE_THREADED + keyLocked = 1; + #endif + keyBuf = ssl->staticKE.ecKey; + if (keyBuf == NULL) + keyBuf = ctx->staticKE.ecKey; + } + #endif -#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + /* try static ECC */ + if (keyBuf == NULL) { + keyBuf = session->sslServer->buffers.key; + } + + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK if (KeyCb != NULL && ksInfo) { + if (keyBuf == NULL) { + ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); + if (ret == 0) + keyBufFree = 1; + } ret = KeyCb(session, ksInfo->named_group, session->srvKs.key, session->srvKs.key_len, session->cliKs.key, session->cliKs.key_len, keyBuf, KeyCbCtx, error); if (ret != 0) { SetError(-1, error, session, FATAL_ERROR_STATE); - return ret; } } -#endif + #endif - idx = 0; - ret = wc_ecc_init_ex(&key, NULL, devId); - if (ret == 0) { - keyInit = 1; - ret = wc_ecc_init(&pubKey); + if (ret == 0 && keyBuf == NULL) { + ret = BUFFER_E; + } + if (ret == 0) { + ret = wc_ecc_init_ex(&key, NULL, devId); + if (ret == 0) + keyInit = 1; } - #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ !defined(HAVE_SELFTEST) @@ -2456,15 +2492,20 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, ret = wc_ecc_set_rng(&key, session->sslServer->rng); } #endif - if (ret == 0) { - pubKeyInit = 1; + idx = 0; ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length); if (ret != 0) { SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); } } + #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + if (keyLocked) { + wc_UnLockMutex(&ctx->staticKELock); + } + #endif + if (ret == 0) { length = wc_ecc_size(&key) * 2 + 1; /* The length should be 2 times the key size (x and y), plus 1 @@ -2483,14 +2524,17 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, useCurveId = key.dp->id; } } - + if (ret == 0) { + ret = wc_ecc_init(&pubKey); + if (ret == 0) + pubKeyInit = 1; + } if (ret == 0) { ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId); if (ret != 0) { SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); } } - if (ret == 0) { session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE; /* Length is in bytes. Subtract 1 for the ECC key type. Divide @@ -2513,10 +2557,10 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } while (ret == WC_PENDING_E); } -#ifdef WOLFSSL_SNIFFER_STATS + #ifdef WOLFSSL_SNIFFER_STATS if (ret != 0) INC_STAT(SnifferStats.sslKeyFails); -#endif + #endif if (keyInit) wc_ecc_free(&key); @@ -2527,15 +2571,34 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, #ifdef HAVE_CURVE25519 /* Static Curve25519 Key */ - if (useCurveId == ECC_X25519 && keys->x25519Key) { - curve25519_key key; - curve25519_key pubKey; + if (useCurveId == ECC_X25519) { + curve25519_key key, pubKey; int length, keyInit = 0, pubKeyInit = 0; - keyBuf = keys->x25519Key; + /* try and load static ephemeral */ +#ifdef WOLFSSL_STATIC_EPHEMERAL + #ifndef SINGLE_THREADED + int keyLocked = 0; + if (ctx->staticKELockInit && + wc_LockMutex(&ctx->staticKELock) == 0) + #endif + { + #ifndef SINGLE_THREADED + keyLocked = 1; + #endif + keyBuf = ssl->staticKE.x25519Key; + if (keyBuf == NULL) + keyBuf = ctx->staticKE.x25519Key; + } +#endif #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK if (KeyCb != NULL && ksInfo) { + if (keyBuf == NULL) { + ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); + if (ret == 0) + keyBufFree = 1; + } ret = KeyCb(session, ksInfo->named_group, session->srvKs.key, session->srvKs.key_len, session->cliKs.key, session->cliKs.key_len, @@ -2547,15 +2610,16 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } #endif - idx = 0; - ret = wc_curve25519_init_ex(&key, NULL, devId); - if (ret == 0) { - keyInit = 1; - ret = wc_curve25519_init(&pubKey); + if (ret == 0 && keyBuf == NULL) { + ret = BUFFER_E; } - if (ret == 0) { - pubKeyInit = 1; + ret = wc_curve25519_init_ex(&key, NULL, devId); + if (ret == 0) + keyInit = 1; + } + if (ret == 0) { + idx = 0; ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length); if (ret != 0) { @@ -2563,6 +2627,12 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } } +#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + if (keyLocked) { + wc_UnLockMutex(&ctx->staticKELock); + } +#endif + if (ret == 0) { length = CURVE25519_KEYSIZE; if (length > *sslBytes) { @@ -2570,7 +2640,11 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, ret = -1; } } - + if (ret == 0) { + ret = wc_curve25519_init(&pubKey); + if (ret == 0) + pubKeyInit = 1; + } if (ret == 0) { ret = wc_curve25519_import_public_ex(input, length, &pubKey, EC25519_LITTLE_ENDIAN); @@ -2601,6 +2675,10 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } #endif /* HAVE_CURVE25519 */ + if (keyBufFree && keyBuf != NULL) { + FreeDer(&keyBuf); + } + /* store for client side as well */ XMEMCPY(session->sslClient->arrays->preMasterSecret, session->sslServer->arrays->preMasterSecret, @@ -2666,12 +2744,13 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, return ret; } -/* Process Client Key Exchange, static RSA */ +/* Process Client Key Exchange */ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, SnifferSession* session, char* error) { - KeyBuffers_t keys; + int ret; +#ifndef WOLFSSL_STATIC_EPHEMERAL if (session->sslServer->buffers.key == NULL || session->sslServer->buffers.key->buffer == NULL || session->sslServer->buffers.key->length == 0) { @@ -2679,23 +2758,11 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE); return -1; } +#endif - XMEMSET(&keys, 0, sizeof(keys)); -#ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef NO_DH - keys.dhKey = session->sslServer->staticKE.dhKey; - #endif - #ifdef HAVE_ECC - keys.ecKey = session->sslServer->staticKE.ecKey; - #endif - #ifdef HAVE_CURVE25519 - keys.x25519Key = session->sslServer->staticKE.x25519Key; - #endif -#endif -#ifndef NO_RSA - keys.rsaKey = session->sslServer->buffers.key; -#endif - return SetupKeys(input, sslBytes, session, error, NULL, &keys); + ret = SetupKeys(input, sslBytes, session, error, NULL); + + return ret; } #ifdef WOLFSSL_TLS13 @@ -3315,25 +3382,8 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, #ifdef WOLFSSL_TLS13 /* Setup handshake keys */ if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len > 0) { - KeyBuffers_t keys; - XMEMSET(&keys, 0, sizeof(keys)); - #ifndef NO_RSA - keys.rsaKey = session->sslServer->buffers.key; - #endif - #ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef NO_DH - keys.dhKey = session->sslServer->staticKE.dhKey; - #endif - #ifdef HAVE_ECC - keys.ecKey = session->sslServer->staticKE.ecKey; - #endif - #ifdef HAVE_CURVE25519 - keys.x25519Key = session->sslServer->staticKE.x25519Key; - #endif - #endif - ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len, - session, error, &session->cliKs, &keys); + session, error, &session->cliKs); if (ret != 0) { SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); return ret; diff --git a/src/ssl.c b/src/ssl.c index e15d248f9..37142b468 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -55597,8 +55597,82 @@ int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey) #endif /* OPENSSL_ALL && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */ #ifdef WOLFSSL_STATIC_EPHEMERAL -static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo, - const char* key, unsigned int keySz, int format, void* heap) +int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr) +{ + int ret = BUFFER_E; + word32 idx = 0; + DerBuffer* der = NULL; + + if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) { + return BAD_FUNC_ARG; + } + +#ifndef SINGLE_THREADED + if (!ssl->ctx->staticKELockInit) { + return BUFFER_E; /* no keys set */ + } + ret = wc_LockMutex(&ssl->ctx->staticKELock); + if (ret != 0) { + return ret; + } +#endif + + switch (keyAlgo) { + #ifndef NO_DH + case WC_PK_TYPE_DH: + if (ssl != NULL) + der = ssl->staticKE.dhKey; + if (der == NULL) + der = ssl->ctx->staticKE.dhKey; + if (der != NULL) { + DhKey* key = (DhKey*)keyPtr; + WOLFSSL_MSG("Using static DH key"); + ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length); + } + break; + #endif + #ifdef HAVE_ECC + case WC_PK_TYPE_ECDH: + if (ssl != NULL) + der = ssl->staticKE.ecKey; + if (der == NULL) + der = ssl->ctx->staticKE.ecKey; + if (der != NULL) { + ecc_key* key = (ecc_key*)keyPtr; + WOLFSSL_MSG("Using static ECDH key"); + ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length); + } + break; + #endif + #ifdef HAVE_CURVE25519 + case WC_PK_TYPE_CURVE25519: + if (ssl != NULL) + der = ssl->staticKE.x25519Key; + if (der == NULL) + der = ssl->ctx->staticKE.x25519Key; + if (der != NULL) { + curve25519_key* key = (curve25519_key*)keyPtr; + WOLFSSL_MSG("Using static X25519 key"); + ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key, + der->length); + } + break; + #endif + default: + /* not supported */ + ret = NOT_COMPILED_IN; + break; + } + +#ifndef SINGLE_THREADED + wc_UnLockMutex(&ssl->ctx->staticKELock); +#endif + return ret; +} + +static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx, + StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key, + unsigned int keySz, int format, void* heap) { int ret = 0; DerBuffer* der = NULL; @@ -55711,53 +55785,55 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo, } #endif - /* if key is already allocated then set free it */ -#ifndef NO_DH - if (keyAlgo == WC_PK_TYPE_DH && staticKE->dhKey && staticKE->weOwnDH) { - FreeDer(&staticKE->dhKey); - } -#endif -#ifdef HAVE_ECC - if (keyAlgo == WC_PK_TYPE_ECDH && staticKE->ecKey && staticKE->weOwnEC) { - FreeDer(&staticKE->ecKey); - } -#endif -#ifdef HAVE_CURVE25519 - if (keyAlgo == WC_PK_TYPE_CURVE25519 && staticKE->x25519Key && - staticKE->weOwnX25519) { - FreeDer(&staticKE->x25519Key); +#ifndef SINGLE_THREADED + if (ret == 0 && !ctx->staticKELockInit) { + ret = wc_InitMutex(&ctx->staticKELock); + if (ret == 0) { + ctx->staticKELockInit = 1; + } } #endif + if (ret == 0 + #ifndef SINGLE_THREADED + && (ret = wc_LockMutex(&ctx->staticKELock)) == 0 + #endif + ) { + switch (keyAlgo) { + #ifndef NO_DH + case WC_PK_TYPE_DH: + FreeDer(&staticKE->dhKey); + staticKE->dhKey = der; der = NULL; + break; + #endif + #ifdef HAVE_ECC + case WC_PK_TYPE_ECDH: + FreeDer(&staticKE->ecKey); + staticKE->ecKey = der; der = NULL; + break; + #endif + #ifdef HAVE_CURVE25519 + case WC_PK_TYPE_CURVE25519: + FreeDer(&staticKE->x25519Key); + staticKE->x25519Key = der; der = NULL; + break; + #endif + default: + /* not supported */ + ret = NOT_COMPILED_IN; + break; + } - switch (keyAlgo) { - #ifndef NO_DH - case WC_PK_TYPE_DH: - staticKE->dhKey = der; der = NULL; - staticKE->weOwnDH = 1; - break; + #ifndef SINGLE_THREADED + wc_UnLockMutex(&ctx->staticKELock); #endif - #ifdef HAVE_ECC - case WC_PK_TYPE_ECDH: - staticKE->ecKey = der; der = NULL; - staticKE->weOwnEC = 1; - break; - #endif - #ifdef HAVE_CURVE25519 - case WC_PK_TYPE_CURVE25519: - staticKE->x25519Key = der; der = NULL; - staticKE->weOwnX25519 = 1; - break; - #endif - default: - /* not supported */ - ret = NOT_COMPILED_IN; - break; } if (ret != 0) { FreeDer(&der); } + (void)ctx; /* not used for single threaded */ + WOLFSSL_LEAVE("SetStaticEphemeralKey", ret); return ret; @@ -55769,48 +55845,58 @@ int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo, if (ctx == NULL) { return BAD_FUNC_ARG; } - - return SetStaticEphemeralKey(&ctx->staticKE, keyAlgo, key, keySz, format, - ctx->heap); + return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo, + key, keySz, format, ctx->heap); } int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo, const char* key, unsigned int keySz, int format) { - if (ssl == NULL) { + if (ssl == NULL || ssl->ctx == NULL) { return BAD_FUNC_ARG; } - - return SetStaticEphemeralKey(&ssl->staticKE, keyAlgo, key, keySz, format, - ssl->heap); + return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo, + key, keySz, format, ssl->heap); } -static int GetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo, - const unsigned char** key, unsigned int* keySz) +static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, + int keyAlgo, const unsigned char** key, unsigned int* keySz) { int ret = 0; DerBuffer* der = NULL; - if (staticKE == NULL || key == NULL || keySz == NULL) { - return BAD_FUNC_ARG; - } + if (key) *key = NULL; + if (keySz) *keySz = 0; - *key = NULL; - *keySz = 0; +#ifndef SINGLE_THREADED + if (ctx->staticKELockInit && + (ret = wc_LockMutex(&ctx->staticKELock)) != 0) { + return ret; + } +#endif switch (keyAlgo) { #ifndef NO_DH case WC_PK_TYPE_DH: - der = staticKE->dhKey; + if (ssl != NULL) + der = ssl->staticKE.dhKey; + if (der == NULL) + der = ctx->staticKE.dhKey; break; #endif #ifdef HAVE_ECC case WC_PK_TYPE_ECDH: - der = staticKE->ecKey; + if (ssl != NULL) + der = ssl->staticKE.ecKey; + if (der == NULL) + der = ctx->staticKE.ecKey; break; #endif #ifdef HAVE_CURVE25519 case WC_PK_TYPE_CURVE25519: - der = staticKE->x25519Key; + if (ssl != NULL) + der = ssl->staticKE.x25519Key; + if (der == NULL) + der = ctx->staticKE.x25519Key; break; #endif default: @@ -55820,10 +55906,16 @@ static int GetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo, } if (der) { - *key = der->buffer; - *keySz = der->length; + if (key) + *key = der->buffer; + if (keySz) + *keySz = der->length; } +#ifndef SINGLE_THREADED + wc_UnLockMutex(&ctx->staticKELock); +#endif + return ret; } @@ -55836,16 +55928,16 @@ int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo, return BAD_FUNC_ARG; } - return GetStaticEphemeralKey(&ctx->staticKE, keyAlgo, key, keySz); + return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz); } int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo, const unsigned char** key, unsigned int* keySz) { - if (ssl == NULL) { + if (ssl == NULL || ssl->ctx == NULL) { return BAD_FUNC_ARG; } - return GetStaticEphemeralKey(&ssl->staticKE, keyAlgo, key, keySz); + return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz); } #endif /* WOLFSSL_STATIC_EPHEMERAL */ diff --git a/src/tls.c b/src/tls.c index 92b2f4034..ee271d0d1 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6217,18 +6217,12 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) if (ret == 0) { #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA) - if (ssl->staticKE.dhKey) { - DerBuffer* keyDer = ssl->staticKE.dhKey; - word32 idx = 0; - WOLFSSL_MSG("Using static DH key"); - ret = wc_DhKeyDecode(keyDer->buffer, &idx, - dhKey, keyDer->length); - if (ret == 0) { - ret = wc_DhExportKeyPair(dhKey, - (byte*)kse->privKey, &kse->keyLen, /* private */ - kse->pubKey, &kse->pubKeyLen /* public */ - ); - } + ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key); + if (ret == 0) { + ret = wc_DhExportKeyPair(dhKey, + (byte*)kse->privKey, &kse->keyLen, /* private */ + kse->pubKey, &kse->pubKeyLen /* public */ + ); } else #endif @@ -6329,16 +6323,12 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse) ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap, INVALID_DEVID); if (ret == 0) { + /* setting "key" means okay to call wc_curve25519_free */ key = (curve25519_key*)kse->key; + #ifdef WOLFSSL_STATIC_EPHEMERAL - if (ssl->staticKE.x25519Key) { - DerBuffer* keyDer = ssl->staticKE.x25519Key; - word32 idx = 0; - WOLFSSL_MSG("Using static X25519 key"); - ret = wc_Curve25519PrivateKeyDecode(keyDer->buffer, &idx, key, - keyDer->length); - } - else + ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key); + if (ret != 0) #endif { ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key); @@ -6536,17 +6526,12 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) /* Make an ECC key */ ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId); if (ret == 0) { + /* setting eccKey means okay to call wc_ecc_free */ eccKey = (ecc_key*)kse->key; #ifdef WOLFSSL_STATIC_EPHEMERAL - if (ssl->staticKE.ecKey) { - DerBuffer* keyDer = ssl->staticKE.ecKey; - word32 idx = 0; - WOLFSSL_MSG("Using static ECDH key"); - ret = wc_EccPrivateKeyDecode(keyDer->buffer, &idx, eccKey, - keyDer->length); - } - else + ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key); + if (ret != 0) #endif { /* set curve info for EccMakeKey "peer" info */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c6639e30b..ad751d9cc 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2731,19 +2731,8 @@ typedef struct { #ifdef HAVE_CURVE25519 DerBuffer* x25519Key; #endif - - /* bits */ -#ifndef NO_DH - byte weOwnDH:1; -#endif -#ifdef HAVE_ECC - byte weOwnEC:1; -#endif -#ifdef HAVE_CURVE25519 - byte weOwnX25519:1; -#endif } StaticKeyExchangeInfo_t; -#endif +#endif /* WOLFSSL_STATIC_EPHEMERAL */ /* wolfSSL context type */ @@ -2846,6 +2835,10 @@ struct WOLFSSL_CTX { #ifdef WOLFSSL_STATIC_MEMORY byte onHeapHint:1; /* whether the ctx/method is put on heap hint */ #endif +#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + byte staticKELockInit:1; +#endif + #ifdef WOLFSSL_MULTICAST byte haveMcast; /* multicast requested */ byte mcastID; /* multicast group ID */ @@ -3074,6 +3067,9 @@ struct WOLFSSL_CTX { #endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */ #ifdef WOLFSSL_STATIC_EPHEMERAL StaticKeyExchangeInfo_t staticKE; + #ifndef SINGLE_THREADED + wolfSSL_Mutex staticKELock; + #endif #endif }; @@ -5029,6 +5025,10 @@ WOLFSSL_LOCAL int oid2nid(word32 oid, int grp); WOLFSSL_LOCAL word32 nid2oid(int nid, int grp); #endif +#ifdef WOLFSSL_STATIC_EPHEMERAL +WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif