/*
 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

/**
 * @author Tom Deneau
 */

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;

import java.util.Random;
import java.util.Arrays;

abstract public class TestAESBase {
  int msgSize = Integer.getInteger("msgSize", 646);
  boolean checkOutput = Boolean.getBoolean("checkOutput");
  boolean noReinit = Boolean.getBoolean("noReinit");
  boolean testingMisalignment;
  private static final int ALIGN = 8;
  int encInputOffset = Integer.getInteger("encInputOffset", 0) % ALIGN;
  int encOutputOffset = Integer.getInteger("encOutputOffset", 0) % ALIGN;
  int decOutputOffset = Integer.getInteger("decOutputOffset", 0) % ALIGN;
  int lastChunkSize = Integer.getInteger("lastChunkSize", 32);
  int keySize = Integer.getInteger("keySize", 128);
  int inputLength;
  int encodeLength;
  int decodeLength;
  int decodeMsgSize;
  String algorithm = System.getProperty("algorithm", "AES");
  String mode = System.getProperty("mode", "CBC");
  String paddingStr = System.getProperty("paddingStr", "PKCS5Padding");
  byte[] input;
  byte[] encode;
  byte[] expectedEncode;
  byte[] decode;
  byte[] expectedDecode;
  Random random = new Random(0);
  Cipher cipher;
  Cipher dCipher;
  AlgorithmParameters algParams = null;
  SecretKey key;
  GCMParameterSpec gcm_spec;
  byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 };
  int tlen = 12;
  byte[] iv = new byte[16];

  static int numThreads = 0;
  int  threadId;
  static synchronized int getThreadId() {
    int id = numThreads;
    numThreads++;
    return id;
  }

  abstract public void run();

  public void prepare() {
    try {
      System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr +
              ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit +
              ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" +
              encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );

      if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 )
        testingMisalignment = true;

      int keyLenBytes = (keySize == 0 ? 16 : keySize/8);
      byte keyBytes[] = new byte[keyLenBytes];
      if (keySize == 128)
        keyBytes = new byte[] {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
      else
        random.nextBytes(keyBytes);

      key = new SecretKeySpec(keyBytes, algorithm);
      if (threadId == 0) {
        System.out.println("Algorithm: " + key.getAlgorithm() + "("
                           + key.getEncoded().length * 8 + "bit)");
      }

      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
      dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");

      // CBC init
      if (mode.equals("CBC")) {
        IvParameterSpec initVector = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
        algParams = cipher.getParameters();
        dCipher.init(Cipher.DECRYPT_MODE, key, initVector);

      // GCM init
      } else if (mode.equals("GCM")) {
        gcm_init(true);
        gcm_init(false);

      // ECB init
      } else {
        cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
        dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
      }

      if (threadId == 0) {
        childShowCipher();
      }

      inputLength = msgSize + encInputOffset;
      if (testingMisalignment) {
        encodeLength = cipher.getOutputSize(msgSize - lastChunkSize) + encOutputOffset;
        encodeLength += cipher.getOutputSize(lastChunkSize);
        decodeLength = dCipher.getOutputSize(encodeLength - lastChunkSize) + decOutputOffset;
        decodeLength += dCipher.getOutputSize(lastChunkSize);
      } else {
        encodeLength = cipher.getOutputSize(msgSize) + encOutputOffset;
        decodeLength = dCipher.getOutputSize(encodeLength) + decOutputOffset;
      }

      input = new byte[inputLength];
      for (int i=encInputOffset, j=0; i<inputLength; i++, j++) {
        input[i] = (byte) (j & 0xff);
      }

      // do one encode and decode in preparation
      encode = new byte[encodeLength];
      decode = new byte[decodeLength];
      if (testingMisalignment) {
        decodeMsgSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset);
        decodeMsgSize += cipher.doFinal(input, (encInputOffset + msgSize - lastChunkSize), lastChunkSize, encode, (encOutputOffset + decodeMsgSize));

        int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
        dCipher.doFinal(encode, (encOutputOffset + decodeMsgSize - lastChunkSize), lastChunkSize, decode, (decOutputOffset + tempSize));
      } else {
        decodeMsgSize = cipher.doFinal(input, encInputOffset, msgSize, encode, encOutputOffset);
        dCipher.doFinal(encode, encOutputOffset, decodeMsgSize, decode, decOutputOffset);
      }
      if (checkOutput) {
        expectedEncode = (byte[]) encode.clone();
        expectedDecode = (byte[]) decode.clone();
        showArray(key.getEncoded()  ,  "key:    ");
        showArray(input,  "input:  ");
        showArray(encode, "encode: ");
        showArray(decode, "decode: ");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  void showArray(byte b[], String name) {
    System.out.format("%s [%d]: ", name, b.length);
    for (int i=0; i<Math.min(b.length, 32); i++) {
      System.out.format("%02x ", b[i] & 0xff);
    }
    System.out.println();
  }

  void compareArrays(byte b[], byte exp[]) {
    if (b.length != exp.length) {
      System.out.format("different lengths for actual and expected output arrays\n");
      showArray(b, "test: ");
      showArray(exp, "exp : ");
      System.exit(1);
    }
    for (int i=0; i< exp.length; i++) {
      if (b[i] != exp[i]) {
        System.out.format("output error at index %d: got %02x, expected %02x\n", i, b[i] & 0xff, exp[i] & 0xff);
        showArray(b, "test: ");
        showArray(exp, "exp : ");
        System.exit(1);
      }
    }
  }


  void showCipher(Cipher c, String kind) {
    System.out.println(kind + " cipher provider: " + cipher.getProvider());
    System.out.println(kind + " cipher algorithm: " + cipher.getAlgorithm());
  }

  abstract void childShowCipher();

  void gcm_init(boolean encrypt) throws Exception {
    gcm_spec = new GCMParameterSpec(tlen * 8, iv);
    if (encrypt) {
      // Get a new instance everytime because of reuse IV restrictions
      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
      cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
      cipher.updateAAD(aad);
    } else {
      dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec);
      dCipher.updateAAD(aad);


    }
  }
}
