/*
 * Copyright (c) 2012, 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.
 */

/*
 * @test
 * @bug     7088989
 * @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
 */
import java.io.*;
import java.security.*;
import java.security.spec.*;
import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class TestAES extends UcryptoTest {

    private static final String[] PADDEDCIPHER_ALGOS = {
        "AES/ECB/PKCS5Padding",
        "AES/CBC/PKCS5Padding",
        "AES/CFB128/PKCS5Padding"
    };

    private static final String[] CIPHER_ALGOS = {
        "AES/ECB/NoPadding",
        "AES/CBC/NoPadding",
        "AES/CFB128/NoPadding",
        "AES/CTR/NoPadding",
    };

    private static final SecretKey CIPHER_KEY =
        new SecretKeySpec(new byte[16], "AES");

    public static void main(String[] args) throws Exception {
        main(new TestAES(), null);
    }

    public void doTest(Provider prov) throws Exception {
        // Provider for testing Interoperability
        Provider sunJCEProv = Security.getProvider("SunJCE");

        testCipherInterop(CIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);
        testCipherInterop(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);

        testCipherOffset(CIPHER_ALGOS, CIPHER_KEY, prov);
        testCipherOffset(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov);

        testCipherKeyWrapping(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);
        testCipherGCM(CIPHER_KEY, prov);
    }

    private static void testCipherInterop(String[] algos, SecretKey key,
                                          Provider p,
                                          Provider interopP) {
        boolean testPassed = true;
        byte[] in = new byte[32];
        (new SecureRandom()).nextBytes(in);

        for (String algo : algos) {
            try {
                // check ENC
                Cipher c;
                try {
                    c = Cipher.getInstance(algo, p);
                } catch (NoSuchAlgorithmException nsae) {
                    System.out.println("Skipping Unsupported CIP algo: " + algo);
                    continue;
                }
                c.init(Cipher.ENCRYPT_MODE, key, (AlgorithmParameters)null, null);
                byte[] eout = c.doFinal(in, 0, in.length);

                AlgorithmParameters params = c.getParameters();
                Cipher c2 = Cipher.getInstance(algo, interopP);
                c2.init(Cipher.ENCRYPT_MODE, key, params, null);
                byte[] eout2 = c2.doFinal(in, 0, in.length);

                if (!Arrays.equals(eout, eout2)) {
                    System.out.println(algo + ": DIFF FAILED");
                    testPassed = false;
                } else {
                    System.out.println(algo + ": ENC Passed");
                }

                // check DEC
                c.init(Cipher.DECRYPT_MODE, key, params, null);
                byte[] dout = c.doFinal(eout);
                c2.init(Cipher.DECRYPT_MODE, key, params, null);
                byte[] dout2 = c2.doFinal(eout2);

                if (!Arrays.equals(dout, dout2)) {
                    System.out.println(algo + ": DIFF FAILED");
                    testPassed = false;
                } else {
                    System.out.println(algo + ": DEC Passed");
                }
            } catch(Exception ex) {
                System.out.println("Unexpected Exception: " + algo);
                ex.printStackTrace();
                testPassed = false;
            }
        }

        if (!testPassed) {
            throw new RuntimeException("One or more CIPHER test failed!");
        } else {
            System.out.println("CIPHER Interop Tests Passed");
        }
    }

    private static void testCipherOffset(String[] algos, SecretKey key,
                                         Provider p) {
        boolean testPassed = true;
        byte[] in = new byte[16];
        (new SecureRandom()).nextBytes(in);
        int blockSize = 16;

        for (int j = 1; j < (in.length - 1); j++) {
            System.out.println("Input offset size: " + j);
            for (int i = 0; i < algos.length; i++) {
                try {
                    // check ENC
                    Cipher c;
                    try {
                        c = Cipher.getInstance(algos[i], p);
                    } catch (NoSuchAlgorithmException nsae) {
                        System.out.println("Skip Unsupported CIP algo: " + algos[i]);
                        continue;
                    }
                    c.init(Cipher.ENCRYPT_MODE, key, (AlgorithmParameters)null, null);
                    byte[] eout = new byte[c.getOutputSize(in.length)];
                    int firstPartLen = in.length - j - 1;
                    //System.out.print("1st UPDATE: " + firstPartLen);
                    int k = c.update(in, 0, firstPartLen, eout, 0);
                    k += c.update(in, firstPartLen, 1, eout, k);
                    k += c.doFinal(in, firstPartLen+1, j, eout, k);

                    AlgorithmParameters params = c.getParameters();

                    Cipher c2 = Cipher.getInstance(algos[i], p);
                    c2.init(Cipher.ENCRYPT_MODE, key, params, null);
                    byte[] eout2 = new byte[c2.getOutputSize(in.length)];
                    int k2 = c2.update(in, 0, j, eout2, 0);
                    k2 += c2.update(in, j, 1, eout2, k2);
                    k2 += c2.doFinal(in, j+1, firstPartLen, eout2, k2);

                    if (!checkArrays(eout, k, eout2, k2)) testPassed = false;

                    // check DEC
                    c.init(Cipher.DECRYPT_MODE, key, params, null);
                    byte[] dout = new byte[c.getOutputSize(eout.length)];
                    k = c.update(eout, 0, firstPartLen, dout, 0);
                    k += c.update(eout, firstPartLen, 1, dout, k);
                    k += c.doFinal(eout, firstPartLen+1, eout.length - firstPartLen - 1, dout, k);
                    if (!checkArrays(in, in.length, dout, k)) testPassed = false;
                } catch(Exception ex) {
                    System.out.println("Unexpected Exception: " + algos[i]);
                    ex.printStackTrace();
                    testPassed = false;
                }
            }
        }
        if (!testPassed) {
            throw new RuntimeException("One or more CIPHER test failed!");
        } else {
            System.out.println("CIPHER Offset Tests Passed");
        }
    }

    private static void testCipherKeyWrapping(String[] algos, SecretKey key,
                                              Provider p, Provider interopP)
        throws NoSuchAlgorithmException {
        boolean testPassed = true;

        // Test SecretKey, PrivateKey and PublicKey
        Key[] tbwKeys = new Key[3];
        int[] tbwKeyTypes = { Cipher.SECRET_KEY, Cipher.PRIVATE_KEY, Cipher.PUBLIC_KEY };
        tbwKeys[0] = new SecretKeySpec(new byte[20], "Blowfish");
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair kp = kpg.generateKeyPair();
        tbwKeys[1] = kp.getPrivate();
        tbwKeys[2] = kp.getPublic();

        for (int i = 0; i < algos.length; i++) {
            try {
                System.out.println(algos[i] + " - Native WRAP/Java UNWRAP");

                Cipher c1;
                try {
                    c1 = Cipher.getInstance(algos[i], p);
                } catch (NoSuchAlgorithmException nsae) {
                    System.out.println("Skipping Unsupported CIP algo: " + algos[i]);
                    continue;
                }
                c1.init(Cipher.WRAP_MODE, key, (AlgorithmParameters)null, null);
                AlgorithmParameters params = c1.getParameters();
                Cipher c2 = Cipher.getInstance(algos[i], interopP);
                c2.init(Cipher.UNWRAP_MODE, key, params, null);

                for (int j = 0; j < tbwKeys.length ; j++) {
                    byte[] wrappedKey = c1.wrap(tbwKeys[j]);
                    Key recovered = c2.unwrap(wrappedKey,
                                              tbwKeys[j].getAlgorithm(), tbwKeyTypes[j]);
                    if (!checkKeys(tbwKeys[j], recovered)) testPassed = false;
                }

                System.out.println(algos[i] + " - Java WRAP/Native UNWRAP");
                c1 = Cipher.getInstance(algos[i], interopP);
                c1.init(Cipher.WRAP_MODE, key, (AlgorithmParameters)null, null);
                params = c1.getParameters();
                c2 = Cipher.getInstance(algos[i], p);
                c2.init(Cipher.UNWRAP_MODE, key, params, null);

                for (int j = 0; j < tbwKeys.length ; j++) {
                    byte[] wrappedKey = c1.wrap(tbwKeys[j]);
                    Key recovered = c2.unwrap(wrappedKey,
                                              tbwKeys[j].getAlgorithm(), tbwKeyTypes[j]);
                    if (!checkKeys(tbwKeys[j], recovered)) testPassed = false;
                }

            } catch(Exception ex) {
                System.out.println("Unexpected Exception: " + algos[i]);
                ex.printStackTrace();
                testPassed = false;
            }
        }
        if (!testPassed) {
            throw new RuntimeException("One or more CIPHER test failed!");
        } else {
            System.out.println("CIPHER KeyWrapping Tests Passed");
        }
    }


    private static void testCipherGCM(SecretKey key,
                                      Provider p) {
        boolean testPassed = true;
        byte[] in = new byte[16];
        (new SecureRandom()).nextBytes(in);

        byte[] iv = new byte[16];
        (new SecureRandom()).nextBytes(iv);


        String algo = "AES/GCM/NoPadding";
        int tagLen[] = { 128, 120, 112, 104, 96, 64, 32 };

        try {
            Cipher c;
            try {
                c = Cipher.getInstance(algo, p);
            } catch (NoSuchAlgorithmException nsae) {
                System.out.println("Skipping Unsupported CIP algo: " + algo);
                return;
            }
            for (int i = 0; i < tagLen.length; i++) {
                AlgorithmParameterSpec paramSpec = new GCMParameterSpec(tagLen[i], iv);
                // check ENC
                c.init(Cipher.ENCRYPT_MODE, key, paramSpec, null);
                c.updateAAD(iv);
                byte[] eout = c.doFinal(in, 0, in.length);

                AlgorithmParameters param = c.getParameters();
                // check DEC
                c.init(Cipher.DECRYPT_MODE, key, param, null);
                c.updateAAD(iv);
                byte[] dout = c.doFinal(eout, 0, eout.length);

                if (!Arrays.equals(dout, in)) {
                    System.out.println(algo + ": PT and RT DIFF FAILED");
                    testPassed = false;
                } else {
                    System.out.println(algo + ": tagLen " + tagLen[i] + " done");
                }
            }
        } catch(Exception ex) {
            System.out.println("Unexpected Exception: " + algo);
            ex.printStackTrace();
            testPassed = false;
        }
        if (!testPassed) {
            throw new RuntimeException("One or more CIPHER test failed!");
        } else {
            System.out.println("CIPHER GCM Tests Passed");
        }
    }

    private static boolean checkArrays(byte[] a1, int a1Len, byte[] a2, int a2Len) {
        boolean equal = true;
        if (a1Len != a2Len) {
            System.out.println("DIFFERENT OUT LENGTH");
            equal = false;
        } else {
            for (int p = 0; p < a1Len; p++) {
                if (a1[p] != a2[p]) {
                    System.out.println("DIFF FAILED");
                    equal = false;
                    break;
                }
            }
        }
        return equal;
    }

    private static boolean checkKeys(Key k1, Key k2) {
        boolean equal = true;
        if (!k1.getAlgorithm().equalsIgnoreCase(k2.getAlgorithm())) {
            System.out.println("DIFFERENT Key Algorithm");
            equal = false;
        } else if (!k1.getFormat().equalsIgnoreCase(k2.getFormat())) {
            System.out.println("DIFFERENT Key Format");
            equal = false;
        } else if (!Arrays.equals(k1.getEncoded(), k2.getEncoded())) {
            System.out.println("DIFFERENT Key Encoding");
            equal = false;
        }
        return equal;
    }
}
