// 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 (
	"crypto/block";
	"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:len(x.plain)];
	} 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];
		for j, v := range p {
			x.buf[j] = p[j];
		}
		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:len(x.crypt)];
		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) {
		// plain and buf share same data,
		// but buf is before plain, so forward loop is correct
		for i := 0; i < len(x.plain); i++ {
			x.buf[i] = x.plain[i];
		}
		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:len(p)];

		// 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;
}

