runner: don't assume BlockMod implements SetIV
It's an undocumented implementation detail, inherited from crypto/tls.
We are probably dropping it from the NewCBC* implementations (if it
doesn't break too many applications).
Change-Id: I2e27bc166bd4c75c449bde6980c68772d9a9191a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/72947
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go
index c43fc09..56626c0 100644
--- a/ssl/test/runner/cipher_suites.go
+++ b/ssl/test/runner/cipher_suites.go
@@ -155,20 +155,37 @@
return nullCipher{}
}
+type cbcMode struct {
+ cipher.BlockMode
+ new func(iv []byte) cipher.BlockMode
+}
+
+func (c *cbcMode) SetIV(iv []byte) {
+ c.BlockMode = c.new(iv)
+}
+
func cipher3DES(key, iv []byte, isRead bool) any {
+ c := &cbcMode{}
block, _ := des.NewTripleDESCipher(key)
if isRead {
- return cipher.NewCBCDecrypter(block, iv)
+ c.new = func(iv []byte) cipher.BlockMode { return cipher.NewCBCDecrypter(block, iv) }
+ } else {
+ c.new = func(iv []byte) cipher.BlockMode { return cipher.NewCBCEncrypter(block, iv) }
}
- return cipher.NewCBCEncrypter(block, iv)
+ c.SetIV(iv)
+ return c
}
func cipherAES(key, iv []byte, isRead bool) any {
+ c := &cbcMode{}
block, _ := aes.NewCipher(key)
if isRead {
- return cipher.NewCBCDecrypter(block, iv)
+ c.new = func(iv []byte) cipher.BlockMode { return cipher.NewCBCDecrypter(block, iv) }
+ } else {
+ c.new = func(iv []byte) cipher.BlockMode { return cipher.NewCBCEncrypter(block, iv) }
}
- return cipher.NewCBCEncrypter(block, iv)
+ c.SetIV(iv)
+ return c
}
// macSHA1 returns a macFunction for the given protocol version.
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 167ab13..d63242e 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -391,7 +391,7 @@
return 8
}
return 0
- case cbcMode:
+ case *cbcMode:
if hc.version >= VersionTLS11 || hc.isDTLS {
return c.BlockSize()
}
@@ -450,12 +450,6 @@
return a + (b-a%b)%b
}
-// cbcMode is an interface for block ciphers using cipher block chaining.
-type cbcMode interface {
- cipher.BlockMode
- SetIV([]byte)
-}
-
// decrypt checks and strips the mac and decrypts the data in record. Returns a
// success boolean, the application payload, the encrypted record type (or 0
// if there is none), and an optional alert value. Decryption occurs in-place,
@@ -511,7 +505,7 @@
if err != nil {
return false, 0, nil, alertBadRecordMAC
}
- case cbcMode:
+ case *cbcMode:
blockSize := c.BlockSize()
if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) {
return false, 0, nil, alertBadRecordMAC
@@ -627,7 +621,7 @@
case cipher.Stream, *nullCipher:
case *tlsAead:
overhead += c.Overhead()
- case cbcMode:
+ case *cbcMode:
overhead += computingCBCPaddingLength(payloadLen+macSize, c.BlockSize(), hc.config)
case nullCipher:
break
@@ -721,7 +715,7 @@
}
record = c.Seal(record[:prefixLen+explicitIVLen], nonce, record[prefixLen+explicitIVLen:], additionalData)
- case cbcMode:
+ case *cbcMode:
if explicitIVLen > 0 {
if _, err := io.ReadFull(hc.config.rand(), explicitIV); err != nil {
return nil, err
@@ -1602,7 +1596,7 @@
var m int
if len(b) > 1 && c.vers <= VersionTLS10 && !c.isDTLS {
- if _, ok := c.out.epoch.cipher.(cipher.BlockMode); ok {
+ if _, ok := c.out.epoch.cipher.(*cbcMode); ok {
n, err := c.writeRecord(recordTypeApplicationData, b[:1])
if err != nil {
return n, c.out.setErrorLocked(err)
diff --git a/ssl/test/runner/dtls.go b/ssl/test/runner/dtls.go
index 87a8081..2f993d1 100644
--- a/ssl/test/runner/dtls.go
+++ b/ssl/test/runner/dtls.go
@@ -247,7 +247,7 @@
// Save information about the current record, including how many more
// bytes the shim could have added.
recordBytesAvailable := c.bytesAvailableInPacket + c.rawInput.Len()
- if cbc, ok := epoch.cipher.(cbcMode); ok {
+ if cbc, ok := epoch.cipher.(*cbcMode); ok {
// It is possible that adding a byte would have added another block.
recordBytesAvailable = max(0, recordBytesAvailable-cbc.BlockSize())
}