/*
 * Copyright 2004-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.security.krb5.internal.crypto.dk;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.spec.KeySpec;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.util.Arrays;

public class Des3DkCrypto extends DkCrypto {

    private static final byte[] ZERO_IV = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};

    public Des3DkCrypto() {
    }

    protected int getKeySeedLength() {
        return 168;   // bits; 3DES key material has 21 bytes
    }

    public byte[] stringToKey(char[] salt) throws GeneralSecurityException {
        byte[] saltUtf8 = null;
        try {
            saltUtf8 = charToUtf8(salt);
            return stringToKey(saltUtf8, null);
        } finally {
            if (saltUtf8 != null) {
                Arrays.fill(saltUtf8, (byte)0);
            }
            // Caller responsible for clearing its own salt
        }
    }

    private byte[] stringToKey(byte[] secretAndSalt, byte[] opaque)
        throws GeneralSecurityException {

        if (opaque != null && opaque.length > 0) {
            throw new RuntimeException("Invalid parameter to stringToKey");
        }

        byte[] tmpKey = randomToKey(nfold(secretAndSalt, getKeySeedLength()));
        return dk(tmpKey, KERBEROS_CONSTANT);
    }

    public byte[] parityFix(byte[] value)
        throws GeneralSecurityException {
        // fix key parity
        setParityBit(value);
        return value;
    }

    /*
     * From RFC 3961.
     *
     * The 168 bits of random key data are converted to a protocol key value
     * as follows.  First, the 168 bits are divided into three groups of 56
     * bits, which are expanded individually into 64 bits as in des3Expand().
     * Result is a 24 byte (192-bit) key.
     */
    protected byte[] randomToKey(byte[] in) {
        if (in.length != 21) {
            throw new IllegalArgumentException("input must be 168 bits");
        }

        byte[] one = keyCorrection(des3Expand(in, 0, 7));
        byte[] two = keyCorrection(des3Expand(in, 7, 14));
        byte[] three = keyCorrection(des3Expand(in, 14, 21));

        byte[] key = new byte[24];
        System.arraycopy(one, 0, key, 0, 8);
        System.arraycopy(two, 0, key, 8, 8);
        System.arraycopy(three, 0, key, 16, 8);

        return key;
    }

    private static byte[] keyCorrection(byte[] key) {
        // check for weak key
        try {
            if (DESKeySpec.isWeak(key, 0)) {
                key[7] = (byte)(key[7] ^ 0xF0);
            }
        } catch (InvalidKeyException ex) {
            // swallow, since it should never happen
        }
        return key;
    }

    /**
     * From RFC 3961.
     *
     * Expands a 7-byte array into an 8-byte array that contains parity bits.
     * The 56 bits are expanded into 64 bits as follows:
     *   1  2  3  4  5  6  7  p
     *   9 10 11 12 13 14 15  p
     *   17 18 19 20 21 22 23  p
     *   25 26 27 28 29 30 31  p
     *   33 34 35 36 37 38 39  p
     *   41 42 43 44 45 46 47  p
     *   49 50 51 52 53 54 55  p
     *   56 48 40 32 24 16  8  p
     *
     * (PI,P2,...,P8) are reserved for parity bits computed on the preceding
     * seven independent bits and set so that the parity of the octet is odd,
     * i.e., there is an odd number of "1" bits in the octet.
     *
     * @param start index of starting byte (inclusive)
     * @param end index of ending byte (exclusive)
     */
    private static byte[] des3Expand(byte[] input, int start, int end) {
        if ((end - start) != 7)
            throw new IllegalArgumentException(
                "Invalid length of DES Key Value:" + start + "," + end);

        byte[] result = new byte[8];
        byte last = 0;
        System.arraycopy(input, start, result, 0, 7);
        byte posn = 0;

        // Fill in last row
        for (int i = start; i < end; i++) {
            byte bit = (byte) (input[i]&0x01);
            if (debug) {
                System.out.println(i + ": " + Integer.toHexString(input[i]) +
                    " bit= " + Integer.toHexString(bit));
            }
            ++posn;
            if (bit != 0) {
                last |= (bit<<posn);
            }
        }

        if (debug) {
            System.out.println("last: " + Integer.toHexString(last));
        }
        result[7] = last;
        setParityBit(result);
        return result;
    }

    /* Mask used to check for parity adjustment */
    private static final byte[] PARITY_BIT_MASK = {
        (byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10,
        (byte)0x08, (byte)0x04, (byte)0x02
    };

    /**
     * Sets the parity bit (0th bit) in each byte so that each byte
     * contains an odd number of 1's.
     */
    private static void setParityBit(byte[] key) {
        for (int i = 0; i < key.length; i++) {
            int bitCount = 0;
            for (int maskIndex = 0;
                 maskIndex < PARITY_BIT_MASK.length; maskIndex++) {
                if ((key[i] & PARITY_BIT_MASK[maskIndex])
                    == PARITY_BIT_MASK[maskIndex]) {
                    bitCount++;
                }
            }
            if ((bitCount & 0x01) == 1) {
                // Odd number of 1 bits in the top 7 bits. Set parity bit to 0
                key[i] = (byte)(key[i] & (byte)0xfe);
            } else {
                // Even number of 1 bits in the top 7 bits. Set parity bit to 1
                key[i] = (byte)(key[i] | 1);
            }
        }
    }

    protected Cipher getCipher(byte[] key, byte[] ivec, int mode)
        throws GeneralSecurityException {
        // NoSuchAlgorithException
        SecretKeyFactory factory = SecretKeyFactory.getInstance("desede");

        // InvalidKeyException
        KeySpec spec = new DESedeKeySpec(key, 0);

        // InvalidKeySpecException
        SecretKey secretKey = factory.generateSecret(spec);

        // IV
        if (ivec == null) {
            ivec = ZERO_IV;
        }

        // NoSuchAlgorithmException, NoSuchPaddingException
        // NoSuchProviderException
        Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
        IvParameterSpec encIv = new IvParameterSpec(ivec, 0, ivec.length);

        // InvalidKeyException, InvalidAlgorithParameterException
        cipher.init(mode, secretKey, encIv);

        return cipher;
    }

    public int getChecksumLength() {
        return 20;  // bytes
    }

    protected byte[] getHmac(byte[] key, byte[] msg)
        throws GeneralSecurityException {

        SecretKey keyKi = new SecretKeySpec(key, "HmacSHA1");
        Mac m = Mac.getInstance("HmacSHA1");
        m.init(keyKi);
        return m.doFinal(msg);
    }
}
