mirror of https://github.com/golang/go.git
crypto/internal/fips/aes/gcm: add SealWithRandomNonce
We don't expose it as an AEAD yet because the logic for that is complex due to overlap issues. For #69981 we will make a cipher.AEAD wrapper outside the FIPS module, but maybe a v2 interface will make it easier, and then we'll be able to use this method more directly. Updates #69981 For #69536 Change-Id: Id88191c01443b0dec89ff0d6c4a6289f519369d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/624916 Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Auto-Submit: Filippo Valsorda <filippo@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
parent
2b1a151524
commit
b86f770bec
|
|
@ -9,6 +9,7 @@ import (
|
|||
"crypto/internal/cryptotest"
|
||||
"crypto/internal/fips/aes"
|
||||
"crypto/internal/fips/aes/gcm"
|
||||
"crypto/internal/fips/drbg"
|
||||
"crypto/internal/fips/sha3"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
|
@ -31,6 +32,30 @@ func TestAllocations(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestXAES(t *testing.T) {
|
||||
key := bytes.Repeat([]byte{0x01}, 32)
|
||||
plaintext := []byte("XAES-256-GCM")
|
||||
additionalData := []byte("c2sp.org/XAES-256-GCM")
|
||||
|
||||
nonce := make([]byte, 24)
|
||||
ciphertext := make([]byte, len(plaintext)+16)
|
||||
|
||||
drbg.Read(nonce[:12])
|
||||
c, _ := aes.New(key)
|
||||
k := gcm.NewCounterKDF(c).DeriveKey(0x58, [12]byte(nonce))
|
||||
a, _ := aes.New(k[:])
|
||||
g, _ := gcm.New(a, 12, 16)
|
||||
gcm.SealWithRandomNonce(g, nonce[12:], ciphertext, plaintext, additionalData)
|
||||
|
||||
got, err := xaesOpen(nil, key, nonce, ciphertext, additionalData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(plaintext, got) {
|
||||
t.Errorf("plaintext and got are not equal")
|
||||
}
|
||||
}
|
||||
|
||||
// ACVP tests consider fixed data part of the output, not part of the input, and
|
||||
// all the pre-generated vectors at
|
||||
// https://github.com/usnistgov/ACVP-Server/blob/3a7333f6/gen-val/json-files/KDF-1.0/expectedResults.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gcm
|
||||
|
||||
import (
|
||||
"crypto/internal/fips/alias"
|
||||
"crypto/internal/fips/drbg"
|
||||
)
|
||||
|
||||
// SealWithRandomNonce encrypts plaintext to out, and writes a random nonce to
|
||||
// nonce. nonce must be 12 bytes, and out must be 16 bytes longer than plaintext.
|
||||
// out and plaintext may overlap exactly or not at all. additionalData and out
|
||||
// must not overlap.
|
||||
//
|
||||
// This complies with FIPS 140-3 IG C.H Resolution 2.
|
||||
//
|
||||
// Note that this is NOT a [cipher.AEAD].Seal method.
|
||||
func SealWithRandomNonce(g *GCM, nonce, out, plaintext, additionalData []byte) {
|
||||
if uint64(len(plaintext)) > uint64((1<<32)-2)*gcmBlockSize {
|
||||
panic("crypto/cipher: message too large for GCM")
|
||||
}
|
||||
if len(nonce) != gcmStandardNonceSize {
|
||||
panic("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce")
|
||||
}
|
||||
if len(out) != len(plaintext)+gcmTagSize {
|
||||
panic("crypto/cipher: incorrect output length given to GCMWithRandomNonce")
|
||||
}
|
||||
if alias.InexactOverlap(out, plaintext) {
|
||||
panic("crypto/cipher: invalid buffer overlap of output and input")
|
||||
}
|
||||
if alias.AnyOverlap(out, additionalData) {
|
||||
panic("crypto/cipher: invalid buffer overlap of output and additional data")
|
||||
}
|
||||
drbg.Read(nonce)
|
||||
seal(out, g, nonce, plaintext, additionalData)
|
||||
}
|
||||
Loading…
Reference in New Issue