Encrypt-then-MAC for Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)
Extracted elements (20)
Introducing encrypt-then-MAC via the extension mechanism rather than waiting for TLS 1.3 is justified because TLS 1.3 would require full implementation and deployment of TLS 1.2 merely to support a trivial ordering change, whereas the extension mechanism allows incremental deployment.
The use of TLS extensions precludes use with SSL 3.0, which is intentional: SSL 3.0 is nearly two decades old and likely vulnerable to many other attacks, making backward compatibility with it not worth the effort.
Using a TLS/DTLS extension to negotiate encrypt-then-MAC is preferred over defining new ciphersuites because new ciphersuites would cause a Cartesian explosion requiring duplication of every existing suite. The extension approach requires a single new extension type and changed less than a dozen lines of code in one implementation.
Encrypt-then-MAC applies exclusively to GenericBlockCipher ciphersuites. GenericStreamCiphers and GenericAEADCiphers already include integrity protection within the cipher and are therefore unaffected by this extension.
Encrypt-then-MAC applies only to block ciphers (GenericBlockCipher). If a server receives an encrypt-then-MAC request extension but then selects a stream or AEAD ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the client.
For TLS, a MAC verification failure MUST generate a fatal bad_record_mac alert. For DTLS, the record MUST be discarded and a fatal bad_record_mac MAY be generated.
Implementations MAY negotiate a truncated MAC through the TLS truncated_hmac extension (RFC 6066) when using encrypt-then-MAC.
Implementations MUST NOT renegotiate a downgrade from encrypt-then-MAC to MAC-then-encrypt, directly or indirectly (e.g., via an intermediate AEAD ciphersuite selection followed by a MAC-then-encrypt selection).
Implementations SHOULD retain the current session's MAC ordering (encrypt-then-MAC or MAC-then-encrypt) across all rehandshakes for that session, and SHOULD NOT change state during a rehandshake.
The client and server MUST NOT use encrypt-then-MAC unless both sides have successfully exchanged encrypt_then_mac extensions.
The MAC SHALL be evaluated before any further processing such as decryption is performed. If MAC verification fails, processing SHALL terminate immediately.
For TLS 1.0 (without explicit IV), the MAC is computed as MAC(MAC_write_key, seq_num + TLSCipherText.type + TLSCipherText.version + TLSCipherText.length + ENC(content+padding+padding_length)). For TLS 1.1 and greater with explicit IV, the IV field is included between the length and the encrypted payload in the MAC input.
The encrypt_then_mac TLS extension is identified by extension_type value 22 (0x16) and carries an empty extension_data field. The client includes it in ClientHello to request encrypt-then-MAC; the server echoes it in ServerHello to confirm.
When an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated during rehandshake, the change takes effect in the first message following the Change Cipher Spec (CCS) message. All messages up to and including the CCS use MAC-then-encrypt.
IANA has added extension code point 22 (0x16) for the encrypt_then_mac extension to the TLS 'ExtensionType Values' registry as specified in TLS (RFC 5246).
An active attacker who can emulate a client or server with extension intolerance may cause implementations to fall back to older protocol versions that do not support extensions, forcing non-encrypt-then-MAC behaviour. The recommended mitigation is to avoid fallback to older, less secure protocol versions.
Immediate MAC verification before decryption eliminates timing side-channels that could otherwise be exploited through manipulated packet data, which were a key vulnerability of the original MAC-then-encrypt construction.
Rehandshake rules for encrypt-then-MAC: MAC-then-encrypt -> MAC-then-encrypt is no change; MAC-then-encrypt -> encrypt-then-MAC is an upgrade; encrypt-then-MAC -> MAC-then-encrypt is an error (downgrade forbidden); encrypt-then-MAC -> encrypt-then-MAC is no change. These rules apply across all rehandshakes, including indirect downgrades via AEAD ciphersuites.
The encrypt-then-MAC TLS packet structure is: {ContentType type; ProtocolVersion version; uint16 length; GenericBlockCipher fragment; opaque MAC;}. The DTLS equivalent adds uint16 epoch and uint48 sequence_number fields between version and length.
Under encrypt-then-MAC, TLS processing switches from encrypt(data||MAC||pad) to encrypt(data||pad)||MAC, with the MAC covering the entire packet up to the start of the MAC value. The TLSCiphertext struct gains a trailing opaque MAC field outside the GenericBlockCipher fragment.