forked from wolfSSL/wolfssl
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.
This commit is contained in:
378
src/internal.c
378
src/internal.c
@ -121,8 +121,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
static INLINE int DtlsCheckWindow(DtlsState* state);
|
static INLINE int DtlsCheckWindow(WOLFSSL* ssl);
|
||||||
static INLINE int DtlsUpdateWindow(DtlsState* state);
|
static INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
/* For DTLS, epoch 0 is always not encrypted. */
|
/* 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;
|
return 0;
|
||||||
#endif /* WOLFSSL_DTLS */
|
#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 */
|
/* convert 16 bit integer to opaque */
|
||||||
static INLINE void c16toa(word16 u16, byte* c)
|
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_hi, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(keys->sequence_number_lo, 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;
|
c16toa(keys->nextEpoch, exp + idx); idx += OPAQUE16_LEN;
|
||||||
c32toa(keys->dtls_state.nextSeq, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->nextSeq, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c16toa(keys->dtls_state.curEpoch, exp + idx); idx += OPAQUE16_LEN;
|
c16toa(keys->curEpoch, exp + idx); idx += OPAQUE16_LEN;
|
||||||
c32toa(keys->dtls_state.curSeq, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->curSeq, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(keys->dtls_state.prevSeq, 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_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN;
|
||||||
c16toa(keys->dtls_expected_peer_handshake_number, exp + idx);
|
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;
|
exp[idx++] = keys->decryptedCur;
|
||||||
|
|
||||||
#ifdef WORD64_AVAILABLE
|
#ifdef WORD64_AVAILABLE
|
||||||
c64toa(keys->dtls_state.window, exp + idx); idx += OPAQUE64_LEN;
|
c64toa(keys->window, exp + idx); idx += OPAQUE64_LEN;
|
||||||
c64toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE64_LEN;
|
c64toa(keys->prevWindow, exp + idx); idx += OPAQUE64_LEN;
|
||||||
#else
|
#else
|
||||||
c32toa(keys->dtls_state.window, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->window, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->prevWindow, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TRUNCATED_HMAC
|
#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_hi); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, &keys->sequence_number_lo); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->sequence_number_lo); idx += OPAQUE32_LEN;
|
||||||
|
|
||||||
ato16(exp + idx, &keys->dtls_state.nextEpoch); idx += OPAQUE16_LEN;
|
ato16(exp + idx, &keys->nextEpoch); idx += OPAQUE16_LEN;
|
||||||
ato32(exp + idx, &keys->dtls_state.nextSeq); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->nextSeq); idx += OPAQUE32_LEN;
|
||||||
ato16(exp + idx, &keys->dtls_state.curEpoch); idx += OPAQUE16_LEN;
|
ato16(exp + idx, &keys->curEpoch); idx += OPAQUE16_LEN;
|
||||||
ato32(exp + idx, &keys->dtls_state.curSeq); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->curSeq); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, &keys->dtls_state.prevSeq); 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_peer_handshake_number); idx += OPAQUE16_LEN;
|
||||||
ato16(exp + idx, &keys->dtls_expected_peer_handshake_number);
|
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++];
|
keys->decryptedCur = exp[idx++];
|
||||||
|
|
||||||
#ifdef WORD64_AVAILABLE
|
#ifdef WORD64_AVAILABLE
|
||||||
ato64(exp + idx, &keys->dtls_state.window); idx += OPAQUE64_LEN;
|
ato64(exp + idx, &keys->window); idx += OPAQUE64_LEN;
|
||||||
ato64(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE64_LEN;
|
ato64(exp + idx, &keys->prevWindow); idx += OPAQUE64_LEN;
|
||||||
#else
|
#else
|
||||||
ato32(exp + idx, &keys->dtls_state.window); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->window); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->prevWindow); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TRUNCATED_HMAC
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
@ -1046,7 +1031,7 @@ static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
|
|||||||
return SOCKET_ERROR_E;
|
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;
|
c16toa((word16)ipSz, exp + idx); idx += DTLS_EXPORT_LEN;
|
||||||
XMEMCPY(exp + idx, ip, ipSz); idx += ipSz;
|
XMEMCPY(exp + idx, ip, ipSz); idx += ipSz;
|
||||||
c16toa(port, exp + idx); idx += DTLS_EXPORT_LEN;
|
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
|
#ifdef WOLFSSL_DTLS
|
||||||
|
|
||||||
int DtlsPoolInit(WOLFSSL* ssl)
|
int DtlsPoolInit(WOLFSSL* ssl)
|
||||||
@ -4022,13 +4099,13 @@ int DtlsPoolSend(WOLFSSL* ssl)
|
|||||||
for (i = 0, buf = pool->buf; i < pool->used; i++, buf++) {
|
for (i = 0, buf = pool->buf; i < pool->used; i++, buf++) {
|
||||||
if (pool->epoch[i] == 0) {
|
if (pool->epoch[i] == 0) {
|
||||||
DtlsRecordLayerHeader* dtls;
|
DtlsRecordLayerHeader* dtls;
|
||||||
word32* seqNumber;
|
int epochZero;
|
||||||
|
|
||||||
dtls = (DtlsRecordLayerHeader*)buf->buffer;
|
dtls = (DtlsRecordLayerHeader*)buf->buffer;
|
||||||
seqNumber = (ssl->keys.dtls_epoch == 0) ?
|
epochZero = (ssl->keys.dtls_epoch == 0) ? 0 : -1;
|
||||||
&ssl->keys.dtls_sequence_number :
|
|
||||||
&ssl->keys.dtls_prev_sequence_number;
|
WriteSEQ(ssl, epochZero, dtls->sequence_number);
|
||||||
c32to48((*seqNumber)++, dtls->sequence_number);
|
DtlsSEQIncrement(ssl, epochZero);
|
||||||
if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
|
if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -4694,8 +4771,7 @@ static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl
|
|||||||
|
|
||||||
/* dtls record layer header extensions */
|
/* dtls record layer header extensions */
|
||||||
dtls = (DtlsRecordLayerHeader*)output;
|
dtls = (DtlsRecordLayerHeader*)output;
|
||||||
c16toa(ssl->keys.dtls_epoch, dtls->epoch);
|
WriteSEQ(ssl, 0, dtls->sequence_number);
|
||||||
c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
|
|
||||||
c16toa((word16)length, dtls->length);
|
c16toa((word16)length, dtls->length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -5085,9 +5161,11 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
/* type and version in same sport */
|
/* type and version in same sport */
|
||||||
XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
|
XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
|
||||||
*inOutIdx += ENUM_LEN + VERSION_SZ;
|
*inOutIdx += ENUM_LEN + VERSION_SZ;
|
||||||
ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
|
ato16(input + *inOutIdx, &ssl->keys.curEpoch);
|
||||||
*inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
|
*inOutIdx += 2;
|
||||||
ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
|
ato16(input + *inOutIdx, &ssl->keys.curSeq_hi);
|
||||||
|
*inOutIdx += 2;
|
||||||
|
ato32(input + *inOutIdx, &ssl->keys.curSeq_lo);
|
||||||
*inOutIdx += 4; /* advance past rest of seq */
|
*inOutIdx += 4; /* advance past rest of seq */
|
||||||
ato16(input + *inOutIdx, size);
|
ato16(input + *inOutIdx, size);
|
||||||
*inOutIdx += LENGTH_SZ;
|
*inOutIdx += LENGTH_SZ;
|
||||||
@ -5096,8 +5174,8 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (IsDtlsNotSctpMode(ssl) &&
|
if (IsDtlsNotSctpMode(ssl) &&
|
||||||
(!DtlsCheckWindow(&ssl->keys.dtls_state) ||
|
(!DtlsCheckWindow(ssl) ||
|
||||||
(ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) {
|
(ssl->options.handShakeDone && ssl->keys.curEpoch == 0))) {
|
||||||
return SEQUENCE_ERROR;
|
return SEQUENCE_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7680,33 +7758,35 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
|
|
||||||
static INLINE int DtlsCheckWindow(DtlsState* state)
|
static INLINE int DtlsCheckWindow(WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
word32 cur;
|
word32 cur_hi, cur_lo, next_hi, next_lo;
|
||||||
word32 next;
|
|
||||||
DtlsSeq window;
|
DtlsSeq window;
|
||||||
|
|
||||||
if (state->curEpoch == state->nextEpoch) {
|
if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
|
||||||
next = state->nextSeq;
|
next_hi = ssl->keys.nextSeq_hi;
|
||||||
window = state->window;
|
next_lo = ssl->keys.nextSeq_lo;
|
||||||
|
window = ssl->keys.window;
|
||||||
}
|
}
|
||||||
else if (state->curEpoch == state->nextEpoch - 1) {
|
else if (ssl->keys.curEpoch == ssl->keys.nextEpoch - 1) {
|
||||||
next = state->prevSeq;
|
next_hi = ssl->keys.prevSeq_hi;
|
||||||
window = state->prevWindow;
|
next_lo = ssl->keys.prevSeq_lo;
|
||||||
|
window = ssl->keys.prevWindow;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* XXX Handle rollover */
|
||||||
|
cur_hi = ssl->keys.curSeq_hi;
|
||||||
|
cur_lo = ssl->keys.curSeq_lo;
|
||||||
|
|
||||||
cur = state->curSeq;
|
if ((next_lo > DTLS_SEQ_BITS) && (cur_lo < next_lo - DTLS_SEQ_BITS)) {
|
||||||
|
|
||||||
if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
|
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (cur > next + DTLS_SEQ_BITS) {
|
else if (cur_lo > next_lo + DTLS_SEQ_BITS) {
|
||||||
return 0;
|
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 cur;
|
||||||
word32* next;
|
word32* next;
|
||||||
DtlsSeq* window;
|
DtlsSeq* window;
|
||||||
|
|
||||||
if (state->curEpoch == state->nextEpoch) {
|
if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
|
||||||
next = &state->nextSeq;
|
next = &ssl->keys.nextSeq_lo;
|
||||||
window = &state->window;
|
window = &ssl->keys.window;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next = &state->prevSeq;
|
next = &ssl->keys.prevSeq_lo;
|
||||||
window = &state->prevWindow;
|
window = &ssl->keys.prevWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = state->curSeq;
|
cur = ssl->keys.curSeq_lo;
|
||||||
|
|
||||||
if (cur < *next) {
|
if (cur < *next) {
|
||||||
*window |= ((DtlsSeq)1 << (*next - cur - 1));
|
*window |= ((DtlsSeq)1 << (*next - cur - 1));
|
||||||
@ -7864,55 +7944,6 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#endif
|
#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
|
#ifdef HAVE_AEAD
|
||||||
static INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
|
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) {
|
if (ssl->options.oldPoly != 0) {
|
||||||
/* get nonce */
|
/* 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 */
|
/* 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. */
|
* the input buffer ahead of the plaintext. */
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
c16toa(ssl->keys.dtls_epoch, add);
|
|
||||||
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -8142,23 +8173,18 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
|
|||||||
|
|
||||||
if (ssl->options.oldPoly != 0) {
|
if (ssl->options.oldPoly != 0) {
|
||||||
/* get nonce */
|
/* 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 */
|
/* sequence number field is 64-bits */
|
||||||
WriteSEQ(ssl, 1, add);
|
WriteSEQ(ssl, 1, add);
|
||||||
|
|
||||||
/* get AD info */
|
/* get AD info */
|
||||||
|
/* Store the type, version. */
|
||||||
add[AEAD_TYPE_OFFSET] = ssl->curRL.type;
|
add[AEAD_TYPE_OFFSET] = ssl->curRL.type;
|
||||||
add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
||||||
add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
|
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 TLS message size to additional data */
|
||||||
add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
|
add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
|
||||||
add[AEAD_AUTH_DATA_SZ - 1] = msgLen & 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. */
|
* the input buffer ahead of the plaintext. */
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
c16toa(ssl->keys.dtls_epoch, additional);
|
|
||||||
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -8323,6 +8348,10 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz)
|
|||||||
additional, AEAD_AUTH_DATA_SZ);
|
additional, AEAD_AUTH_DATA_SZ);
|
||||||
AeadIncrementExpIV(ssl);
|
AeadIncrementExpIV(ssl);
|
||||||
ForceZero(nonce, AESGCM_NONCE_SZ);
|
ForceZero(nonce, AESGCM_NONCE_SZ);
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#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. */
|
* the input buffer ahead of the plaintext. */
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
c16toa(ssl->keys.dtls_epoch, additional);
|
|
||||||
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -8367,6 +8395,10 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz)
|
|||||||
additional, AEAD_AUTH_DATA_SZ);
|
additional, AEAD_AUTH_DATA_SZ);
|
||||||
AeadIncrementExpIV(ssl);
|
AeadIncrementExpIV(ssl);
|
||||||
ForceZero(nonce, AESGCM_NONCE_SZ);
|
ForceZero(nonce, AESGCM_NONCE_SZ);
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -8463,11 +8495,6 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
|
|||||||
/* sequence number field is 64-bits */
|
/* sequence number field is 64-bits */
|
||||||
WriteSEQ(ssl, 1, additional);
|
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_TYPE_OFFSET] = ssl->curRL.type;
|
||||||
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
||||||
additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
|
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 */
|
/* sequence number field is 64-bits */
|
||||||
WriteSEQ(ssl, 1, additional);
|
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_TYPE_OFFSET] = ssl->curRL.type;
|
||||||
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
||||||
additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
|
additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
|
||||||
@ -9353,7 +9375,7 @@ int ProcessReply(WOLFSSL* ssl)
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (IsDtlsNotSctpMode(ssl)) {
|
if (IsDtlsNotSctpMode(ssl)) {
|
||||||
DtlsUpdateWindow(&ssl->keys.dtls_state);
|
DtlsUpdateWindow(ssl);
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
@ -9463,8 +9485,8 @@ int ProcessReply(WOLFSSL* ssl)
|
|||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
DtlsPoolReset(ssl);
|
DtlsPoolReset(ssl);
|
||||||
ssl->keys.dtls_state.nextEpoch++;
|
ssl->keys.nextEpoch++;
|
||||||
ssl->keys.dtls_state.nextSeq = 0;
|
ssl->keys.nextSeq_lo = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -9975,6 +9997,10 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
|
|||||||
#endif
|
#endif
|
||||||
ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
|
ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
|
||||||
type, 0);
|
type, 0);
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -10012,9 +10038,12 @@ int SendFinished(WOLFSSL* ssl)
|
|||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
headerSz += DTLS_HANDSHAKE_EXTRA;
|
headerSz += DTLS_HANDSHAKE_EXTRA;
|
||||||
ssl->keys.dtls_epoch++;
|
ssl->keys.dtls_epoch++;
|
||||||
ssl->keys.dtls_prev_sequence_number =
|
ssl->keys.dtls_prev_sequence_number_hi =
|
||||||
ssl->keys.dtls_sequence_number;
|
ssl->keys.dtls_sequence_number_hi;
|
||||||
ssl->keys.dtls_sequence_number = 0;
|
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
|
#endif
|
||||||
|
|
||||||
@ -10199,7 +10228,6 @@ int SendCertificate(WOLFSSL* ssl)
|
|||||||
HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
|
HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
|
||||||
/* Adding the headers increments these, decrement them for
|
/* Adding the headers increments these, decrement them for
|
||||||
* actual message header. */
|
* actual message header. */
|
||||||
ssl->keys.dtls_sequence_number--;
|
|
||||||
ssl->keys.dtls_handshake_number--;
|
ssl->keys.dtls_handshake_number--;
|
||||||
AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
|
AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
|
||||||
ssl->keys.dtls_handshake_number--;
|
ssl->keys.dtls_handshake_number--;
|
||||||
@ -10286,6 +10314,10 @@ int SendCertificate(WOLFSSL* ssl)
|
|||||||
if (sendSz < 0)
|
if (sendSz < 0)
|
||||||
return sendSz;
|
return sendSz;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (IsDtlsNotSctpMode(ssl)) {
|
if (IsDtlsNotSctpMode(ssl)) {
|
||||||
@ -10310,10 +10342,7 @@ int SendCertificate(WOLFSSL* ssl)
|
|||||||
if (ret != WANT_WRITE) {
|
if (ret != WANT_WRITE) {
|
||||||
/* Clean up the fragment offset. */
|
/* Clean up the fragment offset. */
|
||||||
ssl->fragOffset = 0;
|
ssl->fragOffset = 0;
|
||||||
#ifdef WOLFSSL_DTLS
|
ssl->keys.dtls_handshake_number++;
|
||||||
if (ssl->options.dtls)
|
|
||||||
ssl->keys.dtls_handshake_number++;
|
|
||||||
#endif
|
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END)
|
if (ssl->options.side == WOLFSSL_SERVER_END)
|
||||||
ssl->options.serverState = SERVER_CERT_COMPLETE;
|
ssl->options.serverState = SERVER_CERT_COMPLETE;
|
||||||
}
|
}
|
||||||
@ -10387,6 +10416,8 @@ int SendCertificateRequest(WOLFSSL* ssl)
|
|||||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
@ -10478,8 +10509,13 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
|
|||||||
if (sendSz < 0)
|
if (sendSz < 0)
|
||||||
ret = sendSz;
|
ret = sendSz;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
if (ret == 0 && IsDtlsNotSctpMode(ssl))
|
if (ret == 0 && IsDtlsNotSctpMode(ssl))
|
||||||
@ -12911,6 +12947,10 @@ static void PickHashSigAlgo(WOLFSSL* ssl,
|
|||||||
if (sendSz < 0)
|
if (sendSz < 0)
|
||||||
return sendSz;
|
return sendSz;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -15431,6 +15471,10 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto exit_scke;
|
goto exit_scke;
|
||||||
@ -15911,6 +15955,10 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
#endif
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16134,7 +16182,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
/* Server Hello should use the same sequence number as the
|
/* Server Hello should use the same sequence number as the
|
||||||
* Client Hello. */
|
* 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;
|
idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||||
sendSz += 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)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl->options.dtls) {
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
@ -17539,6 +17592,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
goto exit_sske;
|
goto exit_sske;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
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)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
@ -18975,6 +19034,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
DtlsSEQIncrement(ssl, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* Hello Verify Request should use the same sequence number as the
|
||||||
* Client Hello. */
|
* 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);
|
AddHeaders(output, length, hello_verify_request, ssl);
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
|
63
src/tls.c
63
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])
|
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) {
|
if (verify) {
|
||||||
seq[0] = ssl->keys.peer_sequence_number_hi;
|
seq[0] = ssl->keys.peer_sequence_number_hi;
|
||||||
seq[1] = ssl->keys.peer_sequence_number_lo++;
|
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)
|
static INLINE void WriteSEQ(WOLFSSL* ssl, int verify, byte* out)
|
||||||
{
|
{
|
||||||
word32 seq[2];
|
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[0], out);
|
||||||
c32toa(seq[1], out+4);
|
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 ***/
|
/*** 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);
|
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);
|
WriteSEQ(ssl, verify, inner);
|
||||||
inner[SEQ_SZ] = (byte)content;
|
inner[SEQ_SZ] = (byte)content;
|
||||||
inner[SEQ_SZ + ENUM_LEN] = ssl->version.major;
|
inner[SEQ_SZ + ENUM_LEN] = ssl->version.major;
|
||||||
|
@ -994,7 +994,7 @@ enum Misc {
|
|||||||
|
|
||||||
CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */
|
CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */
|
||||||
CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */
|
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 */
|
/* For any new implicit/explicit IV size adjust AEAD_MAX_***_SZ */
|
||||||
|
|
||||||
@ -1581,18 +1581,6 @@ typedef struct WOLFSSL_DTLS_CTX {
|
|||||||
#endif
|
#endif
|
||||||
#define DTLS_SEQ_BITS (sizeof(DtlsSeq) * CHAR_BIT)
|
#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 */
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
|
|
||||||
@ -1619,13 +1607,27 @@ typedef struct Keys {
|
|||||||
word32 sequence_number_lo;
|
word32 sequence_number_lo;
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#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_peer_handshake_number;
|
||||||
word16 dtls_expected_peer_handshake_number;
|
word16 dtls_expected_peer_handshake_number;
|
||||||
|
|
||||||
word32 dtls_sequence_number; /* Current tx sequence */
|
word16 dtls_epoch; /* Current epoch */
|
||||||
word32 dtls_prev_sequence_number; /* Previous epoch's seq number*/
|
word32 dtls_sequence_number_hi; /* Current epoch */
|
||||||
word16 dtls_epoch; /* Current tx 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 */
|
word16 dtls_handshake_number; /* Current tx handshake seq */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2569,8 +2571,7 @@ typedef struct DtlsRecordLayerHeader {
|
|||||||
byte type;
|
byte type;
|
||||||
byte pvMajor;
|
byte pvMajor;
|
||||||
byte pvMinor;
|
byte pvMinor;
|
||||||
byte epoch[2]; /* increment on cipher state change */
|
byte sequence_number[8]; /* per record */
|
||||||
byte sequence_number[6]; /* per record */
|
|
||||||
byte length[2];
|
byte length[2];
|
||||||
} DtlsRecordLayerHeader;
|
} DtlsRecordLayerHeader;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user