It is in the source code of openssh as described in the RFC and we can simply trace its source from there:
/* K1 = HASH(K || H || "A" || session_id) */
if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
ssh_digest_update(hashctx, &c, 1) != 0 ||
ssh_digest_update(hashctx, kex->session_id,
kex->session_id_len) != 0 ||
ssh_digest_final(hashctx, digest, mdsz) != 0) {
[...]
From the RFC:
The exchange hash H from the first key exchange is additionally used as the session identifier, which is a unique identifier for this connection.
This means, that the session_id
is equal to hash
(H
) for the first key exchange. If there is another key exchange later, it is always the hash from the first key exchange.
Checking also code of DH:
/* calc and verify H */
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
[...]
if (kex->session_id == NULL) {
[...]
memcpy(kex->session_id, hash, kex->session_id_len);
}
if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
[...]
confirms this idea. First we calculate H
, then we update session_id
(if not set already) and then we derive the keys (code above).