TUN-8858: update go to 1.22.10 and include quic-go FIPS changes

## Summary

To have support for new curves and to achieve FIPS compliance Cloudflared must be released with [Go-Boring-1.22.10](https://bitbucket.cfdata.org/projects/PLAT/repos/goboring/browse?at=refs/heads/go-boring/1.22.10 "Follow link") along with the quic-go patches. 

 Closes TUN-8858
This commit is contained in:
Luis Neto
2025-01-30 03:11:54 -08:00
parent 0f1bfe99ce
commit 45f67c23fd
15 changed files with 108 additions and 20 deletions

View File

@@ -8,7 +8,9 @@ import (
"fmt"
"io"
"net"
"os"
"reflect"
"strconv"
"sync"
"sync/atomic"
"time"
@@ -288,6 +290,16 @@ var newConnection = func(
s.logger,
)
s.maxPayloadSizeEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize))))
// Allow server to define custom MaxUDPPayloadSize
maxUDPPayloadSize := protocol.MaxPacketBufferSize
if maxPacketSize := os.Getenv("TUNNEL_MAX_QUIC_PACKET_SIZE"); maxPacketSize != "" {
if customMaxPacketSize, err := strconv.ParseUint(maxPacketSize, 10, 64); err == nil {
maxUDPPayloadSize = int(customMaxPacketSize)
} else {
utils.DefaultLogger.Errorf("failed to parse TUNNEL_MAX_QUIC_PACKET_SIZE: %v", err)
}
}
params := &wire.TransportParameters{
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
@@ -298,7 +310,7 @@ var newConnection = func(
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
MaxAckDelay: protocol.MaxAckDelayInclGranularity,
AckDelayExponent: protocol.AckDelayExponent,
MaxUDPPayloadSize: protocol.MaxPacketBufferSize,
MaxUDPPayloadSize: protocol.ByteCount(maxUDPPayloadSize),
DisableActiveMigration: true,
StatelessResetToken: &statelessResetToken,
OriginalDestinationConnectionID: origDestConnID,

View File

@@ -12,7 +12,9 @@ import (
// These cipher suite implementations are copied from the standard library crypto/tls package.
const aeadNonceLength = 12
const (
aeadNonceLength = 12
)
type cipherSuite struct {
ID uint16
@@ -44,12 +46,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) *xorNonceAEAD {
if err != nil {
panic(err)
}
aead, err := cipher.NewGCM(aes)
aead, err := newAEAD(aes)
if err != nil {
panic(err)
}
ret := &xorNonceAEAD{aead: aead}
ret := &xorNonceAEAD{aead: aead, hasSeenNonceZero: false}
copy(ret.nonceMask[:], nonceMask)
return ret
}
@@ -71,8 +74,9 @@ func aeadChaCha20Poly1305(key, nonceMask []byte) *xorNonceAEAD {
// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
// before each call.
type xorNonceAEAD struct {
nonceMask [aeadNonceLength]byte
aead cipher.AEAD
nonceMask [aeadNonceLength]byte
aead cipher.AEAD
hasSeenNonceZero bool // This value denotes if the aead field was used with a nonce = 0
}
func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number
@@ -80,6 +84,10 @@ func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
return f.seal(nonce, out, plaintext, additionalData)
}
func (f *xorNonceAEAD) doSeal(nonce, out, plaintext, additionalData []byte) []byte {
for i, b := range nonce {
f.nonceMask[4+i] ^= b
}

View File

@@ -0,0 +1,51 @@
//go:build boringcrypto
package handshake
import (
"crypto/cipher"
"crypto/tls"
"os"
"strings"
)
var goBoringDisabled bool = strings.TrimSpace(os.Getenv("QUIC_GO_DISABLE_BORING")) == "1"
func newAEAD(aes cipher.Block) (cipher.AEAD, error) {
if goBoringDisabled {
// In case Go Boring is disabled then
// fallback to normal cryptographic procedure.
return cipher.NewGCM(aes)
}
return tls.NewGCMTLS13(aes)
}
func allZeros(nonce []byte) bool {
for _, e := range nonce {
if e != 0 {
return false
}
}
return true
}
func (f *xorNonceAEAD) sealZeroNonce() {
f.doSeal([]byte{}, []byte{}, []byte{}, []byte{})
}
func (f *xorNonceAEAD) seal(nonce, out, plaintext, additionalData []byte) []byte {
if !goBoringDisabled {
if !f.hasSeenNonceZero {
// BoringSSL expects that the first nonce passed to the
// AEAD instance is zero.
// At this point the nonce argument is either zero or
// an artificial one will be passed to the AEAD through
// [sealZeroNonce]
f.hasSeenNonceZero = true
if !allZeros(nonce) {
f.sealZeroNonce()
}
}
}
return f.doSeal(nonce, out, plaintext, additionalData)
}

View File

@@ -0,0 +1,13 @@
//go:build !boringcrypto
package handshake
import "crypto/cipher"
func newAEAD(aes cipher.Block) (cipher.AEAD, error) {
return cipher.NewGCM(aes)
}
func (f *xorNonceAEAD) seal(nonce, out, plaintext, additionalData []byte) []byte {
return f.doSeal(nonce, out, plaintext, additionalData)
}