mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
Add TLS 1.3 handshake support for crypto callbacks returning WC_PENDING_E
This commit is contained in:
@@ -11900,8 +11900,9 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Crypto callbacks with async crypt may not work for TLS unless
|
||||
# WOLF_CRYPTO_CB_ASYNC_POLL is defined. Report it once here and silence the
|
||||
# Crypto callbacks with async crypt cannot complete TLS 1.2 record ciphers
|
||||
# unless WOLF_CRYPTO_CB_ASYNC_POLL is defined (TLS 1.3 resumes them by
|
||||
# re-invoking the callback). Report it once here and silence the
|
||||
# source-level #warning. AC_MSG_NOTICE, not AC_MSG_WARN: the multi-test
|
||||
# harness fails any scenario whose configure emits "configure: WARNING:".
|
||||
if test "$ENABLED_ASYNCCRYPT" = "yes" && test "x$ENABLED_CRYPTOCB" != "xno" &&
|
||||
@@ -11912,7 +11913,7 @@ then
|
||||
*WOLF_CRYPTO_CB_ASYNC_POLL*)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_NOTICE([crypto callbacks with async crypt may not work for TLS. Define WOLF_CRYPTO_CB_ASYNC_POLL to enable it.])
|
||||
AC_MSG_NOTICE([crypto callbacks with async crypt cannot complete TLS 1.2 record ciphers. Define WOLF_CRYPTO_CB_ASYNC_POLL to enable them.])
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_ASYNC_NO_WARN"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -9520,6 +9520,11 @@ void FreeAsyncCtx(WOLFSSL* ssl, byte freeAsync)
|
||||
}
|
||||
#endif
|
||||
if (freeAsync) {
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_TLS13)
|
||||
/* Teardown only: a suspended record build must keep its
|
||||
* resume marker across handler-tail cleanups. */
|
||||
ssl->options.buildArgs13Set = 0;
|
||||
#endif
|
||||
XFREE(ssl->async, ssl->heap, DYNAMIC_TYPE_ASYNC);
|
||||
ssl->async = NULL;
|
||||
}
|
||||
@@ -9824,6 +9829,10 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
|
||||
#ifdef WOLFSSL_ASYNC_IO
|
||||
/* Cleanup async */
|
||||
FreeAsyncCtx(ssl, 1);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_REINVOKE) && defined(WOLFSSL_TLS13) && \
|
||||
!defined(NO_HMAC)
|
||||
Tls13FreeHsHmac(ssl);
|
||||
#endif
|
||||
if (ssl->options.weOwnRng) {
|
||||
wc_FreeRng(ssl->rng);
|
||||
@@ -19294,6 +19303,12 @@ exit_ppc:
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* TLS 1.3 replays skip the sanity check that re-sets got_certificate;
|
||||
* restore on completion or Finished reports out-of-order. */
|
||||
if (ret == 0 && IsAtLeastTLSv1_3(ssl->version) &&
|
||||
ssl->msgsReceived.got_certificate == 0) {
|
||||
ssl->msgsReceived.got_certificate = 1;
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT || WOLFSSL_NONBLOCK_OCSP */
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
@@ -25250,6 +25265,26 @@ static int DoProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
return ssl->error;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_ASYNC_CRYPT)
|
||||
/* Finish a TLS 1.3 key schedule the last handshake message left pending
|
||||
* before any further record is read or decrypted: the derives install
|
||||
* the very keys that record needs. See DoTls13MsgDerives(). */
|
||||
if (ssl->options.tls1_3 && ssl->kdfMsgStep > 0) {
|
||||
ret = DoTls13MsgDerives(ssl, ssl->kdfMsgType);
|
||||
if (ret != 0) {
|
||||
if (ret != WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
WOLFSSL_ERROR(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/* The pend is resolved; leaving ssl->error set would make the
|
||||
* next message skip its sanity check and got_* marking. */
|
||||
if (ssl->error == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
ssl->error = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_ASYNC_CRYPT)
|
||||
/* process any pending DTLS messages - this flow can happen with async */
|
||||
if (ssl->dtls_rx_msg_list != NULL) {
|
||||
@@ -25942,6 +25977,24 @@ static int DoProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
ssl->buffers.inputBuffer.buffer,
|
||||
&ssl->buffers.inputBuffer.idx,
|
||||
ssl->curStartIdx + ssl->curSize);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
/* A post-handler key-schedule pend consumed the
|
||||
* message but not the record; finish it here so
|
||||
* the retry reads the next record. */
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) &&
|
||||
ssl->kdfMsgStep > 0) {
|
||||
ssl->options.processReply = doProcessInit;
|
||||
if ((ssl->buffers.inputBuffer.idx -
|
||||
ssl->curStartIdx) < ssl->curSize) {
|
||||
ssl->options.processReply =
|
||||
runProcessingOneMessage;
|
||||
}
|
||||
else if (IsEncryptionOn(ssl, 0)) {
|
||||
ssl->buffers.inputBuffer.idx +=
|
||||
ssl->keys.padSz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
/* Post-handshake auth resumes through
|
||||
* wolfSSL_negotiate() instead of reprocessing this
|
||||
@@ -25951,8 +26004,12 @@ static int DoProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||
* the trailing MAC is read as the next record header
|
||||
* and fails with VERSION_ERROR. Mirrors the end of
|
||||
* record block below: resume inside the record when
|
||||
* content is left, else skip the padding. */
|
||||
* content is left, else skip the padding. Skipped for
|
||||
* a key-schedule pend (kdfMsgStep != 0): the block
|
||||
* above already finished the record, and running this
|
||||
* one too would skip the padding twice. */
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) &&
|
||||
ssl->kdfMsgStep == TLS13_MSG_KDF_NONE &&
|
||||
ssl->options.processReply == doProcessInit) {
|
||||
if ((ssl->buffers.inputBuffer.idx -
|
||||
ssl->curStartIdx) < ssl->curSize) {
|
||||
|
||||
25
src/ssl.c
25
src/ssl.c
@@ -5712,6 +5712,31 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
|
||||
ssl->options.onlyPskDheKe = ssl->ctx->onlyPskDheKe;
|
||||
#endif
|
||||
#endif
|
||||
/* An abandoned handshake can leave a key-schedule or record-build
|
||||
* resume marker set; a reused object must not resume into the new
|
||||
* handshake. */
|
||||
ssl->kdfDeriveStep = TLS13_SEND_KDF_NONE;
|
||||
ssl->kdfMsgStep = TLS13_MSG_KDF_NONE;
|
||||
ssl->kdfMsgType = 0;
|
||||
#if defined(WOLFSSL_ASYNC_REINVOKE) && !defined(NO_HMAC)
|
||||
Tls13FreeHsHmac(ssl);
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ssl->options.buildArgs13Set = 0;
|
||||
/* An abandoned handshake can leave a mid-flight handler resume
|
||||
* state and a queued key-schedule event behind; a reused object
|
||||
* must start fresh. */
|
||||
ssl->options.asyncState = TLS_ASYNC_BEGIN;
|
||||
if (ssl->asyncDev == &ssl->kdfAsyncDev) {
|
||||
if (ssl->kdfAsyncDev.event.state == WOLF_EVENT_STATE_PENDING &&
|
||||
ssl->ctx != NULL) {
|
||||
(void)wolfEventQueue_Remove(&ssl->ctx->event_queue,
|
||||
&ssl->kdfAsyncDev.event);
|
||||
}
|
||||
XMEMSET(&ssl->kdfAsyncDev.event, 0, sizeof(WOLF_EVENT));
|
||||
ssl->asyncDev = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
#ifdef WOLFSSL_TLS13
|
||||
|
||||
155
src/tls.c
155
src/tls.c
@@ -8479,7 +8479,7 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* Make an Curve25519 key. */
|
||||
/* Initialize the Curve25519 key. */
|
||||
ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
|
||||
ssl->devId);
|
||||
if (ret == 0) {
|
||||
@@ -8508,28 +8508,32 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
}
|
||||
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
|
||||
WC_ASYNC_ENABLE_X25519 */
|
||||
if (ret == 0) {
|
||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key);
|
||||
if (ret != 0) /* on failure, fallback to local key generation */
|
||||
#endif
|
||||
{
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* initialize event */
|
||||
ret = wolfSSL_AsyncInit(ssl, &key->asyncDev,
|
||||
WC_ASYNC_FLAG_NONE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
|
||||
}
|
||||
|
||||
/* Handle async pending response */
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
return wolfSSL_AsyncPush(ssl, &key->asyncDev);
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
/* Outside the allocation guard: a WC_PENDING_E retry must regenerate,
|
||||
* not export an ungenerated key. pubKeyLen marks a completed export on
|
||||
* every backend; pubSet stops the SW-async retry re-arming forever. */
|
||||
if (ret == 0 && key != NULL && kse->pubKeyLen == 0 && !key->pubSet) {
|
||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519,
|
||||
kse->key);
|
||||
if (ret != 0) /* on failure, fallback to local key generation */
|
||||
#endif
|
||||
{
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* initialize event */
|
||||
ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
|
||||
|
||||
/* Handle async pending response */
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
return wolfSSL_AsyncPush(ssl, &key->asyncDev);
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8759,6 +8763,10 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
|
||||
/* Initialize an ECC key struct for the ephemeral 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;
|
||||
}
|
||||
|
||||
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
|
||||
defined(WC_ASYNC_ENABLE_ECC)
|
||||
@@ -8781,49 +8789,44 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
}
|
||||
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
|
||||
WC_ASYNC_ENABLE_ECC */
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
kse->keyLen = keySize;
|
||||
kse->pubKeyLen = keySize * 2 + 1;
|
||||
/* Outside the allocation guard: a WC_PENDING_E retry must regenerate,
|
||||
* not export an ungenerated key. The key type marks completion;
|
||||
* kse->pubKey covers backends that never touch the ecc_key (TSIP). */
|
||||
if (ret == 0 && eccKey != NULL) {
|
||||
/* Outside the generation guard below: the export alloc reads
|
||||
* pubKeyLen even when generation is skipped. */
|
||||
kse->keyLen = keySize;
|
||||
kse->pubKeyLen = keySize * 2 + 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
|
||||
ret = tsip_Tls13GenEccKeyPair(ssl, kse);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
if (ret == 0 && eccKey != NULL && kse->pubKey == NULL &&
|
||||
eccKey->type != ECC_PRIVATEKEY &&
|
||||
eccKey->type != ECC_PRIVATEKEY_ONLY) {
|
||||
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
|
||||
ret = tsip_Tls13GenEccKeyPair(ssl, kse);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
|
||||
if (ret != 0 || eccKey->dp->id != curveId)
|
||||
#endif
|
||||
{
|
||||
/* set curve info for EccMakeKey "peer" info */
|
||||
ret = wc_ecc_set_curve(eccKey, (int)kse->keyLen, curveId);
|
||||
if (ret == 0) {
|
||||
/* Generate ephemeral ECC key; a crypto callback retry
|
||||
* re-enters here, x963 export follows below. */
|
||||
ret = EccMakeKey(ssl, eccKey, eccKey);
|
||||
}
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* setting eccKey means okay to call wc_ecc_free */
|
||||
eccKey = (ecc_key*)kse->key;
|
||||
|
||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
|
||||
if (ret != 0 || eccKey->dp->id != curveId)
|
||||
#endif
|
||||
{
|
||||
/* set curve info for EccMakeKey "peer" info */
|
||||
ret = wc_ecc_set_curve(eccKey, (int)kse->keyLen, curveId);
|
||||
if (ret == 0) {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* Detect when private key generation is done */
|
||||
if (ssl->error == WC_NO_ERR_TRACE(WC_PENDING_E) &&
|
||||
eccKey->type == ECC_PRIVATEKEY) {
|
||||
ret = 0; /* ECC Key Generation is done */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Generate ephemeral ECC key */
|
||||
/* For async this is called once and when event is done, the
|
||||
* provided buffers in key be populated.
|
||||
* Final processing is x963 key export below. */
|
||||
ret = EccMakeKey(ssl, eccKey, eccKey);
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10661,7 +10664,8 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) || \
|
||||
defined(WOLFSSL_ASYNC_CRYPT)
|
||||
keyShareEntry->derived = (ret == 0);
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@@ -12278,6 +12282,27 @@ int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
|
||||
TLSX* extension;
|
||||
KeyShareEntry* list = NULL;
|
||||
|
||||
/* Find the KeyShare extension if it exists. */
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
|
||||
if (extension != NULL)
|
||||
list = (KeyShareEntry*)extension->data;
|
||||
|
||||
if (list == NULL) {
|
||||
/* Unreachable once the handshake reached this accept state
|
||||
* (TLSX_KeyShare_Setup installed the extension), so no async event
|
||||
* can be stranded by returning before the pop below. */
|
||||
return KEY_SHARE_ERROR;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) || \
|
||||
defined(WOLFSSL_ASYNC_CRYPT)
|
||||
/* Already derived: a later pend's retry re-enters here with the peer
|
||||
* key freed. Checked before the pop so the later operation's queued
|
||||
* event is not stolen. */
|
||||
if (list->derived)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wolfSSL_AsyncPop(ssl, NULL);
|
||||
/* Check for error */
|
||||
@@ -12286,14 +12311,6 @@ int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find the KeyShare extension if it exists. */
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
|
||||
if (extension != NULL)
|
||||
list = (KeyShareEntry*)extension->data;
|
||||
|
||||
if (list == NULL)
|
||||
return KEY_SHARE_ERROR;
|
||||
|
||||
/* Calculate secret. */
|
||||
ret = TLSX_KeyShare_Process(ssl, list);
|
||||
|
||||
|
||||
1062
src/tls13.c
1062
src/tls13.c
File diff suppressed because it is too large
Load Diff
@@ -77,8 +77,9 @@ Crypto Callback Build Options:
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLF_CRYPTO_CB_ASYNC_POLL) && \
|
||||
!defined(WOLFSSL_ASYNC_CRYPT_SW) && !defined(HAVE_INTEL_QA) && \
|
||||
!defined(HAVE_CAVIUM) && !defined(WOLF_CRYPTO_CB_ASYNC_NO_WARN)
|
||||
#warning "crypto callbacks with async crypt may not work for TLS. Define \
|
||||
WOLF_CRYPTO_CB_ASYNC_POLL to enable it, or WOLF_CRYPTO_CB_ASYNC_NO_WARN to \
|
||||
#warning "crypto callbacks with async crypt cannot complete TLS 1.2 \
|
||||
record ciphers (TLS 1.3 resumes them by re-invoking the callback). Define \
|
||||
WOLF_CRYPTO_CB_ASYNC_POLL to enable them, or WOLF_CRYPTO_CB_ASYNC_NO_WARN to \
|
||||
silence."
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2373,6 +2373,19 @@ WOLFSSL_LOCAL int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_LOCAL int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
word16 sz, const byte* aad, word16 aadSz);
|
||||
WOLFSSL_LOCAL int DoTls13MsgDerives(WOLFSSL* ssl, byte type);
|
||||
/* A crypto/PK callback pending is finished by re-invoking the provider:
|
||||
* wolfSSL_AsyncPoll() never runs a callback. Exported so tests compile in
|
||||
* only where a callback pend is resumable. */
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && \
|
||||
(defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)) && \
|
||||
!defined(WOLFSSL_ASYNC_CRYPT_SW) && !defined(HAVE_INTEL_QA) && \
|
||||
!defined(HAVE_CAVIUM)
|
||||
#define WOLFSSL_ASYNC_REINVOKE
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_REINVOKE) && !defined(NO_HMAC)
|
||||
WOLFSSL_LOCAL void Tls13FreeHsHmac(WOLFSSL* ssl);
|
||||
#endif
|
||||
WOLFSSL_LOCAL int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input,
|
||||
word32* inOutIdx, byte type,
|
||||
word32 size, word32 totalSz);
|
||||
@@ -3959,6 +3972,12 @@ typedef struct KeyShareEntry {
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
word16 session; /* NamedGroup that was in session */
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) || \
|
||||
defined(WOLFSSL_ASYNC_CRYPT)
|
||||
/* Also under WOLFSSL_ASYNC_CRYPT: a pending operation retried on the
|
||||
* same accept state re-enters the derive with the peer key freed, and
|
||||
* this is the marker that stops the re-derive. */
|
||||
word16 derived; /* preMaster has been derived */
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@@ -3978,7 +3997,7 @@ WOLFSSL_LOCAL int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions,
|
||||
byte* searched);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl, int* doHelloRetry);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_DeriveSecret(WOLFSSL* sclientKSEclientKSEsl);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_DeriveSecret(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input,
|
||||
word16 length, byte msgType);
|
||||
WOLFSSL_LOCAL int TLSX_KeyShare_Parse_ClientHello(const WOLFSSL* ssl,
|
||||
@@ -5577,6 +5596,19 @@ struct Options {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
word16 buildArgsSet:1; /* buildArgs are set and need to
|
||||
* be free'd */
|
||||
#ifdef WOLFSSL_TLS13
|
||||
word16 buildArgs13Set:1; /* a TLS 1.3 record build is in
|
||||
* progress and must resume,
|
||||
* not restart */
|
||||
word16 chHashInput:1; /* current ClientHello already
|
||||
* hashed into the transcript;
|
||||
* a PSK-binder pend must not
|
||||
* re-hash it on resume */
|
||||
word16 asyncReplayMsg:1; /* the next TLS 1.3 handshake
|
||||
* message is a replay of one
|
||||
* whose handler pended; skip
|
||||
* its sanity check once */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
word16 dtls13SendMoreAcks:1; /* Send more acks during the
|
||||
@@ -6176,8 +6208,8 @@ typedef struct HS_Hashes {
|
||||
} HS_Hashes;
|
||||
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
/* Persistable BuildMessage arguments */
|
||||
#if !defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)
|
||||
/* Persistable BuildMessage/BuildTls13Message arguments */
|
||||
typedef struct BuildMsgArgs {
|
||||
word32 digestSz;
|
||||
word32 sz;
|
||||
@@ -6197,8 +6229,11 @@ typedef struct BuildMsgArgs {
|
||||
typedef void (*FreeArgsCb)(struct WOLFSSL* ssl, void* pArgs);
|
||||
|
||||
struct WOLFSSL_ASYNC {
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_NO_TLS12)
|
||||
BuildMsgArgs buildArgs; /* holder for current BuildMessage args */
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && \
|
||||
(!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13))
|
||||
/* Record builder resume args, shared by BuildMessage() and
|
||||
* BuildTls13Message(): a connection runs only one of them. */
|
||||
BuildMsgArgs buildArgs;
|
||||
#endif
|
||||
FreeArgsCb freeArgs; /* function pointer to cleanup args */
|
||||
#ifdef WC_NO_PTR_INT_CAST
|
||||
@@ -6447,6 +6482,56 @@ enum ConnectionIdUsage {
|
||||
(ssl)->ctx->suites))
|
||||
|
||||
/* wolfSSL ssl type */
|
||||
|
||||
/* TLS 1.3 key-schedule resume steps (kdfMsgStep/kdfDeriveStep). A value is
|
||||
* recorded after its named operation completes ("step <= X" = X not done);
|
||||
* 0 = sequence not entered or finished. Values repeat across sequences. */
|
||||
|
||||
/* Receive side (kdfMsgStep), driven by DoTls13MsgDerives(). */
|
||||
enum Tls13KdfMsgStep {
|
||||
TLS13_MSG_KDF_NONE = 0,
|
||||
/* client processing server_hello */
|
||||
TLS13_MSG_KDF_SH_ENTERED = 1,
|
||||
TLS13_MSG_KDF_SH_EARLY_SECRET = 2,
|
||||
TLS13_MSG_KDF_SH_HS_SECRET = 3,
|
||||
TLS13_MSG_KDF_SH_HS_KEYS = 4,
|
||||
TLS13_MSG_KDF_SH_KEYS_SET = 5,
|
||||
TLS13_MSG_KDF_SH_DTLS_EPOCH = 6,
|
||||
/* client processing finished */
|
||||
TLS13_MSG_KDF_FIN_ENTERED = 1,
|
||||
TLS13_MSG_KDF_FIN_MASTER_SECRET = 2,
|
||||
TLS13_MSG_KDF_FIN_QUIC_EARLY_KEYS = 3,
|
||||
TLS13_MSG_KDF_FIN_TRAFFIC_KEYS = 4,
|
||||
TLS13_MSG_KDF_FIN_TRAFFIC_DONE = 5,
|
||||
TLS13_MSG_KDF_FIN_KEYS_SET = 6,
|
||||
/* server processing finished (resumption secret for tickets) */
|
||||
TLS13_MSG_KDF_SFIN_ENTERED = 1,
|
||||
TLS13_MSG_KDF_SFIN_RESUMPTION_SECRET = 2
|
||||
};
|
||||
|
||||
/* Send side (kdfDeriveStep), inside the senders themselves. */
|
||||
enum Tls13KdfSendStep {
|
||||
TLS13_SEND_KDF_NONE = 0,
|
||||
/* SendTls13EncryptedExtensions() */
|
||||
TLS13_SEND_KDF_EE_HS_SECRET = 1,
|
||||
TLS13_SEND_KDF_EE_HS_KEYS = 2,
|
||||
TLS13_SEND_KDF_EE_ENC_KEYS_SET = 3,
|
||||
TLS13_SEND_KDF_EE_KEYS_SET = 4,
|
||||
TLS13_SEND_KDF_EE_DTLS_EPOCH = 5,
|
||||
/* SendTls13Finished() */
|
||||
TLS13_SEND_KDF_FIN_ENTERED = 1,
|
||||
TLS13_SEND_KDF_FIN_MASTER_SECRET = 2,
|
||||
TLS13_SEND_KDF_FIN_ENC_TRAFFIC_KEYS = 3,
|
||||
TLS13_SEND_KDF_FIN_TRAFFIC_KEYS = 4,
|
||||
TLS13_SEND_KDF_FIN_ENC_KEYS_SET = 5,
|
||||
TLS13_SEND_KDF_FIN_DTLS_TRAFFIC_EPOCH = 6,
|
||||
TLS13_SEND_KDF_FIN_EARLY_ENC_KEYS = 7,
|
||||
TLS13_SEND_KDF_FIN_EARLY_KEYS_SET = 8,
|
||||
TLS13_SEND_KDF_FIN_RESUMPTION_SECRET = 9,
|
||||
TLS13_SEND_KDF_FIN_DTLS_EPOCH_SET = 10
|
||||
};
|
||||
|
||||
|
||||
struct WOLFSSL {
|
||||
WOLFSSL_CTX* ctx;
|
||||
#if defined(WOLFSSL_HAPROXY)
|
||||
@@ -7028,6 +7113,27 @@ struct WOLFSSL {
|
||||
* ciphers; 0 means uncached and is never a valid AEAD overhead. EtM does
|
||||
* not apply to AEAD. */
|
||||
word32 recordSzOverhead;
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* Async device for the TLS 1.3 key schedule: HKDF has no key object
|
||||
* to carry one. Event bookkeeping only, for the callback re-invoke
|
||||
* path (never wolfAsync_DevCtxInit'd, no hardware context). */
|
||||
WC_ASYNC_DEV kdfAsyncDev;
|
||||
#endif
|
||||
/* Key-schedule resume steps: completed derives must not re-run (e.g.
|
||||
* the extract is in place over preMasterSecret). Unconditional so the
|
||||
* schedule needs no ifdefs; without async they stay 0. */
|
||||
byte kdfDeriveStep; /* enum Tls13KdfSendStep (send side) */
|
||||
byte kdfMsgStep; /* enum Tls13KdfMsgStep (receive side) */
|
||||
byte kdfMsgType; /* handshake type kdfMsgStep belongs to */
|
||||
#if defined(WOLFSSL_ASYNC_REINVOKE) && defined(WOLFSSL_TLS13) && \
|
||||
!defined(NO_HMAC)
|
||||
/* Transcript HMAC (Finished verify_data, PSK binders) held across a
|
||||
* WC_PENDING_E so the retry re-invokes the same object and arguments,
|
||||
* bound to its output buffer. */
|
||||
Hmac* hsHmac;
|
||||
byte* hsHmacOut;
|
||||
byte hsHmacStep;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
|
||||
|
||||
@@ -4056,9 +4056,8 @@
|
||||
#error WOLF_CRYPTO_CB_ASYNC_POLL requires bulk cipher async support
|
||||
#endif
|
||||
|
||||
/* Crypto callbacks are the only async backend and cannot finish a pending
|
||||
* bulk cipher op: the record layer has already advanced past the crypto
|
||||
* call, and without poll routing nothing refills the output buffer. */
|
||||
/* Callback-only async cannot finish a pending TLS 1.2 bulk cipher op
|
||||
* (TLS 1.3 resumes them by re-invoking the callback). */
|
||||
#if defined(WOLF_CRYPTO_CB) && !defined(WOLF_CRYPTO_CB_ASYNC_POLL) && \
|
||||
!defined(WOLFSSL_ASYNC_CRYPT_SW) && !defined(HAVE_INTEL_QA) && \
|
||||
!defined(HAVE_CAVIUM)
|
||||
|
||||
Reference in New Issue
Block a user