public void fillBlock() throws LimitReachedException {
   cipher.encryptBlock(buffer, 0, buffer, 0);
 }
  public void setup(Map attributes) {
    boolean newCipher = true;
    String cipherName = (String) attributes.get(CIPHER);
    if (cipherName == null) {
      if (cipher == null) { // happy birthday
        cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER);
      } else { // we already have one. use it as is
        newCipher = false;
      }
    } else {
      cipher = CipherFactory.getInstance(cipherName);
    }

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

    int keyLength = key.length;
    // ensure that keyLength is valid for the chosen underlying cipher
    boolean ok = false;
    for (Iterator it = cipher.keySizes(); it.hasNext(); ) {
      ok = (keyLength == ((Integer) it.next()).intValue());
      if (ok) {
        break;
      }
    }
    if (!ok) {
      throw new IllegalArgumentException("key length");
    }

    // ensure that remaining params make sense
    int index = -1;
    Integer i = (Integer) attributes.get(INDEX);
    if (i != null) {
      index = i.intValue();
      if (index < 0 || index > 255) {
        throw new IllegalArgumentException(INDEX);
      }
    }

    // now initialise the underlying cipher
    Map map = new HashMap();
    if (cipherBlockSize != 0) { // only needed if new or changed
      map.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(cipherBlockSize));
    }
    map.put(IBlockCipher.KEY_MATERIAL, key);
    try {
      cipher.init(map);
    } catch (InvalidKeyException x) {
      throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL);
    }

    buffer = new byte[cipher.currentBlockSize()];
    buffer[cipher.currentBlockSize() - 1] = (byte) index;
    try {
      fillBlock();
    } catch (LimitReachedException impossible) {
    }
  }