/*
 * Copyright (c) 1998, 2007, 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 0000000
 * @summary Makes sure that Cipher.doFinal() returns the right number
 *      of bytes written
 * @author Jan Luehe
 */
import java.security.*;
import java.security.interfaces.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class DoFinalReturnLen {
    static byte[] dataToEncrypt = {
        (byte)0x02, (byte)0xA4, (byte)0x20, (byte)0x87,
        (byte)0xB6, (byte)0xC4, (byte)0x54, (byte)0x89,
        (byte)0xA2, (byte)0xA4, (byte)0x10, (byte)0x87,
        (byte)0xCD, (byte)0x76, (byte)0x43, (byte)0xF0,
        (byte)0x72, (byte)0xA4, (byte)0xA0, (byte)0x82,
        (byte)0x26, (byte)0xC4, (byte)0x54, (byte)0x19,
        (byte)0x09, (byte)0xAC, (byte)0x2A, (byte)0xE7,
        (byte)0x1D, (byte)0x74, (byte)0x13, (byte)0x20,
        (byte)0xAD, (byte)0xD4, (byte)0xD0, (byte)0x87,
        (byte)0xB6, (byte)0xC5, (byte)0x24, (byte)0x89,
        (byte)0x02, (byte)0xF4, (byte)0x90, (byte)0x8E,
        (byte)0x5D, (byte)0x76, (byte)0x43, (byte)0x2F,
        (byte)0x03, (byte)0xAD, (byte)0x20, (byte)0x8C,
        (byte)0xB5, (byte)0xC4, (byte)0xA4, (byte)0x39,
        (byte)0xD2, (byte)0xA4, (byte)0xE0, (byte)0x87,
        (byte)0xCD, (byte)0x56, (byte)0x53, (byte)0x20
    };

    static byte[] dataToEncryptUneven = {
        (byte)0x02, (byte)0xA4, (byte)0x20, (byte)0x87,
        (byte)0xB6, (byte)0xC4, (byte)0x54, (byte)0x89,
        (byte)0xA2, (byte)0xA4, (byte)0x10, (byte)0x87,
        (byte)0xCD, (byte)0x76, (byte)0x43, (byte)0xF0,
        (byte)0x72, (byte)0xA4, (byte)0xA0, (byte)0x82,
        (byte)0x26, (byte)0xC4, (byte)0x54, (byte)0x19,
        (byte)0x09, (byte)0xAC, (byte)0x2A, (byte)0xE7,
        (byte)0x1D, (byte)0x74, (byte)0x13, (byte)0x20,
        (byte)0xAD, (byte)0xD4, (byte)0xD0, (byte)0x87,
        (byte)0xB6, (byte)0xC5, (byte)0x24, (byte)0x89,
        (byte)0x02, (byte)0xF4, (byte)0x90, (byte)0x8E,
        (byte)0x5D, (byte)0x76, (byte)0x43, (byte)0x2F,
        (byte)0x03, (byte)0xAD, (byte)0x20, (byte)0x8C,
        (byte)0xB5, (byte)0xC4, (byte)0xA4, (byte)0x39,
        (byte)0xD2, (byte)0xA4, (byte)0xE0, (byte)0x87,
        (byte)0xCD, (byte)0x56, (byte)0x53, (byte)0x20,
        (byte)0x22
    };

    static byte[] iv = {
        (byte)0x03, (byte)0xAD, (byte)0x20, (byte)0x8C,
        (byte)0xB5, (byte)0xC4, (byte)0xA4, (byte)0x39
    };

    public static void main (String args[]) throws Exception {
        byte[] encryptedData = null;
        byte[] decryptedData = null;
        Cipher newDES = null;
        IvParameterSpec IvParamSpec = null;
        SecretKey sKey = null;

        // Step 0: add providers
        Provider sun = new com.sun.crypto.provider.SunJCE();
        Security.addProvider(sun);
        Provider[] theProviders = Security.getProviders();
        for (int index = 0; index < theProviders.length; index++) {
            System.out.println(theProviders[index].getName());
            System.out.println(theProviders[index].getVersion());
            System.out.println(theProviders[index].getInfo());
        }

        // Cipher Object
        newDES = Cipher.getInstance("DES/CBC/PKCS5Padding",
                                    "SunJCE");
        byte[] keyData = {
            (byte)0x46, (byte)0x19, (byte)0x20, (byte)0x5e,
            (byte)0xef, (byte)0x0b, (byte)0x7c, (byte)0x45
        };
        // Generate secret key
        SecretKeyFactory desFactory
            = SecretKeyFactory.getInstance("DES", "SunJCE");
        DESKeySpec keySpec = new DESKeySpec(keyData);
        sKey = desFactory.generateSecret(keySpec);

        // encrypt data
        System.out.println("DataToEncrypt:");
        printBuffer(dataToEncrypt);

        IvParamSpec = new IvParameterSpec(iv, 0, 8);
        newDES.init(Cipher.ENCRYPT_MODE, sKey, IvParamSpec);

        encryptedData =
            new byte[newDES.getOutputSize(dataToEncrypt.length)];
        int outputLenUpdate = newDES.update(dataToEncrypt, 0,
                                            dataToEncrypt.length,
                                            encryptedData);
        int outputLenFinal = newDES.doFinal(encryptedData,
                                            outputLenUpdate);

        System.out.println("ENCRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("ENCRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Encrypted data:");
        printBuffer(encryptedData);

        // decrypt data
        newDES.init(Cipher.DECRYPT_MODE, sKey, IvParamSpec);

        decryptedData =
            new byte[newDES.getOutputSize(encryptedData.length)];
        System.out.println("encrLen: " + encryptedData.length);
        System.out.println("decrLen: " + decryptedData.length);

        outputLenUpdate = newDES.update(encryptedData, 0,
                                        encryptedData.length,
                                        decryptedData, 0);

        outputLenFinal = newDES.doFinal(decryptedData,
                                        outputLenUpdate);

        System.out.println("DECRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("DECRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Decrypted data:");
        printBuffer(decryptedData);
        int len = 0;
        if (dataToEncrypt.length >= decryptedData.length)
            len = decryptedData.length;
        else
            len = dataToEncrypt.length;
        for (int i=0; i<len; i++)
            if (dataToEncrypt[i] != decryptedData[i])
                throw new Exception("Original and recovered data differ");

        // decrypt data with exact output buffer length
        newDES.init(Cipher.DECRYPT_MODE, sKey, IvParamSpec);

        decryptedData = new byte[dataToEncrypt.length];
        System.out.println("encrLen: " + encryptedData.length);
        System.out.println("decrLen: " + decryptedData.length);

        outputLenUpdate = newDES.update(encryptedData, 0,
                                        encryptedData.length,
                                        decryptedData, 0);

        outputLenFinal = newDES.doFinal(decryptedData,
                                        outputLenUpdate);

        System.out.println("DECRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("DECRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Decrypted data:");
        printBuffer(decryptedData);
        len = 0;
        if (dataToEncrypt.length >= decryptedData.length)
            len = decryptedData.length;
        else
            len = dataToEncrypt.length;
        for (int i=0; i<len; i++)
            if (dataToEncrypt[i] != decryptedData[i])
                throw new Exception("Original and recovered data differ");

        //
        // run the same test for the input data with uneven number of bytes
        //

        // encrypt data
        System.out.println();
        System.out.println("DataToEncrypt:");
        printBuffer(dataToEncryptUneven);

        newDES.init(Cipher.ENCRYPT_MODE, sKey, IvParamSpec);

        encryptedData =
            new byte[newDES.getOutputSize(dataToEncryptUneven.length)];
        outputLenUpdate = newDES.update(dataToEncryptUneven, 0,
                                        dataToEncryptUneven.length,
                                        encryptedData);
        outputLenFinal = newDES.doFinal(encryptedData,
                                        outputLenUpdate);

        System.out.println("ENCRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("ENCRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Encrypted data:");
        printBuffer(encryptedData);

        // decrypt data
        newDES.init(Cipher.DECRYPT_MODE, sKey, IvParamSpec);

        decryptedData =
            new byte[newDES.getOutputSize(encryptedData.length)];
        System.out.println("encrLen: " + encryptedData.length);
        System.out.println("decrLen: " + decryptedData.length);

        outputLenUpdate = newDES.update(encryptedData, 0,
                                        encryptedData.length,
                                        decryptedData, 0);

        outputLenFinal = newDES.doFinal(decryptedData,
                                        outputLenUpdate);

        System.out.println("DECRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("DECRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Decrypted data:");
        printBuffer(decryptedData);
        len = 0;
        if (dataToEncryptUneven.length >= decryptedData.length)
            len = decryptedData.length;
        else
            len = dataToEncryptUneven.length;
        for (int i=0; i<len; i++)
            if (dataToEncryptUneven[i] != decryptedData[i])
                throw new Exception("Original and recovered data differ");

        // decrypt data with exact output buffer length
        newDES.init(Cipher.DECRYPT_MODE, sKey, IvParamSpec);

        decryptedData = new byte[dataToEncryptUneven.length];
        System.out.println("encrLen: " + encryptedData.length);
        System.out.println("decrLen: " + decryptedData.length);

        outputLenUpdate = newDES.update(encryptedData, 0,
                                        encryptedData.length,
                                        decryptedData, 0);

        outputLenFinal = newDES.doFinal(decryptedData,
                                        outputLenUpdate);

        System.out.println("DECRYPT : Update " + outputLenUpdate
                           + " bytes");
        System.out.println("DECRYPT : Final " + outputLenFinal
                           + " bytes");

        System.out.println("Decrypted data:");
        printBuffer(decryptedData);
        len = 0;
        if (dataToEncryptUneven.length >= decryptedData.length)
            len = decryptedData.length;
        else
            len = dataToEncryptUneven.length;
        for (int i=0; i<len; i++)
            if (dataToEncryptUneven[i] != decryptedData[i])
                throw new Exception("Original and recovered data differ");

        System.out.println();
        System.out.println("Test succeeded");
    }

    // These methods print out a byte array in a reasonably pretty format.
    private static void printBuffer(byte[] byteArray) {
        printBuffer(byteArray, byteArray.length);
    }

    private static void printBuffer(byte[] byteArray, int length) {
        StringBuffer textLine = new StringBuffer("                ");
        System.out.print("; 00000000: ");
        for (int i=0; i < length; i++) {
            if (((i%16) == 0) && i != 0) {
                System.out.println("[" + textLine + "]");
                System.out.print("; ");
                hexPrint(i, 8);
                System.out.print(": ");
                for(int j=0; j<16; j++) {
                    textLine.setCharAt(j,' ');
                }
            }
            hexPrint((int) byteArray[i], 2);
            System.out.print(" ");
            if ((byteArray[i] < 32) || (byteArray[i] > 127)) {
                textLine.setCharAt(i%16, '.');
            } else {
                textLine.setCharAt(i%16,(char)byteArray[i]);
            }
        }
        if (((length % 16) != 0) || (length == 0)) {
            for (int i = 0; i < 16 - (length % 16); i++) {
                System.out.print("   ");
            }
        }
        System.out.println("[" + textLine + "]");
    }

    private static void hexPrint(int value, int padding) {
        String hexString = new String("0123456789ABCDEF");
        for (int i = (padding - 1); i >= 0; i--) {
            System.out.print(hexString.charAt((value >> (i*4)) & 0xF));
        }
    }
}
