From 21726d5ae4ad10b6be33042764cb483d28b7a48f Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 19 Sep 2016 16:02:27 -0700 Subject: [PATCH 1/8] 64bit sequence tls proof of concept, dlts needs some work --- src/internal.c | 91 ++++++++++++++++++++++++++++++---------------- src/keys.c | 15 +++++--- src/tls.c | 49 ++++++++++++++++++++----- wolfssl/internal.h | 6 ++- 4 files changed, 113 insertions(+), 48 deletions(-) diff --git a/src/internal.c b/src/internal.c index de6a8e6f9..95424303e 100755 --- a/src/internal.c +++ b/src/internal.c @@ -581,9 +581,10 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) XMEMSET(exp, 0, DTLS_EXPORT_KEY_SZ); - c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->sequence_number, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->peer_sequence_number_hi, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->peer_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->sequence_number_hi, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; c16toa(keys->dtls_state.nextEpoch, exp + idx); idx += OPAQUE16_LEN; c32toa(keys->dtls_state.nextSeq, exp + idx); idx += OPAQUE32_LEN; @@ -706,9 +707,10 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) if (len < DTLS_EXPORT_MIN_KEY_SZ) { return BUFFER_E; } - ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->sequence_number); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->peer_sequence_number_hi); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->peer_sequence_number_lo); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->sequence_number_hi); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->sequence_number_lo); idx += OPAQUE32_LEN; ato16(exp + idx, &keys->dtls_state.nextEpoch); idx += OPAQUE16_LEN; ato32(exp + idx, &keys->dtls_state.nextSeq); idx += OPAQUE32_LEN; @@ -7864,20 +7866,49 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \ || defined(HAVE_AESGCM) -static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify) +static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - if (verify) - return ssl->keys.dtls_state.curSeq; /* explicit from peer */ - else - return ssl->keys.dtls_sequence_number - 1; /* already incremented */ + if (verify) { + seq[0] = 0; + seq[1] = ssl->keys.dtls_state.curSeq; /* explicit from peer */ + } + else { + seq[0] = 0; + /* already incremented dtls seq number */ + seq[1] = ssl->keys.dtls_sequence_number - 1; + } + return; } #endif - if (verify) - return ssl->keys.peer_sequence_number++; - else - return ssl->keys.sequence_number++; + 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++; + } + } +} + + +static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) +{ + word32 seq[2]; + + GetSEQIncrement(ssl, verify, seq); + + c32toa(seq[0], out); + c32toa(seq[1], out+4); } #endif @@ -7967,11 +7998,11 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - c32toa(ssl->keys.sequence_number, nonce + CHACHA20_OLD_OFFSET); + c32toa(ssl->keys.sequence_number_lo, nonce + CHACHA20_OLD_OFFSET); } /* opaque SEQ number stored for AD */ - c32toa(GetSEQIncrement(ssl, 0), add + AEAD_SEQ_OFFSET); + WriteSEQ(ssl, 0, add); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ @@ -8111,11 +8142,11 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - c32toa(ssl->keys.peer_sequence_number, nonce + CHACHA20_OLD_OFFSET); + c32toa(ssl->keys.peer_sequence_number_lo, nonce + CHACHA20_OLD_OFFSET); } - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 1), add + AEAD_SEQ_OFFSET); + /* sequence number field is 64-bits */ + WriteSEQ(ssl, 1, add); /* get AD info */ add[AEAD_TYPE_OFFSET] = ssl->curRL.type; @@ -8262,9 +8293,8 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 0), - additional + AEAD_SEQ_OFFSET); + /* sequence number field is 64-bits */ + WriteSEQ(ssl, 0, additional); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ @@ -8307,9 +8337,8 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 0), - additional + AEAD_SEQ_OFFSET); + /* sequence number field is 64-bits */ + WriteSEQ(ssl, 0, additional); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ @@ -8431,8 +8460,8 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); + /* sequence number field is 64-bits */ + WriteSEQ(ssl, 1, additional); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) @@ -8473,8 +8502,8 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); + /* sequence number field is 64-bits */ + WriteSEQ(ssl, 1, additional); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) @@ -9626,7 +9655,7 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, XMEMSET(seq, 0, SEQ_SZ); conLen[0] = (byte)content; c16toa((word16)sz, &conLen[ENUM_LEN]); - c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]); + WriteSEQ(ssl, verify, seq); if (ssl->specs.mac_algorithm == md5_mac) { wc_InitMd5(&md5); diff --git a/src/keys.c b/src/keys.c index 50e888521..c60a4b235 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2628,10 +2628,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } #endif - if (enc) - keys->sequence_number = 0; - if (dec) - keys->peer_sequence_number = 0; + if (enc) { + keys->sequence_number_hi = 0; + keys->sequence_number_lo = 0; + } + if (dec) { + keys->peer_sequence_number_hi = 0; + keys->peer_sequence_number_lo = 0; + } (void)side; (void)heap; (void)enc; @@ -2766,7 +2770,8 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) #endif } if (wc_decrypt) { - ssl->keys.peer_sequence_number = keys->peer_sequence_number; + ssl->keys.peer_sequence_number_hi = keys->peer_sequence_number_hi; + ssl->keys.peer_sequence_number_lo = keys->peer_sequence_number_lo; #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize decrypt implicit IV by decrypt side */ diff --git a/src/tls.c b/src/tls.c index 648147c2a..c150e2e81 100644 --- a/src/tls.c +++ b/src/tls.c @@ -642,20 +642,49 @@ static INLINE void c32toa(word32 u32, byte* c) } -static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify) +static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - if (verify) - return ssl->keys.dtls_state.curSeq; /* explicit from peer */ - else - return ssl->keys.dtls_sequence_number - 1; /* already incremented */ + if (verify) { + seq[0] = 0; + seq[1] = ssl->keys.dtls_state.curSeq; /* explicit from peer */ + } + else { + seq[0] = 0; + /* already incremented dtls seq number */ + seq[1] = ssl->keys.dtls_sequence_number - 1; + } + return; } #endif - if (verify) - return ssl->keys.peer_sequence_number++; - else - return ssl->keys.sequence_number++; + 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++; + } + } +} + + +static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) +{ + word32 seq[2]; + + GetSEQIncrement(ssl, verify, seq); + + c32toa(seq[0], out); + c32toa(seq[1], out+4); } @@ -733,7 +762,7 @@ int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content, if (ssl->options.dtls) c16toa((word16)GetEpoch(ssl, verify), inner); #endif - c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]); + WriteSEQ(ssl, verify, inner); inner[SEQ_SZ] = (byte)content; inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5f67dc33e..accfc48bb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1613,8 +1613,10 @@ typedef struct Keys { byte aead_dec_imp_IV[AEAD_MAX_IMP_SZ]; #endif - word32 peer_sequence_number; - word32 sequence_number; + word32 peer_sequence_number_hi; + word32 peer_sequence_number_lo; + word32 sequence_number_hi; + word32 sequence_number_lo; #ifdef WOLFSSL_DTLS DtlsState dtls_state; /* Peer's state */ From 67a112773e8b8fe8eb4f1d7fde65506632b2789c Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 19 Sep 2016 17:31:20 -0700 Subject: [PATCH 2/8] fix secure renegotiation --- src/keys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/keys.c b/src/keys.c index c60a4b235..e630072a8 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2751,7 +2751,8 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) keys->server_write_IV, MAX_WRITE_IV_SZ); } if (wc_encrypt) { - ssl->keys.sequence_number = keys->sequence_number; + ssl->keys.sequence_number_hi = keys->sequence_number_hi; + ssl->keys.sequence_number_lo = keys->sequence_number_lo; #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM/CCM explicit IV to a zero. */ From 4522fa335e9f5de29bbfa274c1d86c6d6ee8aec4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 22 Sep 2016 14:13:24 -0700 Subject: [PATCH 3/8] Fixing DTLS for 64-bit sequence numbering 1. Simplify away the DtlsState record. 2. Adding in high order bits for the DTLS sequence number. 3. For DTLS, separated copying the sequence number from incrementing it. --- src/internal.c | 378 ++++++++++++++++++++++++++------------------- src/tls.c | 63 ++++---- wolfssl/internal.h | 39 ++--- 3 files changed, 271 insertions(+), 209 deletions(-) diff --git a/src/internal.c b/src/internal.c index 95424303e..4d87a586d 100755 --- a/src/internal.c +++ b/src/internal.c @@ -121,8 +121,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS #ifdef WOLFSSL_DTLS - static INLINE int DtlsCheckWindow(DtlsState* state); - static INLINE int DtlsUpdateWindow(DtlsState* state); + static INLINE int DtlsCheckWindow(WOLFSSL* ssl); + static INLINE int DtlsUpdateWindow(WOLFSSL* ssl); #endif @@ -187,7 +187,7 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) #ifdef WOLFSSL_DTLS /* For DTLS, epoch 0 is always not encrypted. */ - if (ssl->options.dtls && !isSend && ssl->keys.dtls_state.curEpoch == 0) + if (ssl->options.dtls && !isSend && ssl->keys.curEpoch == 0) return 0; #endif /* WOLFSSL_DTLS */ @@ -336,21 +336,6 @@ void c32to24(word32 in, word24 out) } -#ifdef WOLFSSL_DTLS - -static INLINE void c32to48(word32 in, byte out[6]) -{ - out[0] = 0; - out[1] = 0; - out[2] = (in >> 24) & 0xff; - out[3] = (in >> 16) & 0xff; - out[4] = (in >> 8) & 0xff; - out[5] = in & 0xff; -} - -#endif /* WOLFSSL_DTLS */ - - /* convert 16 bit integer to opaque */ static INLINE void c16toa(word16 u16, byte* c) { @@ -586,11 +571,11 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) c32toa(keys->sequence_number_hi, exp + idx); idx += OPAQUE32_LEN; c32toa(keys->sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; - c16toa(keys->dtls_state.nextEpoch, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->dtls_state.nextSeq, exp + idx); idx += OPAQUE32_LEN; - c16toa(keys->dtls_state.curEpoch, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->dtls_state.curSeq, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->dtls_state.prevSeq, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->nextEpoch, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->nextSeq, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->curEpoch, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->curSeq, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->prevSeq, exp + idx); idx += OPAQUE32_LEN; c16toa(keys->dtls_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN; c16toa(keys->dtls_expected_peer_handshake_number, exp + idx); @@ -606,13 +591,13 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) exp[idx++] = keys->decryptedCur; #ifdef WORD64_AVAILABLE - c64toa(keys->dtls_state.window, exp + idx); idx += OPAQUE64_LEN; - c64toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE64_LEN; + c64toa(keys->window, exp + idx); idx += OPAQUE64_LEN; + c64toa(keys->prevWindow, exp + idx); idx += OPAQUE64_LEN; #else - c32toa(keys->dtls_state.window, exp + idx); idx += OPAQUE32_LEN; - c32toa(0, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE32_LEN; - c32toa(0, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->window, exp + idx); idx += OPAQUE32_LEN; + c32toa(0, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->prevWindow, exp + idx); idx += OPAQUE32_LEN; + c32toa(0, exp + idx); idx += OPAQUE32_LEN; #endif #ifdef HAVE_TRUNCATED_HMAC @@ -712,11 +697,11 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) ato32(exp + idx, &keys->sequence_number_hi); idx += OPAQUE32_LEN; ato32(exp + idx, &keys->sequence_number_lo); idx += OPAQUE32_LEN; - ato16(exp + idx, &keys->dtls_state.nextEpoch); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->dtls_state.nextSeq); idx += OPAQUE32_LEN; - ato16(exp + idx, &keys->dtls_state.curEpoch); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->dtls_state.curSeq); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->dtls_state.prevSeq); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->nextEpoch); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->nextSeq); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->curEpoch); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->curSeq); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->prevSeq); idx += OPAQUE32_LEN; ato16(exp + idx, &keys->dtls_peer_handshake_number); idx += OPAQUE16_LEN; ato16(exp + idx, &keys->dtls_expected_peer_handshake_number); @@ -732,13 +717,13 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) keys->decryptedCur = exp[idx++]; #ifdef WORD64_AVAILABLE - ato64(exp + idx, &keys->dtls_state.window); idx += OPAQUE64_LEN; - ato64(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE64_LEN; + ato64(exp + idx, &keys->window); idx += OPAQUE64_LEN; + ato64(exp + idx, &keys->prevWindow); idx += OPAQUE64_LEN; #else - ato32(exp + idx, &keys->dtls_state.window); idx += OPAQUE32_LEN; - ato32(exp + idx, 0); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE32_LEN; - ato32(exp + idx, 0); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->window); idx += OPAQUE32_LEN; + ato32(exp + idx, 0); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->prevWindow); idx += OPAQUE32_LEN; + ato32(exp + idx, 0); idx += OPAQUE32_LEN; #endif #ifdef HAVE_TRUNCATED_HMAC @@ -1046,7 +1031,7 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver) return SOCKET_ERROR_E; } - c16toa((word16)fam, exp + idx); idx += DTLS_EXPORT_LEN; + c16toa((word16)fam, exp + idx); idx += DTLS_EXPORT_LEN; c16toa((word16)ipSz, exp + idx); idx += DTLS_EXPORT_LEN; XMEMCPY(exp + idx, ip, ipSz); idx += ipSz; c16toa(port, exp + idx); idx += DTLS_EXPORT_LEN; @@ -3922,6 +3907,98 @@ void FreeSSL(WOLFSSL* ssl, void* heap) } +#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \ + || defined(HAVE_AESGCM) +static 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 INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) +{ + if (verify == -1) { + /* Previous epoch case */ + seq[0] = ((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 (verify == 1) { + seq[0] = (ssl->keys.curEpoch << 16) | + (ssl->keys.curSeq_hi & 0xFFFF); + seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ + } + else { + seq[0] = (ssl->keys.dtls_epoch << 16) | + (ssl->keys.dtls_sequence_number_hi & 0xFFFF); + seq[1] = ssl->keys.dtls_sequence_number_lo; + } +} + +static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int verify) +{ + word32 seq; + + if (verify == -1) { + seq = ssl->keys.dtls_prev_sequence_number_lo++; + if (seq > ssl->keys.dtls_prev_sequence_number_lo) { + /* handle rollover */ + ssl->keys.dtls_prev_sequence_number_hi++; + } + } + else if (verify == 1) { + seq = ssl->keys.peer_sequence_number_lo++; + if (seq > ssl->keys.peer_sequence_number_lo) { + /* handle rollover */ + ssl->keys.peer_sequence_number_hi++; + } + } + else { + seq = ssl->keys.dtls_sequence_number_lo++; + if (seq > ssl->keys.dtls_sequence_number_lo) { + /* handle rollover */ + ssl->keys.dtls_sequence_number_hi++; + } + } +} +#endif /* WOLFSSL_DTLS */ + + +static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) +{ + word32 seq[2]; + + if (!ssl->options.dtls) { + GetSEQIncrement(ssl, verify, seq); + } + else { +#ifdef WOLFSSL_DTLS + DtlsGetSEQ(ssl, verify, seq); +#endif + } + + c32toa(seq[0], out); + c32toa(seq[1], out+4); +} +#endif + + #ifdef WOLFSSL_DTLS int DtlsPoolInit(WOLFSSL* ssl) @@ -4022,13 +4099,13 @@ int DtlsPoolSend(WOLFSSL* ssl) for (i = 0, buf = pool->buf; i < pool->used; i++, buf++) { if (pool->epoch[i] == 0) { DtlsRecordLayerHeader* dtls; - word32* seqNumber; + int epochZero; dtls = (DtlsRecordLayerHeader*)buf->buffer; - seqNumber = (ssl->keys.dtls_epoch == 0) ? - &ssl->keys.dtls_sequence_number : - &ssl->keys.dtls_prev_sequence_number; - c32to48((*seqNumber)++, dtls->sequence_number); + epochZero = (ssl->keys.dtls_epoch == 0) ? 0 : -1; + + WriteSEQ(ssl, epochZero, dtls->sequence_number); + DtlsSEQIncrement(ssl, epochZero); if ((ret = CheckAvailableSize(ssl, buf->length)) != 0) return ret; @@ -4694,8 +4771,7 @@ static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl /* dtls record layer header extensions */ dtls = (DtlsRecordLayerHeader*)output; - c16toa(ssl->keys.dtls_epoch, dtls->epoch); - c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number); + WriteSEQ(ssl, 0, dtls->sequence_number); c16toa((word16)length, dtls->length); #endif } @@ -5085,9 +5161,11 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* type and version in same sport */ XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ); *inOutIdx += ENUM_LEN + VERSION_SZ; - ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch); - *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */ - ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq); + ato16(input + *inOutIdx, &ssl->keys.curEpoch); + *inOutIdx += 2; + ato16(input + *inOutIdx, &ssl->keys.curSeq_hi); + *inOutIdx += 2; + ato32(input + *inOutIdx, &ssl->keys.curSeq_lo); *inOutIdx += 4; /* advance past rest of seq */ ato16(input + *inOutIdx, size); *inOutIdx += LENGTH_SZ; @@ -5096,8 +5174,8 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && - (!DtlsCheckWindow(&ssl->keys.dtls_state) || - (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) { + (!DtlsCheckWindow(ssl) || + (ssl->options.handShakeDone && ssl->keys.curEpoch == 0))) { return SEQUENCE_ERROR; } #endif @@ -7680,33 +7758,35 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS -static INLINE int DtlsCheckWindow(DtlsState* state) +static INLINE int DtlsCheckWindow(WOLFSSL* ssl) { - word32 cur; - word32 next; + word32 cur_hi, cur_lo, next_hi, next_lo; DtlsSeq window; - if (state->curEpoch == state->nextEpoch) { - next = state->nextSeq; - window = state->window; + if (ssl->keys.curEpoch == ssl->keys.nextEpoch) { + next_hi = ssl->keys.nextSeq_hi; + next_lo = ssl->keys.nextSeq_lo; + window = ssl->keys.window; } - else if (state->curEpoch == state->nextEpoch - 1) { - next = state->prevSeq; - window = state->prevWindow; + else if (ssl->keys.curEpoch == ssl->keys.nextEpoch - 1) { + next_hi = ssl->keys.prevSeq_hi; + next_lo = ssl->keys.prevSeq_lo; + window = ssl->keys.prevWindow; } else { return 0; } +/* XXX Handle rollover */ + cur_hi = ssl->keys.curSeq_hi; + cur_lo = ssl->keys.curSeq_lo; - cur = state->curSeq; - - if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) { + if ((next_lo > DTLS_SEQ_BITS) && (cur_lo < next_lo - DTLS_SEQ_BITS)) { return 0; } - else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) { + else if ((cur_lo < next_lo) && (window & ((DtlsSeq)1 << (next_lo - cur_lo - 1)))) { return 0; } - else if (cur > next + DTLS_SEQ_BITS) { + else if (cur_lo > next_lo + DTLS_SEQ_BITS) { return 0; } @@ -7714,22 +7794,22 @@ static INLINE int DtlsCheckWindow(DtlsState* state) } -static INLINE int DtlsUpdateWindow(DtlsState* state) +static INLINE int DtlsUpdateWindow(WOLFSSL* ssl) { word32 cur; word32* next; DtlsSeq* window; - if (state->curEpoch == state->nextEpoch) { - next = &state->nextSeq; - window = &state->window; + if (ssl->keys.curEpoch == ssl->keys.nextEpoch) { + next = &ssl->keys.nextSeq_lo; + window = &ssl->keys.window; } else { - next = &state->prevSeq; - window = &state->prevWindow; + next = &ssl->keys.prevSeq_lo; + window = &ssl->keys.prevWindow; } - cur = state->curSeq; + cur = ssl->keys.curSeq_lo; if (cur < *next) { *window |= ((DtlsSeq)1 << (*next - cur - 1)); @@ -7864,55 +7944,6 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif -#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \ - || defined(HAVE_AESGCM) -static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) -{ -#ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - if (verify) { - seq[0] = 0; - seq[1] = ssl->keys.dtls_state.curSeq; /* explicit from peer */ - } - else { - seq[0] = 0; - /* already incremented dtls seq number */ - seq[1] = ssl->keys.dtls_sequence_number - 1; - } - return; - } -#endif - 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++; - } - } -} - - -static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) -{ - word32 seq[2]; - - GetSEQIncrement(ssl, verify, seq); - - c32toa(seq[0], out); - c32toa(seq[1], out+4); -} -#endif - - #ifdef HAVE_AEAD static INLINE void AeadIncrementExpIV(WOLFSSL* ssl) { @@ -7998,7 +8029,7 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - c32toa(ssl->keys.sequence_number_lo, nonce + CHACHA20_OLD_OFFSET); + WriteSEQ(ssl, 0, nonce + CHACHA20_OLD_OFFSET); } /* opaque SEQ number stored for AD */ @@ -8008,8 +8039,8 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, * the input buffer ahead of the plaintext. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - c16toa(ssl->keys.dtls_epoch, add); additionalSrc -= DTLS_HANDSHAKE_EXTRA; + DtlsSEQIncrement(ssl, 0); } #endif @@ -8142,23 +8173,18 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - c32toa(ssl->keys.peer_sequence_number_lo, nonce + CHACHA20_OLD_OFFSET); + WriteSEQ(ssl, 1, nonce + CHACHA20_OLD_OFFSET); } /* sequence number field is 64-bits */ WriteSEQ(ssl, 1, add); /* get AD info */ + /* Store the type, version. */ add[AEAD_TYPE_OFFSET] = ssl->curRL.type; add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; - /* Store the type, version. */ - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - c16toa(ssl->keys.dtls_state.curEpoch, add); - #endif - /* add TLS message size to additional data */ add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff; add[AEAD_AUTH_DATA_SZ - 1] = msgLen & 0xff; @@ -8300,7 +8326,6 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) * the input buffer ahead of the plaintext. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - c16toa(ssl->keys.dtls_epoch, additional); additionalSrc -= DTLS_HANDSHAKE_EXTRA; } #endif @@ -8323,6 +8348,10 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); ForceZero(nonce, AESGCM_NONCE_SZ); + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif } break; #endif @@ -8344,7 +8373,6 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) * the input buffer ahead of the plaintext. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - c16toa(ssl->keys.dtls_epoch, additional); additionalSrc -= DTLS_HANDSHAKE_EXTRA; } #endif @@ -8367,6 +8395,10 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); ForceZero(nonce, AESGCM_NONCE_SZ); + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif } break; #endif @@ -8463,11 +8495,6 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, /* sequence number field is 64-bits */ WriteSEQ(ssl, 1, additional); - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - c16toa(ssl->keys.dtls_state.curEpoch, additional); - #endif - additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; @@ -8505,11 +8532,6 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, /* sequence number field is 64-bits */ WriteSEQ(ssl, 1, additional); - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - c16toa(ssl->keys.dtls_state.curEpoch, additional); - #endif - additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; @@ -9353,7 +9375,7 @@ int ProcessReply(WOLFSSL* ssl) #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - DtlsUpdateWindow(&ssl->keys.dtls_state); + DtlsUpdateWindow(ssl); } #endif /* WOLFSSL_DTLS */ @@ -9463,8 +9485,8 @@ int ProcessReply(WOLFSSL* ssl) #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { DtlsPoolReset(ssl); - ssl->keys.dtls_state.nextEpoch++; - ssl->keys.dtls_state.nextSeq = 0; + ssl->keys.nextEpoch++; + ssl->keys.nextSeq_lo = 0; } #endif @@ -9975,6 +9997,10 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #endif ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0); + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif } if (ret != 0) return ret; @@ -10012,9 +10038,12 @@ int SendFinished(WOLFSSL* ssl) if (ssl->options.dtls) { headerSz += DTLS_HANDSHAKE_EXTRA; ssl->keys.dtls_epoch++; - ssl->keys.dtls_prev_sequence_number = - ssl->keys.dtls_sequence_number; - ssl->keys.dtls_sequence_number = 0; + ssl->keys.dtls_prev_sequence_number_hi = + ssl->keys.dtls_sequence_number_hi; + ssl->keys.dtls_prev_sequence_number_lo = + ssl->keys.dtls_sequence_number_lo; + ssl->keys.dtls_sequence_number_hi = 0; + ssl->keys.dtls_sequence_number_lo = 0; } #endif @@ -10199,7 +10228,6 @@ int SendCertificate(WOLFSSL* ssl) HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA); /* Adding the headers increments these, decrement them for * actual message header. */ - ssl->keys.dtls_sequence_number--; ssl->keys.dtls_handshake_number--; AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl); ssl->keys.dtls_handshake_number--; @@ -10286,6 +10314,10 @@ int SendCertificate(WOLFSSL* ssl) if (sendSz < 0) return sendSz; } + else { + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + } #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { @@ -10310,10 +10342,7 @@ int SendCertificate(WOLFSSL* ssl) if (ret != WANT_WRITE) { /* Clean up the fragment offset. */ ssl->fragOffset = 0; - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - ssl->keys.dtls_handshake_number++; - #endif + ssl->keys.dtls_handshake_number++; if (ssl->options.side == WOLFSSL_SERVER_END) ssl->options.serverState = SERVER_CERT_COMPLETE; } @@ -10387,6 +10416,8 @@ int SendCertificateRequest(WOLFSSL* ssl) if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -10478,8 +10509,13 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, if (sendSz < 0) ret = sendSz; } - else + else { + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif ret = HashOutput(ssl, output, sendSz, 0); + } #ifdef WOLFSSL_DTLS if (ret == 0 && IsDtlsNotSctpMode(ssl)) @@ -12911,6 +12947,10 @@ static void PickHashSigAlgo(WOLFSSL* ssl, if (sendSz < 0) return sendSz; } else { + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) return ret; @@ -15431,6 +15471,10 @@ int SendClientKeyExchange(WOLFSSL* ssl) } } else { + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) { goto exit_scke; @@ -15911,6 +15955,10 @@ int SendCertificateVerify(WOLFSSL* ssl) } } else { + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif ret = HashOutput(ssl, output, sendSz, 0); } @@ -16134,7 +16182,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->options.dtls) { /* Server Hello should use the same sequence number as the * Client Hello. */ - ssl->keys.dtls_sequence_number = ssl->keys.dtls_state.curSeq; + ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi; + ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo; idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; } @@ -16214,6 +16263,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } + + if (ssl->options.dtls) { + DtlsSEQIncrement(ssl, 0); + } #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -17539,6 +17592,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_sske; } } + + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -18757,6 +18813,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return 0; } + + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -18975,6 +19034,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->options.dtls) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; + + DtlsSEQIncrement(ssl, 0); } #endif @@ -19008,7 +19069,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Hello Verify Request should use the same sequence number as the * Client Hello. */ - ssl->keys.dtls_sequence_number = ssl->keys.dtls_state.curSeq; + ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi; + ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo; AddHeaders(output, length, hello_verify_request, ssl); #ifdef OPENSSL_EXTRA diff --git a/src/tls.c b/src/tls.c index c150e2e81..11d2c5dd2 100644 --- a/src/tls.c +++ b/src/tls.c @@ -644,20 +644,6 @@ static INLINE void c32toa(word32 u32, byte* c) static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) { -#ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - if (verify) { - seq[0] = 0; - seq[1] = ssl->keys.dtls_state.curSeq; /* explicit from peer */ - } - else { - seq[0] = 0; - /* already incremented dtls seq number */ - seq[1] = ssl->keys.dtls_sequence_number - 1; - } - return; - } -#endif if (verify) { seq[0] = ssl->keys.peer_sequence_number_hi; seq[1] = ssl->keys.peer_sequence_number_lo++; @@ -677,30 +663,47 @@ static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) } +#ifdef WOLFSSL_DTLS +static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) +{ + if (verify == -1) { + /* Previous epoch case */ + seq[0] = ((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 (verify == 1) { + seq[0] = (ssl->keys.curEpoch << 16) | + (ssl->keys.curSeq_hi & 0xFFFF); + seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ + } + else { + seq[0] = (ssl->keys.dtls_epoch << 16) | + (ssl->keys.dtls_sequence_number_hi & 0xFFFF); + seq[1] = ssl->keys.dtls_sequence_number_lo; + } +} +#endif /* WOLFSSL_DTLS */ + + static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) { word32 seq[2]; - GetSEQIncrement(ssl, verify, seq); + if (!ssl->options.dtls) { + GetSEQIncrement(ssl, verify, seq); + } + else { +#ifdef WOLFSSL_DTLS + DtlsGetSEQ(ssl, verify, seq); +#endif + } c32toa(seq[0], out); c32toa(seq[1], out+4); } -#ifdef WOLFSSL_DTLS - -static INLINE word32 GetEpoch(WOLFSSL* ssl, int verify) -{ - if (verify) - return ssl->keys.dtls_state.curEpoch; - else - return ssl->keys.dtls_epoch; -} - -#endif /* WOLFSSL_DTLS */ - - /*** end copy ***/ @@ -758,10 +761,6 @@ int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content, XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ); -#ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - c16toa((word16)GetEpoch(ssl, verify), inner); -#endif WriteSEQ(ssl, verify, inner); inner[SEQ_SZ] = (byte)content; inner[SEQ_SZ + ENUM_LEN] = ssl->version.major; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index accfc48bb..2961d433d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -994,7 +994,7 @@ enum Misc { CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */ CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */ - CHACHA20_OLD_OFFSET = 8, /* Offset for seq # in old poly1305 */ + CHACHA20_OLD_OFFSET = 4, /* Offset for seq # in old poly1305 */ /* For any new implicit/explicit IV size adjust AEAD_MAX_***_SZ */ @@ -1581,18 +1581,6 @@ typedef struct WOLFSSL_DTLS_CTX { #endif #define DTLS_SEQ_BITS (sizeof(DtlsSeq) * CHAR_BIT) - typedef struct DtlsState { - DtlsSeq window; /* Sliding window for current epoch */ - word16 nextEpoch; /* Expected epoch in next record */ - word32 nextSeq; /* Expected sequence in next record */ - - word16 curEpoch; /* Received epoch in current record */ - word32 curSeq; /* Received sequence in current record */ - - DtlsSeq prevWindow; /* Sliding window for old epoch */ - word32 prevSeq; /* Next sequence in allowed old epoch */ - } DtlsState; - #endif /* WOLFSSL_DTLS */ @@ -1619,13 +1607,27 @@ typedef struct Keys { word32 sequence_number_lo; #ifdef WOLFSSL_DTLS - DtlsState dtls_state; /* Peer's state */ + DtlsSeq window; /* Sliding window for current epoch */ + word16 nextEpoch; /* Expected epoch in next record */ + word16 nextSeq_hi; /* Expected sequence in next record */ + word32 nextSeq_lo; + + word16 curEpoch; /* Received epoch in current record */ + word16 curSeq_hi; /* Received sequence in current record */ + word32 curSeq_lo; + + DtlsSeq prevWindow; /* Sliding window for old epoch */ + word16 prevSeq_hi; /* Next sequence in allowed old epoch */ + word32 prevSeq_lo; + word16 dtls_peer_handshake_number; word16 dtls_expected_peer_handshake_number; - word32 dtls_sequence_number; /* Current tx sequence */ - word32 dtls_prev_sequence_number; /* Previous epoch's seq number*/ - word16 dtls_epoch; /* Current tx epoch */ + word16 dtls_epoch; /* Current epoch */ + word32 dtls_sequence_number_hi; /* Current epoch */ + word32 dtls_sequence_number_lo; + word32 dtls_prev_sequence_number_hi; /* Previous epoch */ + word32 dtls_prev_sequence_number_lo; word16 dtls_handshake_number; /* Current tx handshake seq */ #endif @@ -2569,8 +2571,7 @@ typedef struct DtlsRecordLayerHeader { byte type; byte pvMajor; byte pvMinor; - byte epoch[2]; /* increment on cipher state change */ - byte sequence_number[6]; /* per record */ + byte sequence_number[8]; /* per record */ byte length[2]; } DtlsRecordLayerHeader; From 62d58a70846f4d4e4112104ceeb46f0c9ec01008 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 29 Sep 2016 16:51:55 -0700 Subject: [PATCH 4/8] updated session import/export for seq number --- src/internal.c | 67 ++++++++++++++++++++++++++++------------------ wolfssl/internal.h | 22 +++++++-------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4d87a586d..c8f601d26 100755 --- a/src/internal.c +++ b/src/internal.c @@ -571,22 +571,27 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) c32toa(keys->sequence_number_hi, exp + idx); idx += OPAQUE32_LEN; c32toa(keys->sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; - c16toa(keys->nextEpoch, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->nextSeq, exp + idx); idx += OPAQUE32_LEN; - c16toa(keys->curEpoch, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->curSeq, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->prevSeq, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->nextEpoch, exp + idx); idx += OPAQUE16_LEN; + c16toa(keys->nextSeq_hi, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->nextSeq_lo, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->curEpoch, exp + idx); idx += OPAQUE16_LEN; + c16toa(keys->curSeq_hi, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->curSeq_lo, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->prevSeq_hi, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->prevSeq_lo, exp + idx); idx += OPAQUE32_LEN; c16toa(keys->dtls_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN; c16toa(keys->dtls_expected_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->dtls_sequence_number, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->dtls_prev_sequence_number, exp + idx); idx += OPAQUE32_LEN; - c16toa(keys->dtls_epoch, exp + idx); idx += OPAQUE16_LEN; - c16toa(keys->dtls_handshake_number, exp + idx); idx += OPAQUE16_LEN; - c32toa(keys->encryptSz, exp + idx); idx += OPAQUE32_LEN; - c32toa(keys->padSz, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->dtls_sequence_number_hi, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->dtls_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->dtls_prev_sequence_number_hi, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->dtls_prev_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN; + c16toa(keys->dtls_epoch, exp + idx); idx += OPAQUE16_LEN; + c16toa(keys->dtls_handshake_number, exp + idx); idx += OPAQUE16_LEN; + c32toa(keys->encryptSz, exp + idx); idx += OPAQUE32_LEN; + c32toa(keys->padSz, exp + idx); idx += OPAQUE32_LEN; exp[idx++] = keys->encryptionOn; exp[idx++] = keys->decryptedCur; @@ -697,22 +702,27 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) ato32(exp + idx, &keys->sequence_number_hi); idx += OPAQUE32_LEN; ato32(exp + idx, &keys->sequence_number_lo); idx += OPAQUE32_LEN; - ato16(exp + idx, &keys->nextEpoch); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->nextSeq); idx += OPAQUE32_LEN; - ato16(exp + idx, &keys->curEpoch); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->curSeq); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->prevSeq); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->nextEpoch); idx += OPAQUE16_LEN; + ato16(exp + idx, &keys->nextSeq_hi); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->nextSeq_lo); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->curEpoch); idx += OPAQUE16_LEN; + ato16(exp + idx, &keys->curSeq_hi); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->curSeq_lo); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->prevSeq_hi); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->prevSeq_lo); idx += OPAQUE32_LEN; ato16(exp + idx, &keys->dtls_peer_handshake_number); idx += OPAQUE16_LEN; ato16(exp + idx, &keys->dtls_expected_peer_handshake_number); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->dtls_sequence_number); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->dtls_prev_sequence_number); idx += OPAQUE32_LEN; - ato16(exp + idx, &keys->dtls_epoch); idx += OPAQUE16_LEN; - ato16(exp + idx, &keys->dtls_handshake_number); idx += OPAQUE16_LEN; - ato32(exp + idx, &keys->encryptSz); idx += OPAQUE32_LEN; - ato32(exp + idx, &keys->padSz); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->dtls_sequence_number_hi); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->dtls_sequence_number_lo); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->dtls_prev_sequence_number_hi); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->dtls_prev_sequence_number_lo); idx += OPAQUE32_LEN; + ato16(exp + idx, &keys->dtls_epoch); idx += OPAQUE16_LEN; + ato16(exp + idx, &keys->dtls_handshake_number); idx += OPAQUE16_LEN; + ato32(exp + idx, &keys->encryptSz); idx += OPAQUE32_LEN; + ato32(exp + idx, &keys->padSz); idx += OPAQUE32_LEN; keys->encryptionOn = exp[idx++]; keys->decryptedCur = exp[idx++]; @@ -7776,7 +7786,7 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl) else { return 0; } -/* XXX Handle rollover */ + cur_hi = ssl->keys.curSeq_hi; cur_lo = ssl->keys.curSeq_lo; @@ -10315,8 +10325,10 @@ int SendCertificate(WOLFSSL* ssl) return sendSz; } else { - if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + DtlsSEQIncrement(ssl, 0); + #endif } #ifdef WOLFSSL_DTLS @@ -10342,7 +10354,10 @@ int SendCertificate(WOLFSSL* ssl) if (ret != WANT_WRITE) { /* Clean up the fragment offset. */ ssl->fragOffset = 0; - ssl->keys.dtls_handshake_number++; + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) + ssl->keys.dtls_handshake_number++; + #endif if (ssl->options.side == WOLFSSL_SERVER_END) ssl->options.serverState = SERVER_CERT_COMPLETE; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2961d433d..b56b7b1cd 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1608,25 +1608,25 @@ typedef struct Keys { #ifdef WOLFSSL_DTLS DtlsSeq window; /* Sliding window for current epoch */ - word16 nextEpoch; /* Expected epoch in next record */ - word16 nextSeq_hi; /* Expected sequence in next record */ - word32 nextSeq_lo; + word16 nextEpoch; /* Expected epoch in next record */ + word16 nextSeq_hi; /* Expected sequence in next record */ + word32 nextSeq_lo; - word16 curEpoch; /* Received epoch in current record */ - word16 curSeq_hi; /* Received sequence in current record */ - word32 curSeq_lo; + word16 curEpoch; /* Received epoch in current record */ + word16 curSeq_hi; /* Received sequence in current record */ + word32 curSeq_lo; - DtlsSeq prevWindow; /* Sliding window for old epoch */ - word16 prevSeq_hi; /* Next sequence in allowed old epoch */ - word32 prevSeq_lo; + DtlsSeq prevWindow; /* Sliding window for old epoch */ + word16 prevSeq_hi; /* Next sequence in allowed old epoch */ + word32 prevSeq_lo; word16 dtls_peer_handshake_number; word16 dtls_expected_peer_handshake_number; word16 dtls_epoch; /* Current epoch */ - word32 dtls_sequence_number_hi; /* Current epoch */ + word16 dtls_sequence_number_hi; /* Current epoch */ word32 dtls_sequence_number_lo; - word32 dtls_prev_sequence_number_hi; /* Previous epoch */ + word16 dtls_prev_sequence_number_hi; /* Previous epoch */ word32 dtls_prev_sequence_number_lo; word16 dtls_handshake_number; /* Current tx handshake seq */ #endif From ab371365b962f933037e181b22e41e365dfa69d3 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 30 Sep 2016 17:02:05 -0700 Subject: [PATCH 5/8] updated sequence number window --- src/internal.c | 66 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/internal.c b/src/internal.c index c8f601d26..8a2beb3ef 100755 --- a/src/internal.c +++ b/src/internal.c @@ -7770,8 +7770,10 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, static INLINE int DtlsCheckWindow(WOLFSSL* ssl) { - word32 cur_hi, cur_lo, next_hi, next_lo; DtlsSeq window; + word16 cur_hi, next_hi; + word32 cur_lo, next_lo, diff; + int curLT; if (ssl->keys.curEpoch == ssl->keys.nextEpoch) { next_hi = ssl->keys.nextSeq_hi; @@ -7790,13 +7792,34 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl) cur_hi = ssl->keys.curSeq_hi; cur_lo = ssl->keys.curSeq_lo; - if ((next_lo > DTLS_SEQ_BITS) && (cur_lo < next_lo - DTLS_SEQ_BITS)) { + /* If the difference between next and cur is > 2^32, way outside window. */ + if ((cur_hi > next_hi + 1) || (next_hi > cur_hi + 1)) + return 0; + + if (cur_hi == next_hi) { + curLT = cur_lo < next_lo; + diff = curLT ? next_lo - cur_lo : cur_lo - next_lo; + } + else { + curLT = cur_hi < next_hi; + diff = curLT ? cur_lo - next_lo : next_lo - cur_lo; + } + + /* Check to see that the next value is greater than the number of messages + * trackable in the window (32 or 64), and that the difference between the + * next expected sequence number and the received sequence number is + * inside the window. */ + if ((next_hi || next_lo > DTLS_SEQ_BITS) && + curLT && (diff > DTLS_SEQ_BITS)) { + return 0; } - else if ((cur_lo < next_lo) && (window & ((DtlsSeq)1 << (next_lo - cur_lo - 1)))) { + else if (curLT && (window & ((DtlsSeq)1 << diff))) { + return 0; } - else if (cur_lo > next_lo + DTLS_SEQ_BITS) { + else if ((cur_hi == next_hi) && (diff > DTLS_SEQ_BITS)) { + return 0; } @@ -7806,28 +7829,45 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl) static INLINE int DtlsUpdateWindow(WOLFSSL* ssl) { - word32 cur; - word32* next; DtlsSeq* window; + word32* next_lo; + word16* next_hi; + int curLT; + word32 cur_lo, diff; + word16 cur_hi; if (ssl->keys.curEpoch == ssl->keys.nextEpoch) { - next = &ssl->keys.nextSeq_lo; + next_hi = &ssl->keys.nextSeq_hi; + next_lo = &ssl->keys.nextSeq_lo; window = &ssl->keys.window; } else { - next = &ssl->keys.prevSeq_lo; + next_hi = &ssl->keys.prevSeq_hi; + next_lo = &ssl->keys.prevSeq_lo; window = &ssl->keys.prevWindow; } - cur = ssl->keys.curSeq_lo; + cur_hi = ssl->keys.curSeq_hi; + cur_lo = ssl->keys.curSeq_lo; - if (cur < *next) { - *window |= ((DtlsSeq)1 << (*next - cur - 1)); + if (cur_hi == *next_hi) { + curLT = cur_lo < *next_lo; + diff = curLT ? *next_lo - cur_lo : cur_lo - *next_lo; } else { - *window <<= (1 + cur - *next); + curLT = cur_hi < *next_hi; + diff = curLT ? cur_lo - *next_lo : *next_lo - cur_lo; + } + + if (curLT) { + *window |= ((DtlsSeq)1 << (diff - 1)); + } + else { + *window <<= (1 + diff); *window |= 1; - *next = cur + 1; + *next_lo = cur_lo + 1; + if (*next_lo < cur_lo) + (*next_hi)++; } return 1; From 575785db3ef2354fb63849af005110b793795fab Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sat, 1 Oct 2016 18:11:50 -0700 Subject: [PATCH 6/8] Fixes for DTLS sequence number checking. --- src/internal.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8a2beb3ef..9f41324cb 100755 --- a/src/internal.c +++ b/src/internal.c @@ -7793,8 +7793,10 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl) cur_lo = ssl->keys.curSeq_lo; /* If the difference between next and cur is > 2^32, way outside window. */ - if ((cur_hi > next_hi + 1) || (next_hi > cur_hi + 1)) + if ((cur_hi > next_hi + 1) || (next_hi > cur_hi + 1)) { + WOLFSSL_MSG("Current record from way too far in the future."); return 0; + } if (cur_hi == next_hi) { curLT = cur_lo < next_lo; @@ -7812,14 +7814,15 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl) if ((next_hi || next_lo > DTLS_SEQ_BITS) && curLT && (diff > DTLS_SEQ_BITS)) { + WOLFSSL_MSG("Current record sequence number from the past."); return 0; } - else if (curLT && (window & ((DtlsSeq)1 << diff))) { - + else if (curLT && (window & ((DtlsSeq)1 << (diff - 1)))) { + WOLFSSL_MSG("Current record sequence number already received."); return 0; } - else if ((cur_hi == next_hi) && (diff > DTLS_SEQ_BITS)) { - + else if (!curLT && (diff > DTLS_SEQ_BITS)) { + WOLFSSL_MSG("Rejecting message too far into the future."); return 0; } @@ -7863,7 +7866,10 @@ static INLINE int DtlsUpdateWindow(WOLFSSL* ssl) *window |= ((DtlsSeq)1 << (diff - 1)); } else { - *window <<= (1 + diff); + if (diff >= DTLS_SEQ_BITS) + *window = 0; + else + *window <<= (1 + diff); *window |= 1; *next_lo = cur_lo + 1; if (*next_lo < cur_lo) @@ -9537,6 +9543,8 @@ int ProcessReply(WOLFSSL* ssl) DtlsPoolReset(ssl); ssl->keys.nextEpoch++; ssl->keys.nextSeq_lo = 0; + ssl->keys.prevWindow = ssl->keys.window; + ssl->keys.window = 0; } #endif From a839b61e8159dbfd13e11b4258cef1078dc58a96 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sun, 2 Oct 2016 13:02:20 -0700 Subject: [PATCH 7/8] initialize temp sequence number --- src/internal.c | 2 +- src/tls.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index 9f41324cb..baccdded1 100755 --- a/src/internal.c +++ b/src/internal.c @@ -3992,7 +3992,7 @@ static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int verify) static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) { - word32 seq[2]; + word32 seq[2] = {0, 0}; if (!ssl->options.dtls) { GetSEQIncrement(ssl, verify, seq); diff --git a/src/tls.c b/src/tls.c index 11d2c5dd2..7e3de3cc2 100644 --- a/src/tls.c +++ b/src/tls.c @@ -688,7 +688,7 @@ static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) { - word32 seq[2]; + word32 seq[2] = {0, 0}; if (!ssl->options.dtls) { GetSEQIncrement(ssl, verify, seq); From 12ac0346f541fc8952ada58e2e908c69f4cd2be3 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 3 Oct 2016 13:51:10 -0700 Subject: [PATCH 8/8] change magic numbers to constants, rename verify parameter of WriteSEQ() and subfunctions --- src/internal.c | 84 +++++++++++++++++++++++++--------------------- src/tls.c | 14 ++++---- wolfssl/internal.h | 6 +++- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/src/internal.c b/src/internal.c index baccdded1..ae27ae8a5 100755 --- a/src/internal.c +++ b/src/internal.c @@ -3941,15 +3941,15 @@ static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) #ifdef WOLFSSL_DTLS -static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) +static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) { - if (verify == -1) { + if (order == PREV_ORDER) { /* Previous epoch case */ seq[0] = ((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 (verify == 1) { + else if (order == PEER_ORDER) { seq[0] = (ssl->keys.curEpoch << 16) | (ssl->keys.curSeq_hi & 0xFFFF); seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ @@ -3961,18 +3961,18 @@ static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) } } -static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int verify) +static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order) { word32 seq; - if (verify == -1) { + if (order == PREV_ORDER) { seq = ssl->keys.dtls_prev_sequence_number_lo++; if (seq > ssl->keys.dtls_prev_sequence_number_lo) { /* handle rollover */ ssl->keys.dtls_prev_sequence_number_hi++; } } - else if (verify == 1) { + else if (order == PEER_ORDER) { seq = ssl->keys.peer_sequence_number_lo++; if (seq > ssl->keys.peer_sequence_number_lo) { /* handle rollover */ @@ -3990,21 +3990,21 @@ static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int verify) #endif /* WOLFSSL_DTLS */ -static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) +static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) { word32 seq[2] = {0, 0}; if (!ssl->options.dtls) { - GetSEQIncrement(ssl, verify, seq); + GetSEQIncrement(ssl, verifyOrder, seq); } else { #ifdef WOLFSSL_DTLS - DtlsGetSEQ(ssl, verify, seq); + DtlsGetSEQ(ssl, verifyOrder, seq); #endif } c32toa(seq[0], out); - c32toa(seq[1], out+4); + c32toa(seq[1], out + OPAQUE32_LEN); } #endif @@ -4109,13 +4109,19 @@ int DtlsPoolSend(WOLFSSL* ssl) for (i = 0, buf = pool->buf; i < pool->used; i++, buf++) { if (pool->epoch[i] == 0) { DtlsRecordLayerHeader* dtls; - int epochZero; + int epochOrder; dtls = (DtlsRecordLayerHeader*)buf->buffer; - epochZero = (ssl->keys.dtls_epoch == 0) ? 0 : -1; + /* If the stored record's epoch is 0, and the currently set + * epoch is 0, use the "current order" sequence number. + * If the stored record's epoch is 0 and the currently set + * epoch is not 0, the stored record is considered a "previous + * order" sequence number. */ + epochOrder = (ssl->keys.dtls_epoch == 0) ? + CUR_ORDER : PREV_ORDER; - WriteSEQ(ssl, epochZero, dtls->sequence_number); - DtlsSEQIncrement(ssl, epochZero); + WriteSEQ(ssl, epochOrder, dtls->sequence_number); + DtlsSEQIncrement(ssl, epochOrder); if ((ret = CheckAvailableSize(ssl, buf->length)) != 0) return ret; @@ -5172,11 +5178,11 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ); *inOutIdx += ENUM_LEN + VERSION_SZ; ato16(input + *inOutIdx, &ssl->keys.curEpoch); - *inOutIdx += 2; + *inOutIdx += OPAQUE16_LEN; ato16(input + *inOutIdx, &ssl->keys.curSeq_hi); - *inOutIdx += 2; + *inOutIdx += OPAQUE16_LEN; ato32(input + *inOutIdx, &ssl->keys.curSeq_lo); - *inOutIdx += 4; /* advance past rest of seq */ + *inOutIdx += OPAQUE32_LEN; /* advance past rest of seq */ ato16(input + *inOutIdx, size); *inOutIdx += LENGTH_SZ; #endif @@ -8085,18 +8091,18 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - WriteSEQ(ssl, 0, nonce + CHACHA20_OLD_OFFSET); + WriteSEQ(ssl, CUR_ORDER, nonce + CHACHA20_OLD_OFFSET); } /* opaque SEQ number stored for AD */ - WriteSEQ(ssl, 0, add); + WriteSEQ(ssl, CUR_ORDER, add); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { additionalSrc -= DTLS_HANDSHAKE_EXTRA; - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); } #endif @@ -8229,11 +8235,11 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, if (ssl->options.oldPoly != 0) { /* get nonce */ - WriteSEQ(ssl, 1, nonce + CHACHA20_OLD_OFFSET); + WriteSEQ(ssl, PEER_ORDER, nonce + CHACHA20_OLD_OFFSET); } /* sequence number field is 64-bits */ - WriteSEQ(ssl, 1, add); + WriteSEQ(ssl, PEER_ORDER, add); /* get AD info */ /* Store the type, version. */ @@ -8376,7 +8382,7 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits */ - WriteSEQ(ssl, 0, additional); + WriteSEQ(ssl, CUR_ORDER, additional); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ @@ -8406,7 +8412,7 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) ForceZero(nonce, AESGCM_NONCE_SZ); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif } break; @@ -8423,7 +8429,7 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits */ - WriteSEQ(ssl, 0, additional); + WriteSEQ(ssl, CUR_ORDER, additional); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ @@ -8453,7 +8459,7 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) ForceZero(nonce, AESGCM_NONCE_SZ); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif } break; @@ -8549,7 +8555,7 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits */ - WriteSEQ(ssl, 1, additional); + WriteSEQ(ssl, PEER_ORDER, additional); additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; @@ -8586,7 +8592,7 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); /* sequence number field is 64-bits */ - WriteSEQ(ssl, 1, additional); + WriteSEQ(ssl, PEER_ORDER, additional); additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; @@ -10057,7 +10063,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, type, 0); #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif } if (ret != 0) @@ -10375,7 +10381,7 @@ int SendCertificate(WOLFSSL* ssl) else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif } @@ -10480,7 +10486,7 @@ int SendCertificateRequest(WOLFSSL* ssl) return ret; } if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -10575,7 +10581,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); } @@ -13012,7 +13018,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, } else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) @@ -15536,7 +15542,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) { @@ -16020,7 +16026,7 @@ int SendCertificateVerify(WOLFSSL* ssl) else { #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); } @@ -16328,7 +16334,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } if (ssl->options.dtls) { - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); } #endif @@ -17657,7 +17663,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -18878,7 +18884,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } if (ssl->options.dtls) - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); #endif ret = HashOutput(ssl, output, sendSz, 0); @@ -19098,7 +19104,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; - DtlsSEQIncrement(ssl, 0); + DtlsSEQIncrement(ssl, CUR_ORDER); } #endif diff --git a/src/tls.c b/src/tls.c index 7e3de3cc2..65504a98e 100644 --- a/src/tls.c +++ b/src/tls.c @@ -664,15 +664,15 @@ static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2]) #ifdef WOLFSSL_DTLS -static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) +static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2]) { - if (verify == -1) { + if (order == PREV_ORDER) { /* Previous epoch case */ seq[0] = ((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 (verify == 1) { + else if (order == PEER_ORDER) { seq[0] = (ssl->keys.curEpoch << 16) | (ssl->keys.curSeq_hi & 0xFFFF); seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */ @@ -686,21 +686,21 @@ static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int verify, word32 seq[2]) #endif /* WOLFSSL_DTLS */ -static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out) +static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) { word32 seq[2] = {0, 0}; if (!ssl->options.dtls) { - GetSEQIncrement(ssl, verify, seq); + GetSEQIncrement(ssl, verifyOrder, seq); } else { #ifdef WOLFSSL_DTLS - DtlsGetSEQ(ssl, verify, seq); + DtlsGetSEQ(ssl, verifyOrder, seq); #endif } c32toa(seq[0], out); - c32toa(seq[1], out+4); + c32toa(seq[1], out + OPAQUE32_LEN); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b56b7b1cd..6f1702c82 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1062,7 +1062,11 @@ enum Misc { HASH_SIG_SIZE = 2, /* default SHA1 RSA */ NO_COPY = 0, /* should we copy static buffer for write */ - COPY = 1 /* should we copy static buffer for write */ + COPY = 1, /* should we copy static buffer for write */ + + PREV_ORDER = -1, /* Sequence number is in previous epoch. */ + PEER_ORDER = 1, /* Peer sequence number for verify. */ + CUR_ORDER = 0 /* Current sequence number. */ };