Source file src/vendor/golang.org/x/net/quic/stateless_reset.go

     1  // Copyright 2023 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 quic
     6  
     7  import (
     8  	"crypto/hmac"
     9  	"crypto/rand"
    10  	"crypto/sha256"
    11  	"hash"
    12  	"sync"
    13  )
    14  
    15  const statelessResetTokenLen = 128 / 8
    16  
    17  // A statelessResetToken is a stateless reset token.
    18  // https://www.rfc-editor.org/rfc/rfc9000#section-10.3
    19  type statelessResetToken [statelessResetTokenLen]byte
    20  
    21  type statelessResetTokenGenerator struct {
    22  	canReset bool
    23  
    24  	// The hash.Hash interface is not concurrency safe,
    25  	// so we need a mutex here.
    26  	//
    27  	// There shouldn't be much contention on stateless reset token generation.
    28  	// If this proves to be a problem, we could avoid the mutex by using a separate
    29  	// generator per Conn, or by using a concurrency-safe generator.
    30  	mu  sync.Mutex
    31  	mac hash.Hash
    32  }
    33  
    34  func (g *statelessResetTokenGenerator) init(secret [32]byte) {
    35  	zero := true
    36  	for _, b := range secret {
    37  		if b != 0 {
    38  			zero = false
    39  			break
    40  		}
    41  	}
    42  	if zero {
    43  		// Generate tokens using a random secret, but don't send stateless resets.
    44  		rand.Read(secret[:])
    45  		g.canReset = false
    46  	} else {
    47  		g.canReset = true
    48  	}
    49  	g.mac = hmac.New(sha256.New, secret[:])
    50  }
    51  
    52  func (g *statelessResetTokenGenerator) tokenForConnID(cid []byte) (token statelessResetToken) {
    53  	g.mu.Lock()
    54  	defer g.mu.Unlock()
    55  	defer g.mac.Reset()
    56  	g.mac.Write(cid)
    57  	copy(token[:], g.mac.Sum(nil))
    58  	return token
    59  }
    60  

View as plain text