diff options
| author | Filippo Valsorda <filippo@golang.org> | 2024-11-01 11:46:34 +0100 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-11-19 00:29:22 +0000 |
| commit | c4aea467842efc3baf6cd2f5ad19fe23d7304c2e (patch) | |
| tree | a126f0969ea2fd15c993e627456d052413353ba6 /src/crypto/cipher/ctr.go | |
| parent | 0240c91383fb5bdbdc2676637662db95e87b77db (diff) | |
| download | go-c4aea467842efc3baf6cd2f5ad19fe23d7304c2e.tar.xz | |
crypto/aes: move to crypto/internal/fips/aes
The crypto/aes <-> crypto/cipher interfaces and the hardware support
upgrades were layered over the years, and had grown unwieldily.
Before: conditionally wrap the private crypto/aes type in private types
that implement an interface that's interface-upgraded by crypto/cipher
to replace the generic implementation in crypto/cipher.
crypto/aes depended on crypto/cipher, which is backwards.
After: provide concrete exported implementations of modes in
crypto/internal/fips/aes that crypto/cipher returns if the input Block
is the crypto/internal/fips/aes concrete implementation.
crypto/aes and crypto/cipher both depend on crypto/internal/fips/aes.
Also, made everything follow go.dev/wiki/TargetSpecific by only putting
the minimal code necessary and no exported functions in build-tagged
files.
The GCM integration still uses an interface upgrade, because the generic
implementation is complex enough that it was not trivial to duplicate.
This will be fixed in a future CL to make review easier.
For #69536
Change-Id: I21c2b93a498edb31c562b1aca824e21e8457fdff
Reviewed-on: https://go-review.googlesource.com/c/go/+/624395
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Diffstat (limited to 'src/crypto/cipher/ctr.go')
| -rw-r--r-- | src/crypto/cipher/ctr.go | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/crypto/cipher/ctr.go b/src/crypto/cipher/ctr.go index 8974bf3d88..e53e96609b 100644 --- a/src/crypto/cipher/ctr.go +++ b/src/crypto/cipher/ctr.go @@ -14,6 +14,7 @@ package cipher import ( "bytes" + "crypto/internal/fips/aes" "crypto/internal/fips/alias" "crypto/subtle" ) @@ -28,8 +29,8 @@ type ctr struct { const streamBufferSize = 512 // ctrAble is an interface implemented by ciphers that have a specific optimized -// implementation of CTR, like crypto/aes. NewCTR will check for this interface -// and return the specific Stream if found. +// implementation of CTR. crypto/aes doesn't use this anymore, and we'd like to +// eventually remove it. type ctrAble interface { NewCTR(iv []byte) Stream } @@ -37,6 +38,9 @@ type ctrAble interface { // NewCTR returns a [Stream] which encrypts/decrypts using the given [Block] in // counter mode. The length of iv must be the same as the [Block]'s block size. func NewCTR(block Block, iv []byte) Stream { + if block, ok := block.(*aes.Block); ok { + return aesCtrWrapper{aes.NewCTR(block, iv)} + } if ctr, ok := block.(ctrAble); ok { return ctr.NewCTR(iv) } @@ -55,6 +59,15 @@ func NewCTR(block Block, iv []byte) Stream { } } +// aesCtrWrapper hides extra methods from aes.CTR. +type aesCtrWrapper struct { + c *aes.CTR +} + +func (x aesCtrWrapper) XORKeyStream(dst, src []byte) { + x.c.XORKeyStream(dst, src) +} + func (x *ctr) refill() { remain := len(x.out) - x.outUsed copy(x.out, x.out[x.outUsed:]) @@ -83,6 +96,9 @@ func (x *ctr) XORKeyStream(dst, src []byte) { if alias.InexactOverlap(dst[:len(src)], src) { panic("crypto/cipher: invalid buffer overlap") } + if _, ok := x.b.(*aes.Block); ok { + panic("crypto/cipher: internal error: generic CTR used with AES") + } for len(src) > 0 { if x.outUsed >= len(x.out)-x.b.BlockSize() { x.refill() |
