From 651a7a97b90462e998f565c7bcd3e431618e04d1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 19 May 2020 14:11:05 +0200 Subject: [PATCH 01/17] Add secure renegotiation to DTLS 1.2 - Hash of fragmented certificate was not calculated as a single message and instead we were hashing individual fragments which produced the wrong digest, shared secret, etc... - Reset handshake number after server Finished packet is sent or received (depending on side) - Reserve space in buffer for cipher stuff - Take `DTLS_RECORD_EXTRA` and `DTLS_HANDSHAKE_EXTRA` into size and offset calculations for DTLS path - Fix renegotiation in DTLS with AES128-SHA - Fix renegotiation in DTLS with AES-GCM - Support HelloVerify request during secure renegotiation - Save renegotiation handshake messages for retransmission in timeout - Handle cipher parameters from different epochs. DTLS may need to resend and receive messages from previous epochs so handling different sets of encryption and decryption parameters is crucial. --- src/internal.c | 910 ++++++++++++++++++++++++++++++++++----------- src/keys.c | 102 ++++- src/ssl.c | 68 +++- src/tls.c | 25 +- src/wolfio.c | 4 +- wolfssl/internal.h | 31 +- wolfssl/ssl.h | 1 + 7 files changed, 898 insertions(+), 243 deletions(-) diff --git a/src/internal.c b/src/internal.c index 96e0d8f46..53d1c688e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -161,7 +161,7 @@ static const byte tls13Downgrade[7] = { #if !defined(NO_OLD_TLS) && !defined(WOLFSSL_AEAD_ONLY) static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, - int padSz, int content, int verify); + int padSz, int content, int verify, int epochOrder); #endif @@ -221,15 +221,25 @@ static WC_INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) * If SCTP is enabled returns dtls && !sctp. */ static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) { - int result = ssl->options.dtls; - - if (result) { #ifdef WOLFSSL_SCTP - result = !ssl->options.dtlsSctp; + return ssl->options.dtls && !ssl->options.dtlsSctp; +#else + return ssl->options.dtls; #endif - } +} - return result; +int IsInitialRenegotiationState(WOLFSSL* ssl) +{ + if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE + #ifdef HAVE_SECURE_RENEGOTIATION + || ssl->options.acceptState == ACCEPT_BEGIN_RENEG + #endif + ) { + return 1; + } + else { + return 0; + } } #endif /* DTLS || !WOLFSSL_NO_TLS12 */ @@ -6725,6 +6735,14 @@ static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) #ifdef WOLFSSL_DTLS static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) { +#ifdef HAVE_SECURE_RENEGOTIATION + /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER + * refers to the current epoch */ + if (order == PREV_ORDER && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { + order = CUR_ORDER; + } +#endif if (order == PREV_ORDER) { /* Previous epoch case */ if (ssl->options.haveMcast) { @@ -6770,6 +6788,14 @@ static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) static WC_INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order) { word32 seq; +#ifdef HAVE_SECURE_RENEGOTIATION + /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER + * refers to the current epoch */ + if (order == PREV_ORDER && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { + order = CUR_ORDER; + } +#endif if (order == PREV_ORDER) { seq = ssl->keys.dtls_prev_sequence_number_lo++; @@ -6878,6 +6904,25 @@ void DtlsMsgListDelete(DtlsMsg* head, void* heap) } } +void DtlsTxMsgListClean(WOLFSSL* ssl) +{ + DtlsMsg* head = ssl->dtls_tx_msg_list; + DtlsMsg* next; + while (head) { + next = head->next; + if (VerifyForTxDtlsMsgDelete(ssl, head)) + DtlsMsgDelete(head, ssl->heap); + else + /* Stored packets should be in order so break on first failed + * verify */ + break; + ssl->dtls_tx_msg_list_sz--; + /* Reset timer as deleting a node means that state has progressed */ + ssl->dtls_timeout = ssl->dtls_timeout_init; + head = next; + } + ssl->dtls_tx_msg_list = head; +} /* Create a DTLS Fragment from *begin - end, adjust new *begin and bytesLeft */ static DtlsFrag* CreateFragment(word32* begin, word32 end, const byte* data, @@ -6903,7 +6948,7 @@ static DtlsFrag* CreateFragment(word32* begin, word32 end, const byte* data, } -int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type, +int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte type, word32 fragOffset, word32 fragSz, void* heap) { if (msg != NULL && data != NULL && msg->fragSz <= msg->sz && @@ -6916,6 +6961,7 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type, word32 added; msg->seq = seq; + msg->epoch = epoch; msg->type = type; if (fragOffset == 0) { @@ -7004,16 +7050,16 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type, } -DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq) +DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 epoch, word32 seq) { - while (head != NULL && head->seq != seq) { + while (head != NULL && head->epoch == epoch && head->seq != seq) { head = head->next; } return head; } -void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data, +void DtlsMsgStore(WOLFSSL* ssl, word32 epoch, word32 seq, const byte* data, word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap) { /* See if seq exists in the list. If it isn't in the list, make @@ -7036,12 +7082,12 @@ void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data, DtlsMsg* head = ssl->dtls_rx_msg_list; if (head != NULL) { - DtlsMsg* cur = DtlsMsgFind(head, seq); + DtlsMsg* cur = DtlsMsgFind(head, epoch, seq); if (cur == NULL) { cur = DtlsMsgNew(dataSz, heap); if (cur != NULL) { - if (DtlsMsgSet(cur, seq, data, type, - fragOffset, fragSz, heap) < 0) { + if (DtlsMsgSet(cur, seq, epoch, data, type, + fragOffset, fragSz, heap) < 0) { DtlsMsgDelete(cur, heap); } else { @@ -7052,12 +7098,14 @@ void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data, } else { /* If this fails, the data is just dropped. */ - DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap); + DtlsMsgSet(cur, seq, epoch, data, type, fragOffset, + fragSz, heap); } } else { head = DtlsMsgNew(dataSz, heap); - if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) { + if (DtlsMsgSet(head, seq, epoch, data, type, fragOffset, + fragSz, heap) < 0) { DtlsMsgDelete(head, heap); head = NULL; } @@ -7102,7 +7150,7 @@ DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item) /* DtlsMsgPoolSave() adds the message to the end of the stored transmit list. */ -int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz) +int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz, enum HandShakeType type) { DtlsMsg* item; int ret = 0; @@ -7121,7 +7169,10 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz) XMEMCPY(item->buf, data, dataSz); item->sz = dataSz; - item->seq = ssl->keys.dtls_epoch; + item->epoch = ssl->keys.dtls_epoch; + /* save is called after something incremented this var */ + item->seq = ssl->keys.dtls_handshake_number - 1; + item->type = type; if (cur == NULL) ssl->dtls_tx_msg_list = item; @@ -7163,8 +7214,8 @@ void DtlsMsgPoolReset(WOLFSSL* ssl) ssl->dtls_tx_msg_list = NULL; ssl->dtls_tx_msg = NULL; ssl->dtls_tx_msg_list_sz = 0; - ssl->dtls_timeout = ssl->dtls_timeout_init; } + ssl->dtls_timeout = ssl->dtls_timeout_init; } @@ -7185,12 +7236,37 @@ int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset) } +int VerifyForTxDtlsMsgDelete(WOLFSSL* ssl, DtlsMsg* item) +{ + if (item->epoch < ssl->keys.dtls_epoch - 1) + return 1; + switch (ssl->options.side) { + case WOLFSSL_CLIENT_END: + if (item->type == client_hello && + ssl->options.serverState >= SERVER_HELLODONE_COMPLETE) + return 1; /* client can forget first client_hello if received full + * flight of packets from server */ + else + return 0; + case WOLFSSL_SERVER_END: + if (ssl->options.clientState >= CLIENT_FINISHED_COMPLETE && + item->type <= server_hello_done) + return 1; + else + return 0; + default: + return 0; + } +} + + /* DtlsMsgPoolSend() will send the stored transmit list. The stored list is * updated with new sequence numbers, and will be re-encrypted if needed. */ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) { int ret = 0; DtlsMsg* pool; + int epochOrder; WOLFSSL_ENTER("DtlsMsgPoolSend()"); @@ -7213,9 +7289,8 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) } while (pool != NULL) { - if (pool->seq == 0) { + if (pool->epoch == 0) { DtlsRecordLayerHeader* dtls; - int epochOrder; dtls = (DtlsRecordLayerHeader*)pool->buf; /* If the stored record's epoch is 0, and the currently set @@ -7238,7 +7313,8 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) ssl->buffers.outputBuffer.idx = 0; ssl->buffers.outputBuffer.length = pool->sz; } - else if (pool->seq == ssl->keys.dtls_epoch) { + else { + /* Handle sending packets from previous epoch */ byte* input; byte* output; int inputSz, sendSz; @@ -7247,6 +7323,28 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) inputSz = pool->sz; sendSz = inputSz + MAX_MSG_EXTRA; +#ifdef HAVE_SECURE_RENEGOTIATION + + /* + * CUR_ORDER will use ssl->secure_renegotiation from epoch 2+. + * ssl->keys otherwise + * PREV_ORDER will always use ssl->keys + */ + if (ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (pool->epoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) + epochOrder = CUR_ORDER; + else + epochOrder = PREV_ORDER; + } + else { + epochOrder = CUR_ORDER; + } +#else + epochOrder = CUR_ORDER; +#endif + + if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { WOLFSSL_ERROR(ret); return ret; @@ -7254,8 +7352,15 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) output = ssl->buffers.outputBuffer.buffer + ssl->buffers.outputBuffer.length; - sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 0, 0, 0); + if (inputSz != ENUM_LEN) + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + handshake, 0, 0, 0, epochOrder); + else + /* inputSz == ENUM_LEN must mean that this is a change cipher + * spec message */ + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + change_cipher_spec, 0, 0, 0, epochOrder); + if (sendSz < 0) { WOLFSSL_ERROR(BUILD_MSG_ERROR); return BUILD_MSG_ERROR; @@ -7757,10 +7862,12 @@ int HashInput(WOLFSSL* ssl, const byte* input, int sz) /* add record layer header for message */ -static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl) +static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl, int epochOrder) { RecordLayerHeader* rl; + (void)epochOrder; + /* record layer header */ rl = (RecordLayerHeader*)output; if (rl == NULL) { @@ -7794,7 +7901,7 @@ static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl /* dtls record layer header extensions */ dtls = (DtlsRecordLayerHeader*)output; - WriteSEQ(ssl, 0, dtls->sequence_number); + WriteSEQ(ssl, epochOrder, dtls->sequence_number); c16toa((word16)length, dtls->length); #endif } @@ -7846,7 +7953,7 @@ static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl) } #endif - AddRecordHeader(output, length + lengthAdj, handshake, ssl); + AddRecordHeader(output, length + lengthAdj, handshake, ssl, CUR_ORDER); AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl); } #endif /* !WOLFSSL_NO_TLS12 || (HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER) */ @@ -7869,7 +7976,7 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset, } #endif - AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl); + AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl, CUR_ORDER); AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl); } #endif /* NO_CERTS */ @@ -7941,7 +8048,7 @@ retry: case WOLFSSL_CBIO_ERR_TIMEOUT: #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && - !ssl->options.handShakeDone && + ssl->options.handShakeState != HANDSHAKE_DONE && DtlsMsgPoolTimeout(ssl) == 0 && DtlsMsgPoolSend(ssl, 0) == 0) { @@ -11921,7 +12028,12 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, } #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - DtlsMsgPoolReset(ssl); + if ((!ssl->options.resuming && ssl->options.side == WOLFSSL_CLIENT_END) || + (ssl->options.resuming && ssl->options.side == WOLFSSL_SERVER_END)){ + DtlsMsgPoolReset(ssl); + ssl->keys.dtls_handshake_number = 0; + ssl->keys.dtls_expected_peer_handshake_number = 0; + } } #endif @@ -12231,7 +12343,8 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) if (ssl->options.verifyPeer && ssl->options.havePeerCert) { - if (!ssl->options.havePeerVerify) { + if (!ssl->options.havePeerVerify || + !ssl->msgsReceived.got_certificate_verify) { WOLFSSL_MSG("client didn't send cert verify"); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) @@ -12391,6 +12504,25 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case hello_verify_request: WOLFSSL_MSG("processing hello verify request"); ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size); + if (IsEncryptionOn(ssl, 0)) { + #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + if (ssl->options.startedETMRead) { + word32 digestSz = MacSize(ssl); + if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) + return BUFFER_E; + *inOutIdx += ssl->keys.padSz + digestSz; + } + else + #endif + { + /* access beyond input + size should be checked against totalSz + */ + if (*inOutIdx + ssl->keys.padSz > totalSz) + return BUFFER_E; + + *inOutIdx += ssl->keys.padSz; + } + } break; case server_hello: @@ -12930,9 +13062,13 @@ static int DtlsMsgDrain(WOLFSSL* ssl) item->fragSz == item->sz && ret == 0) { word32 idx = 0; - ssl->keys.dtls_expected_peer_handshake_number++; - ret = DoHandShakeMsgType(ssl, item->msg, - &idx, item->type, item->sz, item->sz); + /* If item is from the wrong epoch then just ignore it */ + if (ssl->keys.dtls_epoch == item->epoch && + (ret = DoHandShakeMsgType(ssl, item->msg, &idx, item->type, + item->sz, item->sz)) == 0) { + ssl->keys.dtls_expected_peer_handshake_number++; + DtlsTxMsgListClean(ssl); + } #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) { ssl->keys.dtls_expected_peer_handshake_number--; @@ -12957,6 +13093,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size; word32 fragOffset, fragSz; int ret = 0; + int ignoreFinished = 0; WOLFSSL_ENTER("DoDtlsHandShakeMsg()"); @@ -12992,6 +13129,19 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, return INCOMPLETE_DATA; } + if (type == finished && ssl->keys.dtls_peer_handshake_number >= + ssl->keys.dtls_expected_peer_handshake_number && + ssl->keys.curEpoch == ssl->keys.dtls_epoch) { + /* finished msg should be ignore if it is in the current epoch + * if it comes from a previous handshake */ + if (ssl->options.side == WOLFSSL_CLIENT_END) { + ignoreFinished = ssl->options.connectState < FINISHED_DONE; + } + else { + ignoreFinished = ssl->options.acceptState < ACCEPT_FINISHED_DONE; + } + } + /* Check the handshake sequence number first. If out of order, * add the current message to the list. If the message is in order, * but it is a fragment, add the current message to the list, then @@ -13002,7 +13152,9 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, * head is out of order, return for more processing. */ if (ssl->keys.dtls_peer_handshake_number > - ssl->keys.dtls_expected_peer_handshake_number) { + ssl->keys.dtls_expected_peer_handshake_number && + (type == client_hello || ssl->options.handShakeState != HANDSHAKE_DONE) && + !ignoreFinished) { /* Current message is out of order. It will get stored in the list. * Storing also takes care of defragmentation. If the messages is a * client hello, we need to process this out of order; the server @@ -13012,13 +13164,31 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, * number. (If the cookie changes multiple times in quick succession, * the client could be sending multiple new client hello messages * with newer and newer cookies.) */ + WOLFSSL_MSG("Current message is out of order"); if (type != client_hello) { if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) { - DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number, + DtlsMsgStore(ssl, ssl->keys.curEpoch, + ssl->keys.dtls_peer_handshake_number, input + *inOutIdx, size, type, fragOffset, fragSz, ssl->heap); } *inOutIdx += fragSz; + #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + if (ssl->options.startedETMRead && ssl->keys.curEpoch != 0) { + word32 digestSz = MacSize(ssl); + if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) + return BUFFER_E; + *inOutIdx += digestSz; + } + else + #endif + { + if (*inOutIdx + ssl->keys.padSz > totalSz) { + WOLFSSL_ERROR(BUFFER_E); + return BUFFER_E; + } + } + *inOutIdx += ssl->keys.padSz; ret = 0; } else { @@ -13030,25 +13200,27 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } } else if (ssl->keys.dtls_peer_handshake_number < - ssl->keys.dtls_expected_peer_handshake_number) { + ssl->keys.dtls_expected_peer_handshake_number || + (ssl->keys.dtls_peer_handshake_number > + ssl->keys.dtls_expected_peer_handshake_number && + ssl->options.handShakeState == HANDSHAKE_DONE) || + ignoreFinished) { /* Already saw this message and processed it. It can be ignored. */ + WOLFSSL_MSG("Already saw this message and processed it"); *inOutIdx += fragSz; - if(type == finished ) { #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) - if (ssl->options.startedETMRead) { - word32 digestSz = MacSize(ssl); - if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) - return BUFFER_E; - *inOutIdx += ssl->keys.padSz + digestSz; - } - else + if (ssl->options.startedETMRead && ssl->keys.curEpoch != 0) { + word32 digestSz = MacSize(ssl); + if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) + return BUFFER_E; + *inOutIdx += digestSz; + } + else #endif - { - if (*inOutIdx + ssl->keys.padSz > totalSz) { - WOLFSSL_ERROR(BUFFER_E); - return BUFFER_E; - } - *inOutIdx += ssl->keys.padSz; + { + if (*inOutIdx + ssl->keys.padSz > totalSz) { + WOLFSSL_ERROR(BUFFER_E); + return BUFFER_E; } } if (IsDtlsNotSctpMode(ssl) && @@ -13056,27 +13228,42 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = DtlsMsgPoolSend(ssl, 0); } + *inOutIdx += ssl->keys.padSz; } else if (fragSz < size) { /* Since this branch is in order, but fragmented, dtls_rx_msg_list will * be pointing to the message with this fragment in it. Check it to see * if it is completed. */ + WOLFSSL_MSG("Branch is in order, but fragmented"); if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) { - DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number, + DtlsMsgStore(ssl, ssl->keys.curEpoch, + ssl->keys.dtls_peer_handshake_number, input + *inOutIdx, size, type, fragOffset, fragSz, ssl->heap); } *inOutIdx += fragSz; + *inOutIdx += ssl->keys.padSz; +#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + if (ssl->options.startedETMRead && ssl->keys.curEpoch != 0) { + word32 digestSz = MacSize(ssl); + if (*inOutIdx + digestSz > totalSz) + return BUFFER_E; + *inOutIdx += digestSz; + } +#endif ret = 0; if (ssl->dtls_rx_msg_list != NULL && ssl->dtls_rx_msg_list->fragSz >= ssl->dtls_rx_msg_list->sz) ret = DtlsMsgDrain(ssl); } else { - /* This branch is in order next, and a complete message. */ + /* This branch is in order next, and a complete message. On success + * clean the tx list. */ + WOLFSSL_MSG("Branch is in order and a complete message"); ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz); if (ret == 0) { - if (type != client_hello || !IsDtlsNotSctpMode(ssl)) + DtlsTxMsgListClean(ssl); + if (type != finished) ssl->keys.dtls_expected_peer_handshake_number++; if (ssl->dtls_rx_msg_list != NULL) { ret = DtlsMsgDrain(ssl); @@ -13869,8 +14056,21 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, ssl->decrypt.additional + AEAD_LEN_OFFSET); - XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); + + #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + if (ssl->options.dtls && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (ssl->keys.curEpoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) + XMEMCPY(ssl->decrypt.nonce, ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); + else + XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); + } + else + #endif + XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); if ((ret = aes_auth_fn(ssl->decrypt.aes, @@ -13994,6 +14194,27 @@ static WC_INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, FALL_THROUGH; case CIPHER_STATE_DO: { + #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + if (ssl->options.dtls && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (ssl->keys.curEpoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) { + if (ssl->decrypt.src != SCR) { + ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED; + if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0) + break; + } + WOLFSSL_BUFFER(ssl->secure_renegotiation->tmp_keys.client_write_key, MAX_SYM_KEY_SIZE); + } + else { + if (ssl->decrypt.src != KEYS) { + ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; + if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0) + break; + } + } + } + #endif + ret = DecryptDo(ssl, plain, input, sz); /* Advance state */ @@ -14229,7 +14450,7 @@ int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz, * either increment the size by (macSz + padLen + 1) before use or check on * the size to make sure is valid. */ ret = ssl->hmac(ssl, verify, input, pLen - macSz - padLen - 1, padLen, - content, 1); + content, 1, PEER_ORDER); good |= MaskMac(input, pLen, ssl->specs.hash_size, verify); /* Non-zero on failure. */ @@ -14515,7 +14736,7 @@ static WC_INLINE int VerifyMacEnc(WOLFSSL* ssl, const byte* input, word32 msgSz, return VERIFY_MAC_ERROR; } - ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1); + ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1, PEER_ORDER); ret |= ConstantCompare(verify, input + msgSz - digestSz, digestSz); if (ret != 0) { return VERIFY_MAC_ERROR; @@ -14568,8 +14789,8 @@ static WC_INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz, badPadLen = 1; } PadCheck(dummy, (byte)pad, MAX_PAD_SIZE); /* timing only */ - ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, pad, - content, 1); + ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, + pad, content, 1, PEER_ORDER); if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1, digestSz) != 0) return VERIFY_MAC_ERROR; @@ -14578,7 +14799,8 @@ static WC_INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz, } } else if (ssl->specs.cipher_type == stream) { - ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1); + ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1, + PEER_ORDER); if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){ return VERIFY_MAC_ERROR; } @@ -14752,12 +14974,6 @@ int ProcessReply(WOLFSSL* ssl) ssl->replayDropCount++; #endif /* WOLFSSL_DTLS_DROP_STATS */ - if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) { - ret = DtlsMsgPoolSend(ssl, 0); - if (ret != 0) - return ret; - } - continue; } #endif @@ -15109,6 +15325,7 @@ int ProcessReply(WOLFSSL* ssl) switch (ssl->curRL.type) { case handshake : + WOLFSSL_MSG("got HANDSHAKE"); /* debugging in DoHandShakeMsg */ if (ssl->options.dtls) { #ifdef WOLFSSL_DTLS @@ -15166,7 +15383,8 @@ int ProcessReply(WOLFSSL* ssl) AddPacketInfo(ssl, "ChangeCipher", change_cipher_spec, ssl->buffers.inputBuffer.buffer + - ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ, + ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ - + (ssl->options.dtls ? DTLS_RECORD_EXTRA : 0), 1 + RECORD_HEADER_SZ, READ_PROTO, ssl->heap); #ifdef WOLFSSL_CALLBACKS AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo); @@ -15199,39 +15417,23 @@ int ProcessReply(WOLFSSL* ssl) #endif #ifndef WOLFSSL_NO_TLS12 - ret = SanityCheckMsgReceived(ssl, change_cipher_hs); - if (ret != 0) { - if (!ssl->options.dtls) { - return ret; - } - else { - #ifdef WOLFSSL_DTLS - /* Check for duplicate CCS message in DTLS mode. - * DTLS allows for duplicate messages, and it should be - * skipped. Also skip if out of order. */ - if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E) - return ret; - - if (IsDtlsNotSctpMode(ssl)) { - ret = DtlsMsgPoolSend(ssl, 1); - if (ret != 0) - return ret; - } - - if (ssl->curSize != 1) { - WOLFSSL_MSG("Malicious or corrupted" - " duplicate ChangeCipher msg"); - return LENGTH_ERROR; - } - ssl->buffers.inputBuffer.idx++; - break; - #endif /* WOLFSSL_DTLS */ - } + if (ssl->buffers.inputBuffer.buffer[ + ssl->buffers.inputBuffer.idx] != 1) { + WOLFSSL_MSG("ChangeCipher msg wrong value"); + return LENGTH_ERROR; } if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) { ssl->buffers.inputBuffer.idx += ssl->keys.padSz; - ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx; + ssl->curSize -= ssl->keys.padSz; +#ifdef HAVE_AEAD + if (ssl->specs.cipher_type == aead && + ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) + ssl->curSize -= AESGCM_EXP_IV_SZ; + else +#endif + ssl->curSize -= ssl->specs.iv_size; + #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { word32 digestSz = MacSize(ssl); @@ -15247,6 +15449,25 @@ int ProcessReply(WOLFSSL* ssl) } ssl->buffers.inputBuffer.idx++; + + ret = SanityCheckMsgReceived(ssl, change_cipher_hs); + if (ret != 0) { + if (!ssl->options.dtls) { + return ret; + } + else { + #ifdef WOLFSSL_DTLS + /* Check for duplicate CCS message in DTLS mode. + * DTLS allows for duplicate messages, and it should be + * skipped. Also skip if out of order. */ + if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E) + return ret; + + break; + #endif /* WOLFSSL_DTLS */ + } + } + ssl->keys.encryptionOn = 1; /* setup decrypt keys for following messages */ @@ -15387,7 +15608,6 @@ int ProcessReply(WOLFSSL* ssl) /* more records */ else { WOLFSSL_MSG("More records in input"); - ssl->options.processReply = doProcessInit; continue; } @@ -15441,7 +15661,7 @@ int SendChangeCipher(WOLFSSL* ssl) output = ssl->buffers.outputBuffer.buffer + ssl->buffers.outputBuffer.length; - AddRecordHeader(output, 1, change_cipher_spec, ssl); + AddRecordHeader(output, 1, change_cipher_spec, ssl, CUR_ORDER); output[idx] = 1; /* turn it on */ @@ -15450,19 +15670,26 @@ int SendChangeCipher(WOLFSSL* ssl) int inputSz = ENUM_LEN; input[0] = 1; /* turn it on */ + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, input, inputSz, change_cipher_hs)) != 0) { + return ret; + } + #endif sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - change_cipher_spec, 0, 0, 0); + change_cipher_spec, 0, 0, 0, CUR_ORDER); if (sendSz < 0) { return sendSz; } } - #ifdef WOLFSSL_DTLS + else { if (IsDtlsNotSctpMode(ssl)) { DtlsSEQIncrement(ssl, CUR_ORDER); - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, change_cipher_hs)) != 0) return ret; } + } #endif #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) if (ssl->hsInfoOn) AddPacketName(ssl, "ChangeCipher"); @@ -15488,7 +15715,7 @@ int SendChangeCipher(WOLFSSL* ssl) #if !defined(NO_OLD_TLS) && !defined(WOLFSSL_AEAD_ONLY) static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, - int padLen, int content, int verify) + int padLen, int content, int verify, int epochOrder) { byte result[WC_MAX_DIGEST_SIZE]; word32 digestSz = ssl->specs.hash_size; /* actual sizes */ @@ -15501,7 +15728,7 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, /* data */ byte seq[SEQ_SZ]; byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */ - const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify); + const byte* macSecret = NULL; (void)padLen; @@ -15510,10 +15737,19 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx); #endif +#ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder); + else + macSecret = wolfSSL_GetMacSecret(ssl, verify); +#else + macSecret = wolfSSL_GetMacSecret(ssl, verify); +#endif + XMEMSET(seq, 0, SEQ_SZ); conLen[0] = (byte)content; c16toa((word16)sz, &conLen[ENUM_LEN]); - WriteSEQ(ssl, verify, seq); + WriteSEQ(ssl, epochOrder, seq); if (ssl->specs.mac_algorithm == md5_mac) { ret = wc_InitMd5_ex(&md5, ssl->heap, ssl->devId); @@ -15774,7 +16010,8 @@ static void FreeBuildMsgArgs(WOLFSSL* ssl, void* pArgs) /* Build SSL Message, encrypted */ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, - int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay) + int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay, + int epochOrder) { #ifndef WOLFSSL_NO_TLS12 int ret = 0; @@ -15793,6 +16030,8 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, return BAD_FUNC_ARG; } + (void)epochOrder; + #ifdef WOLFSSL_NO_TLS12 return BuildTls13Message(ssl, output, outSz, input, inSz, type, hashOutput, sizeOnly, asyncOkay); @@ -15845,6 +16084,42 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, WOLFSSL_MSG("BuildMessage w/sizeOnly doesn't need input/output"); ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg); } + #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + if (ssl->options.dtls && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + switch (epochOrder) { + case PREV_ORDER: + if (ssl->encrypt.src != KEYS) { + ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; + if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) + ERROR_OUT(ret, exit_buildmsg); + WOLFSSL_BUFFER(ssl->keys.client_write_key, MAX_SYM_KEY_SIZE); + } + break; + case CUR_ORDER: + if (ssl->keys.dtls_epoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) { + if (ssl->encrypt.src != SCR) { + ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED; + if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) + ERROR_OUT(ret, exit_buildmsg); + WOLFSSL_BUFFER(ssl->secure_renegotiation->tmp_keys.client_write_key, MAX_SYM_KEY_SIZE); + } + } + else { + if (ssl->encrypt.src != KEYS) { + ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; + if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) + ERROR_OUT(ret, exit_buildmsg); + WOLFSSL_BUFFER(ssl->keys.client_write_key, MAX_SYM_KEY_SIZE); + } + } + break; + default: + WOLFSSL_MSG("BuildMessage only supports PREV_ORDER and CUR_ORDER"); + ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg); + } + } + #endif ssl->options.buildMsgState = BUILD_MSG_SIZE; } @@ -15932,7 +16207,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #endif args->size = (word16)(args->sz - args->headerSz); /* include mac and digest */ - AddRecordHeader(output, args->size, (byte)type, ssl); + AddRecordHeader(output, args->size, (byte)type, ssl, epochOrder); /* write to output */ if (args->ivSz > 0) { @@ -16027,7 +16302,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, ret = ssl->hmac(ssl, hmac, output + args->headerSz + args->ivSz, inSz, - -1, type, 0); + -1, type, 0, epochOrder); XMEMCPY(output + args->idx, hmac, args->digestSz); #ifdef WOLFSSL_SMALL_STACK @@ -16038,7 +16313,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #endif { ret = ssl->hmac(ssl, output + args->idx, output + - args->headerSz + args->ivSz, inSz, -1, type, 0); + args->headerSz + args->ivSz, inSz, -1, type, 0, epochOrder); } } #endif /* WOLFSSL_AEAD_ONLY */ @@ -16050,6 +16325,26 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, FALL_THROUGH; case BUILD_MSG_ENCRYPT: { + #if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) + /* Modify CUR_ORDER sequence number for all encryption algos + * that use it for encryption parameters */ + word16 dtls_epoch; + word16 dtls_sequence_number_hi; + word32 dtls_sequence_number_lo; + int swap_seq = ssl->options.dtls && epochOrder == PREV_ORDER && + ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && + ssl->secure_renegotiation->tmp_keys.dtls_epoch == + ssl->keys.dtls_epoch; + if (swap_seq) { + dtls_epoch = ssl->keys.dtls_epoch; + dtls_sequence_number_hi = ssl->keys.dtls_sequence_number_hi; + dtls_sequence_number_lo = ssl->keys.dtls_sequence_number_lo; + ssl->keys.dtls_epoch--; + ssl->keys.dtls_sequence_number_hi = ssl->keys.dtls_prev_sequence_number_hi; + ssl->keys.dtls_sequence_number_lo = ssl->keys.dtls_prev_sequence_number_lo; + } + #endif #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMWrite) { ret = Encrypt(ssl, output + args->headerSz, @@ -16062,6 +16357,14 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, ret = Encrypt(ssl, output + args->headerSz, output + args->headerSz, args->size, asyncOkay); } + #if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) + /* Restore sequence numbers */ + if (swap_seq) { + ssl->keys.dtls_epoch = dtls_epoch; + ssl->keys.dtls_sequence_number_hi = dtls_sequence_number_hi; + ssl->keys.dtls_sequence_number_lo = dtls_sequence_number_lo; + } + #endif if (ret != 0) goto exit_buildmsg; ssl->options.buildMsgState = BUILD_MSG_ENCRYPTED_VERIFY_MAC; @@ -16091,7 +16394,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, ret = ssl->hmac(ssl, hmac, output + args->headerSz, args->ivSz + inSz + args->pad + 1, -1, type, - 0); + 0, epochOrder); XMEMCPY(output + args->idx + args->pad + 1, hmac, args->digestSz); @@ -16105,7 +16408,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, ret = ssl->hmac(ssl, output + args->idx + args->pad + 1, output + args->headerSz, args->ivSz + inSz + args->pad + 1, -1, type, - 0); + 0, epochOrder); } } #endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */ @@ -16127,7 +16430,7 @@ exit_buildmsg: #ifdef WOLFSSL_DTLS if (ret == 0 && ssl->options.dtls) - DtlsSEQIncrement(ssl, CUR_ORDER); + DtlsSEQIncrement(ssl, epochOrder); #endif /* return sz on success */ @@ -16212,13 +16515,13 @@ int SendFinished(WOLFSSL* ssl) #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, input, headerSz + finishedSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, input, headerSz + finishedSz, finished)) != 0) return ret; } #endif sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); if (sendSz < 0) return BUILD_MSG_ERROR; @@ -16261,6 +16564,13 @@ int SendFinished(WOLFSSL* ssl) ret = SendBuffered(ssl); +#ifdef WOLFSSL_DTLS + if (ssl->options.side == WOLFSSL_SERVER_END) { + ssl->keys.dtls_handshake_number = 0; + ssl->keys.dtls_expected_peer_handshake_number = 0; + } +#endif + WOLFSSL_LEAVE("SendFinished", ret); WOLFSSL_END(WC_FUNC_FINISHED_SEND); @@ -16409,6 +16719,14 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest, #ifndef NO_CERTS #if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH) +static int cipherExtraData(WOLFSSL* ssl) +{ + /* Cipher data that may be added by BuildMessage */ + return ssl->specs.hash_size + ssl->specs.block_size + + ssl->specs.aead_mac_size + ssl->specs.iv_size + + ssl->specs.pad_size; +} + /* handle generation of certificate (11) */ int SendCertificate(WOLFSSL* ssl) { @@ -16516,6 +16834,8 @@ int SendCertificate(WOLFSSL* ssl) #endif } + sendSz += cipherExtraData(ssl); + /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; @@ -16534,10 +16854,9 @@ int SendCertificate(WOLFSSL* ssl) else { #ifdef WOLFSSL_DTLS AddHeaders(output, payloadSz, certificate, ssl); - if (!IsEncryptionOn(ssl, 1)) - HashOutputRaw(ssl, - output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA, - HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA); + HashOutputRaw(ssl, + output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA, + HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA); /* Adding the headers increments these, decrement them for * actual message header. */ ssl->keys.dtls_handshake_number--; @@ -16548,20 +16867,20 @@ int SendCertificate(WOLFSSL* ssl) /* list total */ c32to24(listSz, output + i); - if (!IsEncryptionOn(ssl, 1)) + if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) HashOutputRaw(ssl, output + i, CERT_HEADER_SZ); i += CERT_HEADER_SZ; length -= CERT_HEADER_SZ; fragSz -= CERT_HEADER_SZ; if (certSz) { c32to24(certSz, output + i); - if (!IsEncryptionOn(ssl, 1)) + if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) HashOutputRaw(ssl, output + i, CERT_HEADER_SZ); i += CERT_HEADER_SZ; length -= CERT_HEADER_SZ; fragSz -= CERT_HEADER_SZ; - if (!IsEncryptionOn(ssl, 1)) { + if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) { HashOutputRaw(ssl, ssl->buffers.certificate->buffer, certSz); if (certChainSz) HashOutputRaw(ssl, ssl->buffers.certChain->buffer, @@ -16571,7 +16890,7 @@ int SendCertificate(WOLFSSL* ssl) } else { if (!ssl->options.dtls) { - AddRecordHeader(output, fragSz, handshake, ssl); + AddRecordHeader(output, fragSz, handshake, ssl, CUR_ORDER); } else { #ifdef WOLFSSL_DTLS @@ -16604,7 +16923,12 @@ int SendCertificate(WOLFSSL* ssl) if (IsEncryptionOn(ssl, 1)) { byte* input = NULL; - int inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */ + int inputSz = i; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; if (inputSz < 0) { WOLFSSL_MSG("Send Cert bad inputSz"); @@ -16616,32 +16940,44 @@ int SendCertificate(WOLFSSL* ssl) DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); } +#ifndef WOLFSSL_DTLS sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); +#else + if (!ssl->options.dtls) + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + handshake, 1, 0, 0, CUR_ORDER); + else /* DTLS 1.2 has to ignore fragmentation in hashing so we need to + * calculate the hash ourselves above */ { + if ((ret = DtlsMsgPoolSave(ssl, input, inputSz, certificate)) != 0) { + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + return ret; + } + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + handshake, 0, 0, 0, CUR_ORDER); + } +#endif - if (inputSz > 0) - XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) return sendSz; } else { + sendSz = i; #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate)) != 0) + return ret; + } if (ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif } - #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) - return ret; - } - #endif - #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) if (ssl->hsInfoOn) AddPacketName(ssl, "Certificate"); @@ -16724,6 +17060,9 @@ int SendCertificateRequest(WOLFSSL* ssl) i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; #endif } + + sendSz += cipherExtraData(ssl); + /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; @@ -16778,25 +17117,38 @@ int SendCertificateRequest(WOLFSSL* ssl) if (IsEncryptionOn(ssl, 1)) { byte* input; - int inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */ + int inputSz = i; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, input, inputSz, certificate_request)) != 0) { + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + return ret; + } + #endif sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) return sendSz; } else { + sendSz = i; #ifdef WOLFSSL_DTLS if (ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate_request)) != 0) return ret; } #endif @@ -16881,15 +17233,19 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, if (IsEncryptionOn(ssl, 1)) { byte* input; - int inputSz = idx - RECORD_HEADER_SZ; + int inputSz = idx; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -16905,7 +17261,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, #ifdef WOLFSSL_DTLS if (ret == 0 && IsDtlsNotSctpMode(ssl)) - ret = DtlsMsgPoolSave(ssl, output, sendSz); + ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate_status); #endif #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) @@ -17253,12 +17609,12 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) #endif if (!ssl->options.tls1_3) { sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz, - application_data, 0, 0, 1); + application_data, 0, 0, 1, CUR_ORDER); } else { #ifdef WOLFSSL_TLS13 sendSz = BuildTls13Message(ssl, out, outputSz, sendBuffer, buffSz, - application_data, 0, 0, 1); + application_data, 0, 0, 1, CUR_ORDER); #else sendSz = BUFFER_ERROR; #endif @@ -17483,11 +17839,11 @@ int SendAlert(WOLFSSL* ssl, int severity, int type) */ if (IsEncryptionOn(ssl, 1)) { sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert, - 0, 0, 0); + 0, 0, 0, CUR_ORDER); } else { - AddRecordHeader(output, ALERT_SIZE, alert, ssl); + AddRecordHeader(output, ALERT_SIZE, alert, ssl, CUR_ORDER); output += RECORD_HEADER_SZ; #ifdef WOLFSSL_DTLS if (ssl->options.dtls) @@ -19719,15 +20075,26 @@ exit_dpk: if (IsEncryptionOn(ssl, 1)) { byte* input; - int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */ + int inputSz = idx; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, input, inputSz, client_hello)) != 0) { + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + return ret; + } + #endif sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -19735,7 +20102,7 @@ exit_dpk: } else { #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, client_hello)) != 0) return ret; } if (ssl->options.dtls) @@ -20254,12 +20621,6 @@ exit_dpk: ssl->options.resuming = 0; /* server denied resumption try */ } } - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - DtlsMsgPoolReset(ssl); - } - #endif - return SetCipherSpecs(ssl); } @@ -23265,14 +23626,18 @@ int SendClientKeyExchange(WOLFSSL* ssl) idx += args->encSz; if (IsEncryptionOn(ssl, 1)) { - args->inputSz = idx - RECORD_HEADER_SZ; /* buildmsg adds rechdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + args->inputSz = idx - recordHeaderSz; /* buildmsg adds rechdr */ args->input = (byte*)XMALLOC(args->inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (args->input == NULL) { ERROR_OUT(MEMORY_E, exit_scke); } - XMEMCPY(args->input, args->output + RECORD_HEADER_SZ, + XMEMCPY(args->input, args->output + recordHeaderSz, args->inputSz); } @@ -23284,8 +23649,14 @@ int SendClientKeyExchange(WOLFSSL* ssl) case TLS_ASYNC_END: { if (IsEncryptionOn(ssl, 1)) { + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, client_key_exchange)) != 0) { + goto exit_scke; + } + #endif ret = BuildMessage(ssl, args->output, args->sendSz, - args->input, args->inputSz, handshake, 1, 0, 0); + args->input, args->inputSz, handshake, 1, 0, 0, CUR_ORDER); XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); args->input = NULL; /* make sure its not double free'd on cleanup */ @@ -23296,6 +23667,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) } else { #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz, client_key_exchange)) != 0) { + goto exit_scke; + } + } if (ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif @@ -23306,14 +23682,6 @@ int SendClientKeyExchange(WOLFSSL* ssl) goto exit_scke; } - #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz)) != 0) { - goto exit_scke; - } - } - #endif - #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) if (ssl->hsInfoOn) AddPacketName(ssl, "ClientKeyExchange"); @@ -23802,7 +24170,11 @@ int SendCertificateVerify(WOLFSSL* ssl) #endif if (IsEncryptionOn(ssl, 1)) { - args->inputSz = args->sendSz - RECORD_HEADER_SZ; + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + args->inputSz = args->sendSz - recordHeaderSz; /* build msg adds rec hdr */ args->input = (byte*)XMALLOC(args->inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); @@ -23810,7 +24182,7 @@ int SendCertificateVerify(WOLFSSL* ssl) ERROR_OUT(MEMORY_E, exit_scv); } - XMEMCPY(args->input, args->output + RECORD_HEADER_SZ, + XMEMCPY(args->input, args->output + recordHeaderSz, args->inputSz); } @@ -23822,10 +24194,16 @@ int SendCertificateVerify(WOLFSSL* ssl) case TLS_ASYNC_END: { if (IsEncryptionOn(ssl, 1)) { + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, certificate_verify)) != 0) { + goto exit_scv; + } + #endif ret = BuildMessage(ssl, args->output, MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA, args->input, args->inputSz, handshake, - 1, 0, 1); + 1, 0, 1, CUR_ORDER); #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) goto exit_scv; @@ -23841,6 +24219,9 @@ int SendCertificateVerify(WOLFSSL* ssl) } else { #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz, certificate_verify); + } if (ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif @@ -23851,13 +24232,6 @@ int SendCertificateVerify(WOLFSSL* ssl) goto exit_scv; } - #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { - ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz); - } - #endif - - #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateVerify"); @@ -24277,21 +24651,36 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1)) { byte* input; - int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */ + int inputSz = idx; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, input, inputSz, server_hello)) != 0) { + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + return ret; + } + #endif sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) return sendSz; } else { #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, server_hello)) != 0) + return ret; + } if (ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif @@ -24311,13 +24700,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.serverState = SERVER_HELLO_COMPLETE; ssl->buffers.outputBuffer.length += sendSz; - #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) - return ret; - } - #endif - if (ssl->options.groupMessages) ret = 0; else @@ -25830,7 +26212,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1)) { args->inputSz = args->length + HANDSHAKE_HEADER_SZ; - /* buildmsg adds rechdr */ + if (ssl->options.dtls) + args->inputSz += DTLS_HANDSHAKE_EXTRA; args->input = (byte*)XMALLOC(args->inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (args->input == NULL) { @@ -25841,10 +26224,22 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_sske); } - XMEMCPY(args->input, args->output + RECORD_HEADER_SZ, + if (!ssl->options.dtls) + XMEMCPY(args->input, args->output + RECORD_HEADER_SZ, args->inputSz); + else + XMEMCPY(args->input, args->output + DTLS_RECORD_HEADER_SZ, + args->inputSz); + + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, server_key_exchange)) + != 0) { + goto exit_sske; + } + #endif ret = BuildMessage(ssl, args->output, args->sendSz, - args->input, args->inputSz, handshake, 1, 0, 0); + args->input, args->inputSz, handshake, 1, 0, 0, CUR_ORDER); XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); args->input = NULL; /* make sure its not double free'd on cleanup */ @@ -25858,7 +26253,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsMsgPoolSave(ssl, - args->output, args->sendSz)) != 0) { + args->output, args->sendSz, server_key_exchange)) != 0) { goto exit_sske; } } @@ -26490,7 +26885,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(&pv, input + i, OPAQUE16_LEN); ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" #endif /* NO_SHA && NO_SHA256 */ @@ -26640,7 +27035,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* random */ XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); if (ret != 0) return ret; } @@ -26673,7 +27068,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->arrays->sessionID, input + i, b); #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); if (ret != 0) return ret; } @@ -26758,7 +27153,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, clSuites.suiteSz + OPAQUE16_LEN); @@ -26784,33 +27179,35 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - byte newCookie[MAX_COOKIE_LEN]; + if (!IsInitialRenegotiationState(ssl)) { + byte newCookie[MAX_COOKIE_LEN]; - ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); - if (ret != 0) return ret; - ret = wc_HmacFinal(&cookieHmac, newCookie); - if (ret != 0) return ret; + ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); + if (ret != 0) return ret; + ret = wc_HmacFinal(&cookieHmac, newCookie); + if (ret != 0) return ret; - /* If a cookie callback is set, call it to overwrite the cookie. - * This should be deprecated. The code now calculates the cookie - * using an HMAC as expected. */ - if (ssl->ctx->CBIOCookie != NULL && - ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz, - ssl->IOCB_CookieCtx) != cookieSz) { - return COOKIE_ERROR; - } + /* If a cookie callback is set, call it to overwrite the cookie. + * This should be deprecated. The code now calculates the cookie + * using an HMAC as expected. */ + if (ssl->ctx->CBIOCookie != NULL && + ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz, + ssl->IOCB_CookieCtx) != cookieSz) { + return COOKIE_ERROR; + } - /* Check the cookie, see if we progress the state machine. */ - if (peerCookieSz != cookieSz || - XMEMCMP(peerCookie, newCookie, cookieSz) != 0) { + /* Check the cookie, see if we progress the state machine. */ + if (peerCookieSz != cookieSz || + XMEMCMP(peerCookie, newCookie, cookieSz) != 0) { - /* Send newCookie to client in a HelloVerifyRequest message - * and let the state machine alone. */ - ssl->msgsReceived.got_client_hello = 0; - ssl->keys.dtls_handshake_number = 0; - ssl->keys.dtls_expected_peer_handshake_number = 0; - *inOutIdx += helloSz; - return SendHelloVerifyRequest(ssl, newCookie, cookieSz); + /* Send newCookie to client in a HelloVerifyRequest message + * and let the state machine alone. */ + ssl->msgsReceived.got_client_hello = 0; + ssl->keys.dtls_handshake_number = 0; + ssl->keys.dtls_expected_peer_handshake_number = 0; + *inOutIdx += helloSz; + return SendHelloVerifyRequest(ssl, newCookie, cookieSz); + } } /* This was skipped in the DTLS case so we could handle the hello @@ -27004,6 +27401,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, IsEncryptionOn(ssl, 0)) { ssl->secure_renegotiation->startScr = 1; } +#endif +#ifdef WOLFSSL_DTLS + if (ret == 0 && ssl->options.dtls) + DtlsMsgPoolReset(ssl); #endif WOLFSSL_LEAVE("DoClientHello", ret); WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); @@ -27454,14 +27855,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1)) { byte* input; int inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) { + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz += DTLS_HANDSHAKE_EXTRA; + } input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + (ret = DtlsMsgPoolSave(ssl, input, inputSz, server_hello_done)) != 0) { + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + return ret; + } + #endif sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -27469,7 +27883,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else { #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, server_hello_done)) != 0) return ret; } if (ssl->options.dtls) @@ -27791,15 +28205,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) { byte* input; - int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */ + int inputSz = idx; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + if (ssl->options.dtls) + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz -= recordHeaderSz; input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0); + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -27808,7 +28226,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, session_ticket)) != 0) return ret; DtlsSEQIncrement(ssl, CUR_ORDER); @@ -27850,6 +28268,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1)) sendSz += MAX_MSG_EXTRA; + if (ssl->options.dtls) + sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; @@ -27863,14 +28284,20 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsEncryptionOn(ssl, 1)) { byte* input; int inputSz = HANDSHAKE_HEADER_SZ; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) { + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz += DTLS_HANDSHAKE_EXTRA; + } input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); + XMEMCPY(input, output + recordHeaderSz, inputSz); sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 0, 0, 0); + handshake, 0, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -27900,6 +28327,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int sendSz = length + idx; int ret; + /* are we in scr */ + if (IsEncryptionOn(ssl, 1)) { + sendSz += MAX_MSG_EXTRA; + } + /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; @@ -27936,6 +28368,30 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, sendSz, WRITE_PROTO, ssl->heap); #endif + /* are we in scr */ + if (IsEncryptionOn(ssl, 1)) { + byte* input; + int inputSz = HANDSHAKE_HEADER_SZ + length; /* build msg adds rec hdr */ + int recordHeaderSz = RECORD_HEADER_SZ; + + if (ssl->options.dtls) { + recordHeaderSz += DTLS_RECORD_EXTRA; + inputSz += DTLS_HANDSHAKE_EXTRA; + } + + input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + if (input == NULL) + return MEMORY_E; + + XMEMCPY(input, output + recordHeaderSz, inputSz); + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + handshake, 0, 0, 0, CUR_ORDER); + XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); + + if (sendSz < 0) + return sendSz; + } + ssl->buffers.outputBuffer.length += sendSz; return SendBuffered(ssl); diff --git a/src/keys.c b/src/keys.c index ca6dd4de3..b620dc96d 100644 --- a/src/keys.c +++ b/src/keys.c @@ -3066,7 +3066,11 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) #ifdef HAVE_SECURE_RENEGOTIATION if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status) { keys = &ssl->secure_renegotiation->tmp_keys; - copy = 1; +#ifdef WOLFSSL_DTLS + /* For DTLS, copy is done in StoreKeys */ + if (!ssl->options.dtls) +#endif + copy = 1; } #endif /* HAVE_SECURE_RENEGOTIATION */ @@ -3141,6 +3145,15 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) ssl->heap, ssl->devId, ssl->rng, ssl->options.tls1_3); #ifdef HAVE_SECURE_RENEGOTIATION +#ifdef WOLFSSL_DTLS + if (ret == 0 && ssl->options.dtls) { + if (wc_encrypt) + wc_encrypt->src = keys == &ssl->keys ? KEYS : SCR; + if (wc_decrypt) + wc_decrypt->src = keys == &ssl->keys ? KEYS : SCR; + } +#endif + if (copy) { int clientCopy = 0; @@ -3217,11 +3230,25 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) { int sz, i = 0; Keys* keys = &ssl->keys; +#ifdef WOLFSSL_DTLS + /* In case of DTLS, ssl->keys is updated here */ + int scr_copy = 0; +#endif #ifdef HAVE_SECURE_RENEGOTIATION - if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status == - SCR_CACHE_NEEDED) { + if (ssl->options.dtls && + ssl->secure_renegotiation && + ssl->secure_renegotiation->cache_status == SCR_CACHE_NEEDED) { keys = &ssl->secure_renegotiation->tmp_keys; +#ifdef WOLFSSL_DTLS + /* epoch is incremented after StoreKeys call */ + ssl->secure_renegotiation->tmp_keys.dtls_epoch = ssl->keys.dtls_epoch + 1; + /* we only need to copy keys on second and future renegotiations */ + if (ssl->keys.dtls_epoch > 1) + scr_copy = 1; + ssl->encrypt.src = KEYS_NOT_SET; + ssl->decrypt.src = KEYS_NOT_SET; +#endif CacheStatusPP(ssl->secure_renegotiation); } #endif /* HAVE_SECURE_RENEGOTIATION */ @@ -3232,23 +3259,54 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) if (ssl->specs.cipher_type != aead) { sz = ssl->specs.hash_size; #ifndef WOLFSSL_AEAD_ONLY + + #ifdef WOLFSSL_DTLS + if (scr_copy) { + XMEMCPY(ssl->keys.client_write_MAC_secret, + keys->client_write_MAC_secret, sz); + XMEMCPY(ssl->keys.server_write_MAC_secret, + keys->server_write_MAC_secret, sz); + } + #endif XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz); XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz); #endif i += sz; } sz = ssl->specs.key_size; + #ifdef WOLFSSL_DTLS + if (scr_copy) { + XMEMCPY(ssl->keys.client_write_key, + keys->client_write_key, sz); + XMEMCPY(ssl->keys.server_write_key, + keys->server_write_key, sz); + } + #endif XMEMCPY(keys->client_write_key, &keyData[i], sz); XMEMCPY(keys->server_write_key, &keyData[i], sz); i += sz; sz = ssl->specs.iv_size; + #ifdef WOLFSSL_DTLS + if (scr_copy) { + XMEMCPY(ssl->keys.client_write_IV, + keys->client_write_IV, sz); + XMEMCPY(ssl->keys.server_write_IV, + keys->server_write_IV, sz); + } + #endif XMEMCPY(keys->client_write_IV, &keyData[i], sz); XMEMCPY(keys->server_write_IV, &keyData[i], sz); #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM/CCM explicit IV to a zero. */ + #ifdef WOLFSSL_DTLS + if (scr_copy) { + XMEMCPY(ssl->keys.aead_exp_IV, + keys->aead_exp_IV, AEAD_MAX_EXP_SZ); + } + #endif XMEMSET(keys->aead_exp_IV, 0, AEAD_MAX_EXP_SZ); } #endif /* HAVE_AEAD */ @@ -3261,12 +3319,22 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) sz = ssl->specs.hash_size; if (side & PROVISION_CLIENT) { #ifndef WOLFSSL_AEAD_ONLY + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.client_write_MAC_secret, + keys->client_write_MAC_secret, sz); + #endif XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz); #endif i += sz; } if (side & PROVISION_SERVER) { #ifndef WOLFSSL_AEAD_ONLY + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.server_write_MAC_secret, + keys->server_write_MAC_secret, sz); + #endif XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz); #endif i += sz; @@ -3274,25 +3342,51 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) } sz = ssl->specs.key_size; if (side & PROVISION_CLIENT) { + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.client_write_key, + keys->client_write_key, sz); + #endif XMEMCPY(keys->client_write_key, &keyData[i], sz); i += sz; } if (side & PROVISION_SERVER) { + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.server_write_key, + keys->server_write_key, sz); + #endif XMEMCPY(keys->server_write_key, &keyData[i], sz); i += sz; } sz = ssl->specs.iv_size; if (side & PROVISION_CLIENT) { + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.client_write_IV, + keys->client_write_IV, sz); + #endif XMEMCPY(keys->client_write_IV, &keyData[i], sz); i += sz; } - if (side & PROVISION_SERVER) + if (side & PROVISION_SERVER) { + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.server_write_IV, + keys->server_write_IV, sz); + #endif XMEMCPY(keys->server_write_IV, &keyData[i], sz); + } #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM/CCM explicit IV to a zero. */ + #ifdef WOLFSSL_DTLS + if (scr_copy) + XMEMCPY(ssl->keys.aead_exp_IV, + keys->aead_exp_IV, AEAD_MAX_EXP_SZ); + #endif XMEMSET(keys->aead_exp_IV, 0, AEAD_MAX_EXP_SZ); } #endif diff --git a/src/ssl.c b/src/ssl.c index 145be730a..b22c6efee 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1647,7 +1647,7 @@ int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz) if (inSz > maxSize) return INPUT_SIZE_E; - return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0); + return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0, CUR_ORDER); } @@ -3228,6 +3228,72 @@ int wolfSSL_UseClientSuites(WOLFSSL* ssl) return 0; } +#ifdef WOLFSSL_DTLS +const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder) +{ +#ifndef WOLFSSL_AEAD_ONLY + Keys* keys = NULL; + + (void)epochOrder; + + if (ssl == NULL) + return NULL; + +#ifdef HAVE_SECURE_RENEGOTIATION + switch (epochOrder) { + case PEER_ORDER: + if (ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && + ssl->keys.curEpoch == + ssl->secure_renegotiation->tmp_keys.dtls_epoch) + keys = &ssl->secure_renegotiation->tmp_keys; + else + keys = &ssl->keys; + break; + case PREV_ORDER: + if (ssl->keys.dtls_epoch > 1 || + (ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0)) + keys = &ssl->keys; + else { + WOLFSSL_MSG("No previous cipher epoch"); + return NULL; + } + break; + case CUR_ORDER: + if (ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && + ssl->secure_renegotiation->tmp_keys.dtls_epoch == + ssl->keys.dtls_epoch) + /* new keys are in scr and are only current when the + * ssl->keys.dtls_epoch matches */ + keys = &ssl->secure_renegotiation->tmp_keys; + else + keys = &ssl->keys; + break; + default: + WOLFSSL_MSG("Unknown epoch order"); + return NULL; + } +#else + keys = &ssl->keys; +#endif + + if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) || + (ssl->options.side == WOLFSSL_SERVER_END && verify) ) + return keys->client_write_MAC_secret; + else + return keys->server_write_MAC_secret; +#else + (void)ssl; + (void)verify; + (void)epochOrder; + + return NULL; +#endif +} +#endif /* WOLFSSL_DTLS */ + const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify) { #ifndef WOLFSSL_AEAD_ONLY diff --git a/src/tls.c b/src/tls.c index ad2effa91..18c911bfb 100644 --- a/src/tls.c +++ b/src/tls.c @@ -667,6 +667,14 @@ static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) #ifdef WOLFSSL_DTLS static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) { +#ifdef HAVE_SECURE_RENEGOTIATION + /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER + * refers to the current epoch */ + if (order == PREV_ORDER && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { + order = CUR_ORDER; + } +#endif if (order == PREV_ORDER) { /* Previous epoch case */ seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) | @@ -1169,11 +1177,12 @@ static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in, #endif int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, - int content, int verify) + int content, int verify, int epochOrder) { Hmac hmac; byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ]; int ret = 0; + const byte* macSecret = NULL; word32 hashSz = 0; if (ssl == NULL) @@ -1199,7 +1208,7 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, } #endif - wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); + wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder); #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \ !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION) if (tsip_useable(ssl)) { @@ -1219,9 +1228,19 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, if (ret != 0) return ret; + +#ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder); + else + macSecret = wolfSSL_GetMacSecret(ssl, verify); +#else + macSecret = wolfSSL_GetMacSecret(ssl, verify); +#endif ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl), - wolfSSL_GetMacSecret(ssl, verify), + macSecret, ssl->specs.hash_size); + if (ret == 0) { /* Constant time verification required. */ if (verify && padSz >= 0) { diff --git a/src/wolfio.c b/src/wolfio.c index 8c9932ff0..95bb6171f 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -318,7 +318,9 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) WOLFSSL_ENTER("EmbedReceiveFrom()"); - if (ssl->options.handShakeDone) + /* Don't use ssl->options.handShakeDone since it is true even if + * we are in the process of renegotiation */ + if (ssl->options.handShakeState == HANDSHAKE_DONE) dtls_timeout = 0; if (!wolfSSL_get_using_nonblock(ssl)) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a4af16aea..a8a1e0712 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3003,6 +3003,13 @@ enum CipherType { aead }; #define CIPHER_NONCE #endif +#if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) +enum CipherSrc { + KEYS_NOT_SET = 0, + KEYS, /* keys from ssl->keys are loaded */ + SCR /* keys from ssl->secure_renegotiation->tmp_keys are loaded */ +}; +#endif /* cipher for now */ typedef struct Ciphers { @@ -3042,6 +3049,9 @@ typedef struct Ciphers { #endif byte state; byte setup; /* have we set it up flag for detection */ +#if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) + enum CipherSrc src; +#endif } Ciphers; @@ -3177,7 +3187,7 @@ WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte); WOLFSSL_LOCAL int SetSession(WOLFSSL*, WOLFSSL_SESSION*); -typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int); +typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int, int); #ifndef NO_CLIENT_CACHE WOLFSSL_SESSION* GetSessionClient(WOLFSSL*, const byte*, int); @@ -3734,6 +3744,7 @@ typedef struct DtlsMsg { byte* msg; DtlsFrag* fragList; word32 fragSz; /* Length of fragments received */ + word16 epoch; /* Epoch that this message belongs to */ word32 seq; /* Handshake sequence number */ word32 sz; /* Length of whole message */ byte type; @@ -4355,6 +4366,10 @@ WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_3(const ProtocolVersion pv); +#if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) +WOLFSSL_LOCAL int IsInitialRenegotiationState(WOLFSSL* ssl); +#endif /* DTLS || !WOLFSSL_NO_TLS12 */ + WOLFSSL_LOCAL void FreeHandshakeResources(WOLFSSL* ssl); WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree); WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl); @@ -4451,7 +4466,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength); WOLFSSL_LOCAL int MakeTlsMasterSecret(WOLFSSL*); #ifndef WOLFSSL_AEAD_ONLY WOLFSSL_LOCAL int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, - word32 sz, int padSz, int content, int verify); + word32 sz, int padSz, int content, int verify, int epochOrder); #endif #endif @@ -4473,16 +4488,18 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength); WOLFSSL_LOCAL DtlsMsg* DtlsMsgNew(word32, void*); WOLFSSL_LOCAL void DtlsMsgDelete(DtlsMsg*, void*); WOLFSSL_LOCAL void DtlsMsgListDelete(DtlsMsg*, void*); - WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg*, word32, const byte*, byte, + WOLFSSL_LOCAL void DtlsTxMsgListClean(WOLFSSL* ssl); + WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg*, word32, word16, const byte*, byte, word32, word32, void*); - WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32); - WOLFSSL_LOCAL void DtlsMsgStore(WOLFSSL*, word32, const byte*, word32, + WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32, word32); + WOLFSSL_LOCAL void DtlsMsgStore(WOLFSSL*, word32, word32, const byte*, word32, byte, word32, word32, void*); WOLFSSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*); - WOLFSSL_LOCAL int DtlsMsgPoolSave(WOLFSSL*, const byte*, word32); + WOLFSSL_LOCAL int DtlsMsgPoolSave(WOLFSSL*, const byte*, word32, enum HandShakeType); WOLFSSL_LOCAL int DtlsMsgPoolTimeout(WOLFSSL*); WOLFSSL_LOCAL int VerifyForDtlsMsgPoolSend(WOLFSSL*, byte, word32); + WOLFSSL_LOCAL int VerifyForTxDtlsMsgDelete(WOLFSSL* ssl, DtlsMsg* head); WOLFSSL_LOCAL void DtlsMsgPoolReset(WOLFSSL*); WOLFSSL_LOCAL int DtlsMsgPoolSend(WOLFSSL*, int); #endif /* WOLFSSL_DTLS */ @@ -4587,7 +4604,7 @@ WOLFSSL_LOCAL void FreeHandshakeHashes(WOLFSSL* ssl); WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, int inSz, int type, int hashOutput, - int sizeOnly, int asyncOkay); + int sizeOnly, int asyncOkay, int epochOrder); #ifdef WOLFSSL_TLS13 int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input, diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 39d7a9911..c7a15a15a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2431,6 +2431,7 @@ WOLFSSL_API void wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl); WOLFSSL_API const unsigned char* wolfSSL_GetMacSecret(WOLFSSL*, int); +WOLFSSL_API const unsigned char* wolfSSL_GetDtlsMacSecret(WOLFSSL*, int, int); WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteKey(WOLFSSL*); WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteIV(WOLFSSL*); WOLFSSL_API const unsigned char* wolfSSL_GetServerWriteKey(WOLFSSL*); From eb910a64d001ad8f05658ec1886bbc2865a8fa12 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 19 May 2020 19:49:45 +0200 Subject: [PATCH 02/17] Comments and formatting --- src/internal.c | 114 ++++++++++++++++++++++++++++----------------- src/keys.c | 2 +- src/ssl.c | 3 ++ wolfssl/internal.h | 3 +- 4 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/internal.c b/src/internal.c index 53d1c688e..f255616a3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6904,6 +6904,9 @@ void DtlsMsgListDelete(DtlsMsg* head, void* heap) } } +/** + * Drop messages when they are no longer going to be retransmitted + */ void DtlsTxMsgListClean(WOLFSSL* ssl) { DtlsMsg* head = ssl->dtls_tx_msg_list; @@ -7149,8 +7152,13 @@ DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item) } -/* DtlsMsgPoolSave() adds the message to the end of the stored transmit list. */ -int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz, enum HandShakeType type) +/** + * DtlsMsgPoolSave() adds the message to the end of the stored transmit + * list. Must be called BEFORE BuildMessage or DtlsSEQIncrement or + * anything else that increments ssl->keys.dtls_handshake_number. + */ +int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz, + enum HandShakeType type) { DtlsMsg* item; int ret = 0; @@ -7170,8 +7178,7 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz, enum HandShak XMEMCPY(item->buf, data, dataSz); item->sz = dataSz; item->epoch = ssl->keys.dtls_epoch; - /* save is called after something incremented this var */ - item->seq = ssl->keys.dtls_handshake_number - 1; + item->seq = ssl->keys.dtls_handshake_number; item->type = type; if (cur == NULL) @@ -7251,7 +7258,9 @@ int VerifyForTxDtlsMsgDelete(WOLFSSL* ssl, DtlsMsg* item) case WOLFSSL_SERVER_END: if (ssl->options.clientState >= CLIENT_FINISHED_COMPLETE && item->type <= server_hello_done) - return 1; + return 1; /* server can forget everything up to ServerHelloDone if + * a client finished message has been received and + * successfully processed */ else return 0; default: @@ -7324,7 +7333,6 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) sendSz = inputSz + MAX_MSG_EXTRA; #ifdef HAVE_SECURE_RENEGOTIATION - /* * CUR_ORDER will use ssl->secure_renegotiation from epoch 2+. * ssl->keys otherwise @@ -13132,7 +13140,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (type == finished && ssl->keys.dtls_peer_handshake_number >= ssl->keys.dtls_expected_peer_handshake_number && ssl->keys.curEpoch == ssl->keys.dtls_epoch) { - /* finished msg should be ignore if it is in the current epoch + /* finished msg should be ignore from the current epoch * if it comes from a previous handshake */ if (ssl->options.side == WOLFSSL_CLIENT_END) { ignoreFinished = ssl->options.connectState < FINISHED_DONE; @@ -13153,7 +13161,10 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, */ if (ssl->keys.dtls_peer_handshake_number > ssl->keys.dtls_expected_peer_handshake_number && - (type == client_hello || ssl->options.handShakeState != HANDSHAKE_DONE) && + /* Only client_hello shouldn't be ignored if the handshake + * num is greater */ + (type == client_hello || + ssl->options.handShakeState != HANDSHAKE_DONE) && !ignoreFinished) { /* Current message is out of order. It will get stored in the list. * Storing also takes care of defragmentation. If the messages is a @@ -13201,6 +13212,8 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } else if (ssl->keys.dtls_peer_handshake_number < ssl->keys.dtls_expected_peer_handshake_number || + /* ignore all handshake messages if we are done with the + * handshake */ (ssl->keys.dtls_peer_handshake_number > ssl->keys.dtls_expected_peer_handshake_number && ssl->options.handShakeState == HANDSHAKE_DONE) || @@ -14060,17 +14073,19 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) if (ssl->options.dtls && ssl->secure_renegotiation && ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { - if (ssl->keys.curEpoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) - XMEMCPY(ssl->decrypt.nonce, ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); + if (ssl->keys.curEpoch == + ssl->secure_renegotiation->tmp_keys.dtls_epoch) + XMEMCPY(ssl->decrypt.nonce, + ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); else XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } else #endif XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); if ((ret = aes_auth_fn(ssl->decrypt.aes, @@ -14197,17 +14212,22 @@ static WC_INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) if (ssl->options.dtls && ssl->secure_renegotiation && ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { - if (ssl->keys.curEpoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) { + /* For epochs >1 the current cipher parameters are located in + * ssl->secure_renegotiation->tmp_keys. Previous cipher + * parameters and for epoch 1 use ssl->keys */ + if (ssl->keys.curEpoch == + ssl->secure_renegotiation->tmp_keys.dtls_epoch) { if (ssl->decrypt.src != SCR) { - ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED; + ssl->secure_renegotiation->cache_status = + SCR_CACHE_NEEDED; if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0) break; } - WOLFSSL_BUFFER(ssl->secure_renegotiation->tmp_keys.client_write_key, MAX_SYM_KEY_SIZE); } else { if (ssl->decrypt.src != KEYS) { - ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; + ssl->secure_renegotiation->cache_status = + SCR_CACHE_NULL; if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0) break; } @@ -15685,9 +15705,9 @@ int SendChangeCipher(WOLFSSL* ssl) #ifdef WOLFSSL_DTLS else { if (IsDtlsNotSctpMode(ssl)) { - DtlsSEQIncrement(ssl, CUR_ORDER); if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, change_cipher_hs)) != 0) return ret; + DtlsSEQIncrement(ssl, CUR_ORDER); } } #endif @@ -16087,35 +16107,42 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) if (ssl->options.dtls && ssl->secure_renegotiation && ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + /* For epochs >1 the current cipher parameters are located in + * ssl->secure_renegotiation->tmp_keys. Previous cipher + * parameters and for epoch 1 use ssl->keys */ switch (epochOrder) { case PREV_ORDER: if (ssl->encrypt.src != KEYS) { - ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; + ssl->secure_renegotiation->cache_status = + SCR_CACHE_NULL; if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) ERROR_OUT(ret, exit_buildmsg); - WOLFSSL_BUFFER(ssl->keys.client_write_key, MAX_SYM_KEY_SIZE); } break; case CUR_ORDER: - if (ssl->keys.dtls_epoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) { + if (ssl->keys.dtls_epoch == + ssl->secure_renegotiation->tmp_keys.dtls_epoch) { if (ssl->encrypt.src != SCR) { - ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED; - if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) + ssl->secure_renegotiation->cache_status = + SCR_CACHE_NEEDED; + if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) + != 0) ERROR_OUT(ret, exit_buildmsg); - WOLFSSL_BUFFER(ssl->secure_renegotiation->tmp_keys.client_write_key, MAX_SYM_KEY_SIZE); } } else { if (ssl->encrypt.src != KEYS) { - ssl->secure_renegotiation->cache_status = SCR_CACHE_NULL; - if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) + ssl->secure_renegotiation->cache_status = + SCR_CACHE_NULL; + if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) + != 0) ERROR_OUT(ret, exit_buildmsg); - WOLFSSL_BUFFER(ssl->keys.client_write_key, MAX_SYM_KEY_SIZE); } } break; default: - WOLFSSL_MSG("BuildMessage only supports PREV_ORDER and CUR_ORDER"); + WOLFSSL_MSG("BuildMessage only supports PREV_ORDER and " + "CUR_ORDER"); ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg); } } @@ -16326,8 +16353,8 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, case BUILD_MSG_ENCRYPT: { #if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) - /* Modify CUR_ORDER sequence number for all encryption algos - * that use it for encryption parameters */ + /* If we want the PREV_ORDER then modify CUR_ORDER sequence number + * for all encryption algos that use it for encryption parameters */ word16 dtls_epoch; word16 dtls_sequence_number_hi; word32 dtls_sequence_number_lo; @@ -16341,8 +16368,10 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, dtls_sequence_number_hi = ssl->keys.dtls_sequence_number_hi; dtls_sequence_number_lo = ssl->keys.dtls_sequence_number_lo; ssl->keys.dtls_epoch--; - ssl->keys.dtls_sequence_number_hi = ssl->keys.dtls_prev_sequence_number_hi; - ssl->keys.dtls_sequence_number_lo = ssl->keys.dtls_prev_sequence_number_lo; + ssl->keys.dtls_sequence_number_hi = + ssl->keys.dtls_prev_sequence_number_hi; + ssl->keys.dtls_sequence_number_lo = + ssl->keys.dtls_prev_sequence_number_lo; } #endif #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) @@ -17145,12 +17174,12 @@ int SendCertificateRequest(WOLFSSL* ssl) } else { sendSz = i; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - DtlsSEQIncrement(ssl, CUR_ORDER); if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate_request)) != 0) return ret; } + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) @@ -17244,8 +17273,10 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, return MEMORY_E; XMEMCPY(input, output + recordHeaderSz, inputSz); - sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, - handshake, 1, 0, 0, CUR_ORDER); + ret = DtlsMsgPoolSave(ssl, input, inputSz, certificate_status); + if (ret == 0) + sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, + handshake, 1, 0, 0, CUR_ORDER); XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER); if (sendSz < 0) @@ -17253,17 +17284,14 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, } else { #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) + if (ret == 0 && IsDtlsNotSctpMode(ssl)) + ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate_status); + if (ret == 0 && ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); } - #ifdef WOLFSSL_DTLS - if (ret == 0 && IsDtlsNotSctpMode(ssl)) - ret = DtlsMsgPoolSave(ssl, output, sendSz, certificate_status); - #endif - #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) if (ret == 0 && ssl->hsInfoOn) AddPacketName(ssl, "CertificateStatus"); @@ -17614,7 +17642,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) else { #ifdef WOLFSSL_TLS13 sendSz = BuildTls13Message(ssl, out, outputSz, sendBuffer, buffSz, - application_data, 0, 0, 1, CUR_ORDER); + application_data, 0, 0, 1); #else sendSz = BUFFER_ERROR; #endif diff --git a/src/keys.c b/src/keys.c index b620dc96d..0545d6507 100644 --- a/src/keys.c +++ b/src/keys.c @@ -3241,7 +3241,7 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) ssl->secure_renegotiation->cache_status == SCR_CACHE_NEEDED) { keys = &ssl->secure_renegotiation->tmp_keys; #ifdef WOLFSSL_DTLS - /* epoch is incremented after StoreKeys call */ + /* epoch is incremented after StoreKeys is called */ ssl->secure_renegotiation->tmp_keys.dtls_epoch = ssl->keys.dtls_epoch + 1; /* we only need to copy keys on second and future renegotiations */ if (ssl->keys.dtls_epoch > 1) diff --git a/src/ssl.c b/src/ssl.c index b22c6efee..371f19070 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3240,6 +3240,9 @@ const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder) return NULL; #ifdef HAVE_SECURE_RENEGOTIATION + /* ssl->keys contains the current cipher parameters only for epoch 1. For + * epochs >1 ssl->secure_renegotiation->tmp_keys contains the current + * cipher parameters */ switch (epochOrder) { case PEER_ORDER: if (ssl->secure_renegotiation && diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a8a1e0712..ad8250362 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3050,7 +3050,8 @@ typedef struct Ciphers { byte state; byte setup; /* have we set it up flag for detection */ #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) - enum CipherSrc src; + enum CipherSrc src; /* DTLS uses this to determine which keys + * are currently loaded */ #endif } Ciphers; From c2ca9f614ea4f905bcd7ba77138c9017d5b395b4 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 20 May 2020 10:13:53 +0200 Subject: [PATCH 03/17] Jenkins tests fixes --- src/internal.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index f255616a3..f45320e81 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15445,7 +15445,7 @@ int ProcessReply(WOLFSSL* ssl) if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) { ssl->buffers.inputBuffer.idx += ssl->keys.padSz; - ssl->curSize -= ssl->keys.padSz; + ssl->curSize -= (word16)ssl->keys.padSz; #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead && ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) @@ -17273,7 +17273,9 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, return MEMORY_E; XMEMCPY(input, output + recordHeaderSz, inputSz); - ret = DtlsMsgPoolSave(ssl, input, inputSz, certificate_status); + #ifdef WOLFSSL_DTLS + ret = DtlsMsgPoolSave(ssl, input, inputSz, certificate_status); + #endif if (ret == 0) sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, handshake, 1, 0, 0, CUR_ORDER); @@ -24250,10 +24252,11 @@ int SendCertificateVerify(WOLFSSL* ssl) if (IsDtlsNotSctpMode(ssl)) { ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz, certificate_verify); } - if (ssl->options.dtls) + if (ret == 0 && ssl->options.dtls) DtlsSEQIncrement(ssl, CUR_ORDER); #endif - ret = HashOutput(ssl, args->output, args->sendSz, 0); + if (ret == 0) + ret = HashOutput(ssl, args->output, args->sendSz, 0); } if (ret != 0) { From d2542dcf386e79441f0475b274fb573ecf92559b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 21 May 2020 13:39:17 +0200 Subject: [PATCH 04/17] Restore StoreKeys functionality for TLS case --- src/keys.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/keys.c b/src/keys.c index 0545d6507..2c7bfae69 100644 --- a/src/keys.c +++ b/src/keys.c @@ -3236,18 +3236,19 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side) #endif #ifdef HAVE_SECURE_RENEGOTIATION - if (ssl->options.dtls && - ssl->secure_renegotiation && + if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status == SCR_CACHE_NEEDED) { keys = &ssl->secure_renegotiation->tmp_keys; #ifdef WOLFSSL_DTLS - /* epoch is incremented after StoreKeys is called */ - ssl->secure_renegotiation->tmp_keys.dtls_epoch = ssl->keys.dtls_epoch + 1; - /* we only need to copy keys on second and future renegotiations */ - if (ssl->keys.dtls_epoch > 1) - scr_copy = 1; - ssl->encrypt.src = KEYS_NOT_SET; - ssl->decrypt.src = KEYS_NOT_SET; + if (ssl->options.dtls) { + /* epoch is incremented after StoreKeys is called */ + ssl->secure_renegotiation->tmp_keys.dtls_epoch = ssl->keys.dtls_epoch + 1; + /* we only need to copy keys on second and future renegotiations */ + if (ssl->keys.dtls_epoch > 1) + scr_copy = 1; + ssl->encrypt.src = KEYS_NOT_SET; + ssl->decrypt.src = KEYS_NOT_SET; + } #endif CacheStatusPP(ssl->secure_renegotiation); } From 4e60e4b3b7e54fe3454e8bbd3a6cdc151282f881 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 25 May 2020 23:35:42 +0200 Subject: [PATCH 05/17] DTLS Message Grouping Flush output buffer when we suspect that the grouped messages may exceed MTU. --- src/internal.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index f45320e81..05255612f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7317,10 +7317,11 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) return ret; } - XMEMCPY(ssl->buffers.outputBuffer.buffer, + XMEMCPY(ssl->buffers.outputBuffer.buffer + + ssl->buffers.outputBuffer.idx + + ssl->buffers.outputBuffer.length, pool->buf, pool->sz); - ssl->buffers.outputBuffer.idx = 0; - ssl->buffers.outputBuffer.length = pool->sz; + ssl->buffers.outputBuffer.length += pool->sz; } else { /* Handle sending packets from previous epoch */ @@ -7377,11 +7378,9 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) ssl->buffers.outputBuffer.length += sendSz; } - ret = SendBuffered(ssl); - if (ret < 0) { - WOLFSSL_ERROR(ret); - return ret; - } + + if (!ssl->options.groupMessages) + ret = SendBuffered(ssl); /** * on server side, retransmission is being triggered only by sending @@ -7392,14 +7391,15 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) * be enough to do the trick. */ if (sendOnlyFirstPacket && - ssl->options.side == WOLFSSL_SERVER_END) { - + ssl->options.side == WOLFSSL_SERVER_END) pool = NULL; - } else pool = pool->next; ssl->dtls_tx_msg = pool; } + + if (ret == 0 && ssl->options.groupMessages) + ret = SendBuffered(ssl); } WOLFSSL_LEAVE("DtlsMsgPoolSend()", ret); @@ -8339,7 +8339,10 @@ int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength) } -/* check available size into output buffer, make room if needed */ +/* Check available size into output buffer, make room if needed. + * This function needs to be called before anything gets put + * into the output buffers since it flushes pending data if it + * predicts that the msg will exceed MTU. */ int CheckAvailableSize(WOLFSSL *ssl, int size) { if (size < 0) { @@ -8347,6 +8350,18 @@ int CheckAvailableSize(WOLFSSL *ssl, int size) return BAD_FUNC_ARG; } +#ifdef WOLFSSL_DTLS + if (size + ssl->buffers.outputBuffer.length - ssl->buffers.outputBuffer.idx + > ssl->dtls_expected_rx) { + int ret; + WOLFSSL_MSG("CheckAvailableSize() flushing buffer " + "to make room for new message"); + if ((ret = SendBuffered(ssl)) != 0) { + return ret; + } + } +#endif + if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length < (word32)size) { if (GrowOutputBuffer(ssl, size) < 0) From d88f6f115680b1ab5456f93efd18d882bd21737c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 26 May 2020 14:38:31 +0200 Subject: [PATCH 06/17] DTLS test cases --- src/internal.c | 15 +- tests/suites.c | 28 + tests/test-dtls-group.conf | 1045 +++++++++++++++++++++++++++++ tests/test-dtls-reneg-client.conf | 1045 +++++++++++++++++++++++++++++ tests/test-dtls-reneg-server.conf | 1045 +++++++++++++++++++++++++++++ 5 files changed, 3173 insertions(+), 5 deletions(-) create mode 100644 tests/test-dtls-group.conf create mode 100644 tests/test-dtls-reneg-client.conf create mode 100644 tests/test-dtls-reneg-server.conf diff --git a/src/internal.c b/src/internal.c index 05255612f..e8aa7835f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15459,15 +15459,20 @@ int ProcessReply(WOLFSSL* ssl) } if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) { - ssl->buffers.inputBuffer.idx += ssl->keys.padSz; - ssl->curSize -= (word16)ssl->keys.padSz; #ifdef HAVE_AEAD - if (ssl->specs.cipher_type == aead && - ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - ssl->curSize -= AESGCM_EXP_IV_SZ; + if (ssl->specs.cipher_type == aead) { + if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) + ssl->curSize -= AESGCM_EXP_IV_SZ; + ssl->buffers.inputBuffer.idx += ssl->specs.aead_mac_size; + ssl->curSize -= ssl->specs.aead_mac_size; + } else #endif + { + ssl->buffers.inputBuffer.idx += ssl->keys.padSz; + ssl->curSize -= (word16)ssl->keys.padSz; ssl->curSize -= ssl->specs.iv_size; + } #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { diff --git a/tests/suites.c b/tests/suites.c index 1e5bcd8d3..75c277b6e 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -822,6 +822,34 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + /* add dtls grouping suites */ + strcpy(argv0[1], "tests/test-dtls-group.conf"); + printf("starting dtls message grouping tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } +#ifdef HAVE_SECURE_RENEGOTIATION + /* add dtls renegotiation tests */ + strcpy(argv0[1], "tests/test-dtls-reneg-client.conf"); + printf("starting dtls secure renegotiation client tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } + strcpy(argv0[1], "tests/test-dtls-reneg-server.conf"); + printf("starting dtls secure renegotiation server tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } +#endif #ifdef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES /* add dtls extra suites */ strcpy(argv0[1], "tests/test-dtls-sha2.conf"); diff --git a/tests/test-dtls-group.conf b/tests/test-dtls-group.conf new file mode 100644 index 000000000..8722f7b1e --- /dev/null +++ b/tests/test-dtls-group.conf @@ -0,0 +1,1045 @@ +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-u +-f +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# client TLSv1.2 PSK-CHACHA20-POLY1305 +-u +-f +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-u +-f +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1 IDEA-CBC-SHA +-u +-f +-v 2 +-l IDEA-CBC-SHA + +# client DTLSv1 IDEA-CBC-SHA +-u +-f +-v 2 +-l IDEA-CBC-SHA + +# server DTLSv1 DES-CBC3-SHA +-u +-f +-v 2 +-l DES-CBC3-SHA + +# client DTLSv1 DES-CBC3-SHA +-u +-f +-v 2 +-l DES-CBC3-SHA + +# server DTLSv1.2 DES-CBC3-SHA +-u +-f +-v 3 +-l DES-CBC3-SHA + +# client DTLSv1.2 DES-CBC3-SHA +-u +-f +-v 3 +-l DES-CBC3-SHA + +# server DTLSv1 AES128-SHA +-u +-f +-v 2 +-l AES128-SHA + +# client DTLSv1 AES128-SHA +-u +-f +-v 2 +-l AES128-SHA + +# server DTLSv1.2 AES128-SHA +-u +-f +-v 3 +-l AES128-SHA + +# client DTLSv1.2 AES128-SHA +-u +-f +-v 3 +-l AES128-SHA + +# server DTLSv1 AES256-SHA +-u +-f +-v 2 +-l AES256-SHA + +# client DTLSv1 AES256-SHA +-u +-f +-v 2 +-l AES256-SHA + +# server DTLSv1.2 AES256-SHA +-u +-f +-v 3 +-l AES256-SHA + +# client DTLSv1.2 AES256-SHA +-u +-f +-v 3 +-l AES256-SHA + +# server DTLSv1.2 AES128-SHA256 +-u +-f +-v 3 +-l AES128-SHA256 + +# client DTLSv1.2 AES128-SHA256 +-u +-f +-v 3 +-l AES128-SHA256 + +# server DTLSv1.2 AES256-SHA256 +-u +-f +-v 3 +-l AES256-SHA256 + +# client DTLSv1.2 AES256-SHA256 +-u +-f +-v 3 +-l AES256-SHA256 + +# server DTLSv1.1 ECDHE-RSA-DES3 +-u +-f +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.1 ECDHE-RSA-DES3 +-u +-f +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDHE-RSA-AES128 +-u +-f +-v 2 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.1 ECDHE-RSA-AES128 +-u +-f +-v 2 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.1 ECDHE-RSA-AES256 +-u +-f +-v 2 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.1 ECDHE-RSA-AES256 +-u +-f +-v 2 +-l ECDHE-RSA-AES256-SHA + +# server DTLSv1.2 ECDHE-RSA-DES3 +-u +-f +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.2 ECDHE-RSA-DES3 +-u +-f +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.2 ECDHE-RSA-AES128 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.2 ECDHE-RSA-AES256 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-SHA + +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-u +-f +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-DES3 +-u +-f +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-DES3 +-u +-f +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES128 +-u +-f +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES128 +-u +-f +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES256 +-u +-f +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES256 +-u +-f +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-DES3 +-u +-f +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-DES3 +-u +-f +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-RSA-DES3 +-u +-f +-v 2 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-DES3 +-u +-f +-v 2 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDH-RSA-AES128 +-u +-f +-v 2 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES128 +-u +-f +-v 2 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.1 ECDH-RSA-AES256 +-u +-f +-v 2 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES256 +-u +-f +-v 2 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.2 ECDH-RSA-DES3 +-u +-f +-v 3 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-DES3 +-u +-f +-v 3 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDH-RSA-AES128 +-u +-f +-v 3 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128 +-u +-f +-v 3 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.2 ECDH-RSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDH-RSA-AES128-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDH-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256 +-u +-f +-v 3 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256 +-u +-f +-v 3 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.1 ECDH-ECDSA-DES3 +-u +-f +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-DES3 +-u +-f +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES128 +-u +-f +-v 2 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES128 +-u +-f +-v 2 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES256 +-u +-f +-v 2 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES256 +-u +-f +-v 2 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-DES3 +-u +-f +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-DES3 +-u +-f +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-RSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDH-RSA-AES256-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDH-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-PSK-AES128-SHA256 +-s +-u +-f +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1.2 ECDHE-PSK-AES128-SHA256 +-s +-u +-f +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-u +-f +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-u +-f +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# server DTLSv1 PSK-AES128 +-s +-u +-f +-v 2 +-l PSK-AES128-CBC-SHA + +# client DTLSv1 PSK-AES128 +-s +-u +-f +-v 2 +-l PSK-AES128-CBC-SHA + +# server DTLSv1 PSK-AES256 +-s +-u +-f +-v 2 +-l PSK-AES256-CBC-SHA + +# client DTLSv1 PSK-AES256 +-s +-u +-f +-v 2 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128 +-s +-u +-f +-v 3 +-l PSK-AES128-CBC-SHA + +# client DTLSv1.2 PSK-AES128 +-s +-u +-f +-v 3 +-l PSK-AES128-CBC-SHA + +# server DTLSv1.2 PSK-AES256 +-s +-u +-f +-v 3 +-l PSK-AES256-CBC-SHA + +# client DTLSv1.2 PSK-AES256 +-s +-u +-f +-v 3 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128-SHA256 +-s +-u +-f +-v 3 +-l PSK-AES128-CBC-SHA256 + +# client DTLSv1.2 PSK-AES128-SHA256 +-s +-u +-f +-v 3 +-l PSK-AES128-CBC-SHA256 + +# server DTLSv1.2 PSK-AES256-SHA384 +-s +-u +-f +-v 3 +-l PSK-AES256-CBC-SHA384 + +# client DTLSv1.2 PSK-AES256-SHA384 +-s +-u +-f +-v 3 +-l PSK-AES256-CBC-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-u +-f +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-u +-f +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 PSK-AES128-GCM-SHA256 +-u +-f +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# client DTLSv1.2 PSK-AES128-GCM-SHA256 +-u +-f +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# server DTLSv1.2 PSK-AES256-GCM-SHA384 +-u +-f +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# client DTLSv1.2 PSK-AES256-GCM-SHA384 +-u +-f +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-u +-f +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ADH-AES128-SHA +-u +-f +-a +-v 3 +-l ADH-AES128-SHA + +# client DTLSv1.2 ADH-AES128-SHA +-u +-f +-a +-v 3 +-l ADH-AES128-SHA + +# server DTLSv1.0 ADH-AES128-SHA +-u +-f +-a +-v 2 +-l ADH-AES128-SHA + +# client DTLSv1.0 ADH-AES128-SHA +-u +-f +-a +-v 2 +-l ADH-AES128-SHA diff --git a/tests/test-dtls-reneg-client.conf b/tests/test-dtls-reneg-client.conf new file mode 100644 index 000000000..bb405c16d --- /dev/null +++ b/tests/test-dtls-reneg-client.conf @@ -0,0 +1,1045 @@ +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-M +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-i +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-M +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-i +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-M +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-i +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-M +-u +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-i +-u +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-M +-u +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-i +-u +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 PSK-CHACHA20-POLY1305 +-M +-u +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# client TLSv1.2 PSK-CHACHA20-POLY1305 +-i +-u +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-M +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-i +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-M +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-i +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-M +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-i +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1 IDEA-CBC-SHA +-M +-u +-v 2 +-l IDEA-CBC-SHA + +# client DTLSv1 IDEA-CBC-SHA +-i +-u +-v 2 +-l IDEA-CBC-SHA + +# server DTLSv1 DES-CBC3-SHA +-M +-u +-v 2 +-l DES-CBC3-SHA + +# client DTLSv1 DES-CBC3-SHA +-i +-u +-v 2 +-l DES-CBC3-SHA + +# server DTLSv1.2 DES-CBC3-SHA +-M +-u +-v 3 +-l DES-CBC3-SHA + +# client DTLSv1.2 DES-CBC3-SHA +-i +-u +-v 3 +-l DES-CBC3-SHA + +# server DTLSv1 AES128-SHA +-M +-u +-v 2 +-l AES128-SHA + +# client DTLSv1 AES128-SHA +-i +-u +-v 2 +-l AES128-SHA + +# server DTLSv1.2 AES128-SHA +-M +-u +-v 3 +-l AES128-SHA + +# client DTLSv1.2 AES128-SHA +-i +-u +-v 3 +-l AES128-SHA + +# server DTLSv1 AES256-SHA +-M +-u +-v 2 +-l AES256-SHA + +# client DTLSv1 AES256-SHA +-i +-u +-v 2 +-l AES256-SHA + +# server DTLSv1.2 AES256-SHA +-M +-u +-v 3 +-l AES256-SHA + +# client DTLSv1.2 AES256-SHA +-i +-u +-v 3 +-l AES256-SHA + +# server DTLSv1.2 AES128-SHA256 +-M +-u +-v 3 +-l AES128-SHA256 + +# client DTLSv1.2 AES128-SHA256 +-i +-u +-v 3 +-l AES128-SHA256 + +# server DTLSv1.2 AES256-SHA256 +-M +-u +-v 3 +-l AES256-SHA256 + +# client DTLSv1.2 AES256-SHA256 +-i +-u +-v 3 +-l AES256-SHA256 + +# server DTLSv1.1 ECDHE-RSA-DES3 +-M +-u +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.1 ECDHE-RSA-DES3 +-i +-u +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDHE-RSA-AES128 +-M +-u +-v 2 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.1 ECDHE-RSA-AES128 +-i +-u +-v 2 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.1 ECDHE-RSA-AES256 +-M +-u +-v 2 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.1 ECDHE-RSA-AES256 +-i +-u +-v 2 +-l ECDHE-RSA-AES256-SHA + +# server DTLSv1.2 ECDHE-RSA-DES3 +-M +-u +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.2 ECDHE-RSA-DES3 +-i +-u +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128 +-M +-u +-v 3 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.2 ECDHE-RSA-AES128 +-i +-u +-v 3 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-M +-u +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-i +-u +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256 +-M +-u +-v 3 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.2 ECDHE-RSA-AES256 +-i +-u +-v 3 +-l ECDHE-RSA-AES256-SHA + +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-M +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-i +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-M +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-i +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-M +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-i +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-DES3 +-M +-u +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-DES3 +-i +-u +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES128 +-M +-u +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES128 +-i +-u +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES256 +-M +-u +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES256 +-i +-u +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-DES3 +-M +-u +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-DES3 +-i +-u +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-RSA-DES3 +-M +-u +-v 2 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-DES3 +-i +-u +-v 2 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDH-RSA-AES128 +-M +-u +-v 2 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES128 +-i +-u +-v 2 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.1 ECDH-RSA-AES256 +-M +-u +-v 2 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES256 +-i +-u +-v 2 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.2 ECDH-RSA-DES3 +-M +-u +-v 3 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-DES3 +-i +-u +-v 3 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDH-RSA-AES128 +-M +-u +-v 3 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128 +-i +-u +-v 3 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.2 ECDH-RSA-AES128-SHA256 +-M +-u +-v 3 +-l ECDH-RSA-AES128-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-SHA256 +-i +-u +-v 3 +-l ECDH-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256 +-M +-u +-v 3 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256 +-i +-u +-v 3 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.1 ECDH-ECDSA-DES3 +-M +-u +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-DES3 +-i +-u +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES128 +-M +-u +-v 2 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES128 +-i +-u +-v 2 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES256 +-M +-u +-v 2 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES256 +-i +-u +-v 2 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-DES3 +-M +-u +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-DES3 +-i +-u +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128 +-M +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128 +-i +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-M +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-i +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256 +-M +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256 +-i +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-M +-u +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-i +-u +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-RSA-AES256-SHA384 +-M +-u +-v 3 +-l ECDH-RSA-AES256-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-SHA384 +-i +-u +-v 3 +-l ECDH-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-M +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-i +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-PSK-AES128-SHA256 +-M +-s +-u +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1.2 ECDHE-PSK-AES128-SHA256 +-i +-s +-u +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-M +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-i +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# server DTLSv1 PSK-AES128 +-M +-s +-u +-v 2 +-l PSK-AES128-CBC-SHA + +# client DTLSv1 PSK-AES128 +-i +-s +-u +-v 2 +-l PSK-AES128-CBC-SHA + +# server DTLSv1 PSK-AES256 +-M +-s +-u +-v 2 +-l PSK-AES256-CBC-SHA + +# client DTLSv1 PSK-AES256 +-i +-s +-u +-v 2 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128 +-M +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA + +# client DTLSv1.2 PSK-AES128 +-i +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA + +# server DTLSv1.2 PSK-AES256 +-M +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA + +# client DTLSv1.2 PSK-AES256 +-i +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128-SHA256 +-M +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA256 + +# client DTLSv1.2 PSK-AES128-SHA256 +-i +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA256 + +# server DTLSv1.2 PSK-AES256-SHA384 +-M +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA384 + +# client DTLSv1.2 PSK-AES256-SHA384 +-i +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-M +-u +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-i +-u +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-M +-u +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-i +-u +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-M +-u +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-i +-u +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-M +-u +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-i +-u +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-M +-u +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-i +-u +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-M +-u +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-i +-u +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 PSK-AES128-GCM-SHA256 +-M +-u +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# client DTLSv1.2 PSK-AES128-GCM-SHA256 +-i +-u +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# server DTLSv1.2 PSK-AES256-GCM-SHA384 +-M +-u +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# client DTLSv1.2 PSK-AES256-GCM-SHA384 +-i +-u +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-M +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-i +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-M +-u +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-i +-u +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ADH-AES128-SHA +-M +-u +-a +-v 3 +-l ADH-AES128-SHA + +# client DTLSv1.2 ADH-AES128-SHA +-i +-u +-a +-v 3 +-l ADH-AES128-SHA + +# server DTLSv1.0 ADH-AES128-SHA +-M +-u +-a +-v 2 +-l ADH-AES128-SHA + +# client DTLSv1.0 ADH-AES128-SHA +-i +-u +-a +-v 2 +-l ADH-AES128-SHA diff --git a/tests/test-dtls-reneg-server.conf b/tests/test-dtls-reneg-server.conf new file mode 100644 index 000000000..eba8e7917 --- /dev/null +++ b/tests/test-dtls-reneg-server.conf @@ -0,0 +1,1045 @@ +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-m +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-R +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-m +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-R +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-m +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-R +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-m +-u +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-R +-u +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-m +-u +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-R +-u +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 PSK-CHACHA20-POLY1305 +-m +-u +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# client TLSv1.2 PSK-CHACHA20-POLY1305 +-R +-u +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-m +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-R +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-m +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-R +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-m +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-R +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1 IDEA-CBC-SHA +-m +-u +-v 2 +-l IDEA-CBC-SHA + +# client DTLSv1 IDEA-CBC-SHA +-R +-u +-v 2 +-l IDEA-CBC-SHA + +# server DTLSv1 DES-CBC3-SHA +-m +-u +-v 2 +-l DES-CBC3-SHA + +# client DTLSv1 DES-CBC3-SHA +-R +-u +-v 2 +-l DES-CBC3-SHA + +# server DTLSv1.2 DES-CBC3-SHA +-m +-u +-v 3 +-l DES-CBC3-SHA + +# client DTLSv1.2 DES-CBC3-SHA +-R +-u +-v 3 +-l DES-CBC3-SHA + +# server DTLSv1 AES128-SHA +-m +-u +-v 2 +-l AES128-SHA + +# client DTLSv1 AES128-SHA +-R +-u +-v 2 +-l AES128-SHA + +# server DTLSv1.2 AES128-SHA +-m +-u +-v 3 +-l AES128-SHA + +# client DTLSv1.2 AES128-SHA +-R +-u +-v 3 +-l AES128-SHA + +# server DTLSv1 AES256-SHA +-m +-u +-v 2 +-l AES256-SHA + +# client DTLSv1 AES256-SHA +-R +-u +-v 2 +-l AES256-SHA + +# server DTLSv1.2 AES256-SHA +-m +-u +-v 3 +-l AES256-SHA + +# client DTLSv1.2 AES256-SHA +-R +-u +-v 3 +-l AES256-SHA + +# server DTLSv1.2 AES128-SHA256 +-m +-u +-v 3 +-l AES128-SHA256 + +# client DTLSv1.2 AES128-SHA256 +-R +-u +-v 3 +-l AES128-SHA256 + +# server DTLSv1.2 AES256-SHA256 +-m +-u +-v 3 +-l AES256-SHA256 + +# client DTLSv1.2 AES256-SHA256 +-R +-u +-v 3 +-l AES256-SHA256 + +# server DTLSv1.1 ECDHE-RSA-DES3 +-m +-u +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.1 ECDHE-RSA-DES3 +-R +-u +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDHE-RSA-AES128 +-m +-u +-v 2 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.1 ECDHE-RSA-AES128 +-R +-u +-v 2 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.1 ECDHE-RSA-AES256 +-m +-u +-v 2 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.1 ECDHE-RSA-AES256 +-R +-u +-v 2 +-l ECDHE-RSA-AES256-SHA + +# server DTLSv1.2 ECDHE-RSA-DES3 +-m +-u +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.2 ECDHE-RSA-DES3 +-R +-u +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128 +-m +-u +-v 3 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.2 ECDHE-RSA-AES128 +-R +-u +-v 3 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-m +-u +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-R +-u +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256 +-m +-u +-v 3 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.2 ECDHE-RSA-AES256 +-R +-u +-v 3 +-l ECDHE-RSA-AES256-SHA + +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-m +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-R +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-m +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-R +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-m +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-R +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-DES3 +-m +-u +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-DES3 +-R +-u +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES128 +-m +-u +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES128 +-R +-u +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES256 +-m +-u +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES256 +-R +-u +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-DES3 +-m +-u +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-DES3 +-R +-u +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-RSA-DES3 +-m +-u +-v 2 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-DES3 +-R +-u +-v 2 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDH-RSA-AES128 +-m +-u +-v 2 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES128 +-R +-u +-v 2 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.1 ECDH-RSA-AES256 +-m +-u +-v 2 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES256 +-R +-u +-v 2 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.2 ECDH-RSA-DES3 +-m +-u +-v 3 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-DES3 +-R +-u +-v 3 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDH-RSA-AES128 +-m +-u +-v 3 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128 +-R +-u +-v 3 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.2 ECDH-RSA-AES128-SHA256 +-m +-u +-v 3 +-l ECDH-RSA-AES128-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-SHA256 +-R +-u +-v 3 +-l ECDH-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256 +-m +-u +-v 3 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256 +-R +-u +-v 3 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.1 ECDH-ECDSA-DES3 +-m +-u +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-DES3 +-R +-u +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES128 +-m +-u +-v 2 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES128 +-R +-u +-v 2 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.1 ECDH-ECDSA-AES256 +-m +-u +-v 2 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES256 +-R +-u +-v 2 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-DES3 +-m +-u +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-DES3 +-R +-u +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128 +-m +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128 +-R +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-m +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-R +-u +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256 +-m +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256 +-R +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-m +-u +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-R +-u +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-RSA-AES256-SHA384 +-m +-u +-v 3 +-l ECDH-RSA-AES256-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-SHA384 +-R +-u +-v 3 +-l ECDH-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-m +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-R +-u +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server TLSv1.2 ECDHE-PSK-AES128-SHA256 +-m +-s +-u +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1.2 ECDHE-PSK-AES128-SHA256 +-R +-s +-u +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-m +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-R +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# server DTLSv1 PSK-AES128 +-m +-s +-u +-v 2 +-l PSK-AES128-CBC-SHA + +# client DTLSv1 PSK-AES128 +-R +-s +-u +-v 2 +-l PSK-AES128-CBC-SHA + +# server DTLSv1 PSK-AES256 +-m +-s +-u +-v 2 +-l PSK-AES256-CBC-SHA + +# client DTLSv1 PSK-AES256 +-R +-s +-u +-v 2 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128 +-m +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA + +# client DTLSv1.2 PSK-AES128 +-R +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA + +# server DTLSv1.2 PSK-AES256 +-m +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA + +# client DTLSv1.2 PSK-AES256 +-R +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128-SHA256 +-m +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA256 + +# client DTLSv1.2 PSK-AES128-SHA256 +-R +-s +-u +-v 3 +-l PSK-AES128-CBC-SHA256 + +# server DTLSv1.2 PSK-AES256-SHA384 +-m +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA384 + +# client DTLSv1.2 PSK-AES256-SHA384 +-R +-s +-u +-v 3 +-l PSK-AES256-CBC-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-m +-u +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-R +-u +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-m +-u +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-R +-u +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-m +-u +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-R +-u +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-m +-u +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-R +-u +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-m +-u +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-R +-u +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-m +-u +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-R +-u +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 PSK-AES128-GCM-SHA256 +-m +-u +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# client DTLSv1.2 PSK-AES128-GCM-SHA256 +-R +-u +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# server DTLSv1.2 PSK-AES256-GCM-SHA384 +-m +-u +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# client DTLSv1.2 PSK-AES256-GCM-SHA384 +-R +-u +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-m +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-R +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-m +-u +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-R +-u +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-A ./certs/ca-ecc-cert.pem + +# server DTLSv1.2 ADH-AES128-SHA +-m +-u +-a +-v 3 +-l ADH-AES128-SHA + +# client DTLSv1.2 ADH-AES128-SHA +-R +-u +-a +-v 3 +-l ADH-AES128-SHA + +# server DTLSv1.0 ADH-AES128-SHA +-m +-u +-a +-v 2 +-l ADH-AES128-SHA + +# client DTLSv1.0 ADH-AES128-SHA +-R +-u +-a +-v 2 +-l ADH-AES128-SHA From a107688891ae78cbd8d269252193c0a183b5dada Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 26 May 2020 19:35:01 +0200 Subject: [PATCH 07/17] Fix asynchronous DTLS issue --- src/internal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index e8aa7835f..e68dc7dc2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -13094,7 +13094,6 @@ static int DtlsMsgDrain(WOLFSSL* ssl) } #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) { - ssl->keys.dtls_expected_peer_handshake_number--; break; } #endif From 73105305cf03079e056ffa756e499d43cae93f97 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 27 May 2020 18:08:25 +0200 Subject: [PATCH 08/17] WIP --- src/internal.c | 55 ++++++++++++++++------------------------------ src/ssl.c | 18 +++++++++++++-- tests/include.am | 3 +++ wolfssl/internal.h | 19 ++++++++++++++++ 4 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/internal.c b/src/internal.c index e68dc7dc2..08158e8f3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6197,6 +6197,7 @@ void FreeKeyExchange(WOLFSSL* ssl) ssl->async.freeArgs(ssl, ssl->async.args); ssl->async.freeArgs = NULL; } + FreeBuildMsgArgs(&ssl->async.buildArgs); #endif } @@ -8351,8 +8352,9 @@ int CheckAvailableSize(WOLFSSL *ssl, int size) } #ifdef WOLFSSL_DTLS - if (size + ssl->buffers.outputBuffer.length - ssl->buffers.outputBuffer.idx - > ssl->dtls_expected_rx) { + if (ssl->options.dtls && + size + ssl->buffers.outputBuffer.length - + ssl->buffers.outputBuffer.idx > ssl->dtls_expected_rx) { int ret; WOLFSSL_MSG("CheckAvailableSize() flushing buffer " "to make room for new message"); @@ -15340,8 +15342,8 @@ int ProcessReply(WOLFSSL* ssl) } else #endif - if (ssl->buffers.inputBuffer.length - ssl->keys.padSz - - ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ) { + if (ssl->buffers.inputBuffer.length - + ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ) { WOLFSSL_MSG("Plaintext too long"); #if defined(WOLFSSL_TLS13) || defined(WOLFSSL_EXTRA_ALERTS) SendAlert(ssl, alert_fatal, record_overflow); @@ -16021,28 +16023,12 @@ int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) } #ifndef WOLFSSL_NO_TLS12 -/* Persistable BuildMessage arguments */ -typedef struct BuildMsgArgs { - word32 digestSz; - word32 sz; - word32 pad; - word32 idx; - word32 headerSz; - word16 size; - word32 ivSz; /* TLSv1.1 IV */ - byte* iv; -} BuildMsgArgs; - -static void FreeBuildMsgArgs(WOLFSSL* ssl, void* pArgs) +void FreeBuildMsgArgs(BuildMsgArgs* args) { - BuildMsgArgs* args = (BuildMsgArgs*)pArgs; - - (void)ssl; - (void)args; - - if (args->iv) { - XFREE(args->iv, ssl->heap, DYNAMIC_TYPE_SALT); - args->iv = NULL; + if (args) { + if (args->iv) + XFREE(args->iv, ssl->heap, DYNAMIC_TYPE_SALT); + XMEMSET(args, 0, sizeof(BuildMsgArgs)); } } #endif @@ -16057,9 +16043,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, BuildMsgArgs* args; BuildMsgArgs lcl_args; #ifdef WOLFSSL_ASYNC_CRYPT - args = (BuildMsgArgs*)ssl->async.args; - typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1]; - (void)sizeof(args_test); + args = &ssl->async.buildArgs; #endif #endif @@ -16107,9 +16091,6 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, args->sz = RECORD_HEADER_SZ + inSz; args->idx = RECORD_HEADER_SZ; args->headerSz = RECORD_HEADER_SZ; - #ifdef WOLFSSL_ASYNC_CRYPT - ssl->async.freeArgs = FreeBuildMsgArgs; - #endif } switch (ssl->options.buildMsgState) { @@ -16486,10 +16467,7 @@ exit_buildmsg: ret = args->sz; /* Final cleanup */ - FreeBuildMsgArgs(ssl, args); -#ifdef WOLFSSL_ASYNC_CRYPT - ssl->async.freeArgs = NULL; -#endif + FreeBuildMsgArgs(args); return ret; #endif /* !WOLFSSL_NO_TLS12 */ @@ -16882,7 +16860,8 @@ int SendCertificate(WOLFSSL* ssl) #endif } - sendSz += cipherExtraData(ssl); + if (IsEncryptionOn(ssl, 1)) + sendSz += cipherExtraData(ssl); /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) @@ -28231,6 +28210,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; #endif } + + if (IsEncryptionOn(ssl, 1)) + sendSz += cipherExtraData(ssl); + /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; diff --git a/src/ssl.c b/src/ssl.c index 371f19070..31aa0f033 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2642,7 +2642,7 @@ int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx) /* do a secure renegotiation handshake, user forced, we discourage */ static int _Rehandshake(WOLFSSL* ssl) { - int ret; + int ret, err; if (ssl == NULL) return BAD_FUNC_ARG; @@ -2705,7 +2705,21 @@ static int _Rehandshake(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } } - ret = wolfSSL_negotiate(ssl); + + do { + err = 0; /* reset error */ + ret = wolfSSL_negotiate(ssl); + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); +#ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } +#endif + } + } while (err == WC_PENDING_E); + ssl->secure_rene_count++; return ret; } diff --git a/tests/include.am b/tests/include.am index ee4952667..df925983c 100644 --- a/tests/include.am +++ b/tests/include.am @@ -31,6 +31,9 @@ EXTRA_DIST += tests/test.conf \ tests/test-psk-no-id.conf \ tests/test-psk-no-id-sha2.conf \ tests/test-dtls.conf \ + tests/test-dtls-group.conf \ + tests/test-dtls-reneg-client.conf \ + tests/test-dtls-reneg-server.conf \ tests/test-dtls-sha2.conf \ tests/test-sctp.conf \ tests/test-sctp-sha2.conf \ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ad8250362..d5ccca491 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3815,6 +3815,20 @@ typedef struct HS_Hashes { } HS_Hashes; +#ifndef WOLFSSL_NO_TLS12 +/* Persistable BuildMessage arguments */ +typedef struct BuildMsgArgs { + word32 digestSz; + word32 sz; + word32 pad; + word32 idx; + word32 headerSz; + word16 size; + word32 ivSz; /* TLSv1.1 IV */ + byte* iv; +} BuildMsgArgs; +#endif + #ifdef WOLFSSL_ASYNC_CRYPT #define MAX_ASYNC_ARGS 18 typedef void (*FreeArgsCb)(struct WOLFSSL* ssl, void* pArgs); @@ -3823,6 +3837,7 @@ typedef struct HS_Hashes { WC_ASYNC_DEV* dev; FreeArgsCb freeArgs; /* function pointer to cleanup args */ word32 args[MAX_ASYNC_ARGS]; /* holder for current args */ + BuildMsgArgs buildArgs; /* holder for current BuildMessage args */ }; #endif @@ -4603,6 +4618,10 @@ WOLFSSL_LOCAL int SetDhExternal(WOLFSSL_DH *dh); WOLFSSL_LOCAL int InitHandshakeHashes(WOLFSSL* ssl); WOLFSSL_LOCAL void FreeHandshakeHashes(WOLFSSL* ssl); + +#ifndef WOLFSSL_NO_TLS12 +WOLFSSL_LOCAL void FreeBuildMsgArgs(BuildMsgArgs* args); +#endif WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay, int epochOrder); From 7b604ad7142586a7de50e7ec033947859b2a9345 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 28 May 2020 23:26:37 +0200 Subject: [PATCH 09/17] WIP --- examples/client/client.c | 27 +++++++++++++++++++++------ examples/server/server.c | 19 +++++++++++++++++-- src/internal.c | 38 +++++++++++++------------------------- src/ssl.c | 29 ++++++++++++----------------- wolfssl/internal.h | 4 ---- 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index afe5beabe..c667a274f 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3050,13 +3050,28 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } else { if (!resumeScr) { printf("Beginning secure rengotiation.\n"); - if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) { + if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) { err = wolfSSL_get_error(ssl, 0); - printf("err = %d, %s\n", err, - wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(ssl); ssl = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("wolfSSL_Rehandshake failed"); +#ifdef WOLFSSL_ASYNC_CRYPT + while (err == WC_PENDING_E) { + err = 0; + ret = wolfSSL_negotiate(ssl); + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + } + } +#endif + if (ret != WOLFSSL_SUCCESS) { + printf("err = %d, %s\n", err, + wolfSSL_ERR_error_string(err, buffer)); + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("wolfSSL_Rehandshake failed"); + } } else { printf("RENEGOTIATION SUCCESSFUL\n"); diff --git a/examples/server/server.c b/examples/server/server.c index 695ab6f9b..9c4c2925b 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2385,8 +2385,23 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) printf("not doing secure renegotiation on example with" " nonblocking yet\n"); } else { - if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) { - printf("not doing secure renegotiation\n"); + if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) { +#ifdef WOLFSSL_ASYNC_CRYPT + err = wolfSSL_get_error(ssl, 0); + while (err == WC_PENDING_E) { + err = 0; + ret = wolfSSL_negotiate(ssl); + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + } + } + if (ret != WOLFSSL_SUCCESS) +#endif + printf("not doing secure renegotiation\n"); } else { printf("RENEGOTIATION SUCCESSFUL\n"); diff --git a/src/internal.c b/src/internal.c index 08158e8f3..ac605d0a6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -227,20 +227,6 @@ static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) return ssl->options.dtls; #endif } - -int IsInitialRenegotiationState(WOLFSSL* ssl) -{ - if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE - #ifdef HAVE_SECURE_RENEGOTIATION - || ssl->options.acceptState == ACCEPT_BEGIN_RENEG - #endif - ) { - return 1; - } - else { - return 0; - } -} #endif /* DTLS || !WOLFSSL_NO_TLS12 */ @@ -17692,11 +17678,7 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) WOLFSSL_ENTER("ReceiveData()"); /* reset error state */ - if (ssl->error == WANT_READ - #ifdef WOLFSSL_ASYNC_CRYPT - || ssl->error == WC_PENDING_E - #endif - ) { + if (ssl->error == WANT_READ) { ssl->error = 0; } @@ -17709,11 +17691,17 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) } #endif /* WOLFSSL_DTLS */ - if (ssl->error != 0 && ssl->error != WANT_WRITE) { + if (ssl->error != 0 && ssl->error != WANT_WRITE +#ifdef WOLFSSL_ASYNC_CRYPT + && ssl->error != WC_PENDING_E +#endif + ) { WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed"); return ssl->error; } + if (ssl->error != 0) fprintf(stderr, "ignoring err %d\n", ssl->error); + #ifdef WOLFSSL_EARLY_DATA if (ssl->earlyData != no_early_data) { } @@ -26914,7 +26902,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(&pv, input + i, OPAQUE16_LEN); ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsSCR(ssl)) { #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" #endif /* NO_SHA && NO_SHA256 */ @@ -27064,7 +27052,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* random */ XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsSCR(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); if (ret != 0) return ret; } @@ -27097,7 +27085,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->arrays->sessionID, input + i, b); #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsSCR(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); if (ret != 0) return ret; } @@ -27182,7 +27170,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #ifdef WOLFSSL_DTLS - if (IsDtlsNotSctpMode(ssl) && !IsInitialRenegotiationState(ssl)) { + if (IsDtlsNotSctpMode(ssl) && !IsSCR(ssl)) { ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, clSuites.suiteSz + OPAQUE16_LEN); @@ -27208,7 +27196,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - if (!IsInitialRenegotiationState(ssl)) { + if (!IsSCR(ssl)) { byte newCookie[MAX_COOKIE_LEN]; ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); diff --git a/src/ssl.c b/src/ssl.c index 31aa0f033..8bae5976f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2642,7 +2642,7 @@ int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx) /* do a secure renegotiation handshake, user forced, we discourage */ static int _Rehandshake(WOLFSSL* ssl) { - int ret, err; + int ret; if (ssl == NULL) return BAD_FUNC_ARG; @@ -2705,22 +2705,9 @@ static int _Rehandshake(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } } - - do { - err = 0; /* reset error */ - ret = wolfSSL_negotiate(ssl); - if (ret != WOLFSSL_SUCCESS) { - err = wolfSSL_get_error(ssl, 0); -#ifdef WOLFSSL_ASYNC_CRYPT - if (err == WC_PENDING_E) { - ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); - if (ret < 0) break; - } -#endif - } - } while (err == WC_PENDING_E); - - ssl->secure_rene_count++; + ret = wolfSSL_negotiate(ssl); + if (ret == WOLFSSL_SUCCESS) + ssl->secure_rene_count++; return ret; } @@ -12177,6 +12164,14 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } #endif /* WOLFSSL_DTLS */ +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION) + /* This may be necessary in async so that we don't try to + * renegotiate again */ + if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) { + ssl->secure_renegotiation->startScr = 0; + } +#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */ + #ifdef WOLFSSL_SESSION_EXPORT if (ssl->dtls_export) { if ((ssl->error = wolfSSL_send_session(ssl)) != 0) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d5ccca491..1fdcc69d4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4382,10 +4382,6 @@ WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_3(const ProtocolVersion pv); -#if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) -WOLFSSL_LOCAL int IsInitialRenegotiationState(WOLFSSL* ssl); -#endif /* DTLS || !WOLFSSL_NO_TLS12 */ - WOLFSSL_LOCAL void FreeHandshakeResources(WOLFSSL* ssl); WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree); WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl); From a7c4d88876110b35eed6a7c9e63d8d08a4477849 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 29 May 2020 12:03:36 +0200 Subject: [PATCH 10/17] ASYNC: Working AES128-SHA --- src/internal.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index ac605d0a6..9700782c4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15155,10 +15155,17 @@ int ProcessReply(WOLFSSL* ssl) in->buffer + in->idx, in->buffer + in->idx, ssl->curSize - digestSz); - ssl->keys.padSz = - in->buffer[in->idx + ssl->curSize - digestSz - 1]; - ssl->keys.padSz += 1; - ssl->keys.decryptedCur = 1; + if (ret == 0) { + ssl->keys.padSz = + in->buffer[in->idx + ssl->curSize - + digestSz - 1]; + ssl->keys.padSz += 1; + ssl->keys.decryptedCur = 1; + } + else { + ssl->keys.padSz += 1; + ssl->keys.padSz -= 1; + } } else #endif From eb7a49a1d765f3b2834697ee533d0a2f5ad898d2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 29 May 2020 21:40:00 +0200 Subject: [PATCH 11/17] ASYNC: Working TLS SCR --- src/internal.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index 9700782c4..78685209e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15162,10 +15162,6 @@ int ProcessReply(WOLFSSL* ssl) ssl->keys.padSz += 1; ssl->keys.decryptedCur = 1; } - else { - ssl->keys.padSz += 1; - ssl->keys.padSz -= 1; - } } else #endif @@ -23855,7 +23851,10 @@ int SendCertificateVerify(WOLFSSL* ssl) WOLFSSL_ENTER("SendCertificateVerify"); #ifdef WOLFSSL_ASYNC_CRYPT - ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState); + /* BuildMessage does its own Pop */ + if (ssl->error != WC_PENDING_E || + ssl->options.asyncState != TLS_ASYNC_END) + ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState); if (ret != WC_NOT_PENDING_E) { /* Check for error */ if (ret < 0) From f2d2dadc89f69bba4651d48ecdf34a0dd3fa465e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 3 Jun 2020 13:32:24 +0200 Subject: [PATCH 12/17] ASYNC: Fix issues with TLS and DTLS --- examples/client/client.c | 27 ++++++-- src/internal.c | 140 ++++++++++++++++++++++++++++----------- src/ssl.c | 8 +++ 3 files changed, 129 insertions(+), 46 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index c667a274f..af82da6f1 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3079,13 +3079,28 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } else { printf("Beginning secure resumption.\n"); - if (wolfSSL_SecureResume(ssl) != WOLFSSL_SUCCESS) { + if ((ret = wolfSSL_SecureResume(ssl)) != WOLFSSL_SUCCESS) { err = wolfSSL_get_error(ssl, 0); - printf("err = %d, %s\n", err, - wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(ssl); ssl = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("wolfSSL_SecureResume failed"); +#ifdef WOLFSSL_ASYNC_CRYPT + while (err == WC_PENDING_E) { + err = 0; + ret = wolfSSL_negotiate(ssl); + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + } + } +#endif + if (ret != WOLFSSL_SUCCESS) { + printf("err = %d, %s\n", err, + wolfSSL_ERR_error_string(err, buffer)); + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("wolfSSL_SecureResume failed"); + } } else { printf("SECURE RESUMPTION SUCCESSFUL\n"); diff --git a/src/internal.c b/src/internal.c index 78685209e..69faa7c01 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7042,7 +7042,7 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 epoch, word32 seq) { - while (head != NULL && head->epoch == epoch && head->seq != seq) { + while (head != NULL && !(head->epoch == epoch && head->seq == seq)) { head = head->next; } return head; @@ -7111,7 +7111,8 @@ void DtlsMsgStore(WOLFSSL* ssl, word32 epoch, word32 seq, const byte* data, /* DtlsMsgInsert() is an in-order insert. */ DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item) { - if (head == NULL || item->seq < head->seq) { + if (head == NULL || (item->epoch <= head->epoch && + item->seq < head->seq)) { item->next = head; head = item; } @@ -7122,7 +7123,8 @@ DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item) DtlsMsg* cur = head->next; DtlsMsg* prev = head; while (cur) { - if (item->seq < cur->seq) { + if (item->epoch <= head->epoch && + item->seq < head->seq) { item->next = cur; prev->next = item; break; @@ -11910,10 +11912,13 @@ static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; if (IsEncryptionOn(ssl, 0)) { + /* If size == totalSz then we are in DtlsMsgDrain so no need to worry + * about padding */ #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { word32 digestSz = MacSize(ssl); - if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) + if (size != totalSz && + *inOutIdx + ssl->keys.padSz + digestSz > totalSz) return BUFFER_E; *inOutIdx += ssl->keys.padSz + digestSz; } @@ -11921,7 +11926,8 @@ static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif { /* access beyond input + size should be checked against totalSz */ - if (*inOutIdx + ssl->keys.padSz > totalSz) + if (size != totalSz && + *inOutIdx + ssl->keys.padSz > totalSz) return BUFFER_E; *inOutIdx += ssl->keys.padSz; @@ -11957,7 +11963,10 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, if (finishedSz != size) return BUFFER_ERROR; - /* check against totalSz */ + /* check against totalSz + * If size == totalSz then we are in DtlsMsgDrain so no need to worry about + * padding */ + if (size != totalSz) { #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { if (*inOutIdx + size + ssl->keys.padSz + MacSize(ssl) > totalSz) @@ -11969,6 +11978,7 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, if (*inOutIdx + size + ssl->keys.padSz > totalSz) return BUFFER_E; } + } #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName(ssl, "Finished"); @@ -12304,9 +12314,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) case change_cipher_hs: if (ssl->msgsReceived.got_change_cipher) { WOLFSSL_MSG("Duplicate ChangeCipher received"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, unexpected_message); - #endif return DUPLICATE_MSG_E; } /* DTLS is going to ignore the CCS message if the client key @@ -12641,11 +12648,14 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, } } #endif + /* If size == totalSz then we are in DtlsMsgDrain so no need to worry + * about padding */ if (IsEncryptionOn(ssl, 0)) { #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { word32 digestSz = MacSize(ssl); - if (*inOutIdx + ssl->keys.padSz + digestSz > totalSz) + if (size != totalSz && + *inOutIdx + ssl->keys.padSz + digestSz > totalSz) return BUFFER_E; *inOutIdx += ssl->keys.padSz + digestSz; } @@ -12654,9 +12664,9 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, { /* access beyond input + size should be checked against totalSz */ - if (*inOutIdx + ssl->keys.padSz > totalSz) + if (size != totalSz && + *inOutIdx + ssl->keys.padSz > totalSz) return BUFFER_E; - *inOutIdx += ssl->keys.padSz; } } @@ -13073,11 +13083,10 @@ static int DtlsMsgDrain(WOLFSSL* ssl) item->fragSz == item->sz && ret == 0) { word32 idx = 0; - /* If item is from the wrong epoch then just ignore it */ - if (ssl->keys.dtls_epoch == item->epoch && - (ret = DoHandShakeMsgType(ssl, item->msg, &idx, item->type, - item->sz, item->sz)) == 0) { - ssl->keys.dtls_expected_peer_handshake_number++; + if ((ret = DoHandShakeMsgType(ssl, item->msg, &idx, item->type, + item->sz, item->sz)) == 0) { + if (item->type != finished) + ssl->keys.dtls_expected_peer_handshake_number++; DtlsTxMsgListClean(ssl); } #ifdef WOLFSSL_ASYNC_CRYPT @@ -13107,17 +13116,6 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_ENTER("DoDtlsHandShakeMsg()"); - /* process any pending DTLS messages - this flow can happen with async */ - if (ssl->dtls_rx_msg_list != NULL) { - ret = DtlsMsgDrain(ssl); - if (ret != 0) - return ret; - - /* if done processing fragment exit with success */ - if (totalSz == *inOutIdx) - return ret; - } - /* parse header */ if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type, &size, &fragOffset, &fragSz, totalSz) != 0) { @@ -13274,7 +13272,33 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, else { /* This branch is in order next, and a complete message. On success * clean the tx list. */ +#ifdef WOLFSSL_ASYNC_CRYPT + word32 idx = *inOutIdx; +#endif WOLFSSL_MSG("Branch is in order and a complete message"); +#ifdef WOLFSSL_ASYNC_CRYPT + /* In async mode always store the message and process it with + * DtlsMsgDrain because in case of a WC_PENDING_E it will be + * easier this way. */ + if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) { + DtlsMsgStore(ssl, ssl->keys.curEpoch, + ssl->keys.dtls_peer_handshake_number, + input + idx, size, type, + fragOffset, fragSz, ssl->heap); + } + if (idx + fragSz + ssl->keys.padSz > totalSz) + return BUFFER_E; + *inOutIdx = idx + fragSz + ssl->keys.padSz; +#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + if (ssl->options.startedETMRead && ssl->keys.curEpoch != 0) { + word32 digestSz = MacSize(ssl); + if (*inOutIdx + digestSz > totalSz) + return BUFFER_E; + *inOutIdx += digestSz; + } +#endif + ret = DtlsMsgDrain(ssl); +#else ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz); if (ret == 0) { DtlsTxMsgListClean(ssl); @@ -13284,6 +13308,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = DtlsMsgDrain(ssl); } } +#endif } WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret); @@ -14876,6 +14901,17 @@ int ProcessReply(WOLFSSL* ssl) return ssl->error; } +#ifdef WOLFSSL_ASYNC_CRYPT + /* process any pending DTLS messages - this flow can happen with async */ + if (ssl->dtls_rx_msg_list != NULL) { + ret = DtlsMsgDrain(ssl); + if (ret != 0) { + WOLFSSL_ERROR(ret); + return ret; + } + } +#endif + for (;;) { switch (ssl->options.processReply) { @@ -15319,9 +15355,15 @@ int ProcessReply(WOLFSSL* ssl) #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (IsEncryptionOn(ssl, 0) && ssl->options.startedETMRead) { - if (ssl->buffers.inputBuffer.length - ssl->keys.padSz - - ssl->buffers.inputBuffer.idx - - MacSize(ssl) > MAX_PLAINTEXT_SZ) { + if ((ssl->buffers.inputBuffer.length - + ssl->keys.padSz - + MacSize(ssl) - + ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ) +#ifdef WOLFSSL_ASYNC_CRYPT + && ssl->buffers.inputBuffer.length != + ssl->buffers.inputBuffer.idx +#endif + ) { WOLFSSL_MSG("Plaintext too long - Encrypt-Then-MAC"); #if defined(WOLFSSL_EXTRA_ALERTS) SendAlert(ssl, alert_fatal, record_overflow); @@ -15332,7 +15374,13 @@ int ProcessReply(WOLFSSL* ssl) else #endif if (ssl->buffers.inputBuffer.length - - ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ) { + ssl->keys.padSz - + ssl->buffers.inputBuffer.idx > MAX_PLAINTEXT_SZ +#ifdef WOLFSSL_ASYNC_CRYPT + && ssl->buffers.inputBuffer.length != + ssl->buffers.inputBuffer.idx +#endif + ) { WOLFSSL_MSG("Plaintext too long"); #if defined(WOLFSSL_TLS13) || defined(WOLFSSL_EXTRA_ALERTS) SendAlert(ssl, alert_fatal, record_overflow); @@ -15340,11 +15388,11 @@ int ProcessReply(WOLFSSL* ssl) return BUFFER_ERROR; } - #ifdef WOLFSSL_DTLS +#ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { DtlsUpdateWindow(ssl); } - #endif /* WOLFSSL_DTLS */ +#endif /* WOLFSSL_DTLS */ WOLFSSL_MSG("received record layer msg"); @@ -15392,7 +15440,15 @@ int ProcessReply(WOLFSSL* ssl) ret = BUFFER_ERROR; #endif } - if (ret != 0) { + if (ret != 0 +#ifdef WOLFSSL_ASYNC_CRYPT + /* In async case, on pending, move onto next message. + * Current message should have been DtlsMsgStore'ed and + * should be processed with DtlsMsgDrain */ + && (!ssl->options.dtls + || ret != WC_PENDING_E) +#endif + ) { WOLFSSL_ERROR(ret); return ret; } @@ -15597,7 +15653,7 @@ int ProcessReply(WOLFSSL* ssl) /* input exhausted? */ if (ssl->buffers.inputBuffer.idx >= ssl->buffers.inputBuffer.length) - return 0; + return ret; /* more messages per record */ else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) { @@ -15632,15 +15688,19 @@ int ProcessReply(WOLFSSL* ssl) } } } - - continue; } /* more records */ else { WOLFSSL_MSG("More records in input"); - continue; } - +#ifdef WOLFSSL_ASYNC_CRYPT + /* We are setup to read next message/record but we had an error + * (probably WC_PENDING_E) so return that so it can be handled + * by higher layers. */ + if (ret != 0) + return ret; +#endif + continue; default: WOLFSSL_MSG("Bad process input state, programming error"); return INPUT_CASE_ERROR; diff --git a/src/ssl.c b/src/ssl.c index 8bae5976f..3b74066e7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11783,6 +11783,14 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } #endif /* WOLFSSL_DTLS */ +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION) + /* This may be necessary in async so that we don't try to + * renegotiate again */ + if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) { + ssl->secure_renegotiation->startScr = 0; + } +#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */ + WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS); return WOLFSSL_SUCCESS; From 01b446f469759acfe9aa6ac37c82e0f199b15663 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 5 Jun 2020 18:04:09 +0200 Subject: [PATCH 13/17] Fix SessionTicket length in unencrypted case --- src/internal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index 69faa7c01..2d3d16c7a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -28265,7 +28265,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif } - if (IsEncryptionOn(ssl, 1)) + if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) sendSz += cipherExtraData(ssl); /* check for available size */ @@ -28326,7 +28326,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->buffers.outputBuffer.length += sendSz; - ret = SendBuffered(ssl); + if (!ssl->options.groupMessages) + ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTicket", ret); WOLFSSL_END(WC_FUNC_TICKET_SEND); From 3980d6117d5734546a9402a76033404e0c28873b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 9 Jun 2020 13:28:19 +0200 Subject: [PATCH 14/17] Fix Jenkins --- src/internal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 2d3d16c7a..0c749d9f7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -16076,7 +16076,7 @@ void FreeBuildMsgArgs(BuildMsgArgs* args) { if (args) { if (args->iv) - XFREE(args->iv, ssl->heap, DYNAMIC_TYPE_SALT); + XFREE(args->iv, NULL, DYNAMIC_TYPE_SALT); XMEMSET(args, 0, sizeof(BuildMsgArgs)); } } @@ -17763,8 +17763,6 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) return ssl->error; } - if (ssl->error != 0) fprintf(stderr, "ignoring err %d\n", ssl->error); - #ifdef WOLFSSL_EARLY_DATA if (ssl->earlyData != no_early_data) { } From 69802ed1a97b33bf483e9ee809a0360f9f231c84 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 9 Jun 2020 15:33:17 +0200 Subject: [PATCH 15/17] Missing ssl->heap in FreeBuildMsgArgs --- src/internal.c | 10 +++++----- wolfssl/internal.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0c749d9f7..2789ad57b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6183,7 +6183,7 @@ void FreeKeyExchange(WOLFSSL* ssl) ssl->async.freeArgs(ssl, ssl->async.args); ssl->async.freeArgs = NULL; } - FreeBuildMsgArgs(&ssl->async.buildArgs); + FreeBuildMsgArgs(ssl, &ssl->async.buildArgs); #endif } @@ -16072,11 +16072,11 @@ int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) } #ifndef WOLFSSL_NO_TLS12 -void FreeBuildMsgArgs(BuildMsgArgs* args) +void FreeBuildMsgArgs(WOLFSSL* ssl, BuildMsgArgs* args) { if (args) { - if (args->iv) - XFREE(args->iv, NULL, DYNAMIC_TYPE_SALT); + if (ssl && args->iv) + XFREE(args->iv, ssl->heap, DYNAMIC_TYPE_SALT); XMEMSET(args, 0, sizeof(BuildMsgArgs)); } } @@ -16516,7 +16516,7 @@ exit_buildmsg: ret = args->sz; /* Final cleanup */ - FreeBuildMsgArgs(args); + FreeBuildMsgArgs(ssl, args); return ret; #endif /* !WOLFSSL_NO_TLS12 */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 1fdcc69d4..304ed443b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4616,7 +4616,7 @@ WOLFSSL_LOCAL void FreeHandshakeHashes(WOLFSSL* ssl); #ifndef WOLFSSL_NO_TLS12 -WOLFSSL_LOCAL void FreeBuildMsgArgs(BuildMsgArgs* args); +WOLFSSL_LOCAL void FreeBuildMsgArgs(WOLFSSL* ssl, BuildMsgArgs* args); #endif WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, int inSz, int type, int hashOutput, From ac028e551d3fda94f2584cf86a006cc78bd0d38d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 10 Jun 2020 18:14:39 +0200 Subject: [PATCH 16/17] Code Review --- src/internal.c | 106 ++++++++++++++++++++++++++++++--------------- src/ssl.c | 24 ++-------- src/tls.c | 78 ++------------------------------- src/tls13.c | 4 +- wolfssl/internal.h | 10 +++-- 5 files changed, 87 insertions(+), 135 deletions(-) diff --git a/src/internal.c b/src/internal.c index 2789ad57b..3f58fe9c3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6723,12 +6723,7 @@ static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) { #ifdef HAVE_SECURE_RENEGOTIATION - /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER - * refers to the current epoch */ - if (order == PREV_ORDER && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { - order = CUR_ORDER; - } + order = DtlsCheckOrder(ssl, order); #endif if (order == PREV_ORDER) { /* Previous epoch case */ @@ -6776,12 +6771,7 @@ static WC_INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order) { word32 seq; #ifdef HAVE_SECURE_RENEGOTIATION - /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER - * refers to the current epoch */ - if (order == PREV_ORDER && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { - order = CUR_ORDER; - } + order = DtlsCheckOrder(ssl, order); #endif if (order == PREV_ORDER) { @@ -6809,7 +6799,7 @@ static WC_INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order) #endif /* WOLFSSL_DTLS */ #if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) -static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) +void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) { word32 seq[2] = {0, 0}; @@ -7232,9 +7222,14 @@ int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset) } +/** + * Verify if message `item` from `ssl->dtls_tx_msg_list` should be deleted + * depending on the current state of the handshake negotiation. + */ int VerifyForTxDtlsMsgDelete(WOLFSSL* ssl, DtlsMsg* item) { if (item->epoch < ssl->keys.dtls_epoch - 1) + /* Messages not from current or previous epoch can be deleted */ return 1; switch (ssl->options.side) { case WOLFSSL_CLIENT_END: @@ -7328,8 +7323,7 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) * ssl->keys otherwise * PREV_ORDER will always use ssl->keys */ - if (ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (DtlsSCRKeysSet(ssl)) { if (pool->epoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch) epochOrder = CUR_ORDER; else @@ -14098,17 +14092,10 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, ssl->decrypt.additional + AEAD_LEN_OFFSET); #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) - if (ssl->options.dtls && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { - if (ssl->keys.curEpoch == - ssl->secure_renegotiation->tmp_keys.dtls_epoch) - XMEMCPY(ssl->decrypt.nonce, - ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); - else - XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, - AESGCM_IMP_IV_SZ); - } + if (ssl->options.dtls && IsDtlsMsgSCRKeys(ssl)) + XMEMCPY(ssl->decrypt.nonce, + ssl->secure_renegotiation->tmp_keys.aead_dec_imp_IV, + AESGCM_IMP_IV_SZ); else #endif XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV, @@ -14237,8 +14224,7 @@ static WC_INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, case CIPHER_STATE_DO: { #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) - if (ssl->options.dtls && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (ssl->options.dtls && DtlsSCRKeysSet(ssl)) { /* For epochs >1 the current cipher parameters are located in * ssl->secure_renegotiation->tmp_keys. Previous cipher * parameters and for epoch 1 use ssl->keys */ @@ -16154,8 +16140,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, ERROR_OUT(BAD_FUNC_ARG, exit_buildmsg); } #if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION) - if (ssl->options.dtls && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0) { + if (ssl->options.dtls && DtlsSCRKeysSet(ssl)) { /* For epochs >1 the current cipher parameters are located in * ssl->secure_renegotiation->tmp_keys. Previous cipher * parameters and for epoch 1 use ssl->keys */ @@ -16408,10 +16393,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, word16 dtls_sequence_number_hi; word32 dtls_sequence_number_lo; int swap_seq = ssl->options.dtls && epochOrder == PREV_ORDER && - ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && - ssl->secure_renegotiation->tmp_keys.dtls_epoch == - ssl->keys.dtls_epoch; + DtlsUseSCRKeys(ssl); if (swap_seq) { dtls_epoch = ssl->keys.dtls_epoch; dtls_sequence_number_hi = ssl->keys.dtls_sequence_number_hi; @@ -17137,7 +17119,8 @@ int SendCertificateRequest(WOLFSSL* ssl) #endif } - sendSz += cipherExtraData(ssl); + if (IsEncryptionOn(ssl, 1)) + sendSz += cipherExtraData(ssl); /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) @@ -17543,6 +17526,59 @@ int SendCertificateStatus(WOLFSSL* ssl) #endif /* WOLFSSL_NO_TLS12 */ + +#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) +/** + * Check if the SCR keys are set in ssl->secure_renegotiation->tmp_keys. + */ +int DtlsSCRKeysSet(WOLFSSL* ssl) +{ + return ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0; +} + +/** + * ssl->keys contains the current cipher parameters only for epoch 1. For + * epochs >1 ssl->secure_renegotiation->tmp_keys contains the current + * cipher parameters. This function checks if the message currently being + * processed should use ssl->keys or ssl->secure_renegotiation->tmp_keys. + */ +int IsDtlsMsgSCRKeys(WOLFSSL* ssl) +{ + return DtlsSCRKeysSet(ssl) && + ssl->keys.curEpoch == + ssl->secure_renegotiation->tmp_keys.dtls_epoch; +} + +/** + * ssl->keys contains the current cipher parameters only for epoch 1. For + * epochs >1 ssl->secure_renegotiation->tmp_keys contains the current + * cipher parameters. This function checks if the message currently being + * built should use ssl->keys or ssl->secure_renegotiation->tmp_keys. + */ +int DtlsUseSCRKeys(WOLFSSL* ssl) +{ + return DtlsSCRKeysSet(ssl) && + ssl->secure_renegotiation->tmp_keys.dtls_epoch == + ssl->keys.dtls_epoch; +} + +/** + * If ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch + * then PREV_ORDER refers to the current epoch. + * */ +int DtlsCheckOrder(WOLFSSL* ssl, int order) +{ + if (order == PREV_ORDER && ssl->secure_renegotiation && + ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { + return CUR_ORDER; + } + else { + return order; + } +} +#endif /* HAVE_SECURE_RENEGOTIATION && WOLFSSL_DTLS */ + /* If secure renegotiation is disabled, this will always return false. * Otherwise it checks to see if we are currently renegotiating. */ static WC_INLINE int IsSCR(WOLFSSL* ssl) diff --git a/src/ssl.c b/src/ssl.c index 3b74066e7..eeb024bed 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3241,36 +3241,18 @@ const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder) return NULL; #ifdef HAVE_SECURE_RENEGOTIATION - /* ssl->keys contains the current cipher parameters only for epoch 1. For - * epochs >1 ssl->secure_renegotiation->tmp_keys contains the current - * cipher parameters */ switch (epochOrder) { case PEER_ORDER: - if (ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && - ssl->keys.curEpoch == - ssl->secure_renegotiation->tmp_keys.dtls_epoch) + if (IsDtlsMsgSCRKeys(ssl)) keys = &ssl->secure_renegotiation->tmp_keys; else keys = &ssl->keys; break; case PREV_ORDER: - if (ssl->keys.dtls_epoch > 1 || - (ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0)) - keys = &ssl->keys; - else { - WOLFSSL_MSG("No previous cipher epoch"); - return NULL; - } + keys = &ssl->keys; break; case CUR_ORDER: - if (ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch != 0 && - ssl->secure_renegotiation->tmp_keys.dtls_epoch == - ssl->keys.dtls_epoch) - /* new keys are in scr and are only current when the - * ssl->keys.dtls_epoch matches */ + if (DtlsUseSCRKeys(ssl)) keys = &ssl->secure_renegotiation->tmp_keys; else keys = &ssl->keys; diff --git a/src/tls.c b/src/tls.c index 18c911bfb..51ffe1757 100644 --- a/src/tls.c +++ b/src/tls.c @@ -643,79 +643,6 @@ int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len, } -static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) -{ - if (verify) { - seq[0] = ssl->keys.peer_sequence_number_hi; - seq[1] = ssl->keys.peer_sequence_number_lo++; - if (seq[1] > ssl->keys.peer_sequence_number_lo) { - /* handle rollover */ - ssl->keys.peer_sequence_number_hi++; - } - } - else { - seq[0] = ssl->keys.sequence_number_hi; - seq[1] = ssl->keys.sequence_number_lo++; - if (seq[1] > ssl->keys.sequence_number_lo) { - /* handle rollover */ - ssl->keys.sequence_number_hi++; - } - } -} - - -#ifdef WOLFSSL_DTLS -static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) -{ -#ifdef HAVE_SECURE_RENEGOTIATION - /* if ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch then PREV_ORDER - * refers to the current epoch */ - if (order == PREV_ORDER && ssl->secure_renegotiation && - ssl->secure_renegotiation->tmp_keys.dtls_epoch > ssl->keys.dtls_epoch) { - order = CUR_ORDER; - } -#endif - if (order == PREV_ORDER) { - /* Previous epoch case */ - seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) | - (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF); - seq[1] = ssl->keys.dtls_prev_sequence_number_lo; - } - else if (order == PEER_ORDER) { - seq[0] = ((word32)ssl->keys.curEpoch << 16) | - (ssl->keys.curSeq_hi & 0xFFFF); - seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ - } - else { - seq[0] = ((word32)ssl->keys.dtls_epoch << 16) | - (ssl->keys.dtls_sequence_number_hi & 0xFFFF); - seq[1] = ssl->keys.dtls_sequence_number_lo; - } -} -#endif /* WOLFSSL_DTLS */ - - -static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) -{ - word32 seq[2] = {0, 0}; - - if (!ssl->options.dtls) { - GetSEQIncrement(ssl, verifyOrder, seq); - } - else { -#ifdef WOLFSSL_DTLS - DtlsGetSEQ(ssl, verifyOrder, seq); -#endif - } - - c32toa(seq[0], out); - c32toa(seq[1], out + OPAQUE32_LEN); -} - - -/*** end copy ***/ - - /* return HMAC digest type in wolfSSL format */ int wolfSSL_GetHmacType(WOLFSSL* ssl) { @@ -1208,7 +1135,10 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, } #endif - wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder); + if (!ssl->options.dtls) + wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); + else + wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder); #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \ !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION) if (tsip_useable(ssl)) { diff --git a/src/tls13.c b/src/tls13.c index c70e37241..7507e417a 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1474,7 +1474,7 @@ static void AddTls13FragHeaders(byte* output, word32 fragSz, word32 fragOffset, * verifyOrder Which set of sequence numbers to use. * out The buffer to write into. */ -static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) +static WC_INLINE void WriteSEQTls13(WOLFSSL* ssl, int verifyOrder, byte* out) { word32 seq[2] = {0, 0}; @@ -1510,7 +1510,7 @@ static WC_INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv, int i; /* The nonce is the IV with the sequence XORed into the last bytes. */ - WriteSEQ(ssl, order, nonce + AEAD_NONCE_SZ - SEQ_SZ); + WriteSEQTls13(ssl, order, nonce + AEAD_NONCE_SZ - SEQ_SZ); for (i = 0; i < AEAD_NONCE_SZ - SEQ_SZ; i++) nonce[i] = iv[i]; for (; i < AEAD_NONCE_SZ; i++) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 304ed443b..1aeec5125 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4516,10 +4516,14 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength); WOLFSSL_LOCAL int DtlsMsgPoolSend(WOLFSSL*, int); #endif /* WOLFSSL_DTLS */ -#ifndef NO_TLS +#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) + WOLFSSL_LOCAL int DtlsSCRKeysSet(WOLFSSL* ssl); + WOLFSSL_LOCAL int IsDtlsMsgSCRKeys(WOLFSSL* ssl); + WOLFSSL_LOCAL int DtlsUseSCRKeys(WOLFSSL* ssl); + WOLFSSL_LOCAL int DtlsCheckOrder(WOLFSSL* ssl, int order); +#endif - -#endif /* NO_TLS */ + WOLFSSL_LOCAL void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out); #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) WOLFSSL_LOCAL word32 TimeNowInMilliseconds(void); From cab8dd37311056485e38c23c608220366d763d27 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 12 Jun 2020 12:27:48 +0200 Subject: [PATCH 17/17] Ignore duplicate or out of order CCS message Init variables since compiler complains they might be used without initialization. --- src/internal.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index 3f58fe9c3..6d4b4b91a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15534,7 +15534,8 @@ int ProcessReply(WOLFSSL* ssl) * skipped. Also skip if out of order. */ if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E) return ret; - + /* Reset error */ + ret = 0; break; #endif /* WOLFSSL_DTLS */ } @@ -16389,9 +16390,9 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS) /* If we want the PREV_ORDER then modify CUR_ORDER sequence number * for all encryption algos that use it for encryption parameters */ - word16 dtls_epoch; - word16 dtls_sequence_number_hi; - word32 dtls_sequence_number_lo; + word16 dtls_epoch = 0; + word16 dtls_sequence_number_hi = 0; + word32 dtls_sequence_number_lo = 0; int swap_seq = ssl->options.dtls && epochOrder == PREV_ORDER && DtlsUseSCRKeys(ssl); if (swap_seq) {