// 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: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] = v;
		}
		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;
}

