mirror of
https://github.com/slackhq/nebula.git
synced 2026-07-01 02:50:29 +02:00
WIP
This commit is contained in:
@@ -188,15 +188,20 @@ build/linux-arm64-boringcrypto/%: LDFLAGS += -checklinkname=0
|
||||
|
||||
# fips140
|
||||
build/linux-amd64-fips140/%: GOENV += GOFIPS140=v1.0.0
|
||||
build/linux-amd64-fips140/%: LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only
|
||||
build/linux-amd64-fips140/%: LDFLAGS += -X runtime.godebugDefault=fips140=only
|
||||
build/linux-amd64-fips140/%: BUILD_ARGS += -tags fips140
|
||||
build/linux-arm64-fips140/%: GOENV += GOFIPS140=v1.0.0
|
||||
build/linux-arm64-fips140/%: LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only
|
||||
build/linux-arm64-fips140/%: LDFLAGS += -X runtime.godebugDefault=fips140=only
|
||||
build/linux-arm64-fips140/%: BUILD_ARGS += -tags fips140
|
||||
build/darwin-arm64-fips140/%: GOENV += GOFIPS140=v1.0.0
|
||||
build/darwin-arm64-fips140/%: LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only
|
||||
build/darwin-arm64-fips140/%: LDFLAGS += -X runtime.godebugDefault=fips140=only
|
||||
build/darwin-arm64-fips140/%: BUILD_ARGS += -tags fips140
|
||||
build/windows-amd64-fips140/%: GOENV += GOFIPS140=v1.0.0
|
||||
build/windows-amd64-fips140/%: LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only
|
||||
build/windows-amd64-fips140/%: LDFLAGS += -X runtime.godebugDefault=fips140=only
|
||||
build/windows-amd64-fips140/%: BUILD_ARGS += -tags fips140
|
||||
build/windows-arm64-fips140/%: GOENV += GOFIPS140=v1.0.0
|
||||
build/windows-arm64-fips140/%: LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only
|
||||
build/windows-arm64-fips140/%: LDFLAGS += -X runtime.godebugDefault=fips140=only
|
||||
build/windows-arm64-fips140/%: BUILD_ARGS += -tags fips140
|
||||
|
||||
build/%/nebula: .FORCE
|
||||
GOOS=$(firstword $(subst -, , $*)) \
|
||||
@@ -280,8 +285,8 @@ endif
|
||||
fips140:
|
||||
@echo > $(NULL_FILE)
|
||||
$(eval GOENV += GOFIPS140=v1.0.0)
|
||||
$(eval LDFLAGS += -checklinkname=0 -X runtime.godebugDefault=fips140=only)
|
||||
$(eval TEST_FLAGS += -ldflags -checklinkname=0)
|
||||
$(eval LDFLAGS += -X runtime.godebugDefault=fips140=only)
|
||||
$(eval BUILD_ARGS += -tags fips140)
|
||||
$(eval TEST_ENV += $(GOENV))
|
||||
ifeq ($(words $(MAKECMDGOALS)),1)
|
||||
@$(MAKE) fips140 ${.DEFAULT_GOAL} --no-print-directory
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build fips140v1.0 || fips140v1.26
|
||||
//go:build fips140
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build fips140v1.0 || fips140v1.26
|
||||
//go:build fips140
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build fips140v1.0 || fips140v1.26
|
||||
//go:build fips140
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewCipherState(s *noise.CipherState, cipherFunc noise.CipherFunc) CipherSta
|
||||
return cs
|
||||
}
|
||||
switch cipherFunc.CipherName() {
|
||||
case CipherAESGCM.CipherName():
|
||||
case noise.CipherAESGCM.CipherName():
|
||||
return NewCipherStateAESGCM(s)
|
||||
case noise.CipherChaChaPoly.CipherName():
|
||||
return NewCipherStateChaChaPoly(s)
|
||||
|
||||
+29
-21
@@ -1,3 +1,5 @@
|
||||
//go:build !boringcrypto
|
||||
|
||||
package noiseutil
|
||||
|
||||
import (
|
||||
@@ -11,9 +13,10 @@ import (
|
||||
"github.com/flynn/noise"
|
||||
)
|
||||
|
||||
// TODO: Use NewGCMWithCounterNonce once available:
|
||||
// TODO: Use NewGCMWithCounterNonce or NewGCMForQUIC once available:
|
||||
// - https://github.com/golang/go/issues/73110
|
||||
// Using tls.aeadAESGCM gives us the TLS 1.2 GCM, which also verifies
|
||||
// - https://github.com/golang/go/issues/79219
|
||||
// Using tls.aeadAESGCMTLS13 gives us the TLS 1.3 GCM, which also verifies
|
||||
// that the nonce is strictly increasing.
|
||||
//
|
||||
//go:linkname aeadAESGCMTLS13 crypto/tls.aeadAESGCMTLS13
|
||||
@@ -28,7 +31,7 @@ func (c cipherFn) Cipher(k [32]byte) noise.Cipher { return c.fn(k) }
|
||||
func (c cipherFn) CipherName() string { return c.name }
|
||||
|
||||
// CipherAESGCM is the AES256-GCM AEAD cipher (using aeadAESGCM when fips140 is enabled)
|
||||
var CipherAESGCM noise.CipherFunc = cipherFn{cipherAESGCMFIPS140, "AESGCM"}
|
||||
var CipherAESGCMFIPS140 noise.CipherFunc = cipherFn{cipherAESGCMFIPS140, "AESGCM"}
|
||||
|
||||
// tls.aeadAESGCMTLS13 uses a 4 byte static prefix and an 8 byte XOR mask
|
||||
var emptyPrefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
@@ -36,11 +39,11 @@ var emptyNonce = []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
func cipherAESGCMFIPS140(k [32]byte) noise.Cipher {
|
||||
gcm := aeadAESGCMTLS13(k[:], emptyPrefix)
|
||||
return aeadCipher{
|
||||
gcm,
|
||||
false,
|
||||
func(n uint64) []byte {
|
||||
// tls.aeadAESGCM uses a 4 byte static prefix and an 8 byte nonce
|
||||
return &aeadCipher{
|
||||
AEAD: gcm,
|
||||
ready: false,
|
||||
nonce: func(n uint64) []byte {
|
||||
// tls.aeadAESGCMTLS13 uses a 4 byte static prefix and an 8 byte nonce
|
||||
var nonce [8]byte
|
||||
binary.BigEndian.PutUint64(nonce[:], n)
|
||||
return nonce[:]
|
||||
@@ -48,37 +51,42 @@ func cipherAESGCMFIPS140(k [32]byte) noise.Cipher {
|
||||
}
|
||||
}
|
||||
|
||||
type aeadCipher struct {
|
||||
cipher.AEAD
|
||||
initialized bool
|
||||
nonce func(uint64) []byte
|
||||
}
|
||||
|
||||
func (c aeadCipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
if !c.initialized {
|
||||
func (c *aeadCipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
// runtime.Breakpoint()
|
||||
if !c.ready {
|
||||
// crypto/tls.aeadAESGCMTLS13 expected that the first call to Seal
|
||||
// is with a counter of `0`, this is how it extracts the nonce mask.
|
||||
// We can clean this up in the future when NewGCMWithCounterNonce or
|
||||
// NewGCMForQUIC are available:
|
||||
if !bytes.Equal(emptyNonce, nonce) {
|
||||
c.AEAD.Seal([]byte{}, emptyNonce, []byte{}, []byte{})
|
||||
}
|
||||
c.initialized = true
|
||||
c.ready = true
|
||||
}
|
||||
return c.AEAD.Seal(dst, nonce, plaintext, additionalData)
|
||||
}
|
||||
|
||||
func (c aeadCipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {
|
||||
type aeadCipher struct {
|
||||
cipher.AEAD
|
||||
ready bool
|
||||
nonce func(uint64) []byte
|
||||
}
|
||||
|
||||
func (c *aeadCipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {
|
||||
return c.Seal(out, c.nonce(n), plaintext, ad)
|
||||
}
|
||||
|
||||
func (c aeadCipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) {
|
||||
func (c *aeadCipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) {
|
||||
return c.Open(out, c.nonce(n), ciphertext, ad)
|
||||
}
|
||||
|
||||
func (c aeadCipher) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
|
||||
func (c *aeadCipher) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
|
||||
binary.BigEndian.PutUint64(nb[4:], n)
|
||||
out = c.Seal(out, nb[4:], plaintext, ad)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c aeadCipher) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
|
||||
func (c *aeadCipher) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
|
||||
binary.BigEndian.PutUint64(nb[4:], n)
|
||||
return c.Open(out, nb[4:], ciphertext, ad)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,10 @@ func TestNewAESGCM(t *testing.T) {
|
||||
assert.Equal(t, expected, dst)
|
||||
|
||||
// We expect this to fail since we are re-encrypting with a repeat IV
|
||||
assert.PanicsWithValue(t, "crypto/cipher: counter decreased or remained the same", func() {
|
||||
// TODO: the error message has changed between fips module versions, best way to verify it?
|
||||
// assert.PanicsWithValue(t, "crypto/cipher: counter decreased", func() {
|
||||
// assert.PanicsWithValue(t, "crypto/cipher: counter decreased or remained the same", func() {
|
||||
assert.Panics(t, func() {
|
||||
dst = aead.Seal([]byte{}, iv, plaintext, aad)
|
||||
})
|
||||
}
|
||||
|
||||
+12
-2
@@ -4,10 +4,20 @@ package noiseutil
|
||||
|
||||
import (
|
||||
"crypto/fips140"
|
||||
|
||||
"github.com/flynn/noise"
|
||||
)
|
||||
|
||||
// EncryptLockNeeded indicates if calls to Encrypt need a lock
|
||||
var EncryptLockNeeded = fips140.Enabled()
|
||||
|
||||
// CipherAESGCM is the standard noise.CipherAESGCM when boringcrypto is not enabled
|
||||
// var CipherAESGCM noise.CipherFunc = noise.CipherAESGCM
|
||||
var CipherAESGCM noise.CipherFunc = initAESGCM()
|
||||
|
||||
func initAESGCM() noise.CipherFunc {
|
||||
if fips140.Enabled() {
|
||||
return CipherAESGCMFIPS140
|
||||
} else {
|
||||
return noise.CipherAESGCM
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user