Source file src/crypto/internal/fips140/ssh/kdf.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package ssh implements the SSH KDF as specified in RFC 4253,
     6  // Section 7.2 and allowed by SP 800-135 Revision 1.
     7  package ssh
     8  
     9  import (
    10  	"crypto/internal/fips140"
    11  	_ "crypto/internal/fips140/check"
    12  )
    13  
    14  type Direction struct {
    15  	ivTag     []byte
    16  	keyTag    []byte
    17  	macKeyTag []byte
    18  }
    19  
    20  var ServerKeys, ClientKeys Direction
    21  
    22  func init() {
    23  	ServerKeys = Direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}
    24  	ClientKeys = Direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
    25  }
    26  
    27  func Keys[Hash fips140.Hash](hash func() Hash, d Direction,
    28  	K, H, sessionID []byte,
    29  	ivKeyLen, keyLen, macKeyLen int,
    30  ) (ivKey, key, macKey []byte) {
    31  
    32  	h := hash()
    33  	generateKeyMaterial := func(tag []byte, length int) []byte {
    34  		var key []byte
    35  		for len(key) < length {
    36  			h.Reset()
    37  			h.Write(K)
    38  			h.Write(H)
    39  			if len(key) == 0 {
    40  				h.Write(tag)
    41  				h.Write(sessionID)
    42  			} else {
    43  				h.Write(key)
    44  			}
    45  			key = h.Sum(key)
    46  		}
    47  		return key[:length]
    48  	}
    49  
    50  	ivKey = generateKeyMaterial(d.ivTag, ivKeyLen)
    51  	key = generateKeyMaterial(d.keyTag, keyLen)
    52  	macKey = generateKeyMaterial(d.macKeyTag, macKeyLen)
    53  
    54  	return
    55  }
    56  

View as plain text