mirror of
https://github.com/golang/go
synced 2024-11-22 00:14:42 -07:00
crypto/cipher: add resync open to OCFB mode.
OpenPGP changed its OCFB mode for more modern packets (for example, the MDC symmetrically encrypted packet). This change adds a bool to determine which mode is used. R=bradfitzgo, r, rsc CC=golang-dev https://golang.org/cl/4126041
This commit is contained in:
parent
31ccf19612
commit
fc5c1f0a18
@ -12,11 +12,21 @@ type ocfbEncrypter struct {
|
||||
outUsed int
|
||||
}
|
||||
|
||||
// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
|
||||
// performed.
|
||||
type OCFBResyncOption bool
|
||||
|
||||
const (
|
||||
OCFBResync OCFBResyncOption = true
|
||||
OCFBNoResync OCFBResyncOption = false
|
||||
)
|
||||
|
||||
// NewOCFBEncrypter returns a Stream which encrypts data with OpenPGP's cipher
|
||||
// feedback mode using the given Block, and an initial amount of ciphertext.
|
||||
// randData must be random bytes and be the same length as the Block's block
|
||||
// size.
|
||||
func NewOCFBEncrypter(block Block, randData []byte) (Stream, []byte) {
|
||||
// size. Resync determines if the "resynchronization step" from RFC 4880, 13.9
|
||||
// step 7 is performed. Different parts of OpenPGP vary on this point.
|
||||
func NewOCFBEncrypter(block Block, randData []byte, resync OCFBResyncOption) (Stream, []byte) {
|
||||
blockSize := block.BlockSize()
|
||||
if len(randData) != blockSize {
|
||||
return nil, nil
|
||||
@ -38,7 +48,13 @@ func NewOCFBEncrypter(block Block, randData []byte) (Stream, []byte) {
|
||||
prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
|
||||
prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
|
||||
|
||||
if resync {
|
||||
block.Encrypt(x.fre, prefix[2:])
|
||||
} else {
|
||||
x.fre[0] = prefix[blockSize]
|
||||
x.fre[1] = prefix[blockSize+1]
|
||||
x.outUsed = 2
|
||||
}
|
||||
return x, prefix
|
||||
}
|
||||
|
||||
@ -64,8 +80,10 @@ type ocfbDecrypter struct {
|
||||
// NewOCFBDecrypter returns a Stream which decrypts data with OpenPGP's cipher
|
||||
// feedback mode using the given Block. Prefix must be the first blockSize + 2
|
||||
// bytes of the ciphertext, where blockSize is the Block's block size. If an
|
||||
// incorrect key is detected then nil is returned.
|
||||
func NewOCFBDecrypter(block Block, prefix []byte) Stream {
|
||||
// incorrect key is detected then nil is returned. Resync determines if the
|
||||
// "resynchronization step" from RFC 4880, 13.9 step 7 is performed. Different
|
||||
// parts of OpenPGP vary on this point.
|
||||
func NewOCFBDecrypter(block Block, prefix []byte, resync OCFBResyncOption) Stream {
|
||||
blockSize := block.BlockSize()
|
||||
if len(prefix) != blockSize+2 {
|
||||
return nil
|
||||
@ -93,7 +111,13 @@ func NewOCFBDecrypter(block Block, prefix []byte) Stream {
|
||||
return nil
|
||||
}
|
||||
|
||||
if resync {
|
||||
block.Encrypt(x.fre, prefix[2:])
|
||||
} else {
|
||||
x.fre[0] = prefix[blockSize]
|
||||
x.fre[1] = prefix[blockSize+1]
|
||||
x.outUsed = 2
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -11,29 +11,34 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOCFB(t *testing.T) {
|
||||
func testOCFB(t *testing.T, resync OCFBResyncOption) {
|
||||
block, err := aes.NewCipher(commonKey128)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
plaintext := []byte("this is the plaintext")
|
||||
plaintext := []byte("this is the plaintext, which is long enough to span several blocks.")
|
||||
randData := make([]byte, block.BlockSize())
|
||||
rand.Reader.Read(randData)
|
||||
ocfb, prefix := NewOCFBEncrypter(block, randData)
|
||||
ocfb, prefix := NewOCFBEncrypter(block, randData, resync)
|
||||
ciphertext := make([]byte, len(plaintext))
|
||||
ocfb.XORKeyStream(ciphertext, plaintext)
|
||||
|
||||
ocfbdec := NewOCFBDecrypter(block, prefix)
|
||||
ocfbdec := NewOCFBDecrypter(block, prefix, resync)
|
||||
if ocfbdec == nil {
|
||||
t.Error("NewOCFBDecrypter failed")
|
||||
t.Error("NewOCFBDecrypter failed (resync: %t)", resync)
|
||||
return
|
||||
}
|
||||
plaintextCopy := make([]byte, len(plaintext))
|
||||
ocfbdec.XORKeyStream(plaintextCopy, ciphertext)
|
||||
|
||||
if !bytes.Equal(plaintextCopy, plaintext) {
|
||||
t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
|
||||
t.Errorf("got: %x, want: %x (resync: %t)", plaintextCopy, plaintext, resync)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOCFB(t *testing.T) {
|
||||
testOCFB(t, OCFBNoResync)
|
||||
testOCFB(t, OCFBResync)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user