diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-02-18 09:50:58 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-02-18 09:50:58 +0100 |
commit | c072558b90f1bbedc2022b0f30c8b1ac4712538e (patch) | |
tree | 67767591619e4bd8111fb05fac185cde94fb7378 /src/pkg/crypto/cipher | |
parent | 5859517b767c99749a45651c15d4bae5520ebae8 (diff) | |
download | golang-upstream/2011.02.15.tar.gz |
Imported Upstream version 2011.02.15upstream/2011.02.15
Diffstat (limited to 'src/pkg/crypto/cipher')
-rw-r--r-- | src/pkg/crypto/cipher/ocfb.go | 36 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/ocfb_test.go | 17 |
2 files changed, 41 insertions, 12 deletions
diff --git a/src/pkg/crypto/cipher/ocfb.go b/src/pkg/crypto/cipher/ocfb.go index 43cb5a531..b2d877591 100644 --- a/src/pkg/crypto/cipher/ocfb.go +++ b/src/pkg/crypto/cipher/ocfb.go @@ -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] - block.Encrypt(x.fre, prefix[2:]) + 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 } - block.Encrypt(x.fre, prefix[2:]) + 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 } diff --git a/src/pkg/crypto/cipher/ocfb_test.go b/src/pkg/crypto/cipher/ocfb_test.go index 289bb7c91..40938b589 100644 --- a/src/pkg/crypto/cipher/ocfb_test.go +++ b/src/pkg/crypto/cipher/ocfb_test.go @@ -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.Errorf("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) +} |