// Copyright 2024 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package ssh implements the SSH KDF as specified in RFC 4253, // Section 7.2 and allowed by SP 800-135 Revision 1. package ssh import ( "crypto/internal/fips140" _ "crypto/internal/fips140/check" ) type Direction struct { ivTag []byte keyTag []byte macKeyTag []byte } var ServerKeys, ClientKeys Direction func init() { ServerKeys = Direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}} ClientKeys = Direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}} } func Keys[Hash fips140.Hash](hash func() Hash, d Direction, K, H, sessionID []byte, ivKeyLen, keyLen, macKeyLen int, ) (ivKey, key, macKey []byte) { h := hash() generateKeyMaterial := func(tag []byte, length int) []byte { var key []byte for len(key) < length { h.Reset() h.Write(K) h.Write(H) if len(key) == 0 { h.Write(tag) h.Write(sessionID) } else { h.Write(key) } key = h.Sum(key) } return key[:length] } ivKey = generateKeyMaterial(d.ivTag, ivKeyLen) key = generateKeyMaterial(d.keyTag, keyLen) macKey = generateKeyMaterial(d.macKeyTag, macKeyLen) return }