diff options
Diffstat (limited to 'libgo/go/crypto/block/ecb.go')
-rw-r--r-- | libgo/go/crypto/block/ecb.go | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/libgo/go/crypto/block/ecb.go b/libgo/go/crypto/block/ecb.go deleted file mode 100644 index cf09f7cb3fb..00000000000 --- 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 -} |