blob: 431deda8dda9ae631f6bdf413ff5916dc36abb90 [file] [log] [blame] [edit]
// 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/check"
"hash"
)
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 hash.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
}