From 21726d5ae4ad10b6be33042764cb483d28b7a48f Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 19 Sep 2016 16:02:27 -0700 Subject: [PATCH] 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 */