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:
parent
4fd33b6b5d
commit
e4a661ff6e
120
src/dtls13.c
120
src/dtls13.c
@ -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 */
|
||||
ssl->dtls13Rtx.sendAcks = Dtls13RtxMsgNeedsAck(ssl, hs);
|
||||
#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)
|
||||
ssl->dtls13Rtx.rtxRecordTailPtr = prevNext;
|
||||
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");
|
||||
|
||||
rn = Dtls13NewRecordNumber(epoch, seq, ssl->heap);
|
||||
if (rn == NULL)
|
||||
return MEMORY_E;
|
||||
#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;
|
||||
rn->next = ssl->dtls13Rtx.seenRecords;
|
||||
ssl->dtls13Rtx.seenRecords = rn;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -730,15 +755,23 @@ static void Dtls13RtxFlushAcks(WOLFSSL* ssl)
|
||||
|
||||
WOLFSSL_ENTER("Dtls13RtxFlushAcks");
|
||||
|
||||
list = ssl->dtls13Rtx.seenRecords;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0)
|
||||
#endif
|
||||
{
|
||||
list = ssl->dtls13Rtx.seenRecords;
|
||||
|
||||
while (list != NULL) {
|
||||
rn = list;
|
||||
list = rn->next;
|
||||
XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||
while (list != NULL) {
|
||||
rn = list;
|
||||
list = rn->next;
|
||||
XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||
}
|
||||
|
||||
ssl->dtls13Rtx.seenRecords = NULL;
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssl->dtls13Rtx.seenRecords = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
ret = DoDtls13KeyUpdateAck(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
*processedSize = length + OPAQUE16_LEN;
|
||||
|
||||
@ -2698,9 +2756,17 @@ int SendDtls13Ack(WOLFSSL* ssl)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Dtls13WriteAckMessage(ssl, ssl->dtls13Rtx.seenRecords, &length);
|
||||
if (ret != 0)
|
||||
#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;
|
||||
|
||||
output = GetOutputBuffer(ssl);
|
||||
|
||||
|
525
src/internal.c
525
src/internal.c
@ -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) {
|
||||
@ -24744,10 +24895,33 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
|
||||
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
#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) &&
|
||||
(ssl->options.connReset || ssl->options.isClosed)) {
|
||||
ssl->error = SOCKET_PEER_CLOSED_E;
|
||||
WOLFSSL_ERROR(ssl->error);
|
||||
if ( (error = SendBuffered(ssl)) < 0) {
|
||||
WOLFSSL_ERROR(error);
|
||||
if (error == WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
|
||||
(ssl->options.connReset || ssl->options.isClosed)) {
|
||||
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) &&
|
||||
(ssl->options.connReset || ssl->options.isClosed)) {
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
#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 /* WOLFSSL_DTLS13 */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
if (ssl->secure_renegotiation &&
|
||||
ssl->secure_renegotiation->startScr) {
|
||||
|
@ -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;
|
||||
|
81
src/ssl.c
81
src/ssl.c
@ -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
|
||||
|
@ -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);
|
||||
|
35
src/wolfio.c
35
src/wolfio.c
@ -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));
|
||||
}
|
||||
peer = (SOCKADDR_S*)dtlsCtx->peer.sa;
|
||||
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,8 +839,16 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Store size of saved address */
|
||||
dtlsCtx->peer.sz = peerSz;
|
||||
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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user