/* ICMGenerator.java --
   Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.

This file is a part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.  */


package gnu.javax.crypto.prng;

import gnu.java.security.Registry;
import gnu.java.security.prng.BasePRNG;
import gnu.java.security.prng.LimitReachedException;
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.cipher.IBlockCipher;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.util.HashMap;
import java.util.Map;

/**
 * Counter Mode is a way to define a pseudorandom keystream generator using a
 * block cipher. The keystream can be used for additive encryption, key
 * derivation, or any other application requiring pseudorandom data.
 * <p>
 * In ICM, the keystream is logically broken into segments. Each segment is
 * identified with a segment index, and the segments have equal lengths. This
 * segmentation makes ICM especially appropriate for securing packet-based
 * protocols.
 * <p>
 * This implementation adheres to the definition of the ICM keystream generation
 * function that allows for any symetric key block cipher algorithm
 * (initialisation parameter <code>gnu.crypto.prng.icm.cipher.name</code>
 * taken to be an instance of {@link java.lang.String}) to be used. If such a
 * parameter is not defined/included in the initialisation <code>Map</code>,
 * then the "Rijndael" algorithm is used. Furthermore, if the initialisation
 * parameter <code>gnu.crypto.cipher.block.size</code> (taken to be a instance
 * of {@link java.lang.Integer}) is missing or undefined in the initialisation
 * <code>Map</code>, then the cipher's <em>default</em> block size is used.
 * <p>
 * The practical limits and constraints of such generator are:
 * <ul>
 * <li>The number of blocks in any segment <b>MUST NOT</b> exceed <code>
 *    256 ** BLOCK_INDEX_LENGTH</code>.
 * The number of segments <b>MUST NOT</b> exceed
 * <code>256 ** SEGMENT_INDEX_LENGTH</code>. These restrictions ensure the
 * uniqueness of each block cipher input.</li>
 * <li>Each segment contains <code>SEGMENT_LENGTH</code> octets; this value
 * <b>MUST NOT</b> exceed the value <code>(256 ** BLOCK_INDEX_LENGTH) *
 *    BLOCK_LENGTH</code>.</li>
 * <li>The sum of <code>SEGMENT_INDEX_LENGTH</code> and
 * <code>BLOCK_INDEX_LENGTH</code> <b>MUST NOT</b> exceed <code>BLOCK_LENGTH
 *    / 2</code>.
 * This requirement protects the ICM keystream generator from potentially
 * failing to be pseudorandom.</li>
 * </ul>
 * <p>
 * <b>NOTE</b>: Rijndael is used as the default symmetric key block cipher
 * algorithm because, with its default block and key sizes, it is the AES. Yet
 * being Rijndael, the algorithm offers more versatile block and key sizes which
 * may prove to be useful for generating <em>longer</em> key streams.
 * <p>
 * References:
 * <ol>
 * <li><a
 * href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-icm-00.txt">
 * Integer Counter Mode</a>, David A. McGrew.</li>
 * </ol>
 */
public class ICMGenerator
    extends BasePRNG
    implements Cloneable
{
  /** Property name of underlying block cipher for this ICM generator. */
  public static final String CIPHER = "gnu.crypto.prng.icm.cipher.name";
  /** Property name of ICM's block index length. */
  public static final String BLOCK_INDEX_LENGTH =
      "gnu.crypto.prng.icm.block.index.length";
  /** Property name of ICM's segment index length. */
  public static final String SEGMENT_INDEX_LENGTH =
      "gnu.crypto.prng.icm.segment.index.length";
  /** Property name of ICM's offset. */
  public static final String OFFSET = "gnu.crypto.prng.icm.offset";
  /** Property name of ICM's segment index. */
  public static final String SEGMENT_INDEX = "gnu.crypto.prng.icm.segment.index";
  /** The integer value 256 as a BigInteger. */
  private static final BigInteger TWO_FIFTY_SIX = new BigInteger("256");
  /** The underlying cipher implementation. */
  private IBlockCipher cipher;
  /** This keystream block index length in bytes. */
  private int blockNdxLength = -1;
  /** This keystream segment index length in bytes. */
  private int segmentNdxLength = -1;
  /** The index of the next block for a given keystream segment. */
  private BigInteger blockNdx = BigInteger.ZERO;
  /** The segment index for this keystream. */
  private BigInteger segmentNdx;
  /** The initial counter for a given keystream segment. */
  private BigInteger C0;

  /** Trivial 0-arguments constructor. */
  public ICMGenerator()
  {
    super(Registry.ICM_PRNG);
  }

  // Conceptually, ICM is a keystream generator that takes a secret key and a
  // segment index as an input and then outputs a keystream segment. The
  // segmentation lends itself to packet encryption, as each keystream segment
  // can be used to encrypt a distinct packet.
  //
  // An ICM key consists of the block cipher key and an Offset. The Offset is
  // an integer with BLOCK_LENGTH octets...
  public void setup(Map attributes)
  {
    // find out which cipher algorithm to use
    boolean newCipher = true;
    String underlyingCipher = (String) attributes.get(CIPHER);
    if (underlyingCipher == null)
      if (cipher == null) // happy birthday
        // ensure we have a reliable implementation of this cipher
        cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER);
      else
        // we already have one. use it as is
        newCipher = false;
    else // ensure we have a reliable implementation of this cipher
      cipher = CipherFactory.getInstance(underlyingCipher);

    // find out what block size we should use it in
    int cipherBlockSize = 0;
    Integer bs = (Integer) attributes.get(IBlockCipher.CIPHER_BLOCK_SIZE);
    if (bs != null)
      cipherBlockSize = bs.intValue();
    else
      {
        if (newCipher) // assume we'll use its default block size
          cipherBlockSize = cipher.defaultBlockSize();
        // else use as is
      }
    // get the key material
    byte[] key = (byte[]) attributes.get(IBlockCipher.KEY_MATERIAL);
    if (key == null)
      throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL);
    // now initialise the cipher
    HashMap map = new HashMap();
    if (cipherBlockSize != 0) // only needed if new or changed
      map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize));
    map.put(IBlockCipher.KEY_MATERIAL, key);
    try
      {
        cipher.init(map);
      }
    catch (InvalidKeyException x)
      {
        throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL);
      }
    // at this point we have an initialised (new or otherwise) cipher
    // ensure that remaining params make sense
    cipherBlockSize = cipher.currentBlockSize();
    BigInteger counterRange = TWO_FIFTY_SIX.pow(cipherBlockSize);
    // offset, like the underlying cipher key is not cloneable
    // always look for it and throw an exception if it's not there
    Object obj = attributes.get(OFFSET);
    // allow either a byte[] or a BigInteger
    BigInteger r;
    if (obj instanceof BigInteger)
      r = (BigInteger) obj;
    else // assume byte[]. should be same length as cipher block size
      {
        byte[] offset = (byte[]) obj;
        if (offset.length != cipherBlockSize)
          throw new IllegalArgumentException(OFFSET);
        r = new BigInteger(1, offset);
      }
    int wantBlockNdxLength = -1; // number of octets in the block index
    Integer i = (Integer) attributes.get(BLOCK_INDEX_LENGTH);
    if (i != null)
      {
        wantBlockNdxLength = i.intValue();
        if (wantBlockNdxLength < 1)
          throw new IllegalArgumentException(BLOCK_INDEX_LENGTH);
      }
    int wantSegmentNdxLength = -1; // number of octets in the segment index
    i = (Integer) attributes.get(SEGMENT_INDEX_LENGTH);
    if (i != null)
      {
        wantSegmentNdxLength = i.intValue();
        if (wantSegmentNdxLength < 1)
          throw new IllegalArgumentException(SEGMENT_INDEX_LENGTH);
      }
    // if both are undefined check if it's a reuse
    if ((wantBlockNdxLength == -1) && (wantSegmentNdxLength == -1))
      {
        if (blockNdxLength == -1) // new instance
          throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", "
                                             + SEGMENT_INDEX_LENGTH);
        // else reuse old values
      }
    else // only one is undefined, set it to BLOCK_LENGTH/2 minus the other
      {
        int limit = cipherBlockSize / 2;
        if (wantBlockNdxLength == -1)
          wantBlockNdxLength = limit - wantSegmentNdxLength;
        else if (wantSegmentNdxLength == -1)
          wantSegmentNdxLength = limit - wantBlockNdxLength;
        else if ((wantSegmentNdxLength + wantBlockNdxLength) > limit)
          throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", "
                                             + SEGMENT_INDEX_LENGTH);
        // save new values
        blockNdxLength = wantBlockNdxLength;
        segmentNdxLength = wantSegmentNdxLength;
      }
    // get the segment index as a BigInteger
    BigInteger s = (BigInteger) attributes.get(SEGMENT_INDEX);
    if (s == null)
      {
        if (segmentNdx == null) // segment index was never set
          throw new IllegalArgumentException(SEGMENT_INDEX);
        // reuse; check if still valid
        if (segmentNdx.compareTo(TWO_FIFTY_SIX.pow(segmentNdxLength)) > 0)
          throw new IllegalArgumentException(SEGMENT_INDEX);
      }
    else
      {
        if (s.compareTo(TWO_FIFTY_SIX.pow(segmentNdxLength)) > 0)
          throw new IllegalArgumentException(SEGMENT_INDEX);
        segmentNdx = s;
      }
    // The initial counter of the keystream segment with segment index s is
    // defined as follows, where r denotes the Offset:
    //
    // C[0] = (s * (256^BLOCK_INDEX_LENGTH) + r) modulo (256^BLOCK_LENGTH)
    C0 = segmentNdx.multiply(TWO_FIFTY_SIX.pow(blockNdxLength))
                   .add(r).modPow(BigInteger.ONE, counterRange);
    try
      {
        fillBlock();
      }
    catch (LimitReachedException impossible)
      {
        throw (InternalError)
          new InternalError().initCause(impossible);
      }
  }

  public void fillBlock() throws LimitReachedException
  {
    if (C0 == null)
      throw new IllegalStateException();
    if (blockNdx.compareTo(TWO_FIFTY_SIX.pow(blockNdxLength)) >= 0)
      throw new LimitReachedException();
    int cipherBlockSize = cipher.currentBlockSize();
    BigInteger counterRange = TWO_FIFTY_SIX.pow(cipherBlockSize);
    // encrypt the counter for the current blockNdx
    // C[i] = (C[0] + i) modulo (256^BLOCK_LENGTH).
    BigInteger Ci = C0.add(blockNdx).modPow(BigInteger.ONE, counterRange);
    buffer = Ci.toByteArray();
    int limit = buffer.length;
    if (limit < cipherBlockSize)
      {
        byte[] data = new byte[cipherBlockSize];
        System.arraycopy(buffer, 0, data, cipherBlockSize - limit, limit);
        buffer = data;
      }
    else if (limit > cipherBlockSize)
      {
        byte[] data = new byte[cipherBlockSize];
        System.arraycopy(buffer, limit - cipherBlockSize, data, 0,
                         cipherBlockSize);
        buffer = data;
      }
    cipher.encryptBlock(buffer, 0, buffer, 0);
    blockNdx = blockNdx.add(BigInteger.ONE); // increment blockNdx
  }
}
