| // Copyright 2012 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 | |
| // Message authentication support | |
| import ( | |
| "crypto/fips140" | |
| "crypto/hmac" | |
| "crypto/sha1" | |
| "crypto/sha256" | |
| "crypto/sha512" | |
| "hash" | |
| "slices" | |
| ) | |
| type macMode struct { | |
| keySize int | |
| etm bool | |
| new func(key []byte) hash.Hash | |
| } | |
| // truncatingMAC wraps around a hash.Hash and truncates the output digest to | |
| // a given size. | |
| type truncatingMAC struct { | |
| length int | |
| hmac hash.Hash | |
| } | |
| func (t truncatingMAC) Write(data []byte) (int, error) { | |
| return t.hmac.Write(data) | |
| } | |
| func (t truncatingMAC) Sum(in []byte) []byte { | |
| out := t.hmac.Sum(in) | |
| return out[:len(in)+t.length] | |
| } | |
| func (t truncatingMAC) Reset() { | |
| t.hmac.Reset() | |
| } | |
| func (t truncatingMAC) Size() int { | |
| return t.length | |
| } | |
| func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } | |
| // macModes defines the supported MACs. MACs not included are not supported | |
| // and will not be negotiated, even if explicitly configured. When FIPS mode is | |
| // enabled, only FIPS-approved algorithms are included. | |
| var macModes = map[string]*macMode{} | |
| func init() { | |
| macModes[HMACSHA512ETM] = &macMode{64, true, func(key []byte) hash.Hash { | |
| return hmac.New(sha512.New, key) | |
| }} | |
| macModes[HMACSHA256ETM] = &macMode{32, true, func(key []byte) hash.Hash { | |
| return hmac.New(sha256.New, key) | |
| }} | |
| macModes[HMACSHA512] = &macMode{64, false, func(key []byte) hash.Hash { | |
| return hmac.New(sha512.New, key) | |
| }} | |
| macModes[HMACSHA256] = &macMode{32, false, func(key []byte) hash.Hash { | |
| return hmac.New(sha256.New, key) | |
| }} | |
| if fips140.Enabled() { | |
| defaultMACs = slices.DeleteFunc(defaultMACs, func(algo string) bool { | |
| _, ok := macModes[algo] | |
| return !ok | |
| }) | |
| return | |
| } | |
| macModes[HMACSHA1] = &macMode{20, false, func(key []byte) hash.Hash { | |
| return hmac.New(sha1.New, key) | |
| }} | |
| macModes[InsecureHMACSHA196] = &macMode{20, false, func(key []byte) hash.Hash { | |
| return truncatingMAC{12, hmac.New(sha1.New, key)} | |
| }} | |
| } |