Watching at TLS 1.2 traffic using Wireshark, I figured out that in the Application Data record, the 64-bit sequence number in some connessions is sent and in others not. Does it depend on the Cipher Suite?
2 Answers
For the exact answer, refer to the standard.
For a short summary: the sequence number is implicit and is not transmitted. Both sender and receiver keep track of how many records they sent and received, so they don't need it to be repeated in the record itself (and if it was there, then they would have to verify it, because the point of the sequence number is to detect duplicates, dropped records, and out-of-order records).
However, TLS 1.1 and 1.2 records have explicit IV, for block cipher modes which require them (in SSL 3.0 and TLS 1.0, the IV for a record was a copy of the last encrypted block of the previous record, which allowed for chosen-plaintext attacks, popularized in the case of TLS under the name "BEAST"). For cipher suites which mandate the CBC mode of encryption, the IV should be randomly generated, and from your wireshark eyes these IV will appear "random". TLS 1.2, though, also supports AEAD encryption modes, which are advanced block cipher modes which not only combine the encryption and the MAC (whereas CBC-based cipher suites need an extra HMAC for integrity), but are also less picky about their IV.
Consider in particular GCM cipher suites, specified in RFC 5288. GCM needs a 12-byte IV, which needs not be random; the only constraint is that no IV value shall be used for more than one record, for a given symmetric key. When GCM is used in TLS, the first 4 bytes of the IV are computed as part of the handshake key derivation, and all records in a given connection use the same values for these four bytes; the remaining 8 bytes are transmitted with the record itself, and it is up to the sender to ensure that no 8-byte value is reused within a specific connection. As RFC 5288 puts it:
Each value of the nonce_explicit MUST be distinct for each distinct
invocation of the GCM encrypt function for any fixed key. Failure to
meet this uniqueness requirement can significantly degrade security.
The nonce_explicit MAY be the 64-bit sequence number.
See in particular this last sentence: using a counter is fine, and the record sequence number is such a counter. This is what you observe: the specific TLS implementation that you are studying appears to use a copy of the sequence number as (part of the) IV for each record. This is allowed, and fine (I repeat: this is fine for GCM cipher suites; for CBC cipher suites, this would be weak).
Mind the details, though: it is not mandatory to use the sequence number for this field; it is not actually mandatory to use a counter at all. The receiving end of a TLS record must not assume that the nonce_explicit
field will be equal to the sequence number; instead, it must use the field value as received. Moreover, both sender and receiver must still keep track of the sequence number, since the sequence number is part of the "authenticated data" in the AEAD computation. It is just convenient and smart to use the sequence number as nonce_explicit
, and RFC 5288, foreseeing the question, explicitly states that it is fine.
(The TLS standard would have been slightly less complex if they had specified that the IV for GCM was the sequence number, without needing to send it on the wire at all; but RFC 5246 tries to be generic in order to accommodate other future AEAD modes which may have other requirements on the IV.)
To efficiently study these details, a good strategy is to implement your own SSL/TLS library -- not for production use, but for the pedagogical value. When your client (respectively server) code succeeds at talking with an existing server (respectively client) implementation, you will have learned a great deal. I'll even assert, from experience, that there is no better method to learn TLS.
Yes, visibility of sequence numbers depends on the cipher suite: In an AEAD cipher, the sequence number is included in the additional data (RFC5246, 6.2.3.3):
additional_data = seq_num + TLSCompressed.type +
TLSCompressed.version +
TLSCompressed.length;
Additional data is authenticated, but not encrypted. Thus you can see its content using Wireshark.
In the other ciphers supported by TLS 1.2, namely stream cipher and CBC block cipher mode, the sequence number is implicitly in the MAC (RFC5246, 6.2.3.1):
MAC = HMAC(MAC_write_key, seq_num +
TLSCompressed.type +
TLSCompressed.version +
TLSCompressed.length +
TLSCompressed.fragment);
Hence it isn't visible there.
![](../../users/profiles/163073.webp)
- 145
- 5
-
May I ask you how many byte is seq_num? and how to count it? And is IV included in fragment? – Zeta Sep 05 '18 at 23:07