aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/cipher/ctr.go
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2024-11-01 11:46:34 +0100
committerGopher Robot <gobot@golang.org>2024-11-19 00:29:22 +0000
commitc4aea467842efc3baf6cd2f5ad19fe23d7304c2e (patch)
treea126f0969ea2fd15c993e627456d052413353ba6 /src/crypto/cipher/ctr.go
parent0240c91383fb5bdbdc2676637662db95e87b77db (diff)
downloadgo-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.go20
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()