SSL asynchronous read/write and encrypt

Add support for being able to read and write in different threads with
same SSL object.
Add support for encrypt in threads.
This commit is contained in:
Sean Parkinson 2024-07-26 14:14:30 +10:00
parent 4fd33b6b5d
commit e4a661ff6e
8 changed files with 680 additions and 174 deletions

View File

@ -341,9 +341,17 @@ static void Dtls13MsgWasProcessed(WOLFSSL* ssl, enum HandShakeType hs)
if (ssl->options.dtlsStateful)
ssl->keys.dtls_expected_peer_handshake_number++;
/* we need to send ACKs on the last message of a flight that needs explicit
acknowledgment */
#ifdef WOLFSSL_RW_THREADED
if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0)
#endif
{
/* we need to send ACKs on the last message of a flight that needs
* explicit acknowledgment */
ssl->dtls13Rtx.sendAcks = Dtls13RtxMsgNeedsAck(ssl, hs);
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
}
}
int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
@ -654,8 +662,17 @@ static void Dtls13RtxRecordUnlink(WOLFSSL* ssl, Dtls13RtxRecord** prevNext,
Dtls13RtxRecord* r)
{
/* if r was at the tail of the list, update the tail pointer */
if (r->next == NULL)
if (r->next == NULL) {
#ifdef WOLFSSL_RW_THREADED
if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0)
#endif
{
ssl->dtls13Rtx.rtxRecordTailPtr = prevNext;
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
}
}
/* unlink */
*prevNext = r->next;
@ -712,12 +729,20 @@ static int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq)
WOLFSSL_ENTER("Dtls13RtxAddAck");
#ifdef WOLFSSL_RW_THREADED
if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0)
#endif
{
rn = Dtls13NewRecordNumber(epoch, seq, ssl->heap);
if (rn == NULL)
return MEMORY_E;
rn->next = ssl->dtls13Rtx.seenRecords;
ssl->dtls13Rtx.seenRecords = rn;
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
}
return 0;
}
@ -730,6 +755,10 @@ static void Dtls13RtxFlushAcks(WOLFSSL* ssl)
WOLFSSL_ENTER("Dtls13RtxFlushAcks");
#ifdef WOLFSSL_RW_THREADED
if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0)
#endif
{
list = ssl->dtls13Rtx.seenRecords;
while (list != NULL) {
@ -739,6 +768,10 @@ static void Dtls13RtxFlushAcks(WOLFSSL* ssl)
}
ssl->dtls13Rtx.seenRecords = NULL;
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
}
}
static int Dtls13DetectDisruption(WOLFSSL* ssl, word32 fragOffset)
@ -2519,13 +2552,25 @@ static void Dtls13RtxRemoveRecord(WOLFSSL* ssl, w64wrapper epoch,
int Dtls13DoScheduledWork(WOLFSSL* ssl)
{
int ret;
int sendAcks;
WOLFSSL_ENTER("Dtls13DoScheduledWork");
ssl->dtls13SendingAckOrRtx = 1;
if (ssl->dtls13Rtx.sendAcks) {
#ifdef WOLFSSL_RW_THREADED
ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
if (ret < 0)
return ret;
#endif
sendAcks = ssl->dtls13Rtx.sendAcks;
if (sendAcks) {
ssl->dtls13Rtx.sendAcks = 0;
}
#ifdef WOLFSSL_RW_THREADED
ret = wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
if (sendAcks) {
ret = SendDtls13Ack(ssl);
if (ret != 0)
return ret;
@ -2601,13 +2646,28 @@ static int Dtls13RtxHasKeyUpdateBuffered(WOLFSSL* ssl)
return 0;
}
int DoDtls13KeyUpdateAck(WOLFSSL* ssl)
{
int ret = 0;
if (!Dtls13RtxHasKeyUpdateBuffered(ssl)) {
/* we removed the KeyUpdate message because it was ACKed */
ssl->dtls13WaitKeyUpdateAck = 0;
ret = Dtls13KeyUpdateAckReceived(ssl);
}
return ret;
}
int DoDtls13Ack(WOLFSSL* ssl, const byte* input, word32 inputSize,
word32* processedSize)
{
const byte* ackMessage;
w64wrapper epoch, seq;
word16 length;
#ifndef WOLFSSL_RW_THREADED
int ret;
#endif
int i;
if (inputSize < OPAQUE16_LEN)
@ -2639,15 +2699,13 @@ int DoDtls13Ack(WOLFSSL* ssl, const byte* input, word32 inputSize,
ssl->options.serverState = SERVER_FINISHED_ACKED;
}
#ifndef WOLFSSL_RW_THREADED
if (ssl->dtls13WaitKeyUpdateAck) {
if (!Dtls13RtxHasKeyUpdateBuffered(ssl)) {
/* we removed the KeyUpdate message because it was ACKed */
ssl->dtls13WaitKeyUpdateAck = 0;
ret = Dtls13KeyUpdateAckReceived(ssl);
ret = DoDtls13KeyUpdateAck(ssl);
if (ret != 0)
return ret;
}
}
#endif
*processedSize = length + OPAQUE16_LEN;
@ -2698,7 +2756,15 @@ int SendDtls13Ack(WOLFSSL* ssl)
if (ret != 0)
return ret;
#ifdef WOLFSSL_RW_THREADED
ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
if (ret < 0)
return ret;
#endif
ret = Dtls13WriteAckMessage(ssl, ssl->dtls13Rtx.seenRecords, &length);
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
if (ret != 0)
return ret;

View File

@ -2885,95 +2885,73 @@ void InitCiphers(WOLFSSL* ssl)
}
static void FreeCiphersSide(Ciphers *cipher, void* heap)
{
#ifdef BUILD_ARC4
wc_Arc4Free(cipher->arc4);
XFREE(cipher->arc4, heap, DYNAMIC_TYPE_CIPHER);
cipher->arc4 = NULL;
#endif
#ifdef BUILD_DES3
wc_Des3Free(cipher->des3);
XFREE(cipher->des3, heap, DYNAMIC_TYPE_CIPHER);
cipher->des3 = NULL;
#endif
#if defined(BUILD_AES) || defined(BUILD_AESGCM) || defined(HAVE_ARIA)
/* See: InitKeys() in keys.c on addition of BUILD_AESGCM check (enc->aes,
* dec->aes) */
wc_AesFree(cipher->aes);
XFREE(cipher->aes, heap, DYNAMIC_TYPE_CIPHER);
cipher->aes = NULL;
#endif
#if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)
wc_Sm4Free(cipher->sm4);
XFREE(cipher->sm4, heap, DYNAMIC_TYPE_CIPHER);
cipher->sm4 = NULL;
#endif
#if (defined(BUILD_AESGCM) || defined(BUILD_AESCCM) || defined(HAVE_ARIA)) && \
!defined(WOLFSSL_NO_TLS12)
XFREE(cipher->additional, heap, DYNAMIC_TYPE_CIPHER);
cipher->additional = NULL;
#endif
#ifdef CIPHER_NONCE
XFREE(cipher->nonce, heap, DYNAMIC_TYPE_CIPHER);
cipher->nonce = NULL;
#endif
#ifdef HAVE_ARIA
wc_AriaFreeCrypt(cipher->aria);
XFREE(cipher->aria, heap, DYNAMIC_TYPE_CIPHER);
cipher->aria = NULL;
#endif
#ifdef HAVE_CAMELLIA
XFREE(cipher->cam, heap, DYNAMIC_TYPE_CIPHER);
cipher->cam = NULL;
#endif
#ifdef HAVE_CHACHA
if (cipher->chacha)
ForceZero(cipher->chacha, sizeof(ChaCha));
XFREE(cipher->chacha, heap, DYNAMIC_TYPE_CIPHER);
cipher->chacha = NULL;
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
wc_HmacFree(cipher->hmac);
XFREE(cipher->hmac, heap, DYNAMIC_TYPE_CIPHER);
cipher->hmac = NULL;
#endif
}
/* Free ciphers */
void FreeCiphers(WOLFSSL* ssl)
{
(void)ssl;
#ifdef BUILD_ARC4
wc_Arc4Free(ssl->encrypt.arc4);
wc_Arc4Free(ssl->decrypt.arc4);
XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.arc4 = NULL;
ssl->decrypt.arc4 = NULL;
#endif
#ifdef BUILD_DES3
wc_Des3Free(ssl->encrypt.des3);
wc_Des3Free(ssl->decrypt.des3);
XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.des3 = NULL;
ssl->decrypt.des3 = NULL;
#endif
#if defined(BUILD_AES) || defined(BUILD_AESGCM) || defined(HAVE_ARIA)
/* See: InitKeys() in keys.c on addition of BUILD_AESGCM check (enc->aes, dec->aes) */
wc_AesFree(ssl->encrypt.aes);
wc_AesFree(ssl->decrypt.aes);
XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.aes = NULL;
ssl->decrypt.aes = NULL;
#endif
#if defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)
wc_Sm4Free(ssl->encrypt.sm4);
wc_Sm4Free(ssl->decrypt.sm4);
XFREE(ssl->encrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.sm4, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.sm4 = NULL;
ssl->decrypt.sm4 = NULL;
#endif
#if (defined(BUILD_AESGCM) || defined(BUILD_AESCCM) || defined(HAVE_ARIA)) && \
!defined(WOLFSSL_NO_TLS12)
XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.additional = NULL;
ssl->decrypt.additional = NULL;
#endif
#ifdef CIPHER_NONCE
XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.nonce = NULL;
ssl->decrypt.nonce = NULL;
#endif
#ifdef HAVE_ARIA
wc_AriaFreeCrypt(ssl->encrypt.aria);
wc_AriaFreeCrypt(ssl->decrypt.aria);
XFREE(ssl->encrypt.aria, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.aria, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.aria = NULL;
ssl->decrypt.aria = NULL;
#endif
#ifdef HAVE_CAMELLIA
XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.cam = NULL;
ssl->decrypt.cam = NULL;
#endif
#ifdef HAVE_CHACHA
if (ssl->encrypt.chacha)
ForceZero(ssl->encrypt.chacha, sizeof(ChaCha));
if (ssl->decrypt.chacha)
ForceZero(ssl->decrypt.chacha, sizeof(ChaCha));
XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.chacha = NULL;
ssl->decrypt.chacha = NULL;
#endif
FreeCiphersSide(&ssl->encrypt, ssl->heap);
FreeCiphersSide(&ssl->decrypt, ssl->heap);
#if defined(HAVE_POLY1305) && defined(HAVE_ONE_TIME_AUTH)
if (ssl->auth.poly1305)
ForceZero(ssl->auth.poly1305, sizeof(Poly1305));
XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->auth.poly1305 = NULL;
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
wc_HmacFree(ssl->encrypt.hmac);
wc_HmacFree(ssl->decrypt.hmac);
XFREE(ssl->encrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
XFREE(ssl->decrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
ssl->encrypt.hmac = NULL;
ssl->decrypt.hmac = NULL;
#endif
#ifdef WOLFSSL_DTLS13
#ifdef BUILD_AES
@ -2993,7 +2971,6 @@ void FreeCiphers(WOLFSSL* ssl)
#endif /* WOLFSSL_DTLS13 */
}
void InitCipherSpecs(CipherSpecs* cs)
{
XMEMSET(cs, 0, sizeof(CipherSpecs));
@ -7392,6 +7369,15 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
#ifdef WOLFSSL_THREADED_CRYPT
{
int i;
for (i = 0; i < WOLFSSL_THREADED_CRYPT_CNT; i++) {
ssl->buffers.encrypt[i].avail = 1;
}
}
#endif
#ifdef KEEP_PEER_CERT
InitX509(&ssl->peerCert, 0, ssl->heap);
#endif
@ -7729,6 +7715,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->dtls13DecryptEpoch = &ssl->dtls13Epochs[0];
ssl->options.dtls13SendMoreAcks = WOLFSSL_DTLS13_SEND_MOREACK_DEFAULT;
ssl->dtls13Rtx.rtxRecordTailPtr = &ssl->dtls13Rtx.rtxRecords;
#ifdef WOLFSSL_RW_THREADED
ret = wc_InitMutex(&ssl->dtls13Rtx.mutex);
if (ret < 0) {
return ret;
}
#endif
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_QUIC
@ -8259,6 +8252,25 @@ void SSL_ResourceFree(WOLFSSL* ssl)
ShrinkInputBuffer(ssl, FORCED_FREE);
if (ssl->buffers.outputBuffer.dynamicFlag)
ShrinkOutputBuffer(ssl);
#ifdef WOLFSSL_THREADED_CRYPT
{
int i;
for (i = 0; i < WOLFSSL_THREADED_CRYPT_CNT; i++) {
bufferStatic* buff = &ssl->buffers.encrypt[i].buffer;
ssl->buffers.encrypt[i].stop = 1;
FreeCiphersSide(&ssl->buffers.encrypt[i].encrypt, ssl->heap);
if (buff->dynamicFlag) {
XFREE(buff->buffer - buff->offset, ssl->heap,
DYNAMIC_TYPE_OUT_BUFFER);
buff->buffer = buff->staticBuffer;
buff->bufferSize = STATIC_BUFFER_LEN;
buff->offset = 0;
buff->dynamicFlag = 0;
}
}
}
#endif
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
if (ssl->buffers.tls13CookieSecret.buffer != NULL) {
ForceZero(ssl->buffers.tls13CookieSecret.buffer,
@ -8511,6 +8523,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif
#ifdef WOLFSSL_DTLS13
Dtls13FreeFsmResources(ssl);
#ifdef WOLFSSL_RW_THREADED
wc_FreeMutex(&ssl->dtls13Rtx.mutex);
#endif
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_QUIC
wolfSSL_quic_free(ssl);
@ -10770,6 +10786,69 @@ retry:
return 0;
}
#ifdef WOLFSSL_THREADED_CRYPT
static WC_INLINE int GrowAnOutputBuffer(WOLFSSL* ssl,
bufferStatic* outputBuffer, int size)
{
byte* tmp;
#if WOLFSSL_GENERAL_ALIGNMENT > 0
byte hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
RECORD_HEADER_SZ;
byte align = WOLFSSL_GENERAL_ALIGNMENT;
#else
const byte align = WOLFSSL_GENERAL_ALIGNMENT;
#endif
#if WOLFSSL_GENERAL_ALIGNMENT > 0
/* the encrypted data will be offset from the front of the buffer by
the header, if the user wants encrypted alignment they need
to define their alignment requirement */
while (align < hdrSz)
align *= 2;
#endif
tmp = (byte*)XMALLOC(size + outputBuffer->length + align,
ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
WOLFSSL_MSG("growing output buffer");
if (tmp == NULL)
return MEMORY_E;
#if WOLFSSL_GENERAL_ALIGNMENT > 0
if (align)
tmp += align - hdrSz;
#endif
#ifdef WOLFSSL_STATIC_MEMORY
/* can be from IO memory pool which does not need copy if same buffer */
if (outputBuffer->length && tmp == outputBuffer->buffer) {
outputBuffer->bufferSize = size + outputBuffer->length;
return 0;
}
#endif
if (outputBuffer->length)
XMEMCPY(tmp, outputBuffer->buffer, outputBuffer->length);
if (outputBuffer->dynamicFlag) {
XFREE(outputBuffer->buffer - outputBuffer->offset, ssl->heap,
DYNAMIC_TYPE_OUT_BUFFER);
}
#if WOLFSSL_GENERAL_ALIGNMENT > 0
if (align)
outputBuffer->offset = align - hdrSz;
else
#endif
outputBuffer->offset = 0;
outputBuffer->buffer = tmp;
outputBuffer->dynamicFlag = 1;
outputBuffer->bufferSize = size + outputBuffer->length;
return 0;
}
#endif
/* returns the current location in the output buffer to start writing to */
byte* GetOutputBuffer(WOLFSSL* ssl)
@ -22210,6 +22289,7 @@ default:
#endif
}
#endif
#ifndef WOLFSSL_RW_THREADED
#ifdef WOLFSSL_TLS13
if (ssl->keys.keyUpdateRespond) {
WOLFSSL_MSG("No KeyUpdate from peer seen");
@ -22217,6 +22297,7 @@ default:
return SANITY_MSG_E;
}
#endif
#endif
if ((ret = DoApplicationData(ssl,
ssl->buffers.inputBuffer.buffer,
&ssl->buffers.inputBuffer.idx,
@ -23187,6 +23268,29 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
ssl->keys.dtls_prev_sequence_number_lo;
}
#endif
#ifdef WOLFSSL_THREADED_CRYPT
if (asyncOkay) {
WOLFSSL_MSG("Not encrypting\n");
/* make sure build message state is reset */
ssl->options.buildMsgState = BUILD_MSG_BEGIN;
/* return sz on success */
if (ret == 0) {
ret = args->sz;
}
else {
WOLFSSL_ERROR_VERBOSE(ret);
}
/* Final cleanup */
FreeBuildMsgArgs(ssl, args);
return ret;
}
else
#endif
{
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
if (ssl->options.startedETMWrite) {
ret = Encrypt(ssl, output + args->headerSz,
@ -23209,6 +23313,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
ssl->keys.dtls_sequence_number_lo = dtls_sequence_number_lo;
}
#endif
}
}
if (ret != 0) {
@ -24636,6 +24741,50 @@ static int CheckTLS13AEADSendLimit(WOLFSSL* ssl)
}
#endif /* WOLFSSL_TLS13 && !WOLFSSL_TLS13_IGNORE_AEAD_LIMITS */
#ifdef WOLFSSL_THREADED_CRYPT
int SendAsyncData(WOLFSSL* ssl)
{
int i;
for (i = 0; i < WOLFSSL_THREADED_CRYPT_CNT; i++) {
ThreadCrypt* encrypt = &ssl->buffers.encrypt[i];
if (encrypt->done) {
int error;
GrowOutputBuffer(ssl, encrypt->buffer.length);
XMEMCPY(ssl->buffers.outputBuffer.buffer, encrypt->buffer.buffer,
encrypt->buffer.length);
ssl->buffers.outputBuffer.length = encrypt->buffer.length;
ssl->buffers.outputBuffer.idx = 0;
encrypt->done = 0;
encrypt->avail = 1;
if ((error = SendBuffered(ssl)) < 0) {
ssl->error = error;
WOLFSSL_ERROR(ssl->error);
/* store for next call if WANT_WRITE or user embedSend() that
doesn't present like WANT_WRITE */
ssl->buffers.plainSz = encrypt->buffer.length;
ssl->buffers.prevSent = encrypt->buffer.length;
if (ssl->error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
(ssl->options.connReset || ssl->options.isClosed)) {
return SOCKET_PEER_CLOSED_E; /* peer reset or closed */
}
return ssl->error;
}
/* only one message per attempt */
if (ssl->options.partialWrite == 1) {
WOLFSSL_MSG("Partial Write on, only sending one record");
break;
}
}
}
return 0;
}
#endif
/**
* ssl_in_handshake():
* Invoked in wolfSSL_read/wolfSSL_write to check if wolfSSL_negotiate() is
@ -24690,18 +24839,20 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#if defined(WOLFSSL_EARLY_DATA) && defined(WOLFSSL_EARLY_DATA_GROUP)
int groupMsgs = 0;
#endif
int error = ssl->error;
if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE)
if (error == WC_NO_ERR_TRACE(WANT_WRITE)
#ifdef WOLFSSL_ASYNC_CRYPT
|| ssl->error == WC_NO_ERR_TRACE(WC_PENDING_E)
|| error == WC_NO_ERR_TRACE(WC_PENDING_E)
#endif
) {
error = 0;
ssl->error = 0;
}
/* don't allow write after decrypt or mac error */
if (ssl->error == WC_NO_ERR_TRACE(VERIFY_MAC_ERROR) ||
ssl->error == WC_NO_ERR_TRACE(DECRYPT_ERROR)) {
if (error == WC_NO_ERR_TRACE(VERIFY_MAC_ERROR) ||
error == WC_NO_ERR_TRACE(DECRYPT_ERROR)) {
/* For DTLS allow these possible errors and allow the session
to continue despite them */
if (ssl->options.dtls) {
@ -24748,6 +24899,29 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
}
}
#ifdef WOLFSSL_RW_THREADED
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
/* Dtls13DoScheduledWork(ssl) may return WANT_WRITE */
if ((error = Dtls13DoScheduledWork(ssl)) < 0) {
ssl->error = error;
WOLFSSL_ERROR(error);
return error;
}
}
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_TLS13
if (ssl->options.sendKeyUpdate) {
ssl->options.sendKeyUpdate = 0;
ret = SendTls13KeyUpdate(ssl);
if (ret != 0) {
ssl->error = BUILD_MSG_ERROR;
return WOLFSSL_FATAL_ERROR;
}
}
#endif
#endif
/* last time system socket output buffer was full, try again to send */
if (ssl->buffers.outputBuffer.length > 0
#if defined(WOLFSSL_EARLY_DATA) && defined(WOLFSSL_EARLY_DATA_GROUP)
@ -24755,15 +24929,16 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#endif
) {
WOLFSSL_MSG("output buffer was full, trying to send again");
if ( (ssl->error = SendBuffered(ssl)) < 0) {
WOLFSSL_ERROR(ssl->error);
if (ssl->error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
if ( (error = SendBuffered(ssl)) < 0) {
WOLFSSL_ERROR(error);
if (error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
(ssl->options.connReset || ssl->options.isClosed)) {
ssl->error = SOCKET_PEER_CLOSED_E;
WOLFSSL_ERROR(ssl->error);
error = SOCKET_PEER_CLOSED_E;
ssl->error = error;
WOLFSSL_ERROR(error);
return 0; /* peer reset or closed */
}
return ssl->error;
return (ssl->error = error);
}
else {
/* advance sent to previous sent + plain size just sent */
@ -24772,7 +24947,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
if (sent > sz) {
WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
return ssl->error = BAD_FUNC_ARG;
return (ssl->error = BAD_FUNC_ARG);
}
}
}
@ -24783,6 +24958,19 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
return WOLFSSL_FATAL_ERROR;
}
#ifdef WOLFSSL_THREADED_CRYPT
ret = SendAsyncData(ssl);
if (ret != 0) {
ssl->error = ret;
return WOLFSSL_FATAL_ERROR;
}
if (ssl->dtls13WaitKeyUpdateAck) {
ret = DoDtls13KeyUpdateAck(ssl);
if (ret != 0)
return ret;
}
#endif
for (;;) {
byte* out;
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
@ -24791,6 +24979,10 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#ifdef HAVE_LIBZ
byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
#endif
#ifdef WOLFSSL_THREADED_CRYPT
int i;
ThreadCrypt* encrypt = NULL;
#endif
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS)
if (IsAtLeastTLSv1_3(ssl->version)) {
@ -24855,9 +25047,10 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK)
if (ssl->options.dtls && (buffSz < sz - sent)) {
ssl->error = DTLS_SIZE_ERROR;
WOLFSSL_ERROR(ssl->error);
return ssl->error;
error = DTLS_SIZE_ERROR;
ssl->error = error;
WOLFSSL_ERROR(error);
return error;
}
#endif
outputSz = buffSz + COMP_EXTRA + DTLS_RECORD_HEADER_SZ;
@ -24874,10 +25067,33 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
/* check for available size */
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
return ssl->error = ret;
return (ssl->error = ret);
/* get output buffer */
#ifndef WOLFSSL_THREADED_CRYPT
out = GetOutputBuffer(ssl);
#else
do {
for (i = 0; i < WOLFSSL_THREADED_CRYPT_CNT; i++) {
if (ssl->buffers.encrypt[i].avail) {
encrypt = &ssl->buffers.encrypt[i];
break;
}
}
if (encrypt == NULL) {
ret = SendAsyncData(ssl);
if (ret != 0) {
ssl->error = ret;
return WOLFSSL_FATAL_ERROR;
}
}
}
while (encrypt == NULL);
encrypt->done = 0;
encrypt->avail = 0;
GrowAnOutputBuffer(ssl, &encrypt->buffer, outputSz);
out = encrypt->buffer.buffer;
#endif
#ifdef HAVE_LIBZ
if (ssl->options.usingCompression) {
@ -24921,21 +25137,70 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
#ifdef WOLFSSL_ASYNC_CRYPT
FreeAsyncCtx(ssl, 0);
#endif
#ifdef WOLFSSL_THREADED_CRYPT
if (!encrypt->init) {
SetKeys(&encrypt->encrypt, NULL, &ssl->keys, &ssl->specs,
ssl->options.side, ssl->heap, ssl->devId, ssl->rng,
ssl->options.tls1_3);
encrypt->init = 1;
}
encrypt->buffer.length = sendSz;
encrypt->offset = RECORD_HEADER_SZ;
if (ssl->options.dtls) {
encrypt->offset += DTLS_RECORD_EXTRA;
}
encrypt->cryptLen = outputSz - encrypt->offset;
#ifdef HAVE_TRUNCATED_HMAC
if (ssl->truncated_hmac) {
encrypt->cryptLen -= min(TRUNCATED_HMAC_SZ, ssl->specs.hash_size);
}
else
#endif
{
encrypt->cryptLen -= ssl->specs.hash_size;
}
#if !defined(NO_PUBLIC_GCM_SET_IV) && \
((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
XMEMCPY(encrypt->nonce, ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ);
XMEMCPY(encrypt->nonce + AESGCM_IMP_IV_SZ, ssl->keys.aead_exp_IV,
AESGCM_EXP_IV_SZ);
#endif
XMEMSET(encrypt->additional, 0, AEAD_AUTH_DATA_SZ);
WriteSEQ(ssl, CUR_ORDER, encrypt->additional);
XMEMCPY(encrypt->additional + AEAD_TYPE_OFFSET, encrypt->buffer.buffer,
3);
c16toa(sendSz - encrypt->offset - AESGCM_EXP_IV_SZ -
ssl->specs.aead_mac_size, encrypt->additional + AEAD_LEN_OFFSET);
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
if (encrypt->signal != NULL) {
encrypt->signal(encrypt->signalCtx, ssl);
}
return sendSz;
#else
ssl->buffers.outputBuffer.length += (word32)sendSz;
if ( (ssl->error = SendBuffered(ssl)) < 0) {
WOLFSSL_ERROR(ssl->error);
if ( (error = SendBuffered(ssl)) < 0) {
ssl->error = error;
WOLFSSL_ERROR(error);
/* store for next call if WANT_WRITE or user embedSend() that
doesn't present like WANT_WRITE */
ssl->buffers.plainSz = buffSz;
ssl->buffers.prevSent = sent;
if (ssl->error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
if (error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
(ssl->options.connReset || ssl->options.isClosed)) {
error = SOCKET_PEER_CLOSED_E;
ssl->error = SOCKET_PEER_CLOSED_E;
WOLFSSL_ERROR(ssl->error);
WOLFSSL_ERROR(error);
return 0; /* peer reset or closed */
}
return ssl->error;
return error;
}
sent += buffSz;
@ -24945,6 +25210,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
WOLFSSL_MSG("Partial Write on, only sending one record");
break;
}
#endif
}
return sent;
@ -24954,13 +25220,14 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
{
int size;
int error = ssl->error;
WOLFSSL_ENTER("ReceiveData");
/* reset error state */
if (ssl->error == WC_NO_ERR_TRACE(WANT_READ) ||
ssl->error == WOLFSSL_ERROR_WANT_READ)
{
if (error == WC_NO_ERR_TRACE(WANT_READ) ||
error == WOLFSSL_ERROR_WANT_READ) {
error = 0;
ssl->error = 0;
}
@ -24968,25 +25235,26 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
if (ssl->options.dtls) {
/* In DTLS mode, we forgive some errors and allow the session
* to continue despite them. */
if (ssl->error == WC_NO_ERR_TRACE(VERIFY_MAC_ERROR) ||
ssl->error == WC_NO_ERR_TRACE(DECRYPT_ERROR) ||
ssl->error == WC_NO_ERR_TRACE(DTLS_SIZE_ERROR)) {
if (error == WC_NO_ERR_TRACE(VERIFY_MAC_ERROR) ||
error == WC_NO_ERR_TRACE(DECRYPT_ERROR) ||
error == WC_NO_ERR_TRACE(DTLS_SIZE_ERROR)) {
error = 0;
ssl->error = 0;
}
}
#endif /* WOLFSSL_DTLS */
if (ssl->error != 0 && ssl->error != WC_NO_ERR_TRACE(WANT_WRITE)
if (error != 0 && error != WC_NO_ERR_TRACE(WANT_WRITE)
#ifdef WOLFSSL_ASYNC_CRYPT
&& ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
&& error != WC_NO_ERR_TRACE(WC_PENDING_E)
#endif
#if defined(HAVE_SECURE_RENEGOTIATION) || defined(WOLFSSL_DTLS13)
&& ssl->error != WC_NO_ERR_TRACE(APP_DATA_READY)
&& error != WC_NO_ERR_TRACE(APP_DATA_READY)
#endif
) {
WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
return ssl->error;
return error;
}
#ifdef WOLFSSL_EARLY_DATA
@ -25024,32 +25292,39 @@ startScr:
#endif
while (ssl->buffers.clearOutputBuffer.length == 0) {
if ( (ssl->error = ProcessReply(ssl)) < 0) {
if (ssl->error == WC_NO_ERR_TRACE(ZERO_RETURN)) {
if ( (error = ProcessReply(ssl)) < 0) {
if (error == WC_NO_ERR_TRACE(ZERO_RETURN)) {
ssl->error = error;
WOLFSSL_MSG("Zero return, no more data coming");
return 0; /* no more data coming */
}
if (ssl->error == WC_NO_ERR_TRACE(SOCKET_ERROR_E)) {
if (error == WC_NO_ERR_TRACE(SOCKET_ERROR_E)) {
if (ssl->options.connReset || ssl->options.isClosed) {
WOLFSSL_MSG("Peer reset or closed, connection done");
ssl->error = SOCKET_PEER_CLOSED_E;
WOLFSSL_ERROR(ssl->error);
error = SOCKET_PEER_CLOSED_E;
ssl->error = error;
WOLFSSL_ERROR(error);
return 0; /* peer reset or closed */
}
}
WOLFSSL_ERROR(ssl->error);
return ssl->error;
ssl->error = error;
WOLFSSL_ERROR(error);
return error;
}
#ifndef WOLFSSL_RW_THREADED
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
/* Dtls13DoScheduledWork(ssl) may return WANT_WRITE */
if ((ssl->error = Dtls13DoScheduledWork(ssl)) < 0) {
WOLFSSL_ERROR(ssl->error);
return ssl->error;
if ((error = Dtls13DoScheduledWork(ssl)) < 0) {
ssl->error = error;
WOLFSSL_ERROR(error);
return error;
}
}
#endif /* WOLFSSL_DTLS13 */
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (ssl->secure_renegotiation &&
ssl->secure_renegotiation->startScr) {

View File

@ -2371,7 +2371,7 @@ static int SetPrefix(byte* sha_input, int idx)
#endif
static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
int side, void* heap, int devId, WC_RNG* rng, int tls13)
{
(void)rng;

View File

@ -23672,7 +23672,86 @@ wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
#endif /* OPENSSL_EXTRA */
#ifndef NO_CERTS
#ifdef WOLFSSL_THREADED_CRYPT
int wolfSSL_AsyncEncryptReady(WOLFSSL* ssl, int idx)
{
ThreadCrypt* encrypt;
if (ssl == NULL) {
return 0;
}
encrypt = &ssl->buffers.encrypt[idx];
return (encrypt->avail == 0) && (encrypt->done == 0);
}
int wolfSSL_AsyncEncryptStop(WOLFSSL* ssl, int idx)
{
ThreadCrypt* encrypt;
if (ssl == NULL) {
return 1;
}
encrypt = &ssl->buffers.encrypt[idx];
return encrypt->stop;
}
int wolfSSL_AsyncEncrypt(WOLFSSL* ssl, int idx)
{
int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
ThreadCrypt* encrypt = &ssl->buffers.encrypt[idx];
if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
unsigned char* out = encrypt->buffer.buffer + encrypt->offset;
unsigned char* input = encrypt->buffer.buffer + encrypt->offset;
word32 encSz = encrypt->buffer.length - encrypt->offset;
ret =
#if !defined(NO_GCM_ENCRYPT_EXTRA) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
wc_AesGcmEncrypt_ex
#else
wc_AesGcmEncrypt
#endif
(encrypt->encrypt.aes,
out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
encSz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
encrypt->nonce, AESGCM_NONCE_SZ,
out + encSz - ssl->specs.aead_mac_size,
ssl->specs.aead_mac_size,
encrypt->additional, AEAD_AUTH_DATA_SZ);
#if !defined(NO_PUBLIC_GCM_SET_IV) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
XMEMCPY(out, encrypt->nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ);
#endif
encrypt->done = 1;
}
return ret;
}
int wolfSSL_AsyncEncryptSetSignal(WOLFSSL* ssl, int idx,
WOLFSSL_THREAD_SIGNAL signal, void* ctx)
{
int ret = 0;
if (ssl == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ssl->buffers.encrypt[idx].signal = signal;
ssl->buffers.encrypt[idx].signalCtx = ctx;
}
return ret;
}
#endif
#ifndef NO_CERT
#define WOLFSSL_X509_INCLUDED
#include "src/x509.c"
#endif

View File

@ -11210,7 +11210,7 @@ static int SendTls13Finished(WOLFSSL* ssl)
* ssl The SSL/TLS object.
* returns 0 on success, otherwise failure.
*/
static int SendTls13KeyUpdate(WOLFSSL* ssl)
int SendTls13KeyUpdate(WOLFSSL* ssl)
{
byte* input;
byte* output;
@ -11387,7 +11387,12 @@ static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif /* WOLFSSL_DTLS13 */
#ifndef WOLFSSL_RW_THREADED
return SendTls13KeyUpdate(ssl);
#else
ssl->options.sendKeyUpdate = 1;
return 0;
#endif
}
WOLFSSL_LEAVE("DoTls13KeyUpdate", ret);

View File

@ -650,6 +650,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
#elif !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
word32 invalidPeerPackets = 0;
#endif
int newPeer = 0;
WOLFSSL_ENTER("EmbedReceiveFrom");
@ -677,8 +678,13 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
dtlsCtx->peer.bufSz = sizeof(SOCKADDR_S);
else
dtlsCtx->peer.bufSz = 0;
}
newPeer = 1;
peer = (SOCKADDR_S*)dtlsCtx->peer.sa;
}
else {
peer = &lclPeer;
XMEMCPY(peer, (SOCKADDR_S*)dtlsCtx->peer.sa, sizeof(lclPeer));
}
peerSz = dtlsCtx->peer.bufSz;
}
@ -688,9 +694,20 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
doDtlsTimeout =
doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL ||
doDtlsTimeout = doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL;
#ifdef WOLFSSL_RW_THREADED
{
int ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
if (ret < 0) {
return ret;
}
}
#endif
doDtlsTimeout = doDtlsTimeout ||
(ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
#ifdef WOLFSSL_RW_THREADED
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
#endif
}
#endif /* WOLFSSL_DTLS13 */
@ -822,9 +839,17 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
}
}
else {
if (newPeer) {
/* Store size of saved address */
dtlsCtx->peer.sz = peerSz;
}
#ifndef WOLFSSL_PEER_ADDRESS_CHANGES
else if ((dtlsCtx->peer.sz != (unsigned int)peerSz) ||
(XMEMCMP(peer, dtlsCtx->peer.sa, peerSz) != 0)) {
return WOLFSSL_CBIO_ERR_GENERAL;
}
#endif
}
#ifndef NO_ASN_TIME
ssl->dtls_start_timeout = 0;
#endif /* !NO_ASN_TIME */

View File

@ -2920,8 +2920,8 @@ typedef struct Keys {
byte encryptionOn; /* true after change cipher spec */
byte decryptedCur; /* only decrypt current record once */
#ifdef WOLFSSL_TLS13
byte updateResponseReq:1; /* KeyUpdate response from peer required. */
byte keyUpdateRespond:1; /* KeyUpdate is to be responded to. */
byte updateResponseReq; /* KeyUpdate response from peer required. */
byte keyUpdateRespond; /* KeyUpdate is to be responded to. */
#endif
#ifdef WOLFSSL_RENESAS_TSIP_TLS
@ -4744,10 +4744,34 @@ enum AcceptStateTls13 {
TLS13_TICKET_SENT
};
#ifdef WOLFSSL_THREADED_CRYPT
#include <pthread.h>
typedef struct ThreadCrypt {
Ciphers encrypt;
bufferStatic buffer;
unsigned char nonce[AESGCM_NONCE_SZ];
unsigned char additional[AEAD_AUTH_DATA_SZ];
int init;
int offset;
int cryptLen;
int done;
int avail;
int stop;
WOLFSSL_THREAD_SIGNAL signal;
void* signalCtx;
} ThreadCrypt;
#endif
/* buffers for struct WOLFSSL */
typedef struct Buffers {
bufferStatic inputBuffer;
bufferStatic outputBuffer;
#ifdef WOLFSSL_THREADED_CRYPT
ThreadCrypt encrypt[WOLFSSL_THREADED_CRYPT_CNT];
#endif
buffer domainName; /* for client check */
buffer clearOutputBuffer;
buffer sig; /* signature data */
@ -4901,7 +4925,6 @@ struct Options {
word16 tls:1; /* using TLS ? */
word16 tls1_1:1; /* using TLSv1.1+ ? */
word16 tls1_3:1; /* using TLSv1.3+ ? */
word16 seenUnifiedHdr:1; /* received msg with unified header */
word16 dtls:1; /* using datagrams ? */
#ifdef WOLFSSL_DTLS
word16 dtlsStateful:1; /* allow stateful processing ? */
@ -4910,7 +4933,6 @@ struct Options {
word16 isClosed:1; /* if we consider conn closed */
word16 closeNotify:1; /* we've received a close notify */
word16 sentNotify:1; /* we've sent a close notify */
word16 shutdownDone:1; /* we've completed a shutdown */
word16 usingCompression:1; /* are we using compression */
word16 haveRSA:1; /* RSA available */
word16 haveECC:1; /* ECC available */
@ -4958,7 +4980,6 @@ struct Options {
#endif
word16 dtlsUseNonblock:1; /* are we using nonblocking socket */
word16 dtlsHsRetain:1; /* DTLS retaining HS data */
word16 haveMcast:1; /* using multicast ? */
#ifdef WOLFSSL_SCTP
word16 dtlsSctp:1; /* DTLS-over-SCTP mode */
#endif
@ -5011,8 +5032,6 @@ struct Options {
word16 buildArgsSet:1; /* buildArgs are set and need to
* be free'd */
#endif
word16 buildingMsg:1; /* If set then we need to re-enter the
* handshake logic. */
#ifdef WOLFSSL_DTLS13
word16 dtls13SendMoreAcks:1; /* Send more acks during the
* handshake process */
@ -5039,6 +5058,14 @@ struct Options {
#if defined(HAVE_DANE)
word16 useDANE:1;
#endif /* HAVE_DANE */
#ifdef WOLFSSL_DTLS
byte haveMcast; /* using multicast ? */
#endif
byte buildingMsg; /* If set then we need to re-enter the
* handshake logic. */
byte seenUnifiedHdr; /* received msg with unified header */
byte shutdownDone; /* we've completed a shutdown */
byte sendKeyUpdate; /* Key Update to write */
#if defined(HAVE_RPK)
RpkConfig rpkConfig;
RpkState rpkState;
@ -5678,14 +5705,17 @@ typedef struct Dtls13RecordNumber {
} Dtls13RecordNumber;
typedef struct Dtls13Rtx {
enum Dtls13RtxFsmState state;
#ifdef WOLFSSL_RW_THREADED
wolfSSL_Mutex mutex;
#endif
enum Dtls13RtxFsmState state; /* Unused? */
Dtls13RtxRecord *rtxRecords;
Dtls13RtxRecord **rtxRecordTailPtr;
Dtls13RecordNumber *seenRecords;
word32 lastRtx;
byte triggeredRtxs;
byte sendAcks:1;
byte retransmit:1;
byte triggeredRtxs; /* Unused? */
byte sendAcks;
byte retransmit;
} Dtls13Rtx;
#endif /* WOLFSSL_DTLS13 */
@ -5963,10 +5993,10 @@ struct WOLFSSL {
/* used to store the message if it needs to be fragmented */
buffer dtls13FragmentsBuffer;
byte dtls13SendingFragments:1;
byte dtls13SendingAckOrRtx:1;
byte dtls13SendingAckOrRtx;
byte dtls13FastTimeout:1;
byte dtls13WaitKeyUpdateAck:1;
byte dtls13DoKeyUpdate:1;
byte dtls13WaitKeyUpdateAck;
byte dtls13DoKeyUpdate;
word32 dtls13MessageLength;
word32 dtls13FragOffset;
byte dtls13FragHandshakeType;
@ -6423,6 +6453,9 @@ WOLFSSL_LOCAL int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk,
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len);
#endif /* HAVE_SESSION_TICKET */
WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, int sz);
#ifdef WOLFSSL_THREADED_CRYPT
WOLFSSL_LOCAL int SendAsyncData(WOLFSSL* ssl);
#endif
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType);
#endif
@ -6627,6 +6660,10 @@ WOLFSSL_LOCAL word32 MacSize(const WOLFSSL* ssl);
WOLFSSL_LOCAL int SendServerHelloDone(WOLFSSL* ssl);
#endif /* NO_WOLFSSL_SERVER */
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int SendTls13KeyUpdate(WOLFSSL* ssl);
#endif
#ifdef WOLFSSL_DTLS
WOLFSSL_LOCAL DtlsMsg* DtlsMsgNew(word32 sz, byte tx, void* heap);
WOLFSSL_LOCAL void DtlsMsgDelete(DtlsMsg* item, void* heap);
@ -6773,6 +6810,9 @@ enum encrypt_side {
ENCRYPT_AND_DECRYPT_SIDE
};
WOLFSSL_LOCAL int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys,
CipherSpecs* specs, int side, void* heap, int devId, WC_RNG* rng,
int tls13);
WOLFSSL_LOCAL int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side);
/* Set*Internal and Set*External functions */
@ -6933,6 +6973,7 @@ WOLFSSL_LOCAL int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output,
enum HandShakeType msg_type, word32 length);
#define EE_MASK (0x3)
WOLFSSL_LOCAL int Dtls13FragmentsContinue(WOLFSSL* ssl);
WOLFSSL_LOCAL int DoDtls13KeyUpdateAck(WOLFSSL* ssl);
WOLFSSL_LOCAL int DoDtls13Ack(WOLFSSL* ssl, const byte* input, word32 inputSize,
word32* processedSize);
WOLFSSL_LOCAL int Dtls13ReconstructEpochNumber(WOLFSSL* ssl, byte epochBits,

View File

@ -3364,6 +3364,21 @@ WOLFSSL_API void wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptM
WOLFSSL_API void wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl);
#ifdef WOLFSSL_THREADED_CRYPT
#ifndef WOLFSSL_THREADED_CRYPT_CNT
#define WOLFSSL_THREADED_CRYPT_CNT 16
#endif
typedef void (*WOLFSSL_THREAD_SIGNAL)(void* ctx, WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_AsyncEncryptReady(WOLFSSL* ssl, int idx);
WOLFSSL_API int wolfSSL_AsyncEncryptStop(WOLFSSL* ssl, int idx);
WOLFSSL_API int wolfSSL_AsyncEncrypt(WOLFSSL* ssl, int idx);
WOLFSSL_API int wolfSSL_AsyncEncryptSetSignal(WOLFSSL* ssl, int idx,
WOLFSSL_THREAD_SIGNAL signal, void* ctx);
#endif
typedef int (*CallbackVerifyDecrypt)(WOLFSSL* ssl,
unsigned char* decOut, const unsigned char* decIn,
unsigned int decSz, int content, int verify, unsigned int* padSz,