diff --git a/src/internal.c b/src/internal.c index 9de8836ee..b21d5df1c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2408,6 +2408,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #ifdef HAVE_CURVE25519 FreeDer(&ctx->staticKE.x25519Key); #endif + #ifdef HAVE_CURVE448 + FreeDer(&ctx->staticKE.x448Key); + #endif #ifndef SINGLE_THREADED if (ctx->staticKELockInit) { wc_FreeMutex(&ctx->staticKELock); @@ -7205,6 +7208,9 @@ void SSL_ResourceFree(WOLFSSL* ssl) #ifdef HAVE_CURVE25519 FreeDer(&ssl->staticKE.x25519Key); #endif + #ifdef HAVE_CURVE448 + FreeDer(&ssl->staticKE.x448Key); + #endif #endif #ifdef WOLFSSL_STATIC_MEMORY diff --git a/src/sniffer.c b/src/sniffer.c index defcf0194..5e54eccd0 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1074,10 +1074,10 @@ static void TraceSetNamedServer(const char* name, if (TraceOn) { XFPRINTF(TraceFile, "\tTrying to install a new Sniffer Server with\n"); XFPRINTF(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n", - name ? name : "", - srv ? srv : "", - port, - keyFile ? keyFile : ""); + name ? name : "", + srv ? srv : "", + port, + keyFile ? keyFile : ""); } } @@ -2433,6 +2433,9 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, #ifdef HAVE_CURVE25519 && useCurveId != ECC_X25519 #endif + #ifdef HAVE_CURVE448 + && useCurveId != ECC_X448 + #endif ) { ecc_key key, pubKey; int length, keyInit = 0, pubKeyInit = 0; @@ -2675,6 +2678,111 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } #endif /* HAVE_CURVE25519 */ +#ifdef HAVE_CURVE448 + /* Static Curve448 Key */ + if (useCurveId == ECC_X448) { + curve448_key key, pubKey; + int length, keyInit = 0, pubKeyInit = 0; + + /* 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.x448Key; + if (keyBuf == NULL) + keyBuf = ctx->staticKE.x448Key; + } +#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, + keyBuf, KeyCbCtx, error); + if (ret != 0) { + SetError(-1, error, session, FATAL_ERROR_STATE); + return ret; + } + } +#endif + + if (ret == 0 && keyBuf == NULL) { + ret = BUFFER_E; + } + if (ret == 0) { + ret = wc_curve448_init(&key); + if (ret == 0) + keyInit = 1; + } + if (ret == 0) { + idx = 0; + ret = wc_Curve448PrivateKeyDecode(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 = CURVE448_KEY_SIZE; + if (length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); + ret = -1; + } + } + if (ret == 0) { + ret = wc_curve448_init(&pubKey); + if (ret == 0) + pubKeyInit = 1; + } + if (ret == 0) { + ret = wc_curve448_import_public_ex(input, length, &pubKey, + EC448_LITTLE_ENDIAN); + if (ret != 0) { + SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + session->keySz = CURVE448_KEY_SIZE; + session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; + + ret = wc_curve448_shared_secret_ex(&key, &pubKey, + session->sslServer->arrays->preMasterSecret, + &session->sslServer->arrays->preMasterSz, EC448_LITTLE_ENDIAN); + } + +#ifdef WOLFSSL_SNIFFER_STATS + if (ret != 0) + INC_STAT(SnifferStats.sslKeyFails); +#endif + + if (keyInit) + wc_curve448_free(&key); + if (pubKeyInit) + wc_curve448_free(&pubKey); + } +#endif /* HAVE_CURVE448 */ + if (keyBufFree && keyBuf != NULL) { FreeDer(&keyBuf); } @@ -2846,7 +2954,7 @@ static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len, info->curve_id = ECC_X25519; break; #endif - #ifdef HAVE_X448 + #ifdef HAVE_CURVE448 case WOLFSSL_ECC_X448: info->curve_id = ECC_X448; break; diff --git a/src/ssl.c b/src/ssl.c index 37142b468..47de31d51 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -55657,6 +55657,20 @@ int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr) der->length); } break; + #endif + #ifdef HAVE_CURVE448 + case WC_PK_TYPE_CURVE448: + if (ssl != NULL) + der = ssl->staticKE.x448Key; + if (der == NULL) + der = ssl->ctx->staticKE.x448Key; + if (der != NULL) { + curve448_key* key = (curve448_key*)keyPtr; + WOLFSSL_MSG("Using static X448 key"); + ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key, + der->length); + } + break; #endif default: /* not supported */ @@ -55768,6 +55782,20 @@ static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx, } } #endif + #ifdef HAVE_CURVE448 + if (keyAlgo == WC_PK_TYPE_NONE) { + word32 idx = 0; + curve448_key x448Key; + ret = wc_curve448_init(&x448Key); + if (ret == 0) { + ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, &x448Key, + keySz); + if (ret == 0) + keyAlgo = WC_PK_TYPE_CURVE448; + wc_curve448_free(&x448Key); + } + } + #endif if (keyAlgo != WC_PK_TYPE_NONE) { ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap); @@ -55816,6 +55844,12 @@ static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx, FreeDer(&staticKE->x25519Key); staticKE->x25519Key = der; der = NULL; break; + #endif + #ifdef HAVE_CURVE448 + case WC_PK_TYPE_CURVE448: + FreeDer(&staticKE->x448Key); + staticKE->x448Key = der; der = NULL; + break; #endif default: /* not supported */ @@ -55898,6 +55932,14 @@ static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, if (der == NULL) der = ctx->staticKE.x25519Key; break; + #endif + #ifdef HAVE_CURVE448 + case WC_PK_TYPE_CURVE448: + if (ssl != NULL) + der = ssl->staticKE.x448Key; + if (der == NULL) + der = ctx->staticKE.x448Key; + break; #endif default: /* not supported */ diff --git a/src/tls.c b/src/tls.c index ee271d0d1..ae56f8d01 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6412,7 +6412,14 @@ static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse) ret = wc_curve448_init((curve448_key*)kse->key); if (ret == 0) { key = (curve448_key*)kse->key; - ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key); + + #ifdef WOLFSSL_STATIC_EPHEMERAL + ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE448, kse->key); + if (ret != 0) + #endif + { + ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key); + } } } diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 21e5670f8..3594266e7 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -26,6 +26,7 @@ #include #include +#include #ifndef NO_KDF diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ad751d9cc..36835ffaa 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2731,6 +2731,9 @@ typedef struct { #ifdef HAVE_CURVE25519 DerBuffer* x25519Key; #endif +#ifdef HAVE_CURVE448 + DerBuffer* x448Key; +#endif } StaticKeyExchangeInfo_t; #endif /* WOLFSSL_STATIC_EPHEMERAL */