Use 16-byte secret for SHA2

4-byte secrets are too short for SHA hash algorithm.

PiperOrigin-RevId: 584518939
This commit is contained in:
Zeling Feng
2023-11-21 22:39:54 -08:00
committed by gVisor bot
parent 56109719c5
commit e54bfde792
2 changed files with 16 additions and 13 deletions
+2 -4
View File
@@ -235,15 +235,13 @@ func (h *handshake) resetState() {
// generateSecureISN generates a secure Initial Sequence number based on the
// recommendation here https://tools.ietf.org/html/rfc6528#page-3.
func generateSecureISN(id stack.TransportEndpointID, clock tcpip.Clock, seed uint32) seqnum.Value {
func generateSecureISN(id stack.TransportEndpointID, clock tcpip.Clock, seed [16]byte) seqnum.Value {
isnHasher := sha256.New()
seedBuf := make([]byte, 4)
binary.LittleEndian.PutUint32(seedBuf, seed)
// Per hash.Hash.Writer:
//
// It never returns an error.
_, _ = isnHasher.Write(seedBuf)
_, _ = isnHasher.Write(seed[:])
_, _ = isnHasher.Write(id.LocalAddress.AsSlice())
_, _ = isnHasher.Write(id.RemoteAddress.AsSlice())
portBuf := make([]byte, 2)
+14 -9
View File
@@ -18,6 +18,7 @@ package tcp
import (
"crypto/sha256"
"encoding/binary"
"fmt"
"runtime"
"strings"
"time"
@@ -108,9 +109,8 @@ type protocol struct {
dispatcher dispatcher
// The following secrets are initialized once and stay unchanged after.
seqnumSecret uint32
portOffsetSecret uint32
tsOffsetSecret uint32
seqnumSecret [16]byte
tsOffsetSecret [16]byte
}
// Number returns the tcp protocol number.
@@ -181,12 +181,10 @@ func (p *protocol) tsOffset(src, dst tcpip.Address) tcp.TSOffset {
// why this is required.
h := sha256.New()
secretBuf := make([]byte, 4)
binary.LittleEndian.PutUint32(secretBuf, p.tsOffsetSecret)
// Per hash.Hash.Writer:
//
// It never returns an error.
_, _ = h.Write(secretBuf)
_, _ = h.Write(p.tsOffsetSecret[:])
_, _ = h.Write(src.AsSlice())
_, _ = h.Write(dst.AsSlice())
return tcp.NewTSOffset(binary.LittleEndian.Uint32(h.Sum(nil)[:4]))
@@ -510,6 +508,14 @@ func (*protocol) Parse(pkt stack.PacketBufferPtr) bool {
// NewProtocol returns a TCP transport protocol.
func NewProtocol(s *stack.Stack) stack.TransportProtocol {
rng := s.SecureRNG()
var seqnumSecret [16]byte
var tsOffsetSecret [16]byte
if n, err := rng.Reader.Read(seqnumSecret[:]); err != nil || n != len(seqnumSecret) {
panic(fmt.Sprintf("Read() failed: %v", err))
}
if n, err := rng.Reader.Read(tsOffsetSecret[:]); err != nil || n != len(tsOffsetSecret) {
panic(fmt.Sprintf("Read() failed: %v", err))
}
p := protocol{
stack: s,
sendBufferSize: tcpip.TCPSendBufferSizeRangeOption{
@@ -533,9 +539,8 @@ func NewProtocol(s *stack.Stack) stack.TransportProtocol {
maxRTO: MaxRTO,
maxRetries: MaxRetries,
recovery: tcpip.TCPRACKLossDetection,
seqnumSecret: rng.Uint32(),
portOffsetSecret: rng.Uint32(),
tsOffsetSecret: rng.Uint32(),
seqnumSecret: seqnumSecret,
tsOffsetSecret: tsOffsetSecret,
}
p.dispatcher.init(s.InsecureRNG(), runtime.GOMAXPROCS(0))
return &p