Wade Simmons 1 day ago
parent
commit
0eb92dcab4
3 changed files with 56 additions and 26 deletions
  1. 8 0
      .github/workflows/smoke.yml
  2. 35 20
      noise.go
  3. 13 6
      noiseutil/fips140.go

+ 8 - 0
.github/workflows/smoke.yml

@@ -52,4 +52,12 @@ jobs:
       working-directory: ./.github/workflows/smoke
       working-directory: ./.github/workflows/smoke
       run: NAME="smoke-p256" ./smoke.sh
       run: NAME="smoke-p256" ./smoke.sh
 
 
+    - name: setup docker image for fips140
+      working-directory: ./.github/workflows/smoke
+      run: NAME="smoke-fips140" CURVE=P256 GOFIPS140=v1.0.0 LDFLAGS=-checklinkname=0 ./build.sh
+
+    - name: run smoke-fips140
+      working-directory: ./.github/workflows/smoke
+      run: NAME="smoke-fips140" ./smoke.sh
+
     timeout-minutes: 10
     timeout-minutes: 10

+ 35 - 20
noise.go

@@ -25,6 +25,11 @@ func NewNebulaCipherState(s *noise.CipherState) *NebulaCipherState {
 
 
 }
 }
 
 
+type cipherAEADDanger interface {
+	EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error)
+	DecryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error)
+}
+
 // EncryptDanger encrypts and authenticates a given payload.
 // EncryptDanger encrypts and authenticates a given payload.
 //
 //
 // out is a destination slice to hold the output of the EncryptDanger operation.
 // out is a destination slice to hold the output of the EncryptDanger operation.
@@ -35,20 +40,25 @@ func NewNebulaCipherState(s *noise.CipherState) *NebulaCipherState {
 //     be re-used by callers to minimize garbage collection.
 //     be re-used by callers to minimize garbage collection.
 func (s *NebulaCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
 func (s *NebulaCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
 	if s != nil {
 	if s != nil {
-		// TODO: Is this okay now that we have made messageCounter atomic?
-		// Alternative may be to split the counter space into ranges
-		//if n <= s.n {
-		//	return nil, errors.New("CRITICAL: a duplicate counter value was used")
-		//}
-		//s.n = n
-		nb[0] = 0
-		nb[1] = 0
-		nb[2] = 0
-		nb[3] = 0
-		noiseEndianness.PutUint64(nb[4:], n)
-		out = s.c.(cipher.AEAD).Seal(out, nb, plaintext, ad)
-		//l.Debugf("Encryption: outlen: %d, nonce: %d, ad: %s, plainlen %d", len(out), n, ad, len(plaintext))
-		return out, nil
+		switch ce := s.c.(type) {
+		case cipherAEADDanger:
+			return ce.EncryptDanger(out, ad, plaintext, n, nb)
+		default:
+			// TODO: Is this okay now that we have made messageCounter atomic?
+			// Alternative may be to split the counter space into ranges
+			//if n <= s.n {
+			//	return nil, errors.New("CRITICAL: a duplicate counter value was used")
+			//}
+			//s.n = n
+			nb[0] = 0
+			nb[1] = 0
+			nb[2] = 0
+			nb[3] = 0
+			noiseEndianness.PutUint64(nb[4:], n)
+			out = s.c.(cipher.AEAD).Seal(out, nb, plaintext, ad)
+			//l.Debugf("Encryption: outlen: %d, nonce: %d, ad: %s, plainlen %d", len(out), n, ad, len(plaintext))
+			return out, nil
+		}
 	} else {
 	} else {
 		return nil, errors.New("no cipher state available to encrypt")
 		return nil, errors.New("no cipher state available to encrypt")
 	}
 	}
@@ -56,12 +66,17 @@ func (s *NebulaCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, n
 
 
 func (s *NebulaCipherState) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
 func (s *NebulaCipherState) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
 	if s != nil {
 	if s != nil {
-		nb[0] = 0
-		nb[1] = 0
-		nb[2] = 0
-		nb[3] = 0
-		noiseEndianness.PutUint64(nb[4:], n)
-		return s.c.(cipher.AEAD).Open(out, nb, ciphertext, ad)
+		switch ce := s.c.(type) {
+		case cipherAEADDanger:
+			return ce.DecryptDanger(out, ad, ciphertext, n, nb)
+		default:
+			nb[0] = 0
+			nb[1] = 0
+			nb[2] = 0
+			nb[3] = 0
+			noiseEndianness.PutUint64(nb[4:], n)
+			return s.c.(cipher.AEAD).Open(out, nb, ciphertext, ad)
+		}
 	} else {
 	} else {
 		return []byte{}, nil
 		return []byte{}, nil
 	}
 	}

+ 13 - 6
noiseutil/fips140.go

@@ -40,16 +40,12 @@ var CipherAESGCM noise.CipherFunc = cipherFn{cipherAESGCM, "AESGCM"}
 var emptyPrefix = []byte{0, 0, 0, 0}
 var emptyPrefix = []byte{0, 0, 0, 0}
 
 
 func cipherAESGCM(k [32]byte) noise.Cipher {
 func cipherAESGCM(k [32]byte) noise.Cipher {
-	// c, err := aes.NewCipher(k[:])
-	// if err != nil {
-	// 	panic(err)
-	// }
 	gcm := aeadAESGCM(k[:], emptyPrefix)
 	gcm := aeadAESGCM(k[:], emptyPrefix)
 	return aeadCipher{
 	return aeadCipher{
 		gcm,
 		gcm,
 		func(n uint64) []byte {
 		func(n uint64) []byte {
-			var nonce [12]byte
-			binary.BigEndian.PutUint64(nonce[4:], n)
+			var nonce [8]byte
+			binary.BigEndian.PutUint64(nonce[:], n)
 			return nonce[:]
 			return nonce[:]
 		},
 		},
 	}
 	}
@@ -67,3 +63,14 @@ func (c aeadCipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {
 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)
 	return c.Open(out, c.nonce(n), ciphertext, ad)
 }
 }
+
+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) {
+	binary.BigEndian.PutUint64(nb[4:], n)
+	return c.Open(out, nb[4:], ciphertext, ad)
+}