diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-04-07 17:09:10 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-04-07 17:09:10 +0000 |
commit | 405ca10418216fc078ecb29ff13a39c911e8d806 (patch) | |
tree | 39c2c0da7b6c220dd344f134fae07fba0d0266b2 /libgo/go/crypto | |
parent | a751005d50fa7347131660e562c5fd9ce3dff75d (diff) | |
download | gcc-405ca10418216fc078ecb29ff13a39c911e8d806.zip gcc-405ca10418216fc078ecb29ff13a39c911e8d806.tar.gz gcc-405ca10418216fc078ecb29ff13a39c911e8d806.tar.bz2 |
libgo: Update to current Go library.
From-SVN: r172106
Diffstat (limited to 'libgo/go/crypto')
29 files changed, 2104 insertions, 2305 deletions
diff --git a/libgo/go/crypto/block/cbc.go b/libgo/go/crypto/block/cbc.go deleted file mode 100644 index 23229c0..0000000 --- a/libgo/go/crypto/block/cbc.go +++ /dev/null @@ -1,71 +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 block - -import ( - "io" -) - -type cbcCipher struct { - c Cipher - blockSize int - iv []byte - tmp []byte -} - -func newCBC(c Cipher, iv []byte) *cbcCipher { - n := c.BlockSize() - x := new(cbcCipher) - x.c = c - x.blockSize = n - x.iv = dup(iv) - x.tmp = make([]byte, n) - return x -} - -func (x *cbcCipher) BlockSize() int { return x.blockSize } - -func (x *cbcCipher) Encrypt(dst, src []byte) { - for i := 0; i < x.blockSize; i++ { - x.iv[i] ^= src[i] - } - x.c.Encrypt(x.iv, x.iv) - for i := 0; i < x.blockSize; i++ { - dst[i] = x.iv[i] - } -} - -func (x *cbcCipher) Decrypt(dst, src []byte) { - x.c.Decrypt(x.tmp, src) - for i := 0; i < x.blockSize; i++ { - x.tmp[i] ^= x.iv[i] - x.iv[i] = src[i] - dst[i] = x.tmp[i] - } -} - -// NewCBCDecrypter returns a reader that reads data from r and decrypts it using c -// in cipher block chaining (CBC) mode with the initialization vector iv. -// The returned Reader does not buffer or read ahead except -// as required by the cipher's block size. -func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader { - return NewECBDecrypter(newCBC(c, iv), r) -} - -// NewCBCEncrypter returns a writer that encrypts data using c -// in cipher block chaining (CBC) mode with the initialization vector iv -// and writes the encrypted data to w. -// The returned Writer does no buffering except as required -// by the cipher's block size, so there is no need for a Flush method. -func NewCBCEncrypter(c Cipher, iv []byte, w io.Writer) io.Writer { - return NewECBEncrypter(newCBC(c, iv), w) -} diff --git a/libgo/go/crypto/block/cfb.go b/libgo/go/crypto/block/cfb.go deleted file mode 100644 index f20c0a0..0000000 --- a/libgo/go/crypto/block/cfb.go +++ /dev/null @@ -1,96 +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 feedback (CFB) mode. - -// CFB provides confidentiality by feeding a fraction of -// the previous ciphertext in as the plaintext for the next -// block operation. - -// See NIST SP 800-38A, pp 11-13 - -package block - -import ( - "io" -) - -type cfbCipher struct { - c Cipher - blockSize int // our block size (s/8) - cipherSize int // underlying cipher block size - iv []byte - tmp []byte -} - -func newCFB(c Cipher, s int, iv []byte) *cfbCipher { - if s == 0 || s%8 != 0 { - panic("crypto/block: invalid CFB mode") - } - b := c.BlockSize() - x := new(cfbCipher) - x.c = c - x.blockSize = s / 8 - x.cipherSize = b - x.iv = dup(iv) - x.tmp = make([]byte, b) - return x -} - -func (x *cfbCipher) BlockSize() int { return x.blockSize } - -func (x *cfbCipher) Encrypt(dst, src []byte) { - // Encrypt old IV and xor prefix with src to make dst. - x.c.Encrypt(x.tmp, x.iv) - for i := 0; i < x.blockSize; i++ { - dst[i] = src[i] ^ x.tmp[i] - } - - // Slide unused IV pieces down and insert dst at end. - for i := 0; i < x.cipherSize-x.blockSize; i++ { - x.iv[i] = x.iv[i+x.blockSize] - } - off := x.cipherSize - x.blockSize - for i := off; i < x.cipherSize; i++ { - x.iv[i] = dst[i-off] - } -} - -func (x *cfbCipher) Decrypt(dst, src []byte) { - // Encrypt [sic] old IV and xor prefix with src to make dst. - x.c.Encrypt(x.tmp, x.iv) - for i := 0; i < x.blockSize; i++ { - dst[i] = src[i] ^ x.tmp[i] - } - - // Slide unused IV pieces down and insert src at top. - for i := 0; i < x.cipherSize-x.blockSize; i++ { - x.iv[i] = x.iv[i+x.blockSize] - } - off := x.cipherSize - x.blockSize - for i := off; i < x.cipherSize; i++ { - // Reconstruct src = dst ^ x.tmp - // in case we overwrote src (src == dst). - x.iv[i] = dst[i-off] ^ x.tmp[i-off] - } -} - -// NewCFBDecrypter returns a reader that reads data from r and decrypts it using c -// in s-bit cipher feedback (CFB) mode with the initialization vector iv. -// The returned Reader does not buffer or read ahead except -// as required by the cipher's block size. -// Modes for s not a multiple of 8 are unimplemented. -func NewCFBDecrypter(c Cipher, s int, iv []byte, r io.Reader) io.Reader { - return NewECBDecrypter(newCFB(c, s, iv), r) -} - -// NewCFBEncrypter returns a writer that encrypts data using c -// in s-bit cipher feedback (CFB) mode with the initialization vector iv -// and writes the encrypted data to w. -// The returned Writer does no buffering except as required -// by the cipher's block size, so there is no need for a Flush method. -// Modes for s not a multiple of 8 are unimplemented. -func NewCFBEncrypter(c Cipher, s int, iv []byte, w io.Writer) io.Writer { - return NewECBEncrypter(newCFB(c, s, iv), w) -} diff --git a/libgo/go/crypto/block/cfb_aes_test.go b/libgo/go/crypto/block/cfb_aes_test.go deleted file mode 100644 index e400c18..0000000 --- a/libgo/go/crypto/block/cfb_aes_test.go +++ /dev/null @@ -1,311 +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. - -// CFB 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. 29-52. - -package block - -import ( - "bytes" - "crypto/aes" - "io" - "testing" -) - -type cfbTest struct { - name string - s int - key []byte - iv []byte - in []byte - out []byte -} - -var cfbAESTests = []cfbTest{ - { - "CFB1-AES128", - 1, - commonKey128, - commonIV, - []byte{ - 0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1, - 1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1, - }, - []byte{ - 0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 0<<1, - 1<<7 | 0<<6 | 1<<5 | 1<<4 | 0<<3 | 0<<2 | 1<<1, - }, - }, - { - "CFB1-AES192", - 1, - commonKey192, - commonIV, - []byte{ - 0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1, - 1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1, - }, - []byte{ - 1<<7 | 0<<6 | 0<<5 | 1<<4 | 0<<3 | 0<<2 | 1<<1, - 0<<7 | 1<<6 | 0<<5 | 1<<4 | 1<<3 | 0<<2 | 0<<1, - }, - }, - { - "CFB1-AES256", - 1, - commonKey256, - commonIV, - []byte{ - 0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1, - 1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1, - }, - []byte{ - 1<<7 | 0<<6 | 0<<5 | 1<<4 | 0<<3 | 0<<2 | 0<<1, - 0<<7 | 0<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 0<<1, - }, - }, - - { - "CFB8-AES128", - 8, - commonKey128, - commonIV, - []byte{ - 0x6b, - 0xc1, - 0xbe, - 0xe2, - 0x2e, - 0x40, - 0x9f, - 0x96, - 0xe9, - 0x3d, - 0x7e, - 0x11, - 0x73, - 0x93, - 0x17, - 0x2a, - 0xae, - 0x2d, - }, - []byte{ - 0x3b, - 0x79, - 0x42, - 0x4c, - 0x9c, - 0x0d, - 0xd4, - 0x36, - 0xba, - 0xce, - 0x9e, - 0x0e, - 0xd4, - 0x58, - 0x6a, - 0x4f, - 0x32, - 0xb9, - }, - }, - - { - "CFB8-AES192", - 8, - commonKey192, - commonIV, - []byte{ - 0x6b, - 0xc1, - 0xbe, - 0xe2, - 0x2e, - 0x40, - 0x9f, - 0x96, - 0xe9, - 0x3d, - 0x7e, - 0x11, - 0x73, - 0x93, - 0x17, - 0x2a, - 0xae, - 0x2d, - }, - []byte{ - 0xcd, - 0xa2, - 0x52, - 0x1e, - 0xf0, - 0xa9, - 0x05, - 0xca, - 0x44, - 0xcd, - 0x05, - 0x7c, - 0xbf, - 0x0d, - 0x47, - 0xa0, - 0x67, - 0x8a, - }, - }, - - { - "CFB8-AES256", - 8, - commonKey256, - commonIV, - []byte{ - 0x6b, - 0xc1, - 0xbe, - 0xe2, - 0x2e, - 0x40, - 0x9f, - 0x96, - 0xe9, - 0x3d, - 0x7e, - 0x11, - 0x73, - 0x93, - 0x17, - 0x2a, - 0xae, - 0x2d, - }, - []byte{ - 0xdc, - 0x1f, - 0x1a, - 0x85, - 0x20, - 0xa6, - 0x4d, - 0xb5, - 0x5f, - 0xcc, - 0x8a, - 0xc5, - 0x54, - 0x84, - 0x4e, - 0x88, - 0x97, - 0x00, - }, - }, - - { - "CFB128-AES128", - 128, - commonKey128, - commonIV, - []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, - }, - []byte{ - 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, - 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b, - 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40, 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf, - 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e, 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6, - }, - }, - - { - "CFB128-AES192", - 128, - commonKey192, - commonIV, - []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, - }, - []byte{ - 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, - 0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21, 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a, - 0x2e, 0x1e, 0x8a, 0x1d, 0xd5, 0x9b, 0x88, 0xb1, 0xc8, 0xe6, 0x0f, 0xed, 0x1e, 0xfa, 0xc4, 0xc9, - 0xc0, 0x5f, 0x9f, 0x9c, 0xa9, 0x83, 0x4f, 0xa0, 0x42, 0xae, 0x8f, 0xba, 0x58, 0x4b, 0x09, 0xff, - }, - }, - - { - "CFB128-AES256", - 128, - commonKey256, - commonIV, - []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, - }, - []byte{ - 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, - 0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8, 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b, - 0xdf, 0x10, 0x13, 0x24, 0x15, 0xe5, 0x4b, 0x92, 0xa1, 0x3e, 0xd0, 0xa8, 0x26, 0x7a, 0xe2, 0xf9, - 0x75, 0xa3, 0x85, 0x74, 0x1a, 0xb9, 0xce, 0xf8, 0x20, 0x31, 0x62, 0x3d, 0x55, 0xb1, 0xe4, 0x71, - }, - }, -} - -func TestCFB_AES(t *testing.T) { - for _, tt := range cfbAESTests { - test := tt.name - - if tt.s == 1 { - // 1-bit CFB not implemented - continue - } - - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err) - continue - } - - var crypt bytes.Buffer - w := NewCFBEncrypter(c, tt.s, tt.iv, &crypt) - var r io.Reader = bytes.NewBuffer(tt.in) - n, err := io.Copy(w, r) - if n != int64(len(tt.in)) || err != nil { - t.Errorf("%s: CFBEncrypter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.in)) - } else if d := crypt.Bytes(); !same(tt.out, d) { - t.Errorf("%s: CFBEncrypter\nhave %x\nwant %x", test, d, tt.out) - } - - var plain bytes.Buffer - r = NewCFBDecrypter(c, tt.s, tt.iv, bytes.NewBuffer(tt.out)) - w = &plain - n, err = io.Copy(w, r) - if n != int64(len(tt.out)) || err != nil { - t.Errorf("%s: CFBDecrypter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.out)) - } else if d := plain.Bytes(); !same(tt.in, d) { - t.Errorf("%s: CFBDecrypter\nhave %x\nwant %x", test, d, tt.in) - } - - if t.Failed() { - break - } - } -} diff --git a/libgo/go/crypto/block/cipher.go b/libgo/go/crypto/block/cipher.go deleted file mode 100644 index e1099e9..0000000 --- a/libgo/go/crypto/block/cipher.go +++ /dev/null @@ -1,57 +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. - -// The block package is deprecated, use cipher instead. -// The block package 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 block - -// A Cipher 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 Cipher interface { - // BlockSize returns the cipher's block size. - BlockSize() int - - // Encrypt encrypts the first block in src into dst. - // Src and dst may point at the same memory. - Encrypt(dst, src []byte) - - // Decrypt decrypts the first block in src into dst. - // Src and dst may point at the same memory. - Decrypt(dst, src []byte) -} - -// Utility routines - -func shift1(dst, src []byte) byte { - var b byte - for i := len(src) - 1; i >= 0; i-- { - bb := src[i] >> 7 - dst[i] = src[i]<<1 | b - b = bb - } - return b -} - -func same(p, q []byte) bool { - if len(p) != len(q) { - return false - } - for i := 0; i < len(p); i++ { - if p[i] != q[i] { - return false - } - } - return true -} - -func dup(p []byte) []byte { - q := make([]byte, len(p)) - copy(q, p) - return q -} diff --git a/libgo/go/crypto/block/cmac.go b/libgo/go/crypto/block/cmac.go deleted file mode 100644 index b85cde7..0000000 --- a/libgo/go/crypto/block/cmac.go +++ /dev/null @@ -1,105 +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. - -// CMAC message authentication code, defined in -// NIST Special Publication SP 800-38B. - -package block - -import ( - "hash" - "os" -) - -const ( - // minimal irreducible polynomial of degree b - r64 = 0x1b - r128 = 0x87 -) - -type cmac struct { - k1, k2, ci, digest []byte - p int // position in ci - c Cipher -} - -// TODO(rsc): Should this return an error instead of panic? - -// NewCMAC returns a new instance of a CMAC message authentication code -// digest using the given Cipher. -func NewCMAC(c Cipher) hash.Hash { - var r byte - n := c.BlockSize() - switch n { - case 64 / 8: - r = r64 - case 128 / 8: - r = r128 - default: - panic("crypto/block: NewCMAC: invalid cipher block size") - } - - d := new(cmac) - d.c = c - d.k1 = make([]byte, n) - d.k2 = make([]byte, n) - d.ci = make([]byte, n) - d.digest = make([]byte, n) - - // Subkey generation, p. 7 - c.Encrypt(d.k1, d.k1) - if shift1(d.k1, d.k1) != 0 { - d.k1[n-1] ^= r - } - if shift1(d.k2, d.k1) != 0 { - d.k2[n-1] ^= r - } - - return d -} - -// Reset clears the digest state, starting a new digest. -func (d *cmac) Reset() { - for i := range d.ci { - d.ci[i] = 0 - } - d.p = 0 -} - -// Write adds the given data to the digest state. -func (d *cmac) Write(p []byte) (n int, err os.Error) { - // Xor input into ci. - for _, c := range p { - // If ci is full, encrypt and start over. - if d.p >= len(d.ci) { - d.c.Encrypt(d.ci, d.ci) - d.p = 0 - } - d.ci[d.p] ^= c - d.p++ - } - return len(p), nil -} - -// Sum returns the CMAC digest, one cipher block in length, -// of the data written with Write. -func (d *cmac) Sum() []byte { - // Finish last block, mix in key, encrypt. - // Don't edit ci, in case caller wants - // to keep digesting after call to Sum. - k := d.k1 - if d.p < len(d.digest) { - k = d.k2 - } - for i := 0; i < len(d.ci); i++ { - d.digest[i] = d.ci[i] ^ k[i] - } - if d.p < len(d.digest) { - d.digest[d.p] ^= 0x80 - } - d.c.Encrypt(d.digest, d.digest) - return d.digest -} - -func (d *cmac) Size() int { return len(d.digest) } diff --git a/libgo/go/crypto/block/cmac_aes_test.go b/libgo/go/crypto/block/cmac_aes_test.go deleted file mode 100644 index 0a4a1a4..0000000 --- a/libgo/go/crypto/block/cmac_aes_test.go +++ /dev/null @@ -1,130 +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. - -// CMAC test vectors. See NIST SP 800-38B, Appendix D. - -package block - -import ( - "crypto/aes" - "testing" -) - -type cmacAESTest struct { - key []byte - in []byte - digest []byte -} - -var cmacAESTests = []cmacAESTest{ - { - commonKey128, - nil, - []byte{0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46}, - }, - { - commonKey128, - []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, - []byte{0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c}, - }, - { - commonKey128, - []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, - }, - []byte{0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27}, - }, - { - commonKey128, - []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, - }, - []byte{0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe}, - }, - { - commonKey192, - nil, - []byte{0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67}, - }, - { - commonKey192, - []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, - []byte{0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84}, - }, - { - commonKey192, - []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, - }, - []byte{0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad, 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e}, - }, - { - commonKey192, - []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, - }, - []byte{0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11}, - }, - { - commonKey256, - nil, - []byte{0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83}, - }, - { - commonKey256, - []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, - []byte{0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c}, - }, - { - commonKey256, - []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, - }, - []byte{0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6}, - }, - { - commonKey256, - []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, - }, - []byte{0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10}, - }, -} - -func TestCMAC_AES(t *testing.T) { - for i, tt := range cmacAESTests { - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Errorf("test %d: NewCipher: %s", i, err) - continue - } - d := NewCMAC(c) - n, err := d.Write(tt.in) - if err != nil || n != len(tt.in) { - t.Errorf("test %d: Write %d: %d, %s", i, len(tt.in), n, err) - continue - } - sum := d.Sum() - if !same(sum, tt.digest) { - x := d.(*cmac) - t.Errorf("test %d: digest mismatch\n\twant %x\n\thave %x\n\tk1 %x\n\tk2 %x", i, tt.digest, sum, x.k1, x.k2) - continue - } - } -} diff --git a/libgo/go/crypto/block/ctr.go b/libgo/go/crypto/block/ctr.go deleted file mode 100644 index 5d65c0c..0000000 --- a/libgo/go/crypto/block/ctr.go +++ /dev/null @@ -1,67 +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 block - -import ( - "io" -) - -type ctrStream struct { - c Cipher - ctr []byte - out []byte -} - -func newCTRStream(c Cipher, ctr []byte) *ctrStream { - x := new(ctrStream) - x.c = c - x.ctr = dup(ctr) - x.out = make([]byte, len(ctr)) - return x -} - -func (x *ctrStream) Next() []byte { - // Next block is encryption of counter. - x.c.Encrypt(x.out, x.ctr) - - // Increment counter - for i := len(x.ctr) - 1; i >= 0; i-- { - x.ctr[i]++ - if x.ctr[i] != 0 { - break - } - } - - return x.out -} - -// NewCTRReader returns a reader that reads data from r, decrypts (or encrypts) -// it using c in counter (CTR) mode with the initialization vector iv. -// The returned Reader does not buffer and has no block size. -// In CTR mode, encryption and decryption are the same operation: -// a CTR reader applied to an encrypted stream produces a decrypted -// stream and vice versa. -func NewCTRReader(c Cipher, iv []byte, r io.Reader) io.Reader { - return newXorReader(newCTRStream(c, iv), r) -} - -// NewCTRWriter returns a writer that encrypts (or decrypts) data using c -// in counter (CTR) mode with the initialization vector iv -// and writes the encrypted data to w. -// The returned Writer does not buffer and has no block size. -// In CTR mode, encryption and decryption are the same operation: -// a CTR writer applied to an decrypted stream produces an encrypted -// stream and vice versa. -func NewCTRWriter(c Cipher, iv []byte, w io.Writer) io.Writer { - return newXorWriter(newCTRStream(c, iv), w) -} diff --git a/libgo/go/crypto/block/eax.go b/libgo/go/crypto/block/eax.go deleted file mode 100644 index 3f3b964..0000000 --- a/libgo/go/crypto/block/eax.go +++ /dev/null @@ -1,253 +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. - -// EAX mode, not a NIST standard (yet). -// EAX provides encryption and authentication. -// EAX targets the same uses as NIST's CCM mode, -// but EAX adds the ability to run in streaming mode. - -// See -// http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf -// http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf -// What those papers call OMAC is now called CMAC. - -package block - -import ( - "fmt" - "hash" - "io" - "os" -) - -// An EAXTagError is returned when the message has failed to authenticate, -// because the tag at the end of the message stream (Read) does not match -// the tag computed from the message itself (Computed). -type EAXTagError struct { - Read []byte - Computed []byte -} - -func (e *EAXTagError) String() string { - return fmt.Sprintf("crypto/block: EAX tag mismatch: read %x but computed %x", e.Read, e.Computed) -} - -func setupEAX(c Cipher, iv, hdr []byte, tagBytes int) (ctrIV, tag []byte, cmac hash.Hash) { - n := len(iv) - if n != c.BlockSize() { - panic(fmt.Sprintln("crypto/block: EAX: iv length", n, "!=", c.BlockSize())) - } - buf := make([]byte, n) // zeroed - - // tag = CMAC(0 + iv) ^ CMAC(1 + hdr) ^ CMAC(2 + data) - cmac = NewCMAC(c) - cmac.Write(buf) // 0 - cmac.Write(iv) - sum := cmac.Sum() - ctrIV = dup(sum) - tag = dup(sum[0:tagBytes]) - - cmac.Reset() - buf[n-1] = 1 - cmac.Write(buf) // 1 - cmac.Write(hdr) - sum = cmac.Sum() - for i := 0; i < tagBytes; i++ { - tag[i] ^= sum[i] - } - - cmac.Reset() - buf[n-1] = 2 // 2 - cmac.Write(buf) - - return -} - -func finishEAX(tag []byte, cmac hash.Hash) { - // Finish CMAC #2 and xor into tag. - sum := cmac.Sum() - for i := range tag { - tag[i] ^= sum[i] - } -} - -// Writer adapter. Tees writes into both w and cmac. -// Knows that cmac never returns write errors. -type cmacWriter struct { - w io.Writer - cmac hash.Hash -} - -func (cw *cmacWriter) Write(p []byte) (n int, err os.Error) { - n, err = cw.w.Write(p) - cw.cmac.Write(p[0:n]) - return -} - -// An eaxEncrypter implements the EAX encryption mode. -type eaxEncrypter struct { - ctr io.Writer // CTR encrypter - cw cmacWriter // CTR's output stream - tag []byte -} - -// NewEAXEncrypter creates and returns a new EAX encrypter -// using the given cipher c, initialization vector iv, associated data hdr, -// and tag length tagBytes. The encrypter's Write method encrypts -// the data it receives and writes that data to w. -// The encrypter's Close method writes a final authenticating tag to w. -func NewEAXEncrypter(c Cipher, iv []byte, hdr []byte, tagBytes int, w io.Writer) io.WriteCloser { - x := new(eaxEncrypter) - - // Create new CTR instance writing to both - // w for encrypted output and cmac for digesting. - x.cw.w = w - var ctrIV []byte - ctrIV, x.tag, x.cw.cmac = setupEAX(c, iv, hdr, tagBytes) - x.ctr = NewCTRWriter(c, ctrIV, &x.cw) - return x -} - -func (x *eaxEncrypter) Write(p []byte) (n int, err os.Error) { - return x.ctr.Write(p) -} - -func (x *eaxEncrypter) Close() os.Error { - x.ctr = nil // crash if Write is called again - - // Write tag. - finishEAX(x.tag, x.cw.cmac) - n, err := x.cw.w.Write(x.tag) - if n != len(x.tag) && err == nil { - err = io.ErrShortWrite - } - - return err -} - -// Reader adapter. Returns data read from r but hangs -// on to the last len(tag) bytes for itself (returns EOF len(tag) -// bytes early). Also tees all data returned from Read into -// the cmac digest. The "don't return the last t bytes" -// and the "tee into digest" functionality could be separated, -// but the latter half is trivial. -type cmacReader struct { - r io.Reader - cmac hash.Hash - tag []byte - tmp []byte -} - -func (cr *cmacReader) Read(p []byte) (n int, err os.Error) { - // TODO(rsc): Maybe fall back to simpler code if - // we recognize the underlying r as a ByteBuffer - // or ByteReader. Then we can just take the last piece - // off at the start. - - // First, read a tag-sized chunk. - // It's probably not the tag (unless there's no data). - tag := cr.tag - if len(tag) < cap(tag) { - nt := len(tag) - nn, err1 := io.ReadFull(cr.r, tag[nt:cap(tag)]) - tag = tag[0 : nt+nn] - cr.tag = tag - if err1 != nil { - return 0, err1 - } - } - - tagBytes := len(tag) - if len(p) > 4*tagBytes { - // If p is big, try to read directly into p to avoid a copy. - n, err = cr.r.Read(p[tagBytes:]) - if n == 0 { - goto out - } - // copy old tag into p - for i := 0; i < tagBytes; i++ { - p[i] = tag[i] - } - // copy new tag out of p - for i := 0; i < tagBytes; i++ { - tag[i] = p[n+i] - } - goto out - } - - // Otherwise, read into p and then slide data - n, err = cr.r.Read(p) - if n == 0 { - goto out - } - - // copy tag+p into p+tmp and then swap tmp, tag - tmp := cr.tmp - for i := n + tagBytes - 1; i >= 0; i-- { - var c byte - if i < tagBytes { - c = tag[i] - } else { - c = p[i-tagBytes] - } - if i < n { - p[i] = c - } else { - tmp[i] = c - } - } - cr.tmp, cr.tag = tag, tmp - -out: - cr.cmac.Write(p[0:n]) - return -} - -type eaxDecrypter struct { - ctr io.Reader - cr cmacReader - tag []byte -} - -// NewEAXDecrypter creates and returns a new EAX decrypter -// using the given cipher c, initialization vector iv, associated data hdr, -// and tag length tagBytes. The encrypter's Read method decrypts and -// returns data read from r. At r's EOF, the encrypter checks the final -// authenticating tag and returns an EAXTagError if the tag is invalid. -// In that case, the message should be discarded. -// Note that the data stream returned from Read cannot be -// assumed to be valid, authenticated data until Read returns -// 0, nil to signal the end of the data. -func NewEAXDecrypter(c Cipher, iv []byte, hdr []byte, tagBytes int, r io.Reader) io.Reader { - x := new(eaxDecrypter) - - x.cr.r = r - x.cr.tag = make([]byte, 0, tagBytes) - x.cr.tmp = make([]byte, 0, tagBytes) - var ctrIV []byte - ctrIV, x.tag, x.cr.cmac = setupEAX(c, iv, hdr, tagBytes) - x.ctr = NewCTRReader(c, ctrIV, &x.cr) - return x -} - -func (x *eaxDecrypter) checkTag() os.Error { - x.ctr = nil // crash if Read is called again - - finishEAX(x.tag, x.cr.cmac) - if !same(x.tag, x.cr.tag) { - e := new(EAXTagError) - e.Computed = dup(x.tag) - e.Read = dup(x.cr.tag) - return e - } - return nil -} - -func (x *eaxDecrypter) Read(p []byte) (n int, err os.Error) { - n, err = x.ctr.Read(p) - if n == 0 && err == nil { - err = x.checkTag() - } - return n, err -} diff --git a/libgo/go/crypto/block/eax_aes_test.go b/libgo/go/crypto/block/eax_aes_test.go deleted file mode 100644 index 93aa771..0000000 --- a/libgo/go/crypto/block/eax_aes_test.go +++ /dev/null @@ -1,140 +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 block - -import ( - "bytes" - "crypto/aes" - "fmt" - "io" - "testing" -) - -// Test vectors from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf - -type eaxAESTest struct { - msg []byte - key []byte - nonce []byte - header []byte - cipher []byte -} - -var eaxAESTests = []eaxAESTest{ - { - []byte{}, - []byte{0x23, 0x39, 0x52, 0xDE, 0xE4, 0xD5, 0xED, 0x5F, 0x9B, 0x9C, 0x6D, 0x6F, 0xF8, 0x0F, 0xF4, 0x78}, - []byte{0x62, 0xEC, 0x67, 0xF9, 0xC3, 0xA4, 0xA4, 0x07, 0xFC, 0xB2, 0xA8, 0xC4, 0x90, 0x31, 0xA8, 0xB3}, - []byte{0x6B, 0xFB, 0x91, 0x4F, 0xD0, 0x7E, 0xAE, 0x6B}, - []byte{0xE0, 0x37, 0x83, 0x0E, 0x83, 0x89, 0xF2, 0x7B, 0x02, 0x5A, 0x2D, 0x65, 0x27, 0xE7, 0x9D, 0x01}, - }, - { - []byte{0xF7, 0xFB}, - []byte{0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B, 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4}, - []byte{0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84, 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD}, - []byte{0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA}, - []byte{0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D, 0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79, 0x67, 0xE5}, - }, - { - []byte{0x1A, 0x47, 0xCB, 0x49, 0x33}, - []byte{0x01, 0xF7, 0x4A, 0xD6, 0x40, 0x77, 0xF2, 0xE7, 0x04, 0xC0, 0xF6, 0x0A, 0xDA, 0x3D, 0xD5, 0x23}, - []byte{0x70, 0xC3, 0xDB, 0x4F, 0x0D, 0x26, 0x36, 0x84, 0x00, 0xA1, 0x0E, 0xD0, 0x5D, 0x2B, 0xFF, 0x5E}, - []byte{0x23, 0x4A, 0x34, 0x63, 0xC1, 0x26, 0x4A, 0xC6}, - []byte{0xD8, 0x51, 0xD5, 0xBA, 0xE0, 0x3A, 0x59, 0xF2, 0x38, 0xA2, 0x3E, 0x39, 0x19, 0x9D, 0xC9, 0x26, 0x66, 0x26, 0xC4, 0x0F, 0x80}, - }, - { - []byte{0x48, 0x1C, 0x9E, 0x39, 0xB1}, - []byte{0xD0, 0x7C, 0xF6, 0xCB, 0xB7, 0xF3, 0x13, 0xBD, 0xDE, 0x66, 0xB7, 0x27, 0xAF, 0xD3, 0xC5, 0xE8}, - []byte{0x84, 0x08, 0xDF, 0xFF, 0x3C, 0x1A, 0x2B, 0x12, 0x92, 0xDC, 0x19, 0x9E, 0x46, 0xB7, 0xD6, 0x17}, - []byte{0x33, 0xCC, 0xE2, 0xEA, 0xBF, 0xF5, 0xA7, 0x9D}, - []byte{0x63, 0x2A, 0x9D, 0x13, 0x1A, 0xD4, 0xC1, 0x68, 0xA4, 0x22, 0x5D, 0x8E, 0x1F, 0xF7, 0x55, 0x93, 0x99, 0x74, 0xA7, 0xBE, 0xDE}, - }, - { - []byte{0x40, 0xD0, 0xC0, 0x7D, 0xA5, 0xE4}, - []byte{0x35, 0xB6, 0xD0, 0x58, 0x00, 0x05, 0xBB, 0xC1, 0x2B, 0x05, 0x87, 0x12, 0x45, 0x57, 0xD2, 0xC2}, - []byte{0xFD, 0xB6, 0xB0, 0x66, 0x76, 0xEE, 0xDC, 0x5C, 0x61, 0xD7, 0x42, 0x76, 0xE1, 0xF8, 0xE8, 0x16}, - []byte{0xAE, 0xB9, 0x6E, 0xAE, 0xBE, 0x29, 0x70, 0xE9}, - []byte{0x07, 0x1D, 0xFE, 0x16, 0xC6, 0x75, 0xCB, 0x06, 0x77, 0xE5, 0x36, 0xF7, 0x3A, 0xFE, 0x6A, 0x14, 0xB7, 0x4E, 0xE4, 0x98, 0x44, 0xDD}, - }, - { - []byte{0x4D, 0xE3, 0xB3, 0x5C, 0x3F, 0xC0, 0x39, 0x24, 0x5B, 0xD1, 0xFB, 0x7D}, - []byte{0xBD, 0x8E, 0x6E, 0x11, 0x47, 0x5E, 0x60, 0xB2, 0x68, 0x78, 0x4C, 0x38, 0xC6, 0x2F, 0xEB, 0x22}, - []byte{0x6E, 0xAC, 0x5C, 0x93, 0x07, 0x2D, 0x8E, 0x85, 0x13, 0xF7, 0x50, 0x93, 0x5E, 0x46, 0xDA, 0x1B}, - []byte{0xD4, 0x48, 0x2D, 0x1C, 0xA7, 0x8D, 0xCE, 0x0F}, - []byte{0x83, 0x5B, 0xB4, 0xF1, 0x5D, 0x74, 0x3E, 0x35, 0x0E, 0x72, 0x84, 0x14, 0xAB, 0xB8, 0x64, 0x4F, 0xD6, 0xCC, 0xB8, 0x69, 0x47, 0xC5, 0xE1, 0x05, 0x90, 0x21, 0x0A, 0x4F}, - }, - { - []byte{0x8B, 0x0A, 0x79, 0x30, 0x6C, 0x9C, 0xE7, 0xED, 0x99, 0xDA, 0xE4, 0xF8, 0x7F, 0x8D, 0xD6, 0x16, 0x36}, - []byte{0x7C, 0x77, 0xD6, 0xE8, 0x13, 0xBE, 0xD5, 0xAC, 0x98, 0xBA, 0xA4, 0x17, 0x47, 0x7A, 0x2E, 0x7D}, - []byte{0x1A, 0x8C, 0x98, 0xDC, 0xD7, 0x3D, 0x38, 0x39, 0x3B, 0x2B, 0xF1, 0x56, 0x9D, 0xEE, 0xFC, 0x19}, - []byte{0x65, 0xD2, 0x01, 0x79, 0x90, 0xD6, 0x25, 0x28}, - []byte{0x02, 0x08, 0x3E, 0x39, 0x79, 0xDA, 0x01, 0x48, 0x12, 0xF5, 0x9F, 0x11, 0xD5, 0x26, 0x30, 0xDA, 0x30, 0x13, 0x73, 0x27, 0xD1, 0x06, 0x49, 0xB0, 0xAA, 0x6E, 0x1C, 0x18, 0x1D, 0xB6, 0x17, 0xD7, 0xF2}, - }, - { - []byte{0x1B, 0xDA, 0x12, 0x2B, 0xCE, 0x8A, 0x8D, 0xBA, 0xF1, 0x87, 0x7D, 0x96, 0x2B, 0x85, 0x92, 0xDD, 0x2D, 0x56}, - []byte{0x5F, 0xFF, 0x20, 0xCA, 0xFA, 0xB1, 0x19, 0xCA, 0x2F, 0xC7, 0x35, 0x49, 0xE2, 0x0F, 0x5B, 0x0D}, - []byte{0xDD, 0xE5, 0x9B, 0x97, 0xD7, 0x22, 0x15, 0x6D, 0x4D, 0x9A, 0xFF, 0x2B, 0xC7, 0x55, 0x98, 0x26}, - []byte{0x54, 0xB9, 0xF0, 0x4E, 0x6A, 0x09, 0x18, 0x9A}, - []byte{0x2E, 0xC4, 0x7B, 0x2C, 0x49, 0x54, 0xA4, 0x89, 0xAF, 0xC7, 0xBA, 0x48, 0x97, 0xED, 0xCD, 0xAE, 0x8C, 0xC3, 0x3B, 0x60, 0x45, 0x05, 0x99, 0xBD, 0x02, 0xC9, 0x63, 0x82, 0x90, 0x2A, 0xEF, 0x7F, 0x83, 0x2A}, - }, - { - []byte{0x6C, 0xF3, 0x67, 0x20, 0x87, 0x2B, 0x85, 0x13, 0xF6, 0xEA, 0xB1, 0xA8, 0xA4, 0x44, 0x38, 0xD5, 0xEF, 0x11}, - []byte{0xA4, 0xA4, 0x78, 0x2B, 0xCF, 0xFD, 0x3E, 0xC5, 0xE7, 0xEF, 0x6D, 0x8C, 0x34, 0xA5, 0x61, 0x23}, - []byte{0xB7, 0x81, 0xFC, 0xF2, 0xF7, 0x5F, 0xA5, 0xA8, 0xDE, 0x97, 0xA9, 0xCA, 0x48, 0xE5, 0x22, 0xEC}, - []byte{0x89, 0x9A, 0x17, 0x58, 0x97, 0x56, 0x1D, 0x7E}, - []byte{0x0D, 0xE1, 0x8F, 0xD0, 0xFD, 0xD9, 0x1E, 0x7A, 0xF1, 0x9F, 0x1D, 0x8E, 0xE8, 0x73, 0x39, 0x38, 0xB1, 0xE8, 0xE7, 0xF6, 0xD2, 0x23, 0x16, 0x18, 0x10, 0x2F, 0xDB, 0x7F, 0xE5, 0x5F, 0xF1, 0x99, 0x17, 0x00}, - }, - { - []byte{0xCA, 0x40, 0xD7, 0x44, 0x6E, 0x54, 0x5F, 0xFA, 0xED, 0x3B, 0xD1, 0x2A, 0x74, 0x0A, 0x65, 0x9F, 0xFB, 0xBB, 0x3C, 0xEA, 0xB7}, - []byte{0x83, 0x95, 0xFC, 0xF1, 0xE9, 0x5B, 0xEB, 0xD6, 0x97, 0xBD, 0x01, 0x0B, 0xC7, 0x66, 0xAA, 0xC3}, - []byte{0x22, 0xE7, 0xAD, 0xD9, 0x3C, 0xFC, 0x63, 0x93, 0xC5, 0x7E, 0xC0, 0xB3, 0xC1, 0x7D, 0x6B, 0x44}, - []byte{0x12, 0x67, 0x35, 0xFC, 0xC3, 0x20, 0xD2, 0x5A}, - []byte{0xCB, 0x89, 0x20, 0xF8, 0x7A, 0x6C, 0x75, 0xCF, 0xF3, 0x96, 0x27, 0xB5, 0x6E, 0x3E, 0xD1, 0x97, 0xC5, 0x52, 0xD2, 0x95, 0xA7, 0xCF, 0xC4, 0x6A, 0xFC, 0x25, 0x3B, 0x46, 0x52, 0xB1, 0xAF, 0x37, 0x95, 0xB1, 0x24, 0xAB, 0x6E}, - }, -} - -func TestEAXEncrypt_AES(t *testing.T) { - b := new(bytes.Buffer) - for i, tt := range eaxAESTests { - test := fmt.Sprintf("test %d", i) - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Fatalf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err) - } - b.Reset() - enc := NewEAXEncrypter(c, tt.nonce, tt.header, 16, b) - n, err := io.Copy(enc, bytes.NewBuffer(tt.msg)) - if n != int64(len(tt.msg)) || err != nil { - t.Fatalf("%s: io.Copy into encrypter: %d, %s", test, n, err) - } - err = enc.Close() - if err != nil { - t.Fatalf("%s: enc.Close: %s", test, err) - } - if d := b.Bytes(); !same(d, tt.cipher) { - t.Fatalf("%s: got %x want %x", test, d, tt.cipher) - } - } -} - -func TestEAXDecrypt_AES(t *testing.T) { - b := new(bytes.Buffer) - for i, tt := range eaxAESTests { - test := fmt.Sprintf("test %d", i) - c, err := aes.NewCipher(tt.key) - if err != nil { - t.Fatalf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err) - } - b.Reset() - dec := NewEAXDecrypter(c, tt.nonce, tt.header, 16, bytes.NewBuffer(tt.cipher)) - n, err := io.Copy(b, dec) - if n != int64(len(tt.msg)) || err != nil { - t.Fatalf("%s: io.Copy into decrypter: %d, %s", test, n, err) - } - if d := b.Bytes(); !same(d, tt.msg) { - t.Fatalf("%s: got %x want %x", test, d, tt.msg) - } - } -} diff --git a/libgo/go/crypto/block/ecb.go b/libgo/go/crypto/block/ecb.go deleted file mode 100644 index cf09f7c..0000000 --- a/libgo/go/crypto/block/ecb.go +++ /dev/null @@ -1,270 +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. - -// Electronic codebook (ECB) mode. -// ECB is a fancy name for ``encrypt and decrypt each block separately.'' -// It's a pretty bad thing to do for any large amount of data (more than one block), -// because the individual blocks can still be identified, duplicated, and reordered. -// The ECB implementation exists mainly to provide buffering for -// the other modes, which wrap it by providing modified Ciphers. - -// See NIST SP 800-38A, pp 9-10 - -package block - -import ( - "io" - "os" - "strconv" -) - -type ecbDecrypter struct { - c Cipher - r io.Reader - blockSize int // block size - - // Buffered data. - // The buffer buf is used as storage for both - // plain or crypt; at least one of those is nil at any given time. - buf []byte - plain []byte // plain text waiting to be read - crypt []byte // ciphertext waiting to be decrypted -} - -// Read into x.crypt until it has a full block or EOF or an error happens. -func (x *ecbDecrypter) fillCrypt() os.Error { - var err os.Error - for len(x.crypt) < x.blockSize { - off := len(x.crypt) - var m int - m, err = x.r.Read(x.crypt[off:x.blockSize]) - x.crypt = x.crypt[0 : off+m] - if m == 0 { - break - } - - // If an error happened but we got enough - // data to do some decryption, we can decrypt - // first and report the error (with some data) later. - // But if we don't have enough to decrypt, - // have to stop now. - if err != nil && len(x.crypt) < x.blockSize { - break - } - } - return err -} - -// Read from plain text buffer into p. -func (x *ecbDecrypter) readPlain(p []byte) int { - n := len(x.plain) - if n > len(p) { - n = len(p) - } - for i := 0; i < n; i++ { - p[i] = x.plain[i] - } - if n < len(x.plain) { - x.plain = x.plain[n:] - } else { - x.plain = nil - } - return n -} - -type ecbFragmentError int - -func (n ecbFragmentError) String() string { - return "crypto/block: " + strconv.Itoa(int(n)) + "-byte fragment at EOF" -} - -func (x *ecbDecrypter) Read(p []byte) (n int, err os.Error) { - if len(p) == 0 { - return - } - - // If there's no plaintext waiting and p is not big enough - // to hold a whole cipher block, we'll have to work in the - // cipher text buffer. Set it to non-nil so that the - // code below will fill it. - if x.plain == nil && len(p) < x.blockSize && x.crypt == nil { - x.crypt = x.buf[0:0] - } - - // If there is a leftover cipher text buffer, - // try to accumulate a full block. - if x.crypt != nil { - err = x.fillCrypt() - if err != nil || len(x.crypt) == 0 { - return - } - x.c.Decrypt(x.crypt, x.crypt) - x.plain = x.crypt - x.crypt = nil - } - - // If there is a leftover plain text buffer, read from it. - if x.plain != nil { - n = x.readPlain(p) - return - } - - // Read and decrypt directly in caller's buffer. - n, err = io.ReadAtLeast(x.r, p, x.blockSize) - if err == os.EOF && n > 0 { - // EOF is only okay on block boundary - err = os.ErrorString("block fragment at EOF during decryption") - return - } - var i int - for i = 0; i+x.blockSize <= n; i += x.blockSize { - a := p[i : i+x.blockSize] - x.c.Decrypt(a, a) - } - - // There might be an encrypted fringe remaining. - // Save it for next time. - if i < n { - p = p[i:n] - copy(x.buf, p) - x.crypt = x.buf[0:len(p)] - n = i - } - - return -} - -// NewECBDecrypter returns a reader that reads data from r and decrypts it using c. -// It decrypts by calling c.Decrypt on each block in sequence; -// this mode is known as electronic codebook mode, or ECB. -// The returned Reader does not buffer or read ahead except -// as required by the cipher's block size. -func NewECBDecrypter(c Cipher, r io.Reader) io.Reader { - x := new(ecbDecrypter) - x.c = c - x.r = r - x.blockSize = c.BlockSize() - x.buf = make([]byte, x.blockSize) - return x -} - -type ecbEncrypter struct { - c Cipher - w io.Writer - blockSize int - - // Buffered data. - // The buffer buf is used as storage for both - // plain or crypt. If both are non-nil, plain - // follows crypt in buf. - buf []byte - plain []byte // plain text waiting to be encrypted - crypt []byte // encrypted text waiting to be written -} - -// Flush the x.crypt buffer to x.w. -func (x *ecbEncrypter) flushCrypt() os.Error { - if len(x.crypt) == 0 { - return nil - } - n, err := x.w.Write(x.crypt) - if n < len(x.crypt) { - x.crypt = x.crypt[n:] - if err == nil { - err = io.ErrShortWrite - } - } - if err != nil { - return err - } - x.crypt = nil - return nil -} - -// Slide x.plain down to the beginning of x.buf. -// Plain is known to have less than one block of data, -// so this is cheap enough. -func (x *ecbEncrypter) slidePlain() { - if len(x.plain) == 0 { - x.plain = x.buf[0:0] - } else if cap(x.plain) < cap(x.buf) { - copy(x.buf, x.plain) - x.plain = x.buf[0:len(x.plain)] - } -} - -// Fill x.plain from the data in p. -// Return the number of bytes copied. -func (x *ecbEncrypter) fillPlain(p []byte) int { - off := len(x.plain) - n := len(p) - if max := cap(x.plain) - off; n > max { - n = max - } - x.plain = x.plain[0 : off+n] - for i := 0; i < n; i++ { - x.plain[off+i] = p[i] - } - return n -} - -// Encrypt x.plain; record encrypted range as x.crypt. -func (x *ecbEncrypter) encrypt() { - var i int - n := len(x.plain) - for i = 0; i+x.blockSize <= n; i += x.blockSize { - a := x.plain[i : i+x.blockSize] - x.c.Encrypt(a, a) - } - x.crypt = x.plain[0:i] - x.plain = x.plain[i:n] -} - -func (x *ecbEncrypter) Write(p []byte) (n int, err os.Error) { - for { - // If there is data waiting to be written, write it. - // This can happen on the first iteration - // if a write failed in an earlier call. - if err = x.flushCrypt(); err != nil { - return - } - - // Now that encrypted data is gone (flush ran), - // perhaps we need to slide the plaintext down. - x.slidePlain() - - // Fill plaintext buffer from p. - m := x.fillPlain(p) - if m == 0 { - break - } - n += m - p = p[m:] - - // Encrypt, adjusting crypt and plain. - x.encrypt() - - // Write x.crypt. - if err = x.flushCrypt(); err != nil { - break - } - } - return -} - -// NewECBEncrypter returns a writer that encrypts data using c and writes it to w. -// It encrypts by calling c.Encrypt on each block in sequence; -// this mode is known as electronic codebook mode, or ECB. -// The returned Writer does no buffering except as required -// by the cipher's block size, so there is no need for a Flush method. -func NewECBEncrypter(c Cipher, w io.Writer) io.Writer { - x := new(ecbEncrypter) - x.c = c - x.w = w - x.blockSize = c.BlockSize() - - // Create a buffer that is an integral number of blocks. - x.buf = make([]byte, 8192/x.blockSize*x.blockSize) - return x -} diff --git a/libgo/go/crypto/block/ecb_aes_test.go b/libgo/go/crypto/block/ecb_aes_test.go deleted file mode 100644 index 14481d0..0000000 --- a/libgo/go/crypto/block/ecb_aes_test.go +++ /dev/null @@ -1,127 +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. - -// ECB 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-27. - -package block - -import ( - "bytes" - "crypto/aes" - "io" - "testing" -) - -type ecbTest struct { - name string - key []byte - in []byte - out []byte -} - -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} - -var ecbAESTests = []ecbTest{ - // FIPS 197, Appendix B, C - { - "FIPS-197 Appendix B", - commonKey128, - []byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34}, - []byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32}, - }, - - // NIST SP 800-38A pp 24-27 - { - "ECB-AES128", - commonKey128, - commonInput, - []byte{ - 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, - 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf, - 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88, - 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4, - }, - }, - { - "ECB-AES192", - commonKey192, - commonInput, - []byte{ - 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc, - 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef, - 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e, - 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e, - }, - }, - { - "ECB-AES256", - commonKey256, - commonInput, - []byte{ - 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, - 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70, - 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d, - 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7, - }, - }, -} - -func TestECB_AES(t *testing.T) { - for _, tt := range ecbAESTests { - 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 - } - - var crypt bytes.Buffer - w := NewECBEncrypter(c, &crypt) - var r io.Reader = bytes.NewBuffer(tt.in) - n, err := io.Copy(w, r) - if n != int64(len(tt.in)) || err != nil { - t.Errorf("%s: ECBReader io.Copy = %d, %v want %d, nil", test, n, err, len(tt.in)) - } else if d := crypt.Bytes(); !same(tt.out, d) { - t.Errorf("%s: ECBReader\nhave %x\nwant %x", test, d, tt.out) - } - - var plain bytes.Buffer - r = NewECBDecrypter(c, bytes.NewBuffer(tt.out)) - w = &plain - n, err = io.Copy(w, r) - if n != int64(len(tt.out)) || err != nil { - t.Errorf("%s: ECBWriter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.out)) - } else if d := plain.Bytes(); !same(tt.in, d) { - t.Errorf("%s: ECBWriter\nhave %x\nwant %x", test, d, tt.in) - } - - if t.Failed() { - break - } - } -} diff --git a/libgo/go/crypto/block/ecb_test.go b/libgo/go/crypto/block/ecb_test.go deleted file mode 100644 index 6f79d92..0000000 --- a/libgo/go/crypto/block/ecb_test.go +++ /dev/null @@ -1,181 +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 block - -import ( - "bytes" - "fmt" - "io" - "testing" - "testing/iotest" -) - -// Simple Cipher for testing: adds an incrementing amount -// to each byte in each -type IncCipher struct { - blockSize int - delta byte - encrypting bool -} - -func (c *IncCipher) BlockSize() int { return c.blockSize } - -func (c *IncCipher) Encrypt(dst, src []byte) { - if !c.encrypting { - panic("encrypt: not encrypting") - } - if len(src) != c.blockSize || len(dst) != c.blockSize { - panic(fmt.Sprintln("encrypt: wrong block size", c.blockSize, len(src), len(dst))) - } - c.delta++ - for i, b := range src { - dst[i] = b + c.delta - } -} - -func (c *IncCipher) Decrypt(dst, src []byte) { - if c.encrypting { - panic("decrypt: not decrypting") - } - if len(src) != c.blockSize || len(dst) != c.blockSize { - panic(fmt.Sprintln("decrypt: wrong block size ", c.blockSize, " ", len(src), " ", len(dst))) - } - c.delta-- - for i, b := range src { - dst[i] = b + c.delta - } -} - -func TestECBEncrypter(t *testing.T) { - var plain, crypt [256]byte - for i := 0; i < len(plain); i++ { - plain[i] = byte(i) - } - b := new(bytes.Buffer) - for block := 1; block <= 64; block *= 2 { - // compute encrypted version - delta := byte(0) - for i := 0; i < len(crypt); i++ { - if i%block == 0 { - delta++ - } - crypt[i] = plain[i] + delta - } - - for frag := 0; frag < 2; frag++ { - c := &IncCipher{block, 0, true} - b.Reset() - r := bytes.NewBuffer(plain[0:]) - w := NewECBEncrypter(c, b) - - // copy plain into w in increasingly large chunks: 1, 1, 2, 4, 8, ... - // if frag != 0, move the 1 to the end to cause fragmentation. - if frag == 0 { - _, err := io.Copyn(w, r, 1) - if err != nil { - t.Errorf("block=%d frag=0: first Copyn: %s", block, err) - continue - } - } - for n := 1; n <= len(plain)/2; n *= 2 { - _, err := io.Copyn(w, r, int64(n)) - if err != nil { - t.Errorf("block=%d frag=%d: Copyn %d: %s", block, frag, n, err) - } - } - if frag != 0 { - _, err := io.Copyn(w, r, 1) - if err != nil { - t.Errorf("block=%d frag=1: last Copyn: %s", block, err) - continue - } - } - - // check output - data := b.Bytes() - if len(data) != len(crypt) { - t.Errorf("block=%d frag=%d: want %d bytes, got %d", block, frag, len(crypt), len(data)) - continue - } - - if string(data) != string(crypt[0:]) { - t.Errorf("block=%d frag=%d: want %x got %x", block, frag, data, crypt) - } - } - } -} - -func testECBDecrypter(t *testing.T, maxio int) { - var readers = []func(io.Reader) io.Reader{ - func(r io.Reader) io.Reader { return r }, - iotest.OneByteReader, - iotest.HalfReader, - } - var plain, crypt [256]byte - for i := 0; i < len(plain); i++ { - plain[i] = byte(255 - i) - } - b := new(bytes.Buffer) - for block := 1; block <= 64 && block <= maxio; block *= 2 { - // compute encrypted version - delta := byte(0) - for i := 0; i < len(crypt); i++ { - if i%block == 0 { - delta++ - } - crypt[i] = plain[i] + delta - } - - for mode := 0; mode < len(readers); mode++ { - for frag := 0; frag < 2; frag++ { - test := fmt.Sprintf("block=%d mode=%d frag=%d maxio=%d", block, mode, frag, maxio) - c := &IncCipher{block, 0, false} - b.Reset() - r := NewECBDecrypter(c, readers[mode](bytes.NewBuffer(crypt[0:maxio]))) - - // read from crypt in increasingly large chunks: 1, 1, 2, 4, 8, ... - // if frag == 1, move the 1 to the end to cause fragmentation. - if frag == 0 { - _, err := io.Copyn(b, r, 1) - if err != nil { - t.Errorf("%s: first Copyn: %s", test, err) - continue - } - } - for n := 1; n <= maxio/2; n *= 2 { - _, err := io.Copyn(b, r, int64(n)) - if err != nil { - t.Errorf("%s: Copyn %d: %s", test, n, err) - } - } - if frag != 0 { - _, err := io.Copyn(b, r, 1) - if err != nil { - t.Errorf("%s: last Copyn: %s", test, err) - continue - } - } - - // check output - data := b.Bytes() - if len(data) != maxio { - t.Errorf("%s: want %d bytes, got %d", test, maxio, len(data)) - continue - } - - if string(data) != string(plain[0:maxio]) { - t.Errorf("%s: input=%x want %x got %x", test, crypt[0:maxio], plain[0:maxio], data) - } - } - } - } -} - -func TestECBDecrypter(t *testing.T) { - // Do shorter I/O sizes first; they're easier to debug. - for n := 1; n <= 256 && !t.Failed(); n *= 2 { - testECBDecrypter(t, n) - } -} diff --git a/libgo/go/crypto/block/ofb.go b/libgo/go/crypto/block/ofb.go deleted file mode 100644 index 11aaaa4..0000000 --- a/libgo/go/crypto/block/ofb.go +++ /dev/null @@ -1,60 +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. - -// Output feedback (OFB) mode. - -// OFB converts a block cipher into a stream cipher by -// repeatedly encrypting an initialization vector and -// xoring the resulting stream of data with the input. - -// See NIST SP 800-38A, pp 13-15 - -package block - -import ( - "fmt" - "io" -) - -type ofbStream struct { - c Cipher - iv []byte -} - -func newOFBStream(c Cipher, iv []byte) *ofbStream { - x := new(ofbStream) - x.c = c - n := len(iv) - if n != c.BlockSize() { - panic(fmt.Sprintln("crypto/block: newOFBStream: invalid iv size", n, "!=", c.BlockSize())) - } - x.iv = dup(iv) - return x -} - -func (x *ofbStream) Next() []byte { - x.c.Encrypt(x.iv, x.iv) - return x.iv -} - -// NewOFBReader returns a reader that reads data from r, decrypts (or encrypts) -// it using c in output feedback (OFB) mode with the initialization vector iv. -// The returned Reader does not buffer and has no block size. -// In OFB mode, encryption and decryption are the same operation: -// an OFB reader applied to an encrypted stream produces a decrypted -// stream and vice versa. -func NewOFBReader(c Cipher, iv []byte, r io.Reader) io.Reader { - return newXorReader(newOFBStream(c, iv), r) -} - -// NewOFBWriter returns a writer that encrypts (or decrypts) data using c -// in cipher feedback (OFB) mode with the initialization vector iv -// and writes the encrypted data to w. -// The returned Writer does not buffer and has no block size. -// In OFB mode, encryption and decryption are the same operation: -// an OFB writer applied to an decrypted stream produces an encrypted -// stream and vice versa. -func NewOFBWriter(c Cipher, iv []byte, w io.Writer) io.Writer { - return newXorWriter(newOFBStream(c, iv), w) -} diff --git a/libgo/go/crypto/block/ofb_aes_test.go b/libgo/go/crypto/block/ofb_aes_test.go deleted file mode 100644 index 9c527a6..0000000 --- a/libgo/go/crypto/block/ofb_aes_test.go +++ /dev/null @@ -1,108 +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 block - -import ( - "bytes" - "crypto/aes" - "io" - "testing" -) - -type ofbTest struct { - name string - key []byte - iv []byte - in []byte - out []byte -} - -var ofbAESTests = []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_AES(t *testing.T) { - for _, tt := range ofbAESTests { - 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 { - var crypt bytes.Buffer - in := tt.in[0 : len(tt.in)-j] - w := NewOFBWriter(c, tt.iv, &crypt) - var r io.Reader = bytes.NewBuffer(in) - n, err := io.Copy(w, r) - if n != int64(len(in)) || err != nil { - t.Errorf("%s/%d: OFBWriter io.Copy = %d, %v want %d, nil", test, len(in), n, err, len(in)) - } else if d, out := crypt.Bytes(), tt.out[0:len(in)]; !same(out, d) { - t.Errorf("%s/%d: OFBWriter\ninpt %x\nhave %x\nwant %x", test, len(in), in, d, out) - } - } - - for j := 0; j <= 7; j += 7 { - var plain bytes.Buffer - out := tt.out[0 : len(tt.out)-j] - r := NewOFBReader(c, tt.iv, bytes.NewBuffer(out)) - w := &plain - n, err := io.Copy(w, r) - if n != int64(len(out)) || err != nil { - t.Errorf("%s/%d: OFBReader io.Copy = %d, %v want %d, nil", test, len(out), n, err, len(out)) - } else if d, in := plain.Bytes(), tt.in[0:len(out)]; !same(in, d) { - t.Errorf("%s/%d: OFBReader\nhave %x\nwant %x", test, len(out), d, in) - } - } - - if t.Failed() { - break - } - } -} diff --git a/libgo/go/crypto/block/xor.go b/libgo/go/crypto/block/xor.go deleted file mode 100644 index 9d8b172..0000000 --- a/libgo/go/crypto/block/xor.go +++ /dev/null @@ -1,124 +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. - -// Encrypt/decrypt data by xor with a pseudo-random data stream. - -package block - -import ( - "io" - "os" -) - -// A dataStream is an interface to an unending stream of data, -// used by XorReader and XorWriter to model a pseudo-random generator. -// Calls to Next() return sequential blocks of data from the stream. -// Each call must return at least one byte: there is no EOF. -type dataStream interface { - Next() []byte -} - -type xorReader struct { - r io.Reader - rand dataStream // pseudo-random - buf []byte // data available from last call to rand -} - -func newXorReader(rand dataStream, r io.Reader) io.Reader { - x := new(xorReader) - x.r = r - x.rand = rand - return x -} - -func (x *xorReader) Read(p []byte) (n int, err os.Error) { - n, err = x.r.Read(p) - - // xor input with stream. - bp := 0 - buf := x.buf - for i := 0; i < n; i++ { - if bp >= len(buf) { - buf = x.rand.Next() - bp = 0 - } - p[i] ^= buf[bp] - bp++ - } - x.buf = buf[bp:] - return n, err -} - -type xorWriter struct { - w io.Writer - rand dataStream // pseudo-random - buf []byte // last buffer returned by rand - extra []byte // extra random data (use before buf) - work []byte // work space -} - -func newXorWriter(rand dataStream, w io.Writer) io.Writer { - x := new(xorWriter) - x.w = w - x.rand = rand - x.work = make([]byte, 4096) - return x -} - -func (x *xorWriter) Write(p []byte) (n int, err os.Error) { - for len(p) > 0 { - // Determine next chunk of random data - // and xor with p into x.work. - var chunk []byte - m := len(p) - if nn := len(x.extra); nn > 0 { - // extra points into work, so edit directly - if m > nn { - m = nn - } - for i := 0; i < m; i++ { - x.extra[i] ^= p[i] - } - chunk = x.extra[0:m] - } else { - // xor p ^ buf into work, refreshing buf as needed - if nn := len(x.work); m > nn { - m = nn - } - bp := 0 - buf := x.buf - for i := 0; i < m; i++ { - if bp >= len(buf) { - buf = x.rand.Next() - bp = 0 - } - x.work[i] = buf[bp] ^ p[i] - bp++ - } - x.buf = buf[bp:] - chunk = x.work[0:m] - } - - // Write chunk. - var nn int - nn, err = x.w.Write(chunk) - if nn != len(chunk) && err == nil { - err = io.ErrShortWrite - } - if nn < len(chunk) { - // Reconstruct the random bits from the unwritten - // data and save them for next time. - for i := nn; i < m; i++ { - chunk[i] ^= p[i] - } - x.extra = chunk[nn:] - } - n += nn - if err != nil { - return - } - p = p[m:] - } - return -} diff --git a/libgo/go/crypto/block/xor_test.go b/libgo/go/crypto/block/xor_test.go deleted file mode 100644 index 50f6bb0..0000000 --- a/libgo/go/crypto/block/xor_test.go +++ /dev/null @@ -1,168 +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 block - -import ( - "bytes" - "fmt" - "io" - "testing" - "testing/iotest" -) - -// Simple "pseudo-random" stream for testing. -type incStream struct { - buf []byte - n byte -} - -func newIncStream(blockSize int) *incStream { - x := new(incStream) - x.buf = make([]byte, blockSize) - return x -} - -func (x *incStream) Next() []byte { - x.n++ - for i := range x.buf { - x.buf[i] = x.n - x.n++ - } - return x.buf -} - -func testXorWriter(t *testing.T, maxio int) { - var plain, crypt [256]byte - for i := 0; i < len(plain); i++ { - plain[i] = byte(i) - } - b := new(bytes.Buffer) - for block := 1; block <= 64 && block <= maxio; block *= 2 { - // compute encrypted version - n := byte(0) - for i := 0; i < len(crypt); i++ { - if i%block == 0 { - n++ - } - crypt[i] = plain[i] ^ n - n++ - } - - for frag := 0; frag < 2; frag++ { - test := fmt.Sprintf("block=%d frag=%d maxio=%d", block, frag, maxio) - b.Reset() - r := bytes.NewBuffer(plain[0:]) - s := newIncStream(block) - w := newXorWriter(s, b) - - // copy plain into w in increasingly large chunks: 1, 1, 2, 4, 8, ... - // if frag != 0, move the 1 to the end to cause fragmentation. - if frag == 0 { - _, err := io.Copyn(w, r, 1) - if err != nil { - t.Errorf("%s: first Copyn: %s", test, err) - continue - } - } - for n := 1; n <= len(plain)/2; n *= 2 { - _, err := io.Copyn(w, r, int64(n)) - if err != nil { - t.Errorf("%s: Copyn %d: %s", test, n, err) - } - } - - // check output - crypt := crypt[0 : len(crypt)-frag] - data := b.Bytes() - if len(data) != len(crypt) { - t.Errorf("%s: want %d bytes, got %d", test, len(crypt), len(data)) - continue - } - - if string(data) != string(crypt) { - t.Errorf("%s: want %x got %x", test, data, crypt) - } - } - } -} - - -func TestXorWriter(t *testing.T) { - // Do shorter I/O sizes first; they're easier to debug. - for n := 1; n <= 256 && !t.Failed(); n *= 2 { - testXorWriter(t, n) - } -} - -func testXorReader(t *testing.T, maxio int) { - var readers = []func(io.Reader) io.Reader{ - func(r io.Reader) io.Reader { return r }, - iotest.OneByteReader, - iotest.HalfReader, - } - var plain, crypt [256]byte - for i := 0; i < len(plain); i++ { - plain[i] = byte(255 - i) - } - b := new(bytes.Buffer) - for block := 1; block <= 64 && block <= maxio; block *= 2 { - // compute encrypted version - n := byte(0) - for i := 0; i < len(crypt); i++ { - if i%block == 0 { - n++ - } - crypt[i] = plain[i] ^ n - n++ - } - - for mode := 0; mode < len(readers); mode++ { - for frag := 0; frag < 2; frag++ { - test := fmt.Sprintf("block=%d mode=%d frag=%d maxio=%d", block, mode, frag, maxio) - s := newIncStream(block) - b.Reset() - r := newXorReader(s, readers[mode](bytes.NewBuffer(crypt[0:maxio]))) - - // read from crypt in increasingly large chunks: 1, 1, 2, 4, 8, ... - // if frag == 1, move the 1 to the end to cause fragmentation. - if frag == 0 { - _, err := io.Copyn(b, r, 1) - if err != nil { - t.Errorf("%s: first Copyn: %s", test, err) - continue - } - } - for n := 1; n <= maxio/2; n *= 2 { - _, err := io.Copyn(b, r, int64(n)) - if err != nil { - t.Errorf("%s: Copyn %d: %s", test, n, err) - } - } - - // check output - data := b.Bytes() - crypt := crypt[0 : maxio-frag] - plain := plain[0 : maxio-frag] - if len(data) != len(plain) { - t.Errorf("%s: want %d bytes, got %d", test, len(plain), len(data)) - continue - } - - if string(data) != string(plain) { - t.Errorf("%s: input=%x want %x got %x", test, crypt, plain, data) - } - } - } - } -} - -func TestXorReader(t *testing.T) { - // Do shorter I/O sizes first; they're easier to debug. - for n := 1; n <= 256 && !t.Failed(); n *= 2 { - testXorReader(t, n) - } -} - -// TODO(rsc): Test handling of writes after write errors. diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go new file mode 100644 index 0000000..e18eaed --- /dev/null +++ b/libgo/go/crypto/des/block.go @@ -0,0 +1,98 @@ +// 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. + +package des + +import ( + "encoding/binary" +) + +func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) { + b := binary.BigEndian.Uint64(src) + b = permuteBlock(b, initialPermutation[:]) + left, right := uint32(b>>32), uint32(b) + + var subkey uint64 + for i := 0; i < 16; i++ { + if decrypt { + subkey = subkeys[15-i] + } else { + subkey = subkeys[i] + } + + left, right = right, left^feistel(right, subkey) + } + // switch left & right and perform final permutation + preOutput := (uint64(right) << 32) | uint64(left) + binary.BigEndian.PutUint64(dst, permuteBlock(preOutput, finalPermutation[:])) +} + +// Encrypt one block from src into dst, using the subkeys. +func encryptBlock(subkeys []uint64, dst, src []byte) { + cryptBlock(subkeys, dst, src, false) +} + +// Decrypt one block from src into dst, using the subkeys. +func decryptBlock(subkeys []uint64, dst, src []byte) { + cryptBlock(subkeys, dst, src, true) +} + +// DES Feistel function +func feistel(right uint32, key uint64) (result uint32) { + sBoxLocations := key ^ permuteBlock(uint64(right), expansionFunction[:]) + var sBoxResult uint32 + for i := uint8(0); i < 8; i++ { + sBoxLocation := uint8(sBoxLocations>>42) & 0x3f + sBoxLocations <<= 6 + // row determined by 1st and 6th bit + row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4) + // column is middle four bits + column := (sBoxLocation >> 1) & 0xf + sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i)) + } + return uint32(permuteBlock(uint64(sBoxResult), permutationFunction[:])) +} + +// general purpose function to perform DES block permutations +func permuteBlock(src uint64, permutation []uint8) (block uint64) { + for position, n := range permutation { + bit := (src >> n) & 1 + block |= bit << uint((len(permutation)-1)-position) + } + return +} + +// creates 16 28-bit blocks rotated according +// to the rotation schedule +func ksRotate(in uint32) (out []uint32) { + out = make([]uint32, 16) + last := in + for i := 0; i < 16; i++ { + // 28-bit circular left shift + left := (last << (4 + ksRotations[i])) >> 4 + right := (last << 4) >> (32 - ksRotations[i]) + out[i] = left | right + last = out[i] + } + return +} + +// creates 16 56-bit subkeys from the original key +func (c *Cipher) generateSubkeys(keyBytes []byte) { + // apply PC1 permutation to key + key := binary.BigEndian.Uint64(keyBytes) + permutedKey := permuteBlock(key, permutedChoice1[:]) + + // rotate halves of permuted key according to the rotation schedule + leftRotations := ksRotate(uint32(permutedKey >> 28)) + rightRotations := ksRotate(uint32(permutedKey<<4) >> 4) + + // generate subkeys + for i := 0; i < 16; i++ { + // combine halves to form 56-bit input to PC2 + pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i]) + // apply PC2 permutation to 7 byte input + c.subkeys[i] = permuteBlock(pc2Input, permutedChoice2[:]) + } +} diff --git a/libgo/go/crypto/des/cipher.go b/libgo/go/crypto/des/cipher.go new file mode 100644 index 0000000..d17a1a7 --- /dev/null +++ b/libgo/go/crypto/des/cipher.go @@ -0,0 +1,103 @@ +// 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. + +package des + +import ( + "os" + "strconv" +) + +// The DES block size in bytes. +const BlockSize = 8 + +type KeySizeError int + +func (k KeySizeError) String() string { + return "crypto/des: invalid key size " + strconv.Itoa(int(k)) +} + +// Cipher is an instance of DES encryption. +type Cipher struct { + subkeys [16]uint64 +} + +// NewCipher creates and returns a new Cipher. +func NewCipher(key []byte) (*Cipher, os.Error) { + if len(key) != 8 { + return nil, KeySizeError(len(key)) + } + + c := new(Cipher) + c.generateSubkeys(key) + return c, nil +} + +// BlockSize returns the DES block size, 8 bytes. +func (c *Cipher) BlockSize() int { return BlockSize } + +// Encrypts the 8-byte buffer src and stores the result in dst. +// Note that for amounts of data larger than a block, +// it is not safe to just call Encrypt on successive blocks; +// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). +func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) } + +// Decrypts the 8-byte buffer src and stores the result in dst. +func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) } + +// Reset zeros the key data, so that it will no longer +// appear in the process's memory. +func (c *Cipher) Reset() { + for i := 0; i < len(c.subkeys); i++ { + c.subkeys[i] = 0 + } +} + +// A TripleDESCipher is an instance of TripleDES encryption. +type TripleDESCipher struct { + cipher1, cipher2, cipher3 Cipher +} + +// NewCipher creates and returns a new Cipher. +func NewTripleDESCipher(key []byte) (*TripleDESCipher, os.Error) { + if len(key) != 24 { + return nil, KeySizeError(len(key)) + } + + c := new(TripleDESCipher) + c.cipher1.generateSubkeys(key[:8]) + c.cipher2.generateSubkeys(key[8:16]) + c.cipher3.generateSubkeys(key[16:]) + return c, nil +} + +// BlockSize returns the TripleDES block size, 8 bytes. +// It is necessary to satisfy the Block interface in the +// package "crypto/cipher". +func (c *TripleDESCipher) BlockSize() int { return BlockSize } + +// Encrypts the 8-byte buffer src and stores the result in dst. +// Note that for amounts of data larger than a block, +// it is not safe to just call Encrypt on successive blocks; +// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). +func (c *TripleDESCipher) Encrypt(dst, src []byte) { + c.cipher1.Encrypt(dst, src) + c.cipher2.Decrypt(dst, dst) + c.cipher3.Encrypt(dst, dst) +} + +// Decrypts the 8-byte buffer src and stores the result in dst. +func (c *TripleDESCipher) Decrypt(dst, src []byte) { + c.cipher3.Decrypt(dst, src) + c.cipher2.Encrypt(dst, dst) + c.cipher1.Decrypt(dst, dst) +} + +// Reset zeros the key data, so that it will no longer +// appear in the process's memory. +func (c *TripleDESCipher) Reset() { + c.cipher1.Reset() + c.cipher2.Reset() + c.cipher3.Reset() +} diff --git a/libgo/go/crypto/des/const.go b/libgo/go/crypto/des/const.go new file mode 100644 index 0000000..2bd485e --- /dev/null +++ b/libgo/go/crypto/des/const.go @@ -0,0 +1,139 @@ +// 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 des implements the Data Encryption Standard (DES) and the +// Triple Data Encryption Algorithm (TDEA) as defined +// in U.S. Federal Information Processing Standards Publication 46-3. +package des + +// Used to perform an initial permutation of a 64-bit input block. +var initialPermutation = [64]byte{ + 6, 14, 22, 30, 38, 46, 54, 62, + 4, 12, 20, 28, 36, 44, 52, 60, + 2, 10, 18, 26, 34, 42, 50, 58, + 0, 8, 16, 24, 32, 40, 48, 56, + 7, 15, 23, 31, 39, 47, 55, 63, + 5, 13, 21, 29, 37, 45, 53, 61, + 3, 11, 19, 27, 35, 43, 51, 59, + 1, 9, 17, 25, 33, 41, 49, 57, +} + +// Used to perform a final permutation of a 4-bit preoutput block. This is the +// inverse of initialPermutation +var finalPermutation = [64]byte{ + 24, 56, 16, 48, 8, 40, 0, 32, + 25, 57, 17, 49, 9, 41, 1, 33, + 26, 58, 18, 50, 10, 42, 2, 34, + 27, 59, 19, 51, 11, 43, 3, 35, + 28, 60, 20, 52, 12, 44, 4, 36, + 29, 61, 21, 53, 13, 45, 5, 37, + 30, 62, 22, 54, 14, 46, 6, 38, + 31, 63, 23, 55, 15, 47, 7, 39, +} + +// Used to expand an input block of 32 bits, producing an output block of 48 +// bits. +var expansionFunction = [48]byte{ + 0, 31, 30, 29, 28, 27, 28, 27, + 26, 25, 24, 23, 24, 23, 22, 21, + 20, 19, 20, 19, 18, 17, 16, 15, + 16, 15, 14, 13, 12, 11, 12, 11, + 10, 9, 8, 7, 8, 7, 6, 5, + 4, 3, 4, 3, 2, 1, 0, 31, +} + +// Yields a 32-bit output from a 32-bit input +var permutationFunction = [32]byte{ + 16, 25, 12, 11, 3, 20, 4, 15, + 31, 17, 9, 6, 27, 14, 1, 22, + 30, 24, 8, 18, 0, 5, 29, 23, + 13, 19, 2, 26, 10, 21, 28, 7, +} + +// Used in the key schedule to select 56 bits +// from a 64-bit input. +var permutedChoice1 = [56]byte{ + 7, 15, 23, 31, 39, 47, 55, 63, + 6, 14, 22, 30, 38, 46, 54, 62, + 5, 13, 21, 29, 37, 45, 53, 61, + 4, 12, 20, 28, 1, 9, 17, 25, + 33, 41, 49, 57, 2, 10, 18, 26, + 34, 42, 50, 58, 3, 11, 19, 27, + 35, 43, 51, 59, 36, 44, 52, 60, +} + +// Used in the key schedule to produce each subkey by selecting 48 bits from +// the 56-bit input +var permutedChoice2 = [48]byte{ + 42, 39, 45, 32, 55, 51, 53, 28, + 41, 50, 35, 46, 33, 37, 44, 52, + 30, 48, 40, 49, 29, 36, 43, 54, + 15, 4, 25, 19, 9, 1, 26, 16, + 5, 11, 23, 8, 12, 7, 17, 0, + 22, 3, 10, 14, 6, 20, 27, 24, +} + +// 8 S-boxes composed of 4 rows and 16 columns +// Used in the DES cipher function +var sBoxes = [8][4][16]uint8{ + // S-box 1 + { + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + }, + // S-box 2 + { + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + }, + // S-box 3 + { + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + }, + // S-box 4 + { + {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + }, + // S-box 5 + { + {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + }, + // S-box 6 + { + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + }, + // S-box 7 + { + {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + }, + // S-box 8 + { + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, + }, +} + +// Size of left rotation per round in each half of the key schedule +var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1} diff --git a/libgo/go/crypto/des/des_test.go b/libgo/go/crypto/des/des_test.go new file mode 100644 index 0000000..d1f3aa7 --- /dev/null +++ b/libgo/go/crypto/des/des_test.go @@ -0,0 +1,1497 @@ +// 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. + +package des + +import ( + "bytes" + "testing" +) + +type CryptTest struct { + key []byte + in []byte + out []byte +} + +// some custom tests for DES +var encryptDESTests = []CryptTest{ + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x8c, 0xa6, 0x4d, 0xe9, 0xc1, 0xb1, 0x23, 0xa7}}, + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x35, 0x55, 0x50, 0xb2, 0x15, 0x0e, 0x24, 0x51}}, + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x61, 0x7b, 0x3a, 0x0c, 0xe8, 0xf0, 0x71, 0x00}}, + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x92, 0x31, 0xf2, 0x36, 0xff, 0x9a, 0xa9, 0x5c}}, + { + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xca, 0xaa, 0xaf, 0x4d, 0xea, 0xf1, 0xdb, 0xae}}, + { + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x73, 0x59, 0xb2, 0x16, 0x3e, 0x4e, 0xdc, 0x58}}, + { + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x6d, 0xce, 0x0d, 0xc9, 0x00, 0x65, 0x56, 0xa3}}, + { + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x9e, 0x84, 0xc5, 0xf3, 0x17, 0x0f, 0x8e, 0xff}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xd5, 0xd4, 0x4f, 0xf7, 0x20, 0x68, 0x3d, 0x0d}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x59, 0x73, 0x23, 0x56, 0xf3, 0x6f, 0xde, 0x06}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x56, 0xcc, 0x09, 0xe7, 0xcf, 0xdc, 0x4c, 0xef}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x12, 0xc6, 0x26, 0xaf, 0x05, 0x8b, 0x43, 0x3b}}, + { + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xa6, 0x8c, 0xdc, 0xa9, 0x0c, 0x90, 0x21, 0xf9}}, + { + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x2a, 0x2b, 0xb0, 0x08, 0xdf, 0x97, 0xc2, 0xf2}}, + { + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0xed, 0x39, 0xd9, 0x50, 0xfa, 0x74, 0xbc, 0xc4}}, + { + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0xa9, 0x33, 0xf6, 0x18, 0x30, 0x23, 0xb3, 0x10}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + []byte{0x17, 0x66, 0x8d, 0xfc, 0x72, 0x92, 0x53, 0x2d}}, + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + []byte{0xb4, 0xfd, 0x23, 0x16, 0x47, 0xa5, 0xbe, 0xc0}}, + { + []byte{0x0e, 0x32, 0x92, 0x32, 0xea, 0x6d, 0x0d, 0x73}, + []byte{0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + { + []byte{0x73, 0x65, 0x63, 0x52, 0x33, 0x74, 0x24, 0x3b}, // "secR3t$;" + []byte{0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32}, // "a test12" + []byte{0x37, 0x0d, 0xee, 0x2c, 0x1f, 0xb4, 0xf7, 0xa5}}, + { + []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh" + []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh" + []byte{0x2a, 0x8d, 0x69, 0xde, 0x9d, 0x5f, 0xdf, 0xf9}}, + { + []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh" + []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678" + []byte{0x21, 0xc6, 0x0d, 0xa5, 0x34, 0x24, 0x8b, 0xce}}, + { + []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678" + []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh" + []byte{0x94, 0xd4, 0x43, 0x6b, 0xc3, 0xb5, 0xb6, 0x93}}, + { + []byte{0x1f, 0x79, 0x90, 0x5f, 0x88, 0x01, 0xc8, 0x88}, // random + []byte{0xc7, 0x46, 0x18, 0x73, 0xaf, 0x48, 0x5f, 0xb3}, // random + []byte{0xb0, 0x93, 0x50, 0x88, 0xf9, 0x92, 0x44, 0x6a}}, + { + []byte{0xe6, 0xf4, 0xf2, 0xdb, 0x31, 0x42, 0x53, 0x01}, // random + []byte{0xff, 0x3d, 0x25, 0x50, 0x12, 0xe3, 0x4a, 0xc5}, // random + []byte{0x86, 0x08, 0xd3, 0xd1, 0x6c, 0x2f, 0xd2, 0x55}}, + { + []byte{0x69, 0xc1, 0x9d, 0xc1, 0x15, 0xc5, 0xfb, 0x2b}, // random + []byte{0x1a, 0x22, 0x5c, 0xaf, 0x1f, 0x1d, 0xa3, 0xf9}, // random + []byte{0x64, 0xba, 0x31, 0x67, 0x56, 0x91, 0x1e, 0xa7}}, + { + []byte{0x6e, 0x5e, 0xe2, 0x47, 0xc4, 0xbf, 0xf6, 0x51}, // random + []byte{0x11, 0xc9, 0x57, 0xff, 0x66, 0x89, 0x0e, 0xf0}, // random + []byte{0x94, 0xc5, 0x35, 0xb2, 0xc5, 0x8b, 0x39, 0x72}}, +} + +var weakKeyTests = []CryptTest{ + { + []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + []byte{0x55, 0x74, 0xc0, 0xbd, 0x7c, 0xdf, 0xf7, 0x39}, // random + nil}, + { + []byte{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}, + []byte{0xe8, 0xe1, 0xa7, 0xc1, 0xde, 0x11, 0x89, 0xaa}, // random + nil}, + { + []byte{0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1}, + []byte{0x50, 0x6a, 0x4b, 0x94, 0x3b, 0xed, 0x7d, 0xdc}, // random + nil}, + { + []byte{0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e}, + []byte{0x88, 0x81, 0x56, 0x38, 0xec, 0x3b, 0x1c, 0x97}, // random + nil}, + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x17, 0xa0, 0x83, 0x62, 0x32, 0xfe, 0x9a, 0x0b}, // random + nil}, + { + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0xca, 0x8f, 0xca, 0x1f, 0x50, 0xc5, 0x7b, 0x49}, // random + nil}, + { + []byte{0xe1, 0xe1, 0xe1, 0xe1, 0xf0, 0xf0, 0xf0, 0xf0}, + []byte{0xb1, 0xea, 0xad, 0x7d, 0xe7, 0xc3, 0x7a, 0x43}, // random + nil}, + { + []byte{0x1e, 0x1e, 0x1e, 0x1e, 0x0f, 0x0f, 0x0f, 0x0f}, + []byte{0xae, 0x74, 0x7d, 0x6f, 0xef, 0x16, 0xbb, 0x81}, // random + nil}, +} + +var semiWeakKeyTests = []CryptTest{ + // key and out contain the semi-weak key pair + { + []byte{0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e}, + []byte{0x12, 0xfa, 0x31, 0x16, 0xf9, 0xc5, 0x0a, 0xe4}, // random + []byte{0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01}}, + { + []byte{0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1}, + []byte{0xb0, 0x4c, 0x7a, 0xee, 0xd2, 0xe5, 0x4d, 0xb7}, // random + []byte{0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01}}, + { + []byte{0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe}, + []byte{0xa4, 0x81, 0xcd, 0xb1, 0x64, 0x6f, 0xd3, 0xbc}, // random + []byte{0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01}}, + { + []byte{0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1}, + []byte{0xee, 0x27, 0xdd, 0x88, 0x4c, 0x22, 0xcd, 0xce}, // random + []byte{0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e}}, + { + []byte{0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe}, + []byte{0x19, 0x3d, 0xcf, 0x97, 0x70, 0xfb, 0xab, 0xe1}, // random + []byte{0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e}}, + { + []byte{0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe}, + []byte{0x7c, 0x82, 0x69, 0xe4, 0x1e, 0x86, 0x99, 0xd7}, // random + []byte{0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1}}, +} + +// some custom tests for TripleDES +var encryptTripleDESTests = []CryptTest{ + { + []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x92, 0x95, 0xb5, 0x9b, 0xb3, 0x84, 0x73, 0x6e}}, + { + []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0xc1, 0x97, 0xf5, 0x58, 0x74, 0x8a, 0x20, 0xe7}}, + { + []byte{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x3e, 0x68, 0x0a, 0xa7, 0x8b, 0x75, 0xdf, 0x18}}, + { + []byte{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + []byte{0x6d, 0x6a, 0x4a, 0x64, 0x4c, 0x7b, 0x8c, 0x91}}, + { + []byte{ // "abcdefgh12345678ABCDEFGH" + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48}, + []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}, // "00000000" + []byte{0xe4, 0x61, 0xb7, 0x59, 0x68, 0x8b, 0xff, 0x66}}, + { + []byte{ // "abcdefgh12345678ABCDEFGH" + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48}, + []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678" + []byte{0xdb, 0xd0, 0x92, 0xde, 0xf8, 0x34, 0xff, 0x58}}, + { + []byte{ // "abcdefgh12345678ABCDEFGH" + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48}, + []byte{0xf0, 0xc5, 0x82, 0x22, 0xd3, 0xe6, 0x12, 0xd2}, // random + []byte{0xba, 0xe4, 0x41, 0xb1, 0x3c, 0x37, 0x4d, 0xf4}}, + { + []byte{ // random + 0xd3, 0x7d, 0x45, 0xee, 0x22, 0xe9, 0xcf, 0x52, + 0xf4, 0x65, 0xa2, 0x4f, 0x70, 0xd1, 0x81, 0x8a, + 0x3d, 0xbe, 0x2f, 0x39, 0xc7, 0x71, 0xd2, 0xe9}, + []byte{0x49, 0x53, 0xc3, 0xe9, 0x78, 0xdf, 0x9f, 0xaf}, // random + []byte{0x53, 0x40, 0x51, 0x24, 0xd8, 0x3c, 0xf9, 0x88}}, + { + []byte{ // random + 0xcb, 0x10, 0x7d, 0xda, 0x7e, 0x96, 0x57, 0x0a, + 0xe8, 0xeb, 0xe8, 0x07, 0x8e, 0x87, 0xd3, 0x57, + 0xb2, 0x61, 0x12, 0xb8, 0x2a, 0x90, 0xb7, 0x2f}, + []byte{0xa3, 0xc2, 0x60, 0xb1, 0x0b, 0xb7, 0x28, 0x6e}, // random + []byte{0x56, 0x73, 0x7d, 0xfb, 0xb5, 0xa1, 0xc3, 0xde}}, +} + +// NIST Special Publication 800-20, Appendix A +// Key for use with Table A.1 tests +var tableA1Key = []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +} + +// Table A.1 Resulting Ciphertext from the Variable Plaintext Known Answer Test +var tableA1Tests = []CryptTest{ + {nil, // 0 + []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00}}, + {nil, // 1 + []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xdd, 0x7f, 0x12, 0x1c, 0xa5, 0x01, 0x56, 0x19}}, + {nil, // 2 + []byte{0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x2e, 0x86, 0x53, 0x10, 0x4f, 0x38, 0x34, 0xea}}, + {nil, // 3 + []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x4b, 0xd3, 0x88, 0xff, 0x6c, 0xd8, 0x1d, 0x4f}}, + {nil, // 4 + []byte{0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x20, 0xb9, 0xe7, 0x67, 0xb2, 0xfb, 0x14, 0x56}}, + {nil, // 5 + []byte{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x55, 0x57, 0x93, 0x80, 0xd7, 0x71, 0x38, 0xef}}, + {nil, // 6 + []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x6c, 0xc5, 0xde, 0xfa, 0xaf, 0x04, 0x51, 0x2f}}, + {nil, // 7 + []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x0d, 0x9f, 0x27, 0x9b, 0xa5, 0xd8, 0x72, 0x60}}, + {nil, // 8 + []byte{0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xd9, 0x03, 0x1b, 0x02, 0x71, 0xbd, 0x5a, 0x0a}}, + {nil, // 9 + []byte{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x42, 0x42, 0x50, 0xb3, 0x7c, 0x3d, 0xd9, 0x51}}, + {nil, // 10 + []byte{0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xb8, 0x06, 0x1b, 0x7e, 0xcd, 0x9a, 0x21, 0xe5}}, + {nil, // 11 + []byte{0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xf1, 0x5d, 0x0f, 0x28, 0x6b, 0x65, 0xbd, 0x28}}, + {nil, // 12 + []byte{0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xad, 0xd0, 0xcc, 0x8d, 0x6e, 0x5d, 0xeb, 0xa1}}, + {nil, // 13 + []byte{0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xe6, 0xd5, 0xf8, 0x27, 0x52, 0xad, 0x63, 0xd1}}, + {nil, // 14 + []byte{0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xec, 0xbf, 0xe3, 0xbd, 0x3f, 0x59, 0x1a, 0x5e}}, + {nil, // 15 + []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xf3, 0x56, 0x83, 0x43, 0x79, 0xd1, 0x65, 0xcd}}, + {nil, // 16 + []byte{0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x2b, 0x9f, 0x98, 0x2f, 0x20, 0x03, 0x7f, 0xa9}}, + {nil, // 17 + []byte{0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x88, 0x9d, 0xe0, 0x68, 0xa1, 0x6f, 0x0b, 0xe6}}, + {nil, // 18 + []byte{0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xe1, 0x9e, 0x27, 0x5d, 0x84, 0x6a, 0x12, 0x98}}, + {nil, // 19 + []byte{0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x32, 0x9a, 0x8e, 0xd5, 0x23, 0xd7, 0x1a, 0xec}}, + {nil, // 20 + []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xe7, 0xfc, 0xe2, 0x25, 0x57, 0xd2, 0x3c, 0x97}}, + {nil, // 21 + []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0x12, 0xa9, 0xf5, 0x81, 0x7f, 0xf2, 0xd6, 0x5d}}, + {nil, // 22 + []byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xa4, 0x84, 0xc3, 0xad, 0x38, 0xdc, 0x9c, 0x19}}, + {nil, // 23 + []byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{0xfb, 0xe0, 0x0a, 0x8a, 0x1e, 0xf8, 0xad, 0x72}}, + {nil, // 24 + []byte{0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00}, + []byte{0x75, 0x0d, 0x07, 0x94, 0x07, 0x52, 0x13, 0x63}}, + {nil, // 25 + []byte{0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00}, + []byte{0x64, 0xfe, 0xed, 0x9c, 0x72, 0x4c, 0x2f, 0xaf}}, + {nil, // 26 + []byte{0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00}, + []byte{0xf0, 0x2b, 0x26, 0x3b, 0x32, 0x8e, 0x2b, 0x60}}, + {nil, // 27 + []byte{0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00}, + []byte{0x9d, 0x64, 0x55, 0x5a, 0x9a, 0x10, 0xb8, 0x52}}, + {nil, // 28 + []byte{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, + []byte{0xd1, 0x06, 0xff, 0x0b, 0xed, 0x52, 0x55, 0xd7}}, + {nil, // 29 + []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, + []byte{0xe1, 0x65, 0x2c, 0x6b, 0x13, 0x8c, 0x64, 0xa5}}, + {nil, // 30 + []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00}, + []byte{0xe4, 0x28, 0x58, 0x11, 0x86, 0xec, 0x8f, 0x46}}, + {nil, // 31 + []byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, + []byte{0xae, 0xb5, 0xf5, 0xed, 0xe2, 0x2d, 0x1a, 0x36}}, + {nil, // 32 + []byte{0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}, + []byte{0xe9, 0x43, 0xd7, 0x56, 0x8a, 0xec, 0x0c, 0x5c}}, + {nil, // 33 + []byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00}, + []byte{0xdf, 0x98, 0xc8, 0x27, 0x6f, 0x54, 0xb0, 0x4b}}, + {nil, // 34 + []byte{0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00}, + []byte{0xb1, 0x60, 0xe4, 0x68, 0x0f, 0x6c, 0x69, 0x6f}}, + {nil, // 35 + []byte{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00}, + []byte{0xfa, 0x07, 0x52, 0xb0, 0x7d, 0x9c, 0x4a, 0xb8}}, + {nil, // 36 + []byte{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00}, + []byte{0xca, 0x3a, 0x2b, 0x03, 0x6d, 0xbc, 0x85, 0x02}}, + {nil, // 37 + []byte{0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00}, + []byte{0x5e, 0x09, 0x05, 0x51, 0x7b, 0xb5, 0x9b, 0xcf}}, + {nil, // 38 + []byte{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00}, + []byte{0x81, 0x4e, 0xeb, 0x3b, 0x91, 0xd9, 0x07, 0x26}}, + {nil, // 39 + []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, + []byte{0x4d, 0x49, 0xdb, 0x15, 0x32, 0x91, 0x9c, 0x9f}}, + {nil, // 40 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00}, + []byte{0x25, 0xeb, 0x5f, 0xc3, 0xf8, 0xcf, 0x06, 0x21}}, + {nil, // 41 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}, + []byte{0xab, 0x6a, 0x20, 0xc0, 0x62, 0x0d, 0x1c, 0x6f}}, + {nil, // 42 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00}, + []byte{0x79, 0xe9, 0x0d, 0xbc, 0x98, 0xf9, 0x2c, 0xca}}, + {nil, // 43 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00}, + []byte{0x86, 0x6e, 0xce, 0xdd, 0x80, 0x72, 0xbb, 0x0e}}, + {nil, // 44 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00}, + []byte{0x8b, 0x54, 0x53, 0x6f, 0x2f, 0x3e, 0x64, 0xa8}}, + {nil, // 45 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00}, + []byte{0xea, 0x51, 0xd3, 0x97, 0x55, 0x95, 0xb8, 0x6b}}, + {nil, // 46 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, + []byte{0xca, 0xff, 0xc6, 0xac, 0x45, 0x42, 0xde, 0x31}}, + {nil, // 47 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, + []byte{0x8d, 0xd4, 0x5a, 0x2d, 0xdf, 0x90, 0x79, 0x6c}}, + {nil, // 48 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}, + []byte{0x10, 0x29, 0xd5, 0x5e, 0x88, 0x0e, 0xc2, 0xd0}}, + {nil, // 49 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00}, + []byte{0x5d, 0x86, 0xcb, 0x23, 0x63, 0x9d, 0xbe, 0xa9}}, + {nil, // 50 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00}, + []byte{0x1d, 0x1c, 0xa8, 0x53, 0xae, 0x7c, 0x0c, 0x5f}}, + {nil, // 51 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00}, + []byte{0xce, 0x33, 0x23, 0x29, 0x24, 0x8f, 0x32, 0x28}}, + {nil, // 52 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}, + []byte{0x84, 0x05, 0xd1, 0xab, 0xe2, 0x4f, 0xb9, 0x42}}, + {nil, // 53 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}, + []byte{0xe6, 0x43, 0xd7, 0x80, 0x90, 0xca, 0x42, 0x07}}, + {nil, // 54 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}, + []byte{0x48, 0x22, 0x1b, 0x99, 0x37, 0x74, 0x8a, 0x23}}, + {nil, // 55 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + []byte{0xdd, 0x7c, 0x0b, 0xbd, 0x61, 0xfa, 0xfd, 0x54}}, + {nil, // 56 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, + []byte{0x2f, 0xbc, 0x29, 0x1a, 0x57, 0x0d, 0xb5, 0xc4}}, + {nil, // 57 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}, + []byte{0xe0, 0x7c, 0x30, 0xd7, 0xe4, 0xe2, 0x6e, 0x12}}, + {nil, // 58 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20}, + []byte{0x09, 0x53, 0xe2, 0x25, 0x8e, 0x8e, 0x90, 0xa1}}, + {nil, // 59 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + []byte{0x5b, 0x71, 0x1b, 0xc4, 0xce, 0xeb, 0xf2, 0xee}}, + {nil, // 60 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}, + []byte{0xcc, 0x08, 0x3f, 0x1e, 0x6d, 0x9e, 0x85, 0xf6}}, + {nil, // 61 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}, + []byte{0xd2, 0xfd, 0x88, 0x67, 0xd5, 0x0d, 0x2d, 0xfe}}, + {nil, // 62 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + []byte{0x06, 0xe7, 0xea, 0x22, 0xce, 0x92, 0x70, 0x8f}}, + {nil, // 63 + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + []byte{0x16, 0x6b, 0x40, 0xb4, 0x4a, 0xba, 0x4b, 0xd6}}, +} + +// Plaintext for use with Table A.2 tests +var tableA2Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + +// Table A.2 Resulting Ciphertext from the Variable Key Known Answer Test +var tableA2Tests = []CryptTest{ + { // 0 + []byte{ + 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x95, 0xa8, 0xd7, 0x28, 0x13, 0xda, 0xa9, 0x4d}}, + { // 1 + []byte{ + 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x0e, 0xec, 0x14, 0x87, 0xdd, 0x8c, 0x26, 0xd5}}, + { // 2 + []byte{ + 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x7a, 0xd1, 0x6f, 0xfb, 0x79, 0xc4, 0x59, 0x26}}, + { // 3 + []byte{ + 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xd3, 0x74, 0x62, 0x94, 0xca, 0x6a, 0x6c, 0xf3}}, + { // 4 + []byte{ + 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x80, 0x9f, 0x5f, 0x87, 0x3c, 0x1f, 0xd7, 0x61}}, + { // 5 + []byte{ + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xc0, 0x2f, 0xaf, 0xfe, 0xc9, 0x89, 0xd1, 0xfc}}, + { // 6 + []byte{ + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x46, 0x15, 0xaa, 0x1d, 0x33, 0xe7, 0x2f, 0x10}}, + { // 7 + []byte{ + 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x20, 0x55, 0x12, 0x33, 0x50, 0xc0, 0x08, 0x58}}, + { // 8 + []byte{ + 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xdf, 0x3b, 0x99, 0xd6, 0x57, 0x73, 0x97, 0xc8}}, + { // 9 + []byte{ + 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x31, 0xfe, 0x17, 0x36, 0x9b, 0x52, 0x88, 0xc9}}, + { // 10 + []byte{ + 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xdf, 0xdd, 0x3c, 0xc6, 0x4d, 0xae, 0x16, 0x42}}, + { // 11 + []byte{ + 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x17, 0x8c, 0x83, 0xce, 0x2b, 0x39, 0x9d, 0x94}}, + { // 12 + []byte{ + 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x50, 0xf6, 0x36, 0x32, 0x4a, 0x9b, 0x7f, 0x80}}, + { // 13 + []byte{ + 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xa8, 0x46, 0x8e, 0xe3, 0xbc, 0x18, 0xf0, 0x6d}}, + { // 14 + []byte{ + 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xa2, 0xdc, 0x9e, 0x92, 0xfd, 0x3c, 0xde, 0x92}}, + { // 15 + []byte{ + 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xca, 0xc0, 0x9f, 0x79, 0x7d, 0x03, 0x12, 0x87}}, + { // 16 + []byte{ + 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x90, 0xba, 0x68, 0x0b, 0x22, 0xae, 0xb5, 0x25}}, + { // 17 + []byte{ + 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xce, 0x7a, 0x24, 0xf3, 0x50, 0xe2, 0x80, 0xb6}}, + { // 18 + []byte{ + 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x88, 0x2b, 0xff, 0x0a, 0xa0, 0x1a, 0x0b, 0x87}}, + { // 19 + []byte{ + 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xc2}}, + { // 20 + []byte{ + 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xc7, 0x15, 0x16, 0xc2, 0x9c, 0x75, 0xd1, 0x70}}, + { // 21 + []byte{ + 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x51, 0x99, 0xc2, 0x9a, 0x52, 0xc9, 0xf0, 0x59}}, + { // 22 + []byte{ + 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xc2, 0x2f, 0x0a, 0x29, 0x4a, 0x71, 0xf2, 0x9f}}, + { // 23 + []byte{ + 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xee, 0x37, 0x14, 0x83, 0x71, 0x4c, 0x02, 0xea}}, + { // 24 + []byte{ + 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xa8, 0x1f, 0xbd, 0x44, 0x8f, 0x9e, 0x52, 0x2f}}, + { // 25 + []byte{ + 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x4f, 0x64, 0x4c, 0x92, 0xe1, 0x92, 0xdf, 0xed}}, + { // 26 + []byte{ + 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0x1a, 0xfa, 0x9a, 0x66, 0xa6, 0xdf, 0x92, 0xae}}, + { // 27 + []byte{ + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01}, + nil, + []byte{0xb3, 0xc1, 0xcc, 0x71, 0x5c, 0xb8, 0x79, 0xd8}}, + { // 28 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01}, + nil, + []byte{0x19, 0xd0, 0x32, 0xe6, 0x4a, 0xb0, 0xbd, 0x8b}}, + { // 29 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01}, + nil, + []byte{0x3c, 0xfa, 0xa7, 0xa7, 0xdc, 0x87, 0x20, 0xdc}}, + { // 30 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01}, + nil, + []byte{0xb7, 0x26, 0x5f, 0x7f, 0x44, 0x7a, 0xc6, 0xf3}}, + { // 31 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01}, + nil, + []byte{0x9d, 0xb7, 0x3b, 0x3c, 0x0d, 0x16, 0x3f, 0x54}}, + { // 32 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01}, + nil, + []byte{0x81, 0x81, 0xb6, 0x5b, 0xab, 0xf4, 0xa9, 0x75}}, + { // 33 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01}, + nil, + []byte{0x93, 0xc9, 0xb6, 0x40, 0x42, 0xea, 0xa2, 0x40}}, + { // 34 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01}, + nil, + []byte{0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92}}, + { // 35 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01}, + nil, + []byte{0x86, 0x38, 0x80, 0x9e, 0x87, 0x87, 0x87, 0xa0}}, + { // 36 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01}, + nil, + []byte{0x41, 0xb9, 0xa7, 0x9a, 0xf7, 0x9a, 0xc2, 0x08}}, + { // 37 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01}, + nil, + []byte{0x7a, 0x9b, 0xe4, 0x2f, 0x20, 0x09, 0xa8, 0x92}}, + { // 38 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01}, + nil, + []byte{0x29, 0x03, 0x8d, 0x56, 0xba, 0x6d, 0x27, 0x45}}, + { // 39 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01}, + nil, + []byte{0x54, 0x95, 0xc6, 0xab, 0xf1, 0xe5, 0xdf, 0x51}}, + { // 40 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01}, + nil, + []byte{0xae, 0x13, 0xdb, 0xd5, 0x61, 0x48, 0x89, 0x33}}, + { // 41 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01}, + nil, + []byte{0x02, 0x4d, 0x1f, 0xfa, 0x89, 0x04, 0xe3, 0x89}}, + { // 42 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01}, + nil, + []byte{0xd1, 0x39, 0x97, 0x12, 0xf9, 0x9b, 0xf0, 0x2e}}, + { // 43 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01}, + nil, + []byte{0x14, 0xc1, 0xd7, 0xc1, 0xcf, 0xfe, 0xc7, 0x9e}}, + { // 44 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01}, + nil, + []byte{0x1d, 0xe5, 0x27, 0x9d, 0xae, 0x3b, 0xed, 0x6f}}, + { // 45 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01}, + nil, + []byte{0xe9, 0x41, 0xa3, 0x3f, 0x85, 0x50, 0x13, 0x03}}, + { // 46 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01}, + nil, + []byte{0xda, 0x99, 0xdb, 0xbc, 0x9a, 0x03, 0xf3, 0x79}}, + { // 47 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01}, + nil, + []byte{0xb7, 0xfc, 0x92, 0xf9, 0x1d, 0x8e, 0x92, 0xe9}}, + { // 48 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01}, + nil, + []byte{0xae, 0x8e, 0x5c, 0xaa, 0x3c, 0xa0, 0x4e, 0x85}}, + { // 49 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80}, + nil, + []byte{0x9c, 0xc6, 0x2d, 0xf4, 0x3b, 0x6e, 0xed, 0x74}}, + { // 50 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40}, + nil, + []byte{0xd8, 0x63, 0xdb, 0xb5, 0xc5, 0x9a, 0x91, 0xa0}}, + { // 50 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20}, + nil, + []byte{0xa1, 0xab, 0x21, 0x90, 0x54, 0x5b, 0x91, 0xd7}}, + { // 52 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10}, + nil, + []byte{0x08, 0x75, 0x04, 0x1e, 0x64, 0xc5, 0x70, 0xf7}}, + { // 53 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08}, + nil, + []byte{0x5a, 0x59, 0x45, 0x28, 0xbe, 0xbe, 0xf1, 0xcc}}, + { // 54 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04}, + nil, + []byte{0xfc, 0xdb, 0x32, 0x91, 0xde, 0x21, 0xf0, 0xc0}}, + { // 55 + []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02}, + nil, + []byte{0x86, 0x9e, 0xfd, 0x7f, 0x9f, 0x26, 0x5a, 0x09}}, +} + +// Plaintext for use with Table A.3 tests +var tableA3Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + +// Table A.3 Values To Be Used for the Permutation Operation Known Answer Test +var tableA3Tests = []CryptTest{ + { // 0 + []byte{ + 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31, + 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31, + 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31, + }, + nil, + []byte{0x88, 0xd5, 0x5e, 0x54, 0xf5, 0x4c, 0x97, 0xb4}}, + { // 1 + []byte{ + 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + }, + nil, + []byte{0x0c, 0x0c, 0xc0, 0x0c, 0x83, 0xea, 0x48, 0xfd}}, + { // 2 + []byte{ + 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20, + 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20, + 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20, + }, + nil, + []byte{0x83, 0xbc, 0x8e, 0xf3, 0xa6, 0x57, 0x01, 0x83}}, + { // 3 + []byte{ + 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + }, + nil, + []byte{0xdf, 0x72, 0x5d, 0xca, 0xd9, 0x4e, 0xa2, 0xe9}}, + { // 4 + []byte{ + 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01, + 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01, + 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01, + }, + nil, + []byte{0xe6, 0x52, 0xb5, 0x3b, 0x55, 0x0b, 0xe8, 0xb0}}, + { // 5 + []byte{ + 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01, + 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01, + 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01, + }, + nil, + []byte{0xaf, 0x52, 0x71, 0x20, 0xc4, 0x85, 0xcb, 0xb0}}, + { // 6 + []byte{ + 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01, + 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01, + 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01, + }, + nil, + []byte{0x0f, 0x04, 0xce, 0x39, 0x3d, 0xb9, 0x26, 0xd5}}, + { // 7 + []byte{ + 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01, + 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01, + 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01, + }, + nil, + []byte{0xc9, 0xf0, 0x0f, 0xfc, 0x74, 0x07, 0x90, 0x67}}, + { // 8 + []byte{ + 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01, + 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01, + 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01, + }, + nil, + []byte{0x7c, 0xfd, 0x82, 0xa5, 0x93, 0x25, 0x2b, 0x4e}}, + { // 9 + []byte{ + 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01, + 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01, + 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01, + }, + nil, + []byte{0xcb, 0x49, 0xa2, 0xf9, 0xe9, 0x13, 0x63, 0xe3}}, + { // 10 + []byte{ + 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40, + 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40, + 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40, + }, + nil, + []byte{0x00, 0xb5, 0x88, 0xbe, 0x70, 0xd2, 0x3f, 0x56}}, + { // 11 + []byte{ + 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40, + 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40, + 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40, + }, + nil, + []byte{0x40, 0x6a, 0x9a, 0x6a, 0xb4, 0x33, 0x99, 0xae}}, + { // 12 + []byte{ + 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01, + 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01, + 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01, + }, + nil, + []byte{0x6c, 0xb7, 0x73, 0x61, 0x1d, 0xca, 0x9a, 0xda}}, + { // 13 + []byte{ + 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01, + 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01, + 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01, + }, + nil, + []byte{0x67, 0xfd, 0x21, 0xc1, 0x7d, 0xbb, 0x5d, 0x70}}, + { // 14 + []byte{ + 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01, + 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01, + 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01, + }, + nil, + []byte{0x95, 0x92, 0xcb, 0x41, 0x10, 0x43, 0x07, 0x87}}, + { // 15 + []byte{ + 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20, + 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20, + 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20, + }, + nil, + []byte{0xa6, 0xb7, 0xff, 0x68, 0xa3, 0x18, 0xdd, 0xd3}}, + { // 16 + []byte{ + 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01, + }, + nil, + []byte{0x4d, 0x10, 0x21, 0x96, 0xc9, 0x14, 0xca, 0x16}}, + { // 17 + []byte{ + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01, + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01, + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01, + }, + nil, + []byte{0x2d, 0xfa, 0x9f, 0x45, 0x73, 0x59, 0x49, 0x65}}, + { // 18 + []byte{ + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01, + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01, + 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01, + }, + nil, + []byte{0xb4, 0x66, 0x04, 0x81, 0x6c, 0x0e, 0x07, 0x74}}, + { // 19 + []byte{ + 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01, + 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01, + 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01, + }, + nil, + []byte{0x6e, 0x7e, 0x62, 0x21, 0xa4, 0xf3, 0x4e, 0x87}}, + { // 20 + []byte{ + 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01, + 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01, + 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01, + }, + nil, + []byte{0xaa, 0x85, 0xe7, 0x46, 0x43, 0x23, 0x31, 0x99}}, + { // 21 + []byte{ + 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01, + 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01, + 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01, + }, + nil, + []byte{0x2e, 0x5a, 0x19, 0xdb, 0x4d, 0x19, 0x62, 0xd6}}, + { // 22 + []byte{ + 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01, + 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01, + 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01, + }, + nil, + []byte{0x23, 0xa8, 0x66, 0xa8, 0x09, 0xd3, 0x08, 0x94}}, + { // 23 + []byte{ + 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01, + }, + nil, + []byte{0xd8, 0x12, 0xd9, 0x61, 0xf0, 0x17, 0xd3, 0x20}}, + { // 24 + []byte{ + 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b, + 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b, + 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b, + }, + nil, + []byte{0x05, 0x56, 0x05, 0x81, 0x6e, 0x58, 0x60, 0x8f}}, + { // 25 + []byte{ + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01, + }, + nil, + []byte{0xab, 0xd8, 0x8e, 0x8b, 0x1b, 0x77, 0x16, 0xf1}}, + { // 26 + []byte{ + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02, + }, + nil, + []byte{0x53, 0x7a, 0xc9, 0x5b, 0xe6, 0x9d, 0xa1, 0xe1}}, + { // 27 + []byte{ + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08, + 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08, + }, + nil, + []byte{0xae, 0xd0, 0xf6, 0xae, 0x3c, 0x25, 0xcd, 0xd8}}, + { // 28 + []byte{ + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04, + }, + nil, + []byte{0xb3, 0xe3, 0x5a, 0x5e, 0xe5, 0x3e, 0x7b, 0x8d}}, + { // 29 + []byte{ + 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04, + }, + nil, + []byte{0x61, 0xc7, 0x9c, 0x71, 0x92, 0x1a, 0x2e, 0xf8}}, + { // 30 + []byte{ + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01, + 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01, + }, + nil, + []byte{0xe2, 0xf5, 0x72, 0x8f, 0x09, 0x95, 0x01, 0x3c}}, + { // 31 + []byte{ + 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01, + 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01, + 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01, + }, + nil, + []byte{0x1a, 0xea, 0xc3, 0x9a, 0x61, 0xf0, 0xa4, 0x64}}, +} + +// Table A.4 Values To Be Used for the Substitution Table Known Answer Test +var tableA4Tests = []CryptTest{ + { // 0 + []byte{ + 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57, + 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57, + 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57}, + []byte{0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42}, + []byte{0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b}}, + { // 1 + []byte{ + 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e, + 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e, + 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e}, + []byte{0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda}, + []byte{0x7a, 0x38, 0x9d, 0x10, 0x35, 0x4b, 0xd2, 0x71}}, + { // 2 + []byte{ + 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86, + 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86, + 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86}, + []byte{0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72}, + []byte{0x86, 0x8e, 0xbb, 0x51, 0xca, 0xb4, 0x59, 0x9a}}, + { // 3 + []byte{ + 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e, + 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e, + 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e}, + []byte{0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a}, + []byte{0x71, 0x78, 0x87, 0x6e, 0x01, 0xf1, 0x9b, 0x2a}}, + { // 4 + []byte{ + 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6, + 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6, + 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6}, + []byte{0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2}, + []byte{0xaf, 0x37, 0xfb, 0x42, 0x1f, 0x8c, 0x40, 0x95}}, + { // 5 + []byte{ + 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce, + 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce, + 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce}, + []byte{0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a}, + []byte{0x86, 0xa5, 0x60, 0xf1, 0x0e, 0xc6, 0xd8, 0x5b}}, + { // 6 + []byte{ + 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6, + 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6, + 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6}, + []byte{0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2}, + []byte{0x0c, 0xd3, 0xda, 0x02, 0x00, 0x21, 0xdc, 0x09}}, + { // 7 + []byte{ + 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe, + 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe, + 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe}, + []byte{0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a}, + []byte{0xea, 0x67, 0x6b, 0x2c, 0xb7, 0xdb, 0x2b, 0x7a}}, + { // 8 + []byte{ + 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16, + 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16, + 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16}, + []byte{0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, + []byte{0xdf, 0xd6, 0x4a, 0x81, 0x5c, 0xaf, 0x1a, 0x0f}}, + { // 9 + []byte{ + 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, + 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, + 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f}, + []byte{0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a}, + []byte{0x5c, 0x51, 0x3c, 0x9c, 0x48, 0x86, 0xc0, 0x88}}, + { // 10 + []byte{ + 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46, + 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46, + 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46}, + []byte{0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32}, + []byte{0x0a, 0x2a, 0xee, 0xae, 0x3f, 0xf4, 0xab, 0x77}}, + { // 11 + []byte{ + 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e, + 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e, + 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e}, + []byte{0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca}, + []byte{0xef, 0x1b, 0xf0, 0x3e, 0x5d, 0xfa, 0x57, 0x5a}}, + { // 12 + []byte{ + 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, + 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, + 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76}, + []byte{0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62}, + []byte{0x88, 0xbf, 0x0d, 0xb6, 0xd7, 0x0d, 0xee, 0x56}}, + { // 13 + []byte{ + 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07, + 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07, + 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07}, + []byte{0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2}, + []byte{0xa1, 0xf9, 0x91, 0x55, 0x41, 0x02, 0x0b, 0x56}}, + { // 14 + []byte{ + 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f, + 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f, + 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f}, + []byte{0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa}, + []byte{0x6f, 0xbf, 0x1c, 0xaf, 0xcf, 0xfd, 0x05, 0x56}}, + { // 15 + []byte{ + 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7, + 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7, + 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7}, + []byte{0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92}, + []byte{0x2f, 0x22, 0xe4, 0x9b, 0xab, 0x7c, 0xa1, 0xac}}, + { // 16 + []byte{ + 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf, + 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf, + 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf}, + []byte{0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a}, + []byte{0x5a, 0x6b, 0x61, 0x2c, 0xc2, 0x6c, 0xce, 0x4a}}, + { // 17 + []byte{ + 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6, + 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6, + 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6}, + []byte{0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2}, + []byte{0x5f, 0x4c, 0x03, 0x8e, 0xd1, 0x2b, 0x2e, 0x41}}, + { // 18 + []byte{ + 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef, + 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef, + 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef}, + []byte{0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a}, + []byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}}, +} + +// Use the known weak keys to test DES implementation +func TestWeakKeys(t *testing.T) { + for i, tt := range weakKeyTests { + var encrypt = func(in []byte) (out []byte) { + c, _ := NewCipher(tt.key) + out = make([]byte, len(in)) + encryptBlock(c.subkeys[:], out, in) + return + } + + // Encrypting twice with a DES weak + // key should reproduce the original input + result := encrypt(tt.in) + result = encrypt(result) + + if !bytes.Equal(result, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, result, tt.in) + } + } +} + +// Use the known semi-weak key pairs to test DES implementation +func TestSemiWeakKeyPairs(t *testing.T) { + for i, tt := range semiWeakKeyTests { + var encrypt = func(key, in []byte) (out []byte) { + c, _ := NewCipher(key) + out = make([]byte, len(in)) + encryptBlock(c.subkeys[:], out, in) + return + } + + // Encrypting with one member of the semi-weak pair + // and then encrypting the result with the other member + // should reproduce the original input. + result := encrypt(tt.key, tt.in) + result = encrypt(tt.out, result) + + if !bytes.Equal(result, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, result, tt.in) + } + } +} + +func TestDESEncryptBlock(t *testing.T) { + for i, tt := range encryptDESTests { + c, _ := NewCipher(tt.key) + out := make([]byte, len(tt.in)) + encryptBlock(c.subkeys[:], out, tt.in) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +func TestDESDecryptBlock(t *testing.T) { + for i, tt := range encryptDESTests { + c, _ := NewCipher(tt.key) + plain := make([]byte, len(tt.in)) + decryptBlock(c.subkeys[:], plain, tt.out) + + if !bytes.Equal(plain, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, plain, tt.in) + } + } +} + +func TestEncryptTripleDES(t *testing.T) { + for i, tt := range encryptTripleDESTests { + c, _ := NewTripleDESCipher(tt.key) + out := make([]byte, len(tt.in)) + c.Encrypt(out, tt.in) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +func TestDecryptTripleDES(t *testing.T) { + for i, tt := range encryptTripleDESTests { + c, _ := NewTripleDESCipher(tt.key) + + plain := make([]byte, len(tt.in)) + c.Decrypt(plain, tt.out) + + if !bytes.Equal(plain, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, plain, tt.in) + } + } +} + +// Defined in Pub 800-20 +func TestVariablePlaintextKnownAnswer(t *testing.T) { + for i, tt := range tableA1Tests { + c, _ := NewTripleDESCipher(tableA1Key) + + out := make([]byte, len(tt.in)) + c.Encrypt(out, tt.in) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +// Defined in Pub 800-20 +func TestVariableCiphertextKnownAnswer(t *testing.T) { + for i, tt := range tableA1Tests { + c, _ := NewTripleDESCipher(tableA1Key) + + plain := make([]byte, len(tt.out)) + c.Decrypt(plain, tt.out) + + if !bytes.Equal(plain, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, plain, tt.in) + } + } +} + +// Defined in Pub 800-20 +// Encrypting the Table A.1 ciphertext with the +// 0x01... key produces the original plaintext +func TestInversePermutationKnownAnswer(t *testing.T) { + for i, tt := range tableA1Tests { + c, _ := NewTripleDESCipher(tableA1Key) + + plain := make([]byte, len(tt.in)) + c.Encrypt(plain, tt.out) + + if !bytes.Equal(plain, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, plain, tt.in) + } + } +} + +// Defined in Pub 800-20 +// Decrypting the Table A.1 plaintext with the +// 0x01... key produces the corresponding ciphertext +func TestInitialPermutationKnownAnswer(t *testing.T) { + for i, tt := range tableA1Tests { + c, _ := NewTripleDESCipher(tableA1Key) + + out := make([]byte, len(tt.in)) + c.Decrypt(out, tt.in) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +// Defined in Pub 800-20 +func TestVariableKeyKnownAnswerEncrypt(t *testing.T) { + for i, tt := range tableA2Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tableA2Plaintext)) + c.Encrypt(out, tableA2Plaintext) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +// Defined in Pub 800-20 +func TestVariableKeyKnownAnswerDecrypt(t *testing.T) { + for i, tt := range tableA2Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tt.out)) + c.Decrypt(out, tt.out) + + if !bytes.Equal(out, tableA2Plaintext) { + t.Errorf("#%d: result: %x want: %x", i, out, tableA2Plaintext) + } + } +} + +// Defined in Pub 800-20 +func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) { + for i, tt := range tableA3Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tableA3Plaintext)) + c.Encrypt(out, tableA3Plaintext) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +// Defined in Pub 800-20 +func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) { + for i, tt := range tableA3Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tt.out)) + c.Decrypt(out, tt.out) + + if !bytes.Equal(out, tableA3Plaintext) { + t.Errorf("#%d: result: %x want: %x", i, out, tableA3Plaintext) + } + } +} + +// Defined in Pub 800-20 +func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) { + for i, tt := range tableA4Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tt.in)) + c.Encrypt(out, tt.in) + + if !bytes.Equal(out, tt.out) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.out) + } + } +} + +// Defined in Pub 800-20 +func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) { + for i, tt := range tableA4Tests { + c, _ := NewTripleDESCipher(tt.key) + + out := make([]byte, len(tt.out)) + c.Decrypt(out, tt.out) + + if !bytes.Equal(out, tt.in) { + t.Errorf("#%d: result: %x want: %x", i, out, tt.in) + } + } +} diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index 1f37849..7bce1bc 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -37,7 +37,7 @@ var one = new(big.Int).SetInt64(1) // curve using the procedure given in [NSA] A.2.1. func randFieldElement(c *elliptic.Curve, rand io.Reader) (k *big.Int, err os.Error) { b := make([]byte, c.BitSize/8+8) - _, err = rand.Read(b) + _, err = io.ReadFull(rand, b) if err != nil { return } diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go index 66b72c0..3a06aa8 100644 --- a/libgo/go/crypto/rand/rand_unix.go +++ b/libgo/go/crypto/rand/rand_unix.go @@ -32,7 +32,7 @@ func (r *devReader) Read(b []byte) (n int, err os.Error) { r.mu.Lock() defer r.mu.Unlock() if r.f == nil { - f, err := os.Open(r.name, os.O_RDONLY, 0) + f, err := os.Open(r.name) if f == nil { return 0, err } diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go index 2eaadee..9a71841 100644 --- a/libgo/go/crypto/rsa/pkcs1v15.go +++ b/libgo/go/crypto/rsa/pkcs1v15.go @@ -127,7 +127,7 @@ func nonZeroRandomBytes(s []byte, rand io.Reader) (err os.Error) { for i := 0; i < len(s); i++ { for s[i] == 0 { - _, err = rand.Read(s[i : i+1]) + _, err = io.ReadFull(rand, s[i:i+1]) if err != nil { return } diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index faf9149..b3b212c 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -13,6 +13,7 @@ import ( "hash" "io" "os" + "sync" ) var bigZero = big.NewInt(0) @@ -91,15 +92,21 @@ type PublicKey struct { type PrivateKey struct { PublicKey // public part. D *big.Int // private exponent - P, Q *big.Int // prime factors of N + P, Q, R *big.Int // prime factors of N (R may be nil) + + rwMutex sync.RWMutex // protects the following + dP, dQ, dR *big.Int // D mod (P-1) (or mod Q-1 etc) + qInv *big.Int // q^-1 mod p + pq *big.Int // P*Q + tr *big.Int // pq·tr ≡ 1 mod r } // Validate performs basic sanity checks on the key. // It returns nil if the key is valid, or else an os.Error describing a problem. -func (priv PrivateKey) Validate() os.Error { - // Check that p and q are prime. Note that this is just a sanity - // check. Since the random witnesses chosen by ProbablyPrime are +func (priv *PrivateKey) Validate() os.Error { + // Check that p, q and, maybe, r are prime. Note that this is just a + // sanity check. Since the random witnesses chosen by ProbablyPrime are // deterministic, given the candidate number, it's easy for an attack // to generate composites that pass this test. if !big.ProbablyPrime(priv.P, 20) { @@ -108,16 +115,26 @@ func (priv PrivateKey) Validate() os.Error { if !big.ProbablyPrime(priv.Q, 20) { return os.ErrorString("Q is composite") } + if priv.R != nil && !big.ProbablyPrime(priv.R, 20) { + return os.ErrorString("R is composite") + } - // Check that p*q == n. + // Check that p*q*r == n. modulus := new(big.Int).Mul(priv.P, priv.Q) + if priv.R != nil { + modulus.Mul(modulus, priv.R) + } if modulus.Cmp(priv.N) != 0 { return os.ErrorString("invalid modulus") } - // Check that e and totient(p, q) are coprime. + // Check that e and totient(p, q, r) are coprime. pminus1 := new(big.Int).Sub(priv.P, bigOne) qminus1 := new(big.Int).Sub(priv.Q, bigOne) totient := new(big.Int).Mul(pminus1, qminus1) + if priv.R != nil { + rminus1 := new(big.Int).Sub(priv.R, bigOne) + totient.Mul(totient, rminus1) + } e := big.NewInt(int64(priv.E)) gcd := new(big.Int) x := new(big.Int) @@ -126,7 +143,7 @@ func (priv PrivateKey) Validate() os.Error { if gcd.Cmp(bigOne) != 0 { return os.ErrorString("invalid public exponent E") } - // Check that de ≡ 1 (mod totient(p, q)) + // Check that de ≡ 1 (mod totient(p, q, r)) de := new(big.Int).Mul(priv.D, e) de.Mod(de, totient) if de.Cmp(bigOne) != 0 { @@ -135,7 +152,7 @@ func (priv PrivateKey) Validate() os.Error { return nil } -// GenerateKeyPair generates an RSA keypair of the given bit size. +// GenerateKey generates an RSA keypair of the given bit size. func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) { priv = new(PrivateKey) // Smaller public exponents lead to faster public key @@ -191,6 +208,77 @@ func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) { return } +// Generate3PrimeKey generates a 3-prime RSA keypair of the given bit size, as +// suggested in [1]. Although the public keys are compatible (actually, +// indistinguishable) from the 2-prime case, the private keys are not. Thus it +// may not be possible to export 3-prime private keys in certain formats or to +// subsequently import them into other code. +// +// Table 1 in [2] suggests that size should be >= 1024 when using 3 primes. +// +// [1] US patent 4405829 (1972, expired) +// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf +func Generate3PrimeKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) { + priv = new(PrivateKey) + priv.E = 3 + + pminus1 := new(big.Int) + qminus1 := new(big.Int) + rminus1 := new(big.Int) + totient := new(big.Int) + + for { + p, err := randomPrime(rand, bits/3) + if err != nil { + return nil, err + } + + todo := bits - p.BitLen() + q, err := randomPrime(rand, todo/2) + if err != nil { + return nil, err + } + + todo -= q.BitLen() + r, err := randomPrime(rand, todo) + if err != nil { + return nil, err + } + + if p.Cmp(q) == 0 || + q.Cmp(r) == 0 || + r.Cmp(p) == 0 { + continue + } + + n := new(big.Int).Mul(p, q) + n.Mul(n, r) + pminus1.Sub(p, bigOne) + qminus1.Sub(q, bigOne) + rminus1.Sub(r, bigOne) + totient.Mul(pminus1, qminus1) + totient.Mul(totient, rminus1) + + g := new(big.Int) + priv.D = new(big.Int) + y := new(big.Int) + e := big.NewInt(int64(priv.E)) + big.GcdInt(g, priv.D, y, e, totient) + + if g.Cmp(bigOne) == 0 { + priv.D.Add(priv.D, totient) + priv.P = p + priv.Q = q + priv.R = r + priv.N = n + + break + } + } + + return +} + // incCounter increments a four byte, big-endian counter. func incCounter(c *[4]byte) { if c[3]++; c[3] != 0 { @@ -321,6 +409,26 @@ func modInverse(a, n *big.Int) (ia *big.Int, ok bool) { return x, true } +// precompute performs some calculations that speed up private key operations +// in the future. +func (priv *PrivateKey) precompute() { + priv.dP = new(big.Int).Sub(priv.P, bigOne) + priv.dP.Mod(priv.D, priv.dP) + + priv.dQ = new(big.Int).Sub(priv.Q, bigOne) + priv.dQ.Mod(priv.D, priv.dQ) + + priv.qInv = new(big.Int).ModInverse(priv.Q, priv.P) + + if priv.R != nil { + priv.dR = new(big.Int).Sub(priv.R, bigOne) + priv.dR.Mod(priv.D, priv.dR) + + priv.pq = new(big.Int).Mul(priv.P, priv.Q) + priv.tr = new(big.Int).ModInverse(priv.pq, priv.R) + } +} + // decrypt performs an RSA decryption, resulting in a plaintext integer. If a // random source is given, RSA blinding is used. func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) { @@ -359,7 +467,48 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E c.Mod(c, priv.N) } - m = new(big.Int).Exp(c, priv.D, priv.N) + priv.rwMutex.RLock() + + if priv.dP == nil && priv.P != nil { + priv.rwMutex.RUnlock() + priv.rwMutex.Lock() + if priv.dP == nil && priv.P != nil { + priv.precompute() + } + priv.rwMutex.Unlock() + priv.rwMutex.RLock() + } + + if priv.dP == nil { + m = new(big.Int).Exp(c, priv.D, priv.N) + } else { + // We have the precalculated values needed for the CRT. + m = new(big.Int).Exp(c, priv.dP, priv.P) + m2 := new(big.Int).Exp(c, priv.dQ, priv.Q) + m.Sub(m, m2) + if m.Sign() < 0 { + m.Add(m, priv.P) + } + m.Mul(m, priv.qInv) + m.Mod(m, priv.P) + m.Mul(m, priv.Q) + m.Add(m, m2) + + if priv.dR != nil { + // 3-prime CRT. + m2.Exp(c, priv.dR, priv.R) + m2.Sub(m2, m) + m2.Mul(m2, priv.tr) + m2.Mod(m2, priv.R) + if m2.Sign() < 0 { + m2.Add(m2, priv.R) + } + m2.Mul(m2, priv.pq) + m.Add(m, m2) + } + } + + priv.rwMutex.RUnlock() if ir != nil { // Unblind. diff --git a/libgo/go/crypto/rsa/rsa_test.go b/libgo/go/crypto/rsa/rsa_test.go index bf7c051..d8a936e 100644 --- a/libgo/go/crypto/rsa/rsa_test.go +++ b/libgo/go/crypto/rsa/rsa_test.go @@ -13,28 +13,48 @@ import ( ) func TestKeyGeneration(t *testing.T) { - random := rand.Reader - size := 1024 if testing.Short() { size = 128 } - priv, err := GenerateKey(random, size) + priv, err := GenerateKey(rand.Reader, size) + if err != nil { + t.Errorf("failed to generate key") + } + testKeyBasics(t, priv) +} + +func Test3PrimeKeyGeneration(t *testing.T) { + if testing.Short() { + return + } + + size := 768 + priv, err := Generate3PrimeKey(rand.Reader, size) if err != nil { t.Errorf("failed to generate key") } + testKeyBasics(t, priv) +} + +func testKeyBasics(t *testing.T, priv *PrivateKey) { + if err := priv.Validate(); err != nil { + t.Errorf("Validate() failed: %s", err) + } + pub := &priv.PublicKey m := big.NewInt(42) c := encrypt(new(big.Int), pub, m) m2, err := decrypt(nil, priv, c) if err != nil { t.Errorf("error while decrypting: %s", err) + return } if m.Cmp(m2) != 0 { - t.Errorf("got:%v, want:%v (%s)", m2, m, priv) + t.Errorf("got:%v, want:%v (%+v)", m2, m, priv) } - m3, err := decrypt(random, priv, c) + m3, err := decrypt(rand.Reader, priv, c) if err != nil { t.Errorf("error while decrypting (blind): %s", err) } @@ -43,6 +63,57 @@ func TestKeyGeneration(t *testing.T) { } } +func fromBase10(base10 string) *big.Int { + i := new(big.Int) + i.SetString(base10, 10) + return i +} + +func BenchmarkRSA2048Decrypt(b *testing.B) { + b.StopTimer() + priv := &PrivateKey{ + PublicKey: PublicKey{ + N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"), + E: 3, + }, + D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"), + P: fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"), + Q: fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"), + } + priv.precompute() + + c := fromBase10("1000") + + b.StartTimer() + + for i := 0; i < b.N; i++ { + decrypt(nil, priv, c) + } +} + +func Benchmark3PrimeRSA2048Decrypt(b *testing.B) { + b.StopTimer() + priv := &PrivateKey{ + PublicKey: PublicKey{ + N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"), + E: 3, + }, + D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"), + P: fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"), + Q: fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"), + R: fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"), + } + priv.precompute() + + c := fromBase10("1000") + + b.StartTimer() + + for i := 0; i < b.N; i++ { + decrypt(nil, priv, c) + } +} + type testEncryptOAEPMessage struct { in []byte seed []byte @@ -85,10 +156,12 @@ func TestDecryptOAEP(t *testing.T) { for i, test := range testEncryptOAEPData { n.SetString(test.modulus, 16) d.SetString(test.d, 16) - private := PrivateKey{PublicKey{n, test.e}, d, nil, nil} + private := new(PrivateKey) + private.PublicKey = PublicKey{n, test.e} + private.D = d for j, message := range test.msgs { - out, err := DecryptOAEP(sha1, nil, &private, message.out, nil) + out, err := DecryptOAEP(sha1, nil, private, message.out, nil) if err != nil { t.Errorf("#%d,%d error: %s", i, j, err) } else if bytes.Compare(out, message.in) != 0 { @@ -96,7 +169,7 @@ func TestDecryptOAEP(t *testing.T) { } // Decrypt with blinding. - out, err = DecryptOAEP(sha1, random, &private, message.out, nil) + out, err = DecryptOAEP(sha1, random, private, message.out, nil) if err != nil { t.Errorf("#%d,%d (blind) error: %s", i, j, err) } else if bytes.Compare(out, message.in) != 0 { diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go index ee77f94..5b8c700 100644 --- a/libgo/go/crypto/tls/generate_cert.go +++ b/libgo/go/crypto/tls/generate_cert.go @@ -50,7 +50,7 @@ func main() { return } - certOut, err := os.Open("cert.pem", os.O_WRONLY|os.O_CREAT, 0644) + certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("failed to open cert.pem for writing: %s", err) return @@ -59,7 +59,7 @@ func main() { certOut.Close() log.Print("written cert.pem\n") - keyOut, err := os.Open("key.pem", os.O_WRONLY|os.O_CREAT, 0600) + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0600) if err != nil { log.Print("failed to open key.pem for writing:", err) return diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index f66449c..7de44bb 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.go @@ -124,7 +124,16 @@ func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os. if err != nil { return } + keyPEMBlock, err := ioutil.ReadFile(keyFile) + if err != nil { + return + } + return X509KeyPair(certPEMBlock, keyPEMBlock) +} +// X509KeyPair parses a public/private key pair from a pair of +// PEM encoded data. +func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err os.Error) { var certDERBlock *pem.Block for { certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) @@ -141,11 +150,6 @@ func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os. return } - keyPEMBlock, err := ioutil.ReadFile(keyFile) - if err != nil { - return - } - keyDERBlock, _ := pem.Decode(keyPEMBlock) if keyDERBlock == nil { err = os.ErrorString("crypto/tls: failed to parse key PEM data") diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 853bcde..6825030 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -54,20 +54,21 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err os.Error) { return } - key = &rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ - E: priv.E, - N: new(big.Int).SetBytes(priv.N.Bytes), - }, - D: new(big.Int).SetBytes(priv.D.Bytes), - P: new(big.Int).SetBytes(priv.P.Bytes), - Q: new(big.Int).SetBytes(priv.Q.Bytes), + key = new(rsa.PrivateKey) + key.PublicKey = rsa.PublicKey{ + E: priv.E, + N: new(big.Int).SetBytes(priv.N.Bytes), } + key.D = new(big.Int).SetBytes(priv.D.Bytes) + key.P = new(big.Int).SetBytes(priv.P.Bytes) + key.Q = new(big.Int).SetBytes(priv.Q.Bytes) + err = key.Validate() if err != nil { return nil, err } + return } diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go index 57889e7..d9511b8 100644 --- a/libgo/go/crypto/x509/x509_test.go +++ b/libgo/go/crypto/x509/x509_test.go @@ -11,7 +11,6 @@ import ( "crypto/rsa" "encoding/hex" "encoding/pem" - "reflect" "testing" "time" ) @@ -22,7 +21,11 @@ func TestParsePKCS1PrivateKey(t *testing.T) { if err != nil { t.Errorf("Failed to parse private key: %s", err) } - if !reflect.DeepEqual(priv, rsaPrivateKey) { + if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 || + priv.PublicKey.E != rsaPrivateKey.PublicKey.E || + priv.D.Cmp(rsaPrivateKey.D) != 0 || + priv.P.Cmp(rsaPrivateKey.P) != 0 || + priv.Q.Cmp(rsaPrivateKey.Q) != 0 { t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey) } } |