diff options
Diffstat (limited to 'src/pkg/crypto/cipher')
-rw-r--r-- | src/pkg/crypto/cipher/benchmark_test.go | 139 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cbc.go | 133 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cbc_aes_test.go | 104 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cfb.go | 72 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cfb_test.go | 38 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cipher.go | 53 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/cipher_test.go | 36 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/common_test.go | 28 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/ctr.go | 76 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/ctr_aes_test.go | 102 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/example_test.go | 283 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/gcm.go | 343 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/gcm_test.go | 159 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/io.go | 55 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/ofb.go | 66 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/ofb_test.go | 102 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/xor.go | 84 | ||||
-rw-r--r-- | src/pkg/crypto/cipher/xor_test.go | 28 |
18 files changed, 0 insertions, 1901 deletions
diff --git a/src/pkg/crypto/cipher/benchmark_test.go b/src/pkg/crypto/cipher/benchmark_test.go deleted file mode 100644 index 027b24851..000000000 --- a/src/pkg/crypto/cipher/benchmark_test.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -import ( - "crypto/aes" - "crypto/cipher" - "testing" -) - -func BenchmarkAESGCMSeal1K(b *testing.B) { - buf := make([]byte, 1024) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var nonce [12]byte - aes, _ := aes.NewCipher(key[:]) - aesgcm, _ := cipher.NewGCM(aes) - var out []byte - - b.ResetTimer() - for i := 0; i < b.N; i++ { - out = aesgcm.Seal(out[:0], nonce[:], buf, nonce[:]) - } -} - -func BenchmarkAESGCMOpen1K(b *testing.B) { - buf := make([]byte, 1024) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var nonce [12]byte - aes, _ := aes.NewCipher(key[:]) - aesgcm, _ := cipher.NewGCM(aes) - var out []byte - out = aesgcm.Seal(out[:0], nonce[:], buf, nonce[:]) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := aesgcm.Open(buf[:0], nonce[:], out, nonce[:]) - if err != nil { - b.Errorf("Open: %v", err) - } - } -} - -// If we test exactly 1K blocks, we would generate exact multiples of -// the cipher's block size, and the cipher stream fragments would -// always be wordsize aligned, whereas non-aligned is a more typical -// use-case. -const almost1K = 1024 - 5 - -func BenchmarkAESCFBEncrypt1K(b *testing.B) { - buf := make([]byte, almost1K) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - ctr := cipher.NewCFBEncrypter(aes, iv[:]) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - ctr.XORKeyStream(buf, buf) - } -} - -func BenchmarkAESCFBDecrypt1K(b *testing.B) { - buf := make([]byte, almost1K) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - ctr := cipher.NewCFBDecrypter(aes, iv[:]) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - ctr.XORKeyStream(buf, buf) - } -} - -func BenchmarkAESOFB1K(b *testing.B) { - buf := make([]byte, almost1K) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - ctr := cipher.NewOFB(aes, iv[:]) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - ctr.XORKeyStream(buf, buf) - } -} - -func BenchmarkAESCTR1K(b *testing.B) { - buf := make([]byte, almost1K) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - ctr := cipher.NewCTR(aes, iv[:]) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - ctr.XORKeyStream(buf, buf) - } -} - -func BenchmarkAESCBCEncrypt1K(b *testing.B) { - buf := make([]byte, 1024) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - cbc := cipher.NewCBCEncrypter(aes, iv[:]) - for i := 0; i < b.N; i++ { - cbc.CryptBlocks(buf, buf) - } -} - -func BenchmarkAESCBCDecrypt1K(b *testing.B) { - buf := make([]byte, 1024) - b.SetBytes(int64(len(buf))) - - var key [16]byte - var iv [16]byte - aes, _ := aes.NewCipher(key[:]) - cbc := cipher.NewCBCDecrypter(aes, iv[:]) - for i := 0; i < b.N; i++ { - cbc.CryptBlocks(buf, buf) - } -} diff --git a/src/pkg/crypto/cipher/cbc.go b/src/pkg/crypto/cipher/cbc.go deleted file mode 100644 index 241e122ee..000000000 --- a/src/pkg/crypto/cipher/cbc.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Cipher block chaining (CBC) mode. - -// CBC provides confidentiality by xoring (chaining) each plaintext block -// with the previous ciphertext block before applying the block cipher. - -// See NIST SP 800-38A, pp 10-11 - -package cipher - -type cbc struct { - b Block - blockSize int - iv []byte - tmp []byte -} - -func newCBC(b Block, iv []byte) *cbc { - return &cbc{ - b: b, - blockSize: b.BlockSize(), - iv: dup(iv), - tmp: make([]byte, b.BlockSize()), - } -} - -type cbcEncrypter cbc - -// NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining -// mode, using the given Block. The length of iv must be the same as the -// Block's block size. -func NewCBCEncrypter(b Block, iv []byte) BlockMode { - if len(iv) != b.BlockSize() { - panic("cipher.NewCBCEncrypter: IV length must equal block size") - } - return (*cbcEncrypter)(newCBC(b, iv)) -} - -func (x *cbcEncrypter) BlockSize() int { return x.blockSize } - -func (x *cbcEncrypter) CryptBlocks(dst, src []byte) { - if len(src)%x.blockSize != 0 { - panic("crypto/cipher: input not full blocks") - } - if len(dst) < len(src) { - panic("crypto/cipher: output smaller than input") - } - - iv := x.iv - - for len(src) > 0 { - // Write the xor to dst, then encrypt in place. - xorBytes(dst[:x.blockSize], src[:x.blockSize], iv) - x.b.Encrypt(dst[:x.blockSize], dst[:x.blockSize]) - - // Move to the next block with this block as the next iv. - iv = dst[:x.blockSize] - src = src[x.blockSize:] - dst = dst[x.blockSize:] - } - - // Save the iv for the next CryptBlocks call. - copy(x.iv, iv) -} - -func (x *cbcEncrypter) SetIV(iv []byte) { - if len(iv) != len(x.iv) { - panic("cipher: incorrect length IV") - } - copy(x.iv, iv) -} - -type cbcDecrypter cbc - -// NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining -// mode, using the given Block. The length of iv must be the same as the -// Block's block size and must match the iv used to encrypt the data. -func NewCBCDecrypter(b Block, iv []byte) BlockMode { - if len(iv) != b.BlockSize() { - panic("cipher.NewCBCDecrypter: IV length must equal block size") - } - return (*cbcDecrypter)(newCBC(b, iv)) -} - -func (x *cbcDecrypter) BlockSize() int { return x.blockSize } - -func (x *cbcDecrypter) CryptBlocks(dst, src []byte) { - if len(src)%x.blockSize != 0 { - panic("crypto/cipher: input not full blocks") - } - if len(dst) < len(src) { - panic("crypto/cipher: output smaller than input") - } - if len(src) == 0 { - return - } - - // For each block, we need to xor the decrypted data with the previous block's ciphertext (the iv). - // To avoid making a copy each time, we loop over the blocks BACKWARDS. - end := len(src) - start := end - x.blockSize - prev := start - x.blockSize - - // Copy the last block of ciphertext in preparation as the new iv. - copy(x.tmp, src[start:end]) - - // Loop over all but the first block. - for start > 0 { - x.b.Decrypt(dst[start:end], src[start:end]) - xorBytes(dst[start:end], dst[start:end], src[prev:start]) - - end = start - start = prev - prev -= x.blockSize - } - - // The first block is special because it uses the saved iv. - x.b.Decrypt(dst[start:end], src[start:end]) - xorBytes(dst[start:end], dst[start:end], x.iv) - - // Set the new iv to the first block we copied earlier. - x.iv, x.tmp = x.tmp, x.iv -} - -func (x *cbcDecrypter) SetIV(iv []byte) { - if len(iv) != len(x.iv) { - panic("cipher: incorrect length IV") - } - copy(x.iv, iv) -} diff --git a/src/pkg/crypto/cipher/cbc_aes_test.go b/src/pkg/crypto/cipher/cbc_aes_test.go deleted file mode 100644 index bf9e7ad70..000000000 --- a/src/pkg/crypto/cipher/cbc_aes_test.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CBC AES test vectors. - -// See U.S. National Institute of Standards and Technology (NIST) -// Special Publication 800-38A, ``Recommendation for Block Cipher -// Modes of Operation,'' 2001 Edition, pp. 24-29. - -package cipher_test - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "testing" -) - -var cbcAESTests = []struct { - name string - key []byte - iv []byte - in []byte - out []byte -}{ - // NIST SP 800-38A pp 27-29 - { - "CBC-AES128", - commonKey128, - commonIV, - commonInput, - []byte{ - 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, - 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, - 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, - 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, - }, - }, - { - "CBC-AES192", - commonKey192, - commonIV, - commonInput, - []byte{ - 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8, - 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a, - 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0, - 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd, - }, - }, - { - "CBC-AES256", - commonKey256, - commonIV, - commonInput, - []byte{ - 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, - 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d, - 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, - 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, - }, - }, -} - -func TestCBCEncrypterAES(t *testing.T) { - for _, test := range cbcAESTests { - c, err := aes.NewCipher(test.key) - if err != nil { - t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err) - continue - } - - encrypter := cipher.NewCBCEncrypter(c, test.iv) - - data := make([]byte, len(test.in)) - copy(data, test.in) - - encrypter.CryptBlocks(data, data) - if !bytes.Equal(test.out, data) { - t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test.name, data, test.out) - } - } -} - -func TestCBCDecrypterAES(t *testing.T) { - for _, test := range cbcAESTests { - c, err := aes.NewCipher(test.key) - if err != nil { - t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err) - continue - } - - decrypter := cipher.NewCBCDecrypter(c, test.iv) - - data := make([]byte, len(test.out)) - copy(data, test.out) - - decrypter.CryptBlocks(data, data) - if !bytes.Equal(test.in, data) { - t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test.name, data, test.in) - } - } -} diff --git a/src/pkg/crypto/cipher/cfb.go b/src/pkg/crypto/cipher/cfb.go deleted file mode 100644 index 9b4eebf5b..000000000 --- a/src/pkg/crypto/cipher/cfb.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CFB (Cipher Feedback) Mode. - -package cipher - -type cfb struct { - b Block - next []byte - out []byte - outUsed int - - decrypt bool -} - -func (x *cfb) XORKeyStream(dst, src []byte) { - for len(src) > 0 { - if x.outUsed == len(x.out) { - x.b.Encrypt(x.out, x.next) - x.outUsed = 0 - } - - if x.decrypt { - // We can precompute a larger segment of the - // keystream on decryption. This will allow - // larger batches for xor, and we should be - // able to match CTR/OFB performance. - copy(x.next[x.outUsed:], src) - } - n := xorBytes(dst, src, x.out[x.outUsed:]) - if !x.decrypt { - copy(x.next[x.outUsed:], dst) - } - dst = dst[n:] - src = src[n:] - x.outUsed += n - } -} - -// NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode, -// using the given Block. The iv must be the same length as the Block's block -// size. -func NewCFBEncrypter(block Block, iv []byte) Stream { - return newCFB(block, iv, false) -} - -// NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode, -// using the given Block. The iv must be the same length as the Block's block -// size. -func NewCFBDecrypter(block Block, iv []byte) Stream { - return newCFB(block, iv, true) -} - -func newCFB(block Block, iv []byte, decrypt bool) Stream { - blockSize := block.BlockSize() - if len(iv) != blockSize { - // stack trace will indicate whether it was de or encryption - panic("cipher.newCFB: IV length must equal block size") - } - x := &cfb{ - b: block, - out: make([]byte, blockSize), - next: make([]byte, blockSize), - outUsed: blockSize, - decrypt: decrypt, - } - copy(x.next, iv) - - return x -} diff --git a/src/pkg/crypto/cipher/cfb_test.go b/src/pkg/crypto/cipher/cfb_test.go deleted file mode 100644 index ec708ab2b..000000000 --- a/src/pkg/crypto/cipher/cfb_test.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "testing" -) - -func TestCFB(t *testing.T) { - block, err := aes.NewCipher(commonKey128) - if err != nil { - t.Error(err) - return - } - - plaintext := []byte("this is the plaintext. this is the plaintext.") - iv := make([]byte, block.BlockSize()) - rand.Reader.Read(iv) - cfb := cipher.NewCFBEncrypter(block, iv) - ciphertext := make([]byte, len(plaintext)) - copy(ciphertext, plaintext) - cfb.XORKeyStream(ciphertext, ciphertext) - - cfbdec := cipher.NewCFBDecrypter(block, iv) - plaintextCopy := make([]byte, len(plaintext)) - copy(plaintextCopy, ciphertext) - cfbdec.XORKeyStream(plaintextCopy, plaintextCopy) - - if !bytes.Equal(plaintextCopy, plaintext) { - t.Errorf("got: %x, want: %x", plaintextCopy, plaintext) - } -} diff --git a/src/pkg/crypto/cipher/cipher.go b/src/pkg/crypto/cipher/cipher.go deleted file mode 100644 index 67afdb1e0..000000000 --- a/src/pkg/crypto/cipher/cipher.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cipher implements standard block cipher modes that can be wrapped -// around low-level block cipher implementations. -// See http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html -// and NIST Special Publication 800-38A. -package cipher - -// A Block represents an implementation of block cipher -// using a given key. It provides the capability to encrypt -// or decrypt individual blocks. The mode implementations -// extend that capability to streams of blocks. -type Block interface { - // BlockSize returns the cipher's block size. - BlockSize() int - - // Encrypt encrypts the first block in src into dst. - // Dst and src may point at the same memory. - Encrypt(dst, src []byte) - - // Decrypt decrypts the first block in src into dst. - // Dst and src may point at the same memory. - Decrypt(dst, src []byte) -} - -// A Stream represents a stream cipher. -type Stream interface { - // XORKeyStream XORs each byte in the given slice with a byte from the - // cipher's key stream. Dst and src may point to the same memory. - XORKeyStream(dst, src []byte) -} - -// A BlockMode represents a block cipher running in a block-based mode (CBC, -// ECB etc). -type BlockMode interface { - // BlockSize returns the mode's block size. - BlockSize() int - - // CryptBlocks encrypts or decrypts a number of blocks. The length of - // src must be a multiple of the block size. Dst and src may point to - // the same memory. - CryptBlocks(dst, src []byte) -} - -// Utility routines - -func dup(p []byte) []byte { - q := make([]byte, len(p)) - copy(q, p) - return q -} diff --git a/src/pkg/crypto/cipher/cipher_test.go b/src/pkg/crypto/cipher/cipher_test.go deleted file mode 100644 index 8da5bce93..000000000 --- a/src/pkg/crypto/cipher/cipher_test.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -import ( - "crypto/aes" - "crypto/cipher" - "testing" -) - -func TestCryptBlocks(t *testing.T) { - buf := make([]byte, 16) - block, _ := aes.NewCipher(buf) - - mode := cipher.NewCBCDecrypter(block, buf) - mustPanic(t, "crypto/cipher: input not full blocks", func() { mode.CryptBlocks(buf, buf[:3]) }) - mustPanic(t, "crypto/cipher: output smaller than input", func() { mode.CryptBlocks(buf[:3], buf) }) - - mode = cipher.NewCBCEncrypter(block, buf) - mustPanic(t, "crypto/cipher: input not full blocks", func() { mode.CryptBlocks(buf, buf[:3]) }) - mustPanic(t, "crypto/cipher: output smaller than input", func() { mode.CryptBlocks(buf[:3], buf) }) -} - -func mustPanic(t *testing.T, msg string, f func()) { - defer func() { - err := recover() - if err == nil { - t.Errorf("function did not panic, wanted %q", msg) - } else if err != msg { - t.Errorf("got panic %v, wanted %q", err, msg) - } - }() - f() -} diff --git a/src/pkg/crypto/cipher/common_test.go b/src/pkg/crypto/cipher/common_test.go deleted file mode 100644 index c75c919d1..000000000 --- a/src/pkg/crypto/cipher/common_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -// Common values for tests. - -var commonInput = []byte{ - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, -} - -var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c} - -var commonKey192 = []byte{ - 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, - 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, -} - -var commonKey256 = []byte{ - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, -} - -var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} diff --git a/src/pkg/crypto/cipher/ctr.go b/src/pkg/crypto/cipher/ctr.go deleted file mode 100644 index 70ac40f6a..000000000 --- a/src/pkg/crypto/cipher/ctr.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Counter (CTR) mode. - -// CTR converts a block cipher into a stream cipher by -// repeatedly encrypting an incrementing counter and -// xoring the resulting stream of data with the input. - -// See NIST SP 800-38A, pp 13-15 - -package cipher - -type ctr struct { - b Block - ctr []byte - out []byte - outUsed int -} - -const streamBufferSize = 512 - -// 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 len(iv) != block.BlockSize() { - panic("cipher.NewCTR: IV length must equal block size") - } - bufSize := streamBufferSize - if bufSize < block.BlockSize() { - bufSize = block.BlockSize() - } - return &ctr{ - b: block, - ctr: dup(iv), - out: make([]byte, 0, bufSize), - outUsed: 0, - } -} - -func (x *ctr) refill() { - remain := len(x.out) - x.outUsed - if remain > x.outUsed { - return - } - copy(x.out, x.out[x.outUsed:]) - x.out = x.out[:cap(x.out)] - bs := x.b.BlockSize() - for remain < len(x.out)-bs { - x.b.Encrypt(x.out[remain:], x.ctr) - remain += bs - - // Increment counter - for i := len(x.ctr) - 1; i >= 0; i-- { - x.ctr[i]++ - if x.ctr[i] != 0 { - break - } - } - } - x.out = x.out[:remain] - x.outUsed = 0 -} - -func (x *ctr) XORKeyStream(dst, src []byte) { - for len(src) > 0 { - if x.outUsed >= len(x.out)-x.b.BlockSize() { - x.refill() - } - n := xorBytes(dst, src, x.out[x.outUsed:]) - dst = dst[n:] - src = src[n:] - x.outUsed += n - } -} diff --git a/src/pkg/crypto/cipher/ctr_aes_test.go b/src/pkg/crypto/cipher/ctr_aes_test.go deleted file mode 100644 index d019ae0d0..000000000 --- a/src/pkg/crypto/cipher/ctr_aes_test.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CTR AES test vectors. - -// See U.S. National Institute of Standards and Technology (NIST) -// Special Publication 800-38A, ``Recommendation for Block Cipher -// Modes of Operation,'' 2001 Edition, pp. 55-58. - -package cipher_test - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "testing" -) - -var commonCounter = []byte{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff} - -var ctrAESTests = []struct { - name string - key []byte - iv []byte - in []byte - out []byte -}{ - // NIST SP 800-38A pp 55-58 - { - "CTR-AES128", - commonKey128, - commonCounter, - commonInput, - []byte{ - 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, - 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, - 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, - 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee, - }, - }, - { - "CTR-AES192", - commonKey192, - commonCounter, - commonInput, - []byte{ - 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b, - 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94, - 0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6, 0x70, 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7, - 0x4f, 0x78, 0xa7, 0xf6, 0xd2, 0x98, 0x09, 0x58, 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50, - }, - }, - { - "CTR-AES256", - commonKey256, - commonCounter, - commonInput, - []byte{ - 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, - 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, - 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, - 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6, - }, - }, -} - -func TestCTR_AES(t *testing.T) { - for _, tt := range ctrAESTests { - test := tt.name - - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err) - continue - } - - for j := 0; j <= 5; j += 5 { - in := tt.in[0 : len(tt.in)-j] - ctr := cipher.NewCTR(c, tt.iv) - encrypted := make([]byte, len(in)) - ctr.XORKeyStream(encrypted, in) - if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) { - t.Errorf("%s/%d: CTR\ninpt %x\nhave %x\nwant %x", test, len(in), in, encrypted, out) - } - } - - for j := 0; j <= 7; j += 7 { - in := tt.out[0 : len(tt.out)-j] - ctr := cipher.NewCTR(c, tt.iv) - plain := make([]byte, len(in)) - ctr.XORKeyStream(plain, in) - if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) { - t.Errorf("%s/%d: CTRReader\nhave %x\nwant %x", test, len(out), plain, out) - } - } - - if t.Failed() { - break - } - } -} diff --git a/src/pkg/crypto/cipher/example_test.go b/src/pkg/crypto/cipher/example_test.go deleted file mode 100644 index 373f6791b..000000000 --- a/src/pkg/crypto/cipher/example_test.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/hex" - "fmt" - "io" - "os" -) - -func ExampleNewCBCDecrypter() { - key := []byte("example key 1234") - ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - if len(ciphertext) < aes.BlockSize { - panic("ciphertext too short") - } - iv := ciphertext[:aes.BlockSize] - ciphertext = ciphertext[aes.BlockSize:] - - // CBC mode always works in whole blocks. - if len(ciphertext)%aes.BlockSize != 0 { - panic("ciphertext is not a multiple of the block size") - } - - mode := cipher.NewCBCDecrypter(block, iv) - - // CryptBlocks can work in-place if the two arguments are the same. - mode.CryptBlocks(ciphertext, ciphertext) - - // If the original plaintext lengths are not a multiple of the block - // size, padding would have to be added when encrypting, which would be - // removed at this point. For an example, see - // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's - // critical to note that ciphertexts must be authenticated (i.e. by - // using crypto/hmac) before being decrypted in order to avoid creating - // a padding oracle. - - fmt.Printf("%s\n", ciphertext) - // Output: exampleplaintext -} - -func ExampleNewCBCEncrypter() { - key := []byte("example key 1234") - plaintext := []byte("exampleplaintext") - - // CBC mode works on blocks so plaintexts may need to be padded to the - // next whole block. For an example of such padding, see - // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll - // assume that the plaintext is already of the correct length. - if len(plaintext)%aes.BlockSize != 0 { - panic("plaintext is not a multiple of the block size") - } - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - ciphertext := make([]byte, aes.BlockSize+len(plaintext)) - iv := ciphertext[:aes.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) - } - - mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) - - // It's important to remember that ciphertexts must be authenticated - // (i.e. by using crypto/hmac) as well as being encrypted in order to - // be secure. - - fmt.Printf("%x\n", ciphertext) -} - -func ExampleNewCFBDecrypter() { - key := []byte("example key 1234") - ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - if len(ciphertext) < aes.BlockSize { - panic("ciphertext too short") - } - iv := ciphertext[:aes.BlockSize] - ciphertext = ciphertext[aes.BlockSize:] - - stream := cipher.NewCFBDecrypter(block, iv) - - // XORKeyStream can work in-place if the two arguments are the same. - stream.XORKeyStream(ciphertext, ciphertext) - fmt.Printf("%s", ciphertext) - // Output: some plaintext -} - -func ExampleNewCFBEncrypter() { - key := []byte("example key 1234") - plaintext := []byte("some plaintext") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - ciphertext := make([]byte, aes.BlockSize+len(plaintext)) - iv := ciphertext[:aes.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) - } - - stream := cipher.NewCFBEncrypter(block, iv) - stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) - - // It's important to remember that ciphertexts must be authenticated - // (i.e. by using crypto/hmac) as well as being encrypted in order to - // be secure. -} - -func ExampleNewCTR() { - key := []byte("example key 1234") - plaintext := []byte("some plaintext") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - ciphertext := make([]byte, aes.BlockSize+len(plaintext)) - iv := ciphertext[:aes.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) - } - - stream := cipher.NewCTR(block, iv) - stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) - - // It's important to remember that ciphertexts must be authenticated - // (i.e. by using crypto/hmac) as well as being encrypted in order to - // be secure. - - // CTR mode is the same for both encryption and decryption, so we can - // also decrypt that ciphertext with NewCTR. - - plaintext2 := make([]byte, len(plaintext)) - stream = cipher.NewCTR(block, iv) - stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:]) - - fmt.Printf("%s\n", plaintext2) - // Output: some plaintext -} - -func ExampleNewOFB() { - key := []byte("example key 1234") - plaintext := []byte("some plaintext") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // The IV needs to be unique, but not secure. Therefore it's common to - // include it at the beginning of the ciphertext. - ciphertext := make([]byte, aes.BlockSize+len(plaintext)) - iv := ciphertext[:aes.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) - } - - stream := cipher.NewOFB(block, iv) - stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) - - // It's important to remember that ciphertexts must be authenticated - // (i.e. by using crypto/hmac) as well as being encrypted in order to - // be secure. - - // OFB mode is the same for both encryption and decryption, so we can - // also decrypt that ciphertext with NewOFB. - - plaintext2 := make([]byte, len(plaintext)) - stream = cipher.NewOFB(block, iv) - stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:]) - - fmt.Printf("%s\n", plaintext2) - // Output: some plaintext -} - -func ExampleStreamReader() { - key := []byte("example key 1234") - - inFile, err := os.Open("encrypted-file") - if err != nil { - panic(err) - } - defer inFile.Close() - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // If the key is unique for each ciphertext, then it's ok to use a zero - // IV. - var iv [aes.BlockSize]byte - stream := cipher.NewOFB(block, iv[:]) - - outFile, err := os.OpenFile("decrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - panic(err) - } - defer outFile.Close() - - reader := &cipher.StreamReader{S: stream, R: inFile} - // Copy the input file to the output file, decrypting as we go. - if _, err := io.Copy(outFile, reader); err != nil { - panic(err) - } - - // Note that this example is simplistic in that it omits any - // authentication of the encrypted data. It you were actually to use - // StreamReader in this manner, an attacker could flip arbitrary bits in - // the output. -} - -func ExampleStreamWriter() { - key := []byte("example key 1234") - - inFile, err := os.Open("plaintext-file") - if err != nil { - panic(err) - } - defer inFile.Close() - - block, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - - // If the key is unique for each ciphertext, then it's ok to use a zero - // IV. - var iv [aes.BlockSize]byte - stream := cipher.NewOFB(block, iv[:]) - - outFile, err := os.OpenFile("encrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - panic(err) - } - defer outFile.Close() - - writer := &cipher.StreamWriter{S: stream, W: outFile} - // Copy the input file to the output file, encrypting as we go. - if _, err := io.Copy(writer, inFile); err != nil { - panic(err) - } - - // Note that this example is simplistic in that it omits any - // authentication of the encrypted data. It you were actually to use - // StreamReader in this manner, an attacker could flip arbitrary bits in - // the decrypted result. -} diff --git a/src/pkg/crypto/cipher/gcm.go b/src/pkg/crypto/cipher/gcm.go deleted file mode 100644 index bdafd85fc..000000000 --- a/src/pkg/crypto/cipher/gcm.go +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher - -import ( - "crypto/subtle" - "errors" -) - -// AEAD is a cipher mode providing authenticated encryption with associated -// data. -type AEAD interface { - // NonceSize returns the size of the nonce that must be passed to Seal - // and Open. - NonceSize() int - - // Overhead returns the maximum difference between the lengths of a - // plaintext and ciphertext. - Overhead() int - - // Seal encrypts and authenticates plaintext, authenticates the - // additional data and appends the result to dst, returning the updated - // slice. The nonce must be NonceSize() bytes long and unique for all - // time, for a given key. - // - // The plaintext and dst may alias exactly or not at all. - Seal(dst, nonce, plaintext, data []byte) []byte - - // Open decrypts and authenticates ciphertext, authenticates the - // additional data and, if successful, appends the resulting plaintext - // to dst, returning the updated slice. The nonce must be NonceSize() - // bytes long and both it and the additional data must match the - // value passed to Seal. - // - // The ciphertext and dst may alias exactly or not at all. - Open(dst, nonce, ciphertext, data []byte) ([]byte, error) -} - -// gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM -// standard and make getUint64 suitable for marshaling these values, the bits -// are stored backwards. For example: -// the coefficient of x⁰ can be obtained by v.low >> 63. -// the coefficient of x⁶³ can be obtained by v.low & 1. -// the coefficient of x⁶⁴ can be obtained by v.high >> 63. -// the coefficient of x¹²⁷ can be obtained by v.high & 1. -type gcmFieldElement struct { - low, high uint64 -} - -// gcm represents a Galois Counter Mode with a specific key. See -// http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf -type gcm struct { - cipher Block - // productTable contains the first sixteen powers of the key, H. - // However, they are in bit reversed order. See NewGCM. - productTable [16]gcmFieldElement -} - -// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode. -func NewGCM(cipher Block) (AEAD, error) { - if cipher.BlockSize() != gcmBlockSize { - return nil, errors.New("cipher: NewGCM requires 128-bit block cipher") - } - - var key [gcmBlockSize]byte - cipher.Encrypt(key[:], key[:]) - - g := &gcm{cipher: cipher} - - // We precompute 16 multiples of |key|. However, when we do lookups - // into this table we'll be using bits from a field element and - // therefore the bits will be in the reverse order. So normally one - // would expect, say, 4*key to be in index 4 of the table but due to - // this bit ordering it will actually be in index 0010 (base 2) = 2. - x := gcmFieldElement{ - getUint64(key[:8]), - getUint64(key[8:]), - } - g.productTable[reverseBits(1)] = x - - for i := 2; i < 16; i += 2 { - g.productTable[reverseBits(i)] = gcmDouble(&g.productTable[reverseBits(i/2)]) - g.productTable[reverseBits(i+1)] = gcmAdd(&g.productTable[reverseBits(i)], &x) - } - - return g, nil -} - -const ( - gcmBlockSize = 16 - gcmTagSize = 16 - gcmNonceSize = 12 -) - -func (*gcm) NonceSize() int { - return gcmNonceSize -} - -func (*gcm) Overhead() int { - return gcmTagSize -} - -func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte { - if len(nonce) != gcmNonceSize { - panic("cipher: incorrect nonce length given to GCM") - } - - ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) - - // See GCM spec, section 7.1. - var counter, tagMask [gcmBlockSize]byte - copy(counter[:], nonce) - counter[gcmBlockSize-1] = 1 - - g.cipher.Encrypt(tagMask[:], counter[:]) - gcmInc32(&counter) - - g.counterCrypt(out, plaintext, &counter) - g.auth(out[len(plaintext):], out[:len(plaintext)], data, &tagMask) - - return ret -} - -var errOpen = errors.New("cipher: message authentication failed") - -func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { - if len(nonce) != gcmNonceSize { - panic("cipher: incorrect nonce length given to GCM") - } - - if len(ciphertext) < gcmTagSize { - return nil, errOpen - } - tag := ciphertext[len(ciphertext)-gcmTagSize:] - ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] - - // See GCM spec, section 7.1. - var counter, tagMask [gcmBlockSize]byte - copy(counter[:], nonce) - counter[gcmBlockSize-1] = 1 - - g.cipher.Encrypt(tagMask[:], counter[:]) - gcmInc32(&counter) - - var expectedTag [gcmTagSize]byte - g.auth(expectedTag[:], ciphertext, data, &tagMask) - - if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 { - return nil, errOpen - } - - ret, out := sliceForAppend(dst, len(ciphertext)) - g.counterCrypt(out, ciphertext, &counter) - - return ret, nil -} - -// reverseBits reverses the order of the bits of 4-bit number in i. -func reverseBits(i int) int { - i = ((i << 2) & 0xc) | ((i >> 2) & 0x3) - i = ((i << 1) & 0xa) | ((i >> 1) & 0x5) - return i -} - -// gcmAdd adds two elements of GF(2¹²⁸) and returns the sum. -func gcmAdd(x, y *gcmFieldElement) gcmFieldElement { - // Addition in a characteristic 2 field is just XOR. - return gcmFieldElement{x.low ^ y.low, x.high ^ y.high} -} - -// gcmDouble returns the result of doubling an element of GF(2¹²⁸). -func gcmDouble(x *gcmFieldElement) (double gcmFieldElement) { - msbSet := x.high&1 == 1 - - // Because of the bit-ordering, doubling is actually a right shift. - double.high = x.high >> 1 - double.high |= x.low << 63 - double.low = x.low >> 1 - - // If the most-significant bit was set before shifting then it, - // conceptually, becomes a term of x^128. This is greater than the - // irreducible polynomial so the result has to be reduced. The - // irreducible polynomial is 1+x+x^2+x^7+x^128. We can subtract that to - // eliminate the term at x^128 which also means subtracting the other - // four terms. In characteristic 2 fields, subtraction == addition == - // XOR. - if msbSet { - double.low ^= 0xe100000000000000 - } - - return -} - -var gcmReductionTable = []uint16{ - 0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0, - 0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0, -} - -// mul sets y to y*H, where H is the GCM key, fixed during NewGCM. -func (g *gcm) mul(y *gcmFieldElement) { - var z gcmFieldElement - - for i := 0; i < 2; i++ { - word := y.high - if i == 1 { - word = y.low - } - - // Multiplication works by multiplying z by 16 and adding in - // one of the precomputed multiples of H. - for j := 0; j < 64; j += 4 { - msw := z.high & 0xf - z.high >>= 4 - z.high |= z.low << 60 - z.low >>= 4 - z.low ^= uint64(gcmReductionTable[msw]) << 48 - - // the values in |table| are ordered for - // little-endian bit positions. See the comment - // in NewGCM. - t := &g.productTable[word&0xf] - - z.low ^= t.low - z.high ^= t.high - word >>= 4 - } - } - - *y = z -} - -// updateBlocks extends y with more polynomial terms from blocks, based on -// Horner's rule. There must be a multiple of gcmBlockSize bytes in blocks. -func (g *gcm) updateBlocks(y *gcmFieldElement, blocks []byte) { - for len(blocks) > 0 { - y.low ^= getUint64(blocks) - y.high ^= getUint64(blocks[8:]) - g.mul(y) - blocks = blocks[gcmBlockSize:] - } -} - -// update extends y with more polynomial terms from data. If data is not a -// multiple of gcmBlockSize bytes long then the remainder is zero padded. -func (g *gcm) update(y *gcmFieldElement, data []byte) { - fullBlocks := (len(data) >> 4) << 4 - g.updateBlocks(y, data[:fullBlocks]) - - if len(data) != fullBlocks { - var partialBlock [gcmBlockSize]byte - copy(partialBlock[:], data[fullBlocks:]) - g.updateBlocks(y, partialBlock[:]) - } -} - -// gcmInc32 treats the final four bytes of counterBlock as a big-endian value -// and increments it. -func gcmInc32(counterBlock *[16]byte) { - for i := gcmBlockSize - 1; i >= gcmBlockSize-4; i-- { - counterBlock[i]++ - if counterBlock[i] != 0 { - break - } - } -} - -// sliceForAppend takes a slice and a requested number of bytes. It returns a -// slice with the contents of the given slice followed by that many bytes and a -// second slice that aliases into it and contains only the extra bytes. If the -// original slice has sufficient capacity then no allocation is performed. -func sliceForAppend(in []byte, n int) (head, tail []byte) { - if total := len(in) + n; cap(in) >= total { - head = in[:total] - } else { - head = make([]byte, total) - copy(head, in) - } - tail = head[len(in):] - return -} - -// counterCrypt crypts in to out using g.cipher in counter mode. -func (g *gcm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) { - var mask [gcmBlockSize]byte - - for len(in) >= gcmBlockSize { - g.cipher.Encrypt(mask[:], counter[:]) - gcmInc32(counter) - - xorWords(out, in, mask[:]) - out = out[gcmBlockSize:] - in = in[gcmBlockSize:] - } - - if len(in) > 0 { - g.cipher.Encrypt(mask[:], counter[:]) - gcmInc32(counter) - xorBytes(out, in, mask[:]) - } -} - -// auth calculates GHASH(ciphertext, additionalData), masks the result with -// tagMask and writes the result to out. -func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]byte) { - var y gcmFieldElement - g.update(&y, additionalData) - g.update(&y, ciphertext) - - y.low ^= uint64(len(additionalData)) * 8 - y.high ^= uint64(len(ciphertext)) * 8 - - g.mul(&y) - - putUint64(out, y.low) - putUint64(out[8:], y.high) - - xorWords(out, out, tagMask[:]) -} - -func getUint64(data []byte) uint64 { - r := uint64(data[0])<<56 | - uint64(data[1])<<48 | - uint64(data[2])<<40 | - uint64(data[3])<<32 | - uint64(data[4])<<24 | - uint64(data[5])<<16 | - uint64(data[6])<<8 | - uint64(data[7]) - return r -} - -func putUint64(out []byte, v uint64) { - out[0] = byte(v >> 56) - out[1] = byte(v >> 48) - out[2] = byte(v >> 40) - out[3] = byte(v >> 32) - out[4] = byte(v >> 24) - out[5] = byte(v >> 16) - out[6] = byte(v >> 8) - out[7] = byte(v) -} diff --git a/src/pkg/crypto/cipher/gcm_test.go b/src/pkg/crypto/cipher/gcm_test.go deleted file mode 100644 index 0c502ce40..000000000 --- a/src/pkg/crypto/cipher/gcm_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher_test - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "encoding/hex" - "testing" -) - -// AES-GCM test vectors taken from gcmEncryptExtIV128.rsp from -// http://csrc.nist.gov/groups/STM/cavp/index.html. -var aesGCMTests = []struct { - key, nonce, plaintext, ad, result string -}{ - { - "11754cd72aec309bf52f7687212e8957", - "3c819d9a9bed087615030b65", - "", - "", - "250327c674aaf477aef2675748cf6971", - }, - { - "ca47248ac0b6f8372a97ac43508308ed", - "ffd2b598feabc9019262d2be", - "", - "", - "60d20404af527d248d893ae495707d1a", - }, - { - "77be63708971c4e240d1cb79e8d77feb", - "e0e00f19fed7ba0136a797f3", - "", - "7a43ec1d9c0a5a78a0b16533a6213cab", - "209fcc8d3675ed938e9c7166709dd946", - }, - { - "7680c5d3ca6154758e510f4d25b98820", - "f8f105f9c3df4965780321f8", - "", - "c94c410194c765e3dcc7964379758ed3", - "94dca8edfcf90bb74b153c8d48a17930", - }, - { - "7fddb57453c241d03efbed3ac44e371c", - "ee283a3fc75575e33efd4887", - "d5de42b461646c255c87bd2962d3b9a2", - "", - "2ccda4a5415cb91e135c2a0f78c9b2fdb36d1df9b9d5e596f83e8b7f52971cb3", - }, - { - "ab72c77b97cb5fe9a382d9fe81ffdbed", - "54cc7dc2c37ec006bcc6d1da", - "007c5e5b3e59df24a7c355584fc1518d", - "", - "0e1bde206a07a9c2c1b65300f8c649972b4401346697138c7a4891ee59867d0c", - }, - { - "fe47fcce5fc32665d2ae399e4eec72ba", - "5adb9609dbaeb58cbd6e7275", - "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1b840382c4bccaf3bafb4ca8429bea063", - "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a", - "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf5393043736365253ddbc5db8778371495da76d269e5db3e291ef1982e4defedaa2249f898556b47", - }, - { - "ec0c2ba17aa95cd6afffe949da9cc3a8", - "296bce5b50b7d66096d627ef", - "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987b764b9611f6c0f8641843d5d58f3a242", - "f8d00f05d22bf68599bcdeb131292ad6e2df5d14", - "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a07162995506fde6309ffc19e716eddf1a828c5a890147971946b627c40016da1ecf3e77", - }, - { - "2c1f21cf0f6fb3661943155c3e3d8492", - "23cb5ff362e22426984d1907", - "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d68b5615ba7c1220ff6510e259f06655d8", - "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f4488f33cfb5e979e42b6e1cfc0a60238982a7aec", - "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222b6ad57af43e1895df9dca2a5344a62cc57a3ee28136e94c74838997ae9823f3a", - }, - { - "d9f7d2411091f947b4d6f1e2d1f0fb2e", - "e1934f5db57cc983e6b180e7", - "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490c2c6f6166f4a59431e182663fcaea05a", - "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a20115d2e51398344b16bee1ed7c499b353d6c597af8", - "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d573c7891c2a91fbc48db29967ec9542b2321b51ca862cb637cdd03b99a0f93b134", - }, - { - "fe9bb47deb3a61e423c2231841cfd1fb", - "4d328eb776f500a2f7fb47aa", - "f1cc3818e421876bb6b8bbd6c9", - "", - "b88c5c1977b35b517b0aeae96743fd4727fe5cdb4b5b42818dea7ef8c9", - }, - { - "6703df3701a7f54911ca72e24dca046a", - "12823ab601c350ea4bc2488c", - "793cd125b0b84a043e3ac67717", - "", - "b2051c80014f42f08735a7b0cd38e6bcd29962e5f2c13626b85a877101", - }, -} - -func TestAESGCM(t *testing.T) { - for i, test := range aesGCMTests { - key, _ := hex.DecodeString(test.key) - aes, err := aes.NewCipher(key) - if err != nil { - t.Fatal(err) - } - - nonce, _ := hex.DecodeString(test.nonce) - plaintext, _ := hex.DecodeString(test.plaintext) - ad, _ := hex.DecodeString(test.ad) - aesgcm, err := cipher.NewGCM(aes) - if err != nil { - t.Fatal(err) - } - - ct := aesgcm.Seal(nil, nonce, plaintext, ad) - if ctHex := hex.EncodeToString(ct); ctHex != test.result { - t.Errorf("#%d: got %s, want %s", i, ctHex, test.result) - continue - } - - plaintext2, err := aesgcm.Open(nil, nonce, ct, ad) - if err != nil { - t.Errorf("#%d: Open failed", i) - continue - } - - if !bytes.Equal(plaintext, plaintext2) { - t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext) - continue - } - - if len(ad) > 0 { - ad[0] ^= 0x80 - if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { - t.Errorf("#%d: Open was successful after altering additional data", i) - } - ad[0] ^= 0x80 - } - - nonce[0] ^= 0x80 - if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { - t.Errorf("#%d: Open was successful after altering nonce", i) - } - nonce[0] ^= 0x80 - - ct[0] ^= 0x80 - if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { - t.Errorf("#%d: Open was successful after altering ciphertext", i) - } - ct[0] ^= 0x80 - } -} diff --git a/src/pkg/crypto/cipher/io.go b/src/pkg/crypto/cipher/io.go deleted file mode 100644 index 3938c0a4c..000000000 --- a/src/pkg/crypto/cipher/io.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher - -import "io" - -// The Stream* objects are so simple that all their members are public. Users -// can create them themselves. - -// StreamReader wraps a Stream into an io.Reader. It calls XORKeyStream -// to process each slice of data which passes through. -type StreamReader struct { - S Stream - R io.Reader -} - -func (r StreamReader) Read(dst []byte) (n int, err error) { - n, err = r.R.Read(dst) - r.S.XORKeyStream(dst[:n], dst[:n]) - return -} - -// StreamWriter wraps a Stream into an io.Writer. It calls XORKeyStream -// to process each slice of data which passes through. If any Write call -// returns short then the StreamWriter is out of sync and must be discarded. -// A StreamWriter has no internal buffering; Close does not need -// to be called to flush write data. -type StreamWriter struct { - S Stream - W io.Writer - Err error // unused -} - -func (w StreamWriter) Write(src []byte) (n int, err error) { - c := make([]byte, len(src)) - w.S.XORKeyStream(c, src) - n, err = w.W.Write(c) - if n != len(src) { - if err == nil { // should never happen - err = io.ErrShortWrite - } - } - return -} - -// Close closes the underlying Writer and returns its Close return value, if the Writer -// is also an io.Closer. Otherwise it returns nil. -func (w StreamWriter) Close() error { - if c, ok := w.W.(io.Closer); ok { - return c.Close() - } - return nil -} diff --git a/src/pkg/crypto/cipher/ofb.go b/src/pkg/crypto/cipher/ofb.go deleted file mode 100644 index e86ebcb23..000000000 --- a/src/pkg/crypto/cipher/ofb.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// OFB (Output Feedback) Mode. - -package cipher - -type ofb struct { - b Block - cipher []byte - out []byte - outUsed int -} - -// NewOFB returns a Stream that encrypts or decrypts using the block cipher b -// in output feedback mode. The initialization vector iv's length must be equal -// to b's block size. -func NewOFB(b Block, iv []byte) Stream { - blockSize := b.BlockSize() - if len(iv) != blockSize { - return nil - } - bufSize := streamBufferSize - if bufSize < blockSize { - bufSize = blockSize - } - x := &ofb{ - b: b, - cipher: make([]byte, blockSize), - out: make([]byte, 0, bufSize), - outUsed: 0, - } - - copy(x.cipher, iv) - return x -} - -func (x *ofb) refill() { - bs := x.b.BlockSize() - remain := len(x.out) - x.outUsed - if remain > x.outUsed { - return - } - copy(x.out, x.out[x.outUsed:]) - x.out = x.out[:cap(x.out)] - for remain < len(x.out)-bs { - x.b.Encrypt(x.cipher, x.cipher) - copy(x.out[remain:], x.cipher) - remain += bs - } - x.out = x.out[:remain] - x.outUsed = 0 -} - -func (x *ofb) XORKeyStream(dst, src []byte) { - for len(src) > 0 { - if x.outUsed >= len(x.out)-x.b.BlockSize() { - x.refill() - } - n := xorBytes(dst, src, x.out[x.outUsed:]) - dst = dst[n:] - src = src[n:] - x.outUsed += n - } -} diff --git a/src/pkg/crypto/cipher/ofb_test.go b/src/pkg/crypto/cipher/ofb_test.go deleted file mode 100644 index 8d3c5d3a3..000000000 --- a/src/pkg/crypto/cipher/ofb_test.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// OFB AES test vectors. - -// See U.S. National Institute of Standards and Technology (NIST) -// Special Publication 800-38A, ``Recommendation for Block Cipher -// Modes of Operation,'' 2001 Edition, pp. 52-55. - -package cipher_test - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "testing" -) - -type ofbTest struct { - name string - key []byte - iv []byte - in []byte - out []byte -} - -var ofbTests = []ofbTest{ - // NIST SP 800-38A pp 52-55 - { - "OFB-AES128", - commonKey128, - commonIV, - commonInput, - []byte{ - 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e, - }, - }, - { - "OFB-AES192", - commonKey192, - commonIV, - commonInput, - []byte{ - 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a, - }, - }, - { - "OFB-AES256", - commonKey256, - commonIV, - commonInput, - []byte{ - 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84, - }, - }, -} - -func TestOFB(t *testing.T) { - for _, tt := range ofbTests { - test := tt.name - - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err) - continue - } - - for j := 0; j <= 5; j += 5 { - plaintext := tt.in[0 : len(tt.in)-j] - ofb := cipher.NewOFB(c, tt.iv) - ciphertext := make([]byte, len(plaintext)) - ofb.XORKeyStream(ciphertext, plaintext) - if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) { - t.Errorf("%s/%d: encrypting\ninput % x\nhave % x\nwant % x", test, len(plaintext), plaintext, ciphertext, tt.out) - } - } - - for j := 0; j <= 5; j += 5 { - ciphertext := tt.out[0 : len(tt.in)-j] - ofb := cipher.NewOFB(c, tt.iv) - plaintext := make([]byte, len(ciphertext)) - ofb.XORKeyStream(plaintext, ciphertext) - if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) { - t.Errorf("%s/%d: decrypting\nhave % x\nwant % x", test, len(ciphertext), plaintext, tt.in) - } - } - - if t.Failed() { - break - } - } -} diff --git a/src/pkg/crypto/cipher/xor.go b/src/pkg/crypto/cipher/xor.go deleted file mode 100644 index f88dc8914..000000000 --- a/src/pkg/crypto/cipher/xor.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher - -import ( - "runtime" - "unsafe" -) - -const wordSize = int(unsafe.Sizeof(uintptr(0))) -const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" - -// fastXORBytes xors in bulk. It only works on architectures that -// support unaligned read/writes. -func fastXORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - - w := n / wordSize - if w > 0 { - dw := *(*[]uintptr)(unsafe.Pointer(&dst)) - aw := *(*[]uintptr)(unsafe.Pointer(&a)) - bw := *(*[]uintptr)(unsafe.Pointer(&b)) - for i := 0; i < w; i++ { - dw[i] = aw[i] ^ bw[i] - } - } - - for i := (n - n%wordSize); i < n; i++ { - dst[i] = a[i] ^ b[i] - } - - return n -} - -func safeXORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } - return n -} - -// xorBytes xors the bytes in a and b. The destination is assumed to have enough -// space. Returns the number of bytes xor'd. -func xorBytes(dst, a, b []byte) int { - if supportsUnaligned { - return fastXORBytes(dst, a, b) - } else { - // TODO(hanwen): if (dst, a, b) have common alignment - // we could still try fastXORBytes. It is not clear - // how often this happens, and it's only worth it if - // the block encryption itself is hardware - // accelerated. - return safeXORBytes(dst, a, b) - } -} - -// fastXORWords XORs multiples of 4 or 8 bytes (depending on architecture.) -// The arguments are assumed to be of equal length. -func fastXORWords(dst, a, b []byte) { - dw := *(*[]uintptr)(unsafe.Pointer(&dst)) - aw := *(*[]uintptr)(unsafe.Pointer(&a)) - bw := *(*[]uintptr)(unsafe.Pointer(&b)) - n := len(b) / wordSize - for i := 0; i < n; i++ { - dw[i] = aw[i] ^ bw[i] - } -} - -func xorWords(dst, a, b []byte) { - if supportsUnaligned { - fastXORWords(dst, a, b) - } else { - safeXORBytes(dst, a, b) - } -} diff --git a/src/pkg/crypto/cipher/xor_test.go b/src/pkg/crypto/cipher/xor_test.go deleted file mode 100644 index cc1c9d72d..000000000 --- a/src/pkg/crypto/cipher/xor_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cipher - -import ( - "bytes" - "testing" -) - -func TestXOR(t *testing.T) { - for alignP := 0; alignP < 2; alignP++ { - for alignQ := 0; alignQ < 2; alignQ++ { - for alignD := 0; alignD < 2; alignD++ { - p := make([]byte, 1024)[alignP:] - q := make([]byte, 1024)[alignQ:] - d1 := make([]byte, 1024+alignD)[alignD:] - d2 := make([]byte, 1024+alignD)[alignD:] - xorBytes(d1, p, q) - safeXORBytes(d2, p, q) - if bytes.Compare(d1, d2) != 0 { - t.Error("not equal") - } - } - } - } -} |