In the last post of the TLS traffic visibility series, before a survey of solutions, I drew attention to how in TLS 1.3 different kinds of traffic are protected under different keys and sometimes with different ciphers, and how client and server can update their application traffic keys at any time. I referred to this as the multiple protection state problem of TLS 1.3.
This problem means that PFS visibility solutions where a single symmetric session key per direction of traffic is sent to a passive visibility middlebox will not work for TLS 1.3 even if they work for TLS 1.2. I mentioned two such solutions in the previous post, one of them being Nubeva’s Symmetric Key Intercept (SKI), described in a presentation at a NIST workshop.
In response to the blog post, Nubeva has sent me a detailed explanation of how their SKI solution handles the multiplicity of symmetric keys in TLS 1.3. It turns out that, although the solution is called Symmetric Key Intercept and the workshop presentation referred to the extraction of symmetric keys from system memory, it is not the symmetric keys that are extracted and sent to a decryptor, but rather the TLS 1.3 traffic secrets, from which the symmetric keys are derived by the decryptor as described in Nubeva’s response.
The Nubeva solution is thus similar to the ST variant of the Pomcor visibility solution, where the server sends the traffic secrets to the visibility middlebox. Sending the traffic secrets to the decryptor rather than the traffic keys solves the key update problem of TLS 1.3. I explained this in the third post of the series as follows:
Notice also that the server must send the application traffic secrets and let the middlebox derive the traffic keys from the traffic secrets instead of sending the traffic keys, because the application traffic secrets established during the handshake are only the first versions of those secrets, client_application_secret_0 and server_application_secret_0, and the middlebox may need the secrets to derive subsequent versions of the secrets and the traffic keys if the client and/or the server perform a key update as described in Sections 4.6.3 and 7.2 of the RFC. For consistency, the server also sends the handshake and early traffic secrets instead of the handshake and early traffic keys in Figure 3.
Nubeva provides a similar explanation in its response.
Nubeva’s SKI and the ST variant are similar in this respect, but they are substantially different in another respect. In SKI the traffic secrets are extracted from the system memory of the TLS server (or the TLS client) by an “SKI Sensor” that is given access to the system memory of the machine. This has the practical advantage that the code of the TLS server does not need to be modified to support the visibility solution. On the other hand, for inbound traffic, i.e. in the case where the client is in the external network, it has the disadvantage that only those secrets that the server computes can be extracted.
If the client sends early data the server is free to reject it by sending a HelloRetryRequest message or not including an early_data extension in the EncryptedExtensions message. When it does so, it does not compute the client_early_traffic_secret, and the SKI Sensor cannot extract that secret and send it to the decryptor. By contrast, in ST, “the server must send the early traffic secret when the client sends early data even if the server intends to reject the early data, so that the middlebox can decrypt the data and forward it to the monitoring facility”.
The SKI Sensor can extract traffic secrets from the client as well as from the server, so when the client is in the internal network, i.e. in the case of outbound traffic or traffic entirely within the intranet, the SKI Sensor can extract the early traffic secret from the client whether or not the server rejects the early data, and send it to the decryptor.
In the case of inbound traffic, one could argue that there is no need to decrypt rejected early data because the server does not see it. But the purpose of decrypting TLS traffic is to inspect it, and one reason for inspecting traffic is to perform intrusion detection. Therefore one must assume that the early data may be malicious. As an example of malicious early data, an attacker who has gained a foothold on a network appliance along the client-server path could use early data rejected by the server and ignored by the visibility middlebox as a convenient vector for silently configuring and controlling the malicious code in the network device. If I’m not mistaken, the fact that the server can reject early data without decrypting it creates a cybersecurity risk.
To mitigate that risk, the visibility middlebox must attempt to decrypt rejected early data. Decryption may fail if the data is malicious, but decryption failure would be an indication that the early data is malicious and a sign of intrusion.
To decrypt the rejected early data the visibility middlebox needs the client_early_traffic_secret. But that’s not all. It also needs the cypher suite associated with the first PSK listed by the client so that is can use the hash function specified by the cypher suite in the derivation of the early traffic keys from the early traffic secret, and the AEAD algorithm to decrypt the early data with those keys.
It would make sense for the client to list the cypher suite associated with the first PSK as the first of its proposed cypher suites, but TLS 1.3 does not require that. The server is supposed to have the PSK and know what cipher suite is associated with it. So the middlebox has to be told what cypher suite to use. I had not realized that when I wrote the third post of the series, so I’ve updated it now to specify that the server sends the cypher suite associated with the fist PSK, which I call the “early cipher suite” along with the early traffic secret, and, for consistency, also sends the cypher suite selected by the server, which I call the “late cypher suite”, along with the handshake traffic secrets and the non-early application traffic secrets.