Skip to main content

7.2. Output from Key Exchange

7.2. Output from Key Exchange

The key exchange produces two values: a shared secret K, and an exchange hash H. Encryption and authentication keys are derived from these. The exchange hash H from the first key exchange is additionally used as the session identifier, which is a unique identifier for this connection. It is used by authentication methods as a part of the data that is signed as a proof of possession of a private key. Once computed, the session identifier is not changed, even if keys are later re-exchanged.

Each key exchange method specifies a hash function that is used in the key exchange. The same hash algorithm MUST be used in key derivation. Here, we'll call it HASH.

Encryption keys MUST be computed as HASH, of a known value and K, as follows:

  • Initial IV client to server: HASH(K || H || "A" || session_id)
  • Initial IV server to client: HASH(K || H || "B" || session_id)
  • Encryption key client to server: HASH(K || H || "C" || session_id)
  • Encryption key server to client: HASH(K || H || "D" || session_id)
  • Integrity key client to server: HASH(K || H || "E" || session_id)
  • Integrity key server to client: HASH(K || H || "F" || session_id)

Key data MUST be taken from the beginning of the hash output. As many bytes as needed are taken from the beginning of the hash value. If the key length needed is longer than the output of the HASH, the key is extended by computing HASH of the concatenation of K and H and the entire key so far, and appending the resulting bytes (as many as HASH generates) to the key. This process is repeated until enough key material is available; the key is taken from the beginning of this value. In other words:

K1 = HASH(K || H || X || session_id)   (X is e.g., "A")
K2 = HASH(K || H || K1)
K3 = HASH(K || H || K1 || K2)
...
key = K1 || K2 || K3 || ...

This process will lose entropy if the amount of entropy in K is larger than the internal state size of HASH.