directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [05/42] directory-kerberos git commit: Initially import Haox codebase (https://github.com/drankye/haox)
Date Sat, 10 Jan 2015 13:30:49 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiCmacEnc.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
new file mode 100644
index 0000000..2342c82
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
@@ -0,0 +1,34 @@
+package org.apache.kerberos.kerb.crypto.enc;
+
+import org.apache.kerberos.kerb.crypto.Cmac;
+import org.apache.kerberos.kerb.KrbException;
+
+public abstract class KeKiCmacEnc extends KeKiEnc {
+
+    public KeKiCmacEnc(EncryptProvider encProvider) {
+        super(encProvider, null);
+    }
+
+    @Override
+    public int paddingSize() {
+        return 0;
+    }
+
+    @Override
+    public int checksumSize() {
+        return encProvider().blockSize();
+    }
+
+    @Override
+    protected byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+            throws KrbException {
+
+        // generate hash
+        byte[] hash = Cmac.cmac(encProvider(), key, data);
+
+        // truncate hash
+        byte[] output = new byte[hashSize];
+        System.arraycopy(hash, 0, output, 0, hashSize);
+        return output;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiEnc.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiEnc.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiEnc.java
new file mode 100644
index 0000000..5e49a35
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiEnc.java
@@ -0,0 +1,110 @@
+package org.apache.kerberos.kerb.crypto.enc;
+
+import org.apache.kerberos.kerb.KrbErrorCode;
+import org.apache.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerberos.kerb.crypto.Confounder;
+import org.apache.kerberos.kerb.crypto.cksum.HashProvider;
+import org.apache.kerberos.kerb.crypto.key.DkKeyMaker;
+import org.apache.kerberos.kerb.KrbException;
+
+public abstract class KeKiEnc extends AbstractEncTypeHandler {
+
+    public KeKiEnc(EncryptProvider encProvider,
+                   HashProvider hashProvider) {
+        super(encProvider, hashProvider);
+    }
+
+    @Override
+    public int paddingSize() {
+        return 0;
+    }
+
+
+    @Override
+    protected void encryptWith(byte[] workBuffer, int[] workLens,
+                               byte[] key, byte[] iv, int usage) throws KrbException {
+        int confounderLen = workLens[0];
+        int checksumLen = workLens[1];
+        int inputLen = workLens[2];
+        int paddingLen = workLens[3];
+
+        byte[] Ke, Ki;
+        byte[] constant = new byte[5];
+        constant[0] = (byte) ((usage>>24)&0xff);
+        constant[1] = (byte) ((usage>>16)&0xff);
+        constant[2] = (byte) ((usage>>8)&0xff);
+        constant[3] = (byte) (usage&0xff);
+        constant[4] = (byte) 0xaa;
+        Ke = ((DkKeyMaker) keyMaker()).dk(key, constant);
+        constant[4] = (byte) 0x55;
+        Ki = ((DkKeyMaker) keyMaker()).dk(key, constant);
+
+        /**
+         * Instead of E(Confounder | Checksum | Plaintext | Padding),
+         * E(Confounder | Plaintext | Padding) | Checksum,
+         * so need to adjust the workBuffer arrangement
+         */
+
+        byte[] tmpEnc = new byte[confounderLen + inputLen + paddingLen];
+        // confounder
+        byte[] confounder = Confounder.makeBytes(confounderLen);
+        System.arraycopy(confounder, 0, tmpEnc, 0, confounderLen);
+
+        // data
+        System.arraycopy(workBuffer, confounderLen + checksumLen,
+                tmpEnc, confounderLen, inputLen);
+
+        // padding
+        for (int i = confounderLen + inputLen; i < paddingLen; ++i) {
+            tmpEnc[i] = 0;
+        }
+
+        // checksum & encrypt
+        byte[] checksum;
+        checksum = makeChecksum(Ki, tmpEnc, checksumLen);
+        encProvider().encrypt(Ke, iv, tmpEnc);
+
+        System.arraycopy(tmpEnc, 0, workBuffer, 0, tmpEnc.length);
+        System.arraycopy(checksum, 0, workBuffer, tmpEnc.length, checksum.length);
+    }
+
+    @Override
+    protected byte[] decryptWith(byte[] workBuffer, int[] workLens,
+                                 byte[] key, byte[] iv, int usage) throws KrbException {
+        int confounderLen = workLens[0];
+        int checksumLen = workLens[1];
+        int dataLen = workLens[2];
+
+        byte[] Ke, Ki;
+        byte[] constant = new byte[5];
+        BytesUtil.int2bytes(usage, constant, 0, true);
+        constant[4] = (byte) 0xaa;
+        Ke = ((DkKeyMaker) keyMaker()).dk(key, constant);
+        constant[4] = (byte) 0x55;
+        Ki = ((DkKeyMaker) keyMaker()).dk(key, constant);
+
+        // decrypt and verify checksum
+
+        byte[] tmpEnc = new byte[confounderLen + dataLen];
+        System.arraycopy(workBuffer, 0,
+                tmpEnc, 0, confounderLen + dataLen);
+        byte[] checksum = new byte[checksumLen];
+        System.arraycopy(workBuffer, confounderLen + dataLen,
+                checksum, 0, checksumLen);
+
+        byte[] newChecksum;
+        encProvider().decrypt(Ke, iv, tmpEnc);
+        newChecksum = makeChecksum(Ki, tmpEnc, checksumLen);
+
+        if (! checksumEqual(checksum, newChecksum)) {
+            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BAD_INTEGRITY);
+        }
+
+        byte[] data = new byte[dataLen];
+        System.arraycopy(tmpEnc, confounderLen, data, 0, dataLen);
+        return data;
+    }
+
+    protected abstract byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+            throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
new file mode 100644
index 0000000..4d5e268
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
@@ -0,0 +1,31 @@
+package org.apache.kerberos.kerb.crypto.enc;
+
+import org.apache.kerberos.kerb.crypto.Hmac;
+import org.apache.kerberos.kerb.crypto.cksum.HashProvider;
+import org.apache.kerberos.kerb.KrbException;
+
+public abstract class KeKiHmacSha1Enc extends KeKiEnc {
+
+    public KeKiHmacSha1Enc(EncryptProvider encProvider,
+                           HashProvider hashProvider) {
+        super(encProvider, hashProvider);
+    }
+
+    @Override
+    public int paddingSize() {
+        return 0;
+    }
+
+    @Override
+    protected byte[] makeChecksum(byte[] key, byte[] data, int hashSize)
+            throws KrbException {
+
+        // generate hash
+        byte[] hash = Hmac.hmac(hashProvider(), key, data);
+
+        // truncate hash
+        byte[] output = new byte[hashSize];
+        System.arraycopy(hash, 0, output, 0, hashSize);
+        return output;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacEnc.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
new file mode 100644
index 0000000..070c748
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
@@ -0,0 +1,130 @@
+package org.apache.kerberos.kerb.crypto.enc;
+
+import org.apache.kerberos.kerb.KrbErrorCode;
+import org.apache.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerberos.kerb.crypto.Confounder;
+import org.apache.kerberos.kerb.crypto.Rc4;
+import org.apache.kerberos.kerb.crypto.Hmac;
+import org.apache.kerberos.kerb.crypto.cksum.provider.Md5Provider;
+import org.apache.kerberos.kerb.crypto.enc.provider.Rc4Provider;
+import org.apache.kerberos.kerb.crypto.key.Rc4KeyMaker;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.CheckSumType;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+
+public class Rc4HmacEnc extends AbstractEncTypeHandler {
+    private boolean exportable;
+
+    public Rc4HmacEnc() {
+        this(false);
+    }
+
+    public Rc4HmacEnc(boolean exportable) {
+        super(new Rc4Provider(), new Md5Provider());
+        keyMaker(new Rc4KeyMaker(this.encProvider()));
+        this.exportable = exportable;
+    }
+
+    public EncryptionType eType() {
+        return EncryptionType.ARCFOUR_HMAC;
+    }
+
+    @Override
+    public int confounderSize() {
+        return 8;
+    }
+
+    @Override
+    public int paddingSize() {
+        return 0;
+    }
+
+    public CheckSumType checksumType() {
+        return CheckSumType.HMAC_MD5_ARCFOUR;
+    }
+
+    protected void encryptWith(byte[] workBuffer, int[] workLens,
+         byte[] key, byte[] iv, int usage) throws KrbException {
+        int confounderLen = workLens[0];
+        int checksumLen = workLens[1];
+        int dataLen = workLens[2];
+
+        /**
+         * Instead of E(Confounder | Checksum | Plaintext | Padding),
+         * Checksum | E(Confounder | Plaintext)
+         */
+
+        // confounder
+        byte[] confounder = Confounder.makeBytes(confounderLen);
+        System.arraycopy(confounder, 0, workBuffer, checksumLen, confounderLen);
+
+        // no padding
+
+        /* checksum and encryption */
+        byte[] usageKey = makeUsageKey(key, usage);
+
+        byte[] checksum = Hmac.hmac(hashProvider(), usageKey, workBuffer,
+                checksumLen, confounderLen + dataLen);
+
+        byte[] encKey = makeEncKey(usageKey, checksum);
+
+        byte[] tmpEnc = new byte[confounderLen + dataLen];
+        System.arraycopy(workBuffer, checksumLen,
+                tmpEnc, 0, confounderLen + dataLen);
+        encProvider().encrypt(encKey, iv, tmpEnc);
+        System.arraycopy(checksum, 0, workBuffer, 0, checksumLen);
+        System.arraycopy(tmpEnc, 0, workBuffer, checksumLen, tmpEnc.length);
+    }
+
+    protected byte[] makeUsageKey(byte[] key, int usage) throws KrbException {
+        byte[] salt = Rc4.getSalt(usage, exportable);
+        byte[] usageKey = Hmac.hmac(hashProvider(), key, salt);
+        return usageKey;
+    }
+
+    protected byte[] makeEncKey(byte[] usageKey, byte[] checksum) throws KrbException {
+        byte[] tmpKey = usageKey;
+
+        if (exportable) {
+            tmpKey = BytesUtil.duplicate(usageKey);
+            for (int i = 0; i < 9; ++i) {
+                tmpKey[i + 7] = (byte) 0xab;
+            }
+        }
+
+        byte[] encKey = Hmac.hmac(hashProvider(), tmpKey, checksum);
+        return encKey;
+    }
+
+    @Override
+    protected byte[] decryptWith(byte[] workBuffer, int[] workLens,
+                                 byte[] key, byte[] iv, int usage) throws KrbException {
+        int confounderLen = workLens[0];
+        int checksumLen = workLens[1];
+        int dataLen = workLens[2];
+
+        /* checksum and decryption */
+        byte[] usageKey = makeUsageKey(key, usage);
+
+        byte[] checksum = new byte[checksumLen];
+        System.arraycopy(workBuffer, 0, checksum, 0, checksumLen);
+
+        byte[] encKey = makeEncKey(usageKey, checksum);
+
+        byte[] tmpEnc = new byte[confounderLen + dataLen];
+        System.arraycopy(workBuffer, checksumLen,
+                tmpEnc, 0, confounderLen + dataLen);
+        encProvider().decrypt(encKey, iv, tmpEnc);
+
+        byte[] newChecksum = Hmac.hmac(hashProvider(), usageKey, tmpEnc);
+        if (! checksumEqual(checksum, newChecksum)) {
+            throw new KrbException(KrbErrorCode.KRB_AP_ERR_BAD_INTEGRITY);
+        }
+
+        byte[] data = new byte[dataLen];
+        System.arraycopy(tmpEnc, confounderLen,
+                data, 0, dataLen);
+
+        return data;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
new file mode 100644
index 0000000..adfde46
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/Rc4HmacExpEnc.java
@@ -0,0 +1,14 @@
+package org.apache.kerberos.kerb.crypto.enc;
+
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+
+public class Rc4HmacExpEnc extends Rc4HmacEnc {
+
+    public Rc4HmacExpEnc() {
+        super(true);
+    }
+
+    public EncryptionType eType() {
+        return EncryptionType.ARCFOUR_HMAC_EXP;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
new file mode 100644
index 0000000..9d35e7a
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
@@ -0,0 +1,80 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerberos.kerb.KrbException;
+
+public abstract class AbstractEncryptProvider implements EncryptProvider {
+    private int blockSize;
+    private int keyInputSize;
+    private int keySize;
+
+    public AbstractEncryptProvider(int blockSize, int keyInputSize, int keySize) {
+        this.blockSize = blockSize;
+        this.keyInputSize = keyInputSize;
+        this.keySize = keySize;
+    }
+
+    @Override
+    public int keyInputSize() {
+        return keyInputSize;
+    }
+
+    @Override
+    public int keySize() {
+        return keySize;
+    }
+
+    @Override
+    public int blockSize() {
+        return blockSize;
+    }
+
+    @Override
+    public byte[] initState(byte[] key, int keyUsage) {
+        return new byte[0];
+    }
+
+    @Override
+    public void encrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+        doEncrypt(data, key, cipherState, true);
+    }
+
+    @Override
+    public void decrypt(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+        doEncrypt(data, key, cipherState, false);
+    }
+
+    @Override
+    public void encrypt(byte[] key, byte[] data) throws KrbException {
+        byte[] cipherState = new byte[blockSize()];
+        encrypt(key, cipherState, data);
+    }
+
+    @Override
+    public void decrypt(byte[] key, byte[] data) throws KrbException {
+        byte[] cipherState = new byte[blockSize()];
+        decrypt(key, cipherState, data);
+    }
+
+    protected abstract void doEncrypt(byte[] data, byte[] key, byte[] cipherState, boolean encrypt) throws KrbException;
+
+    @Override
+    public byte[] cbcMac(byte[] key, byte[] iv, byte[] data) throws KrbException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean supportCbcMac() {
+        return false;
+    }
+
+    @Override
+    public void cleanState() {
+
+    }
+
+    @Override
+    public void cleanKey() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes128Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
new file mode 100644
index 0000000..2efd4f0
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes128Provider.java
@@ -0,0 +1,8 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+public class Aes128Provider extends AesProvider {
+
+    public Aes128Provider() {
+        super(16, 16, 16);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes256Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
new file mode 100644
index 0000000..377de2b
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Aes256Provider.java
@@ -0,0 +1,8 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+public class Aes256Provider extends AesProvider {
+
+    public Aes256Provider() {
+        super(16, 32, 32);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AesProvider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AesProvider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AesProvider.java
new file mode 100644
index 0000000..d2ecf6a
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/AesProvider.java
@@ -0,0 +1,43 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public abstract class AesProvider extends AbstractEncryptProvider {
+
+    public AesProvider(int blockSize, int keyInputSize, int keySize) {
+        super(blockSize, keyInputSize, keySize);
+    }
+
+    @Override
+    protected void doEncrypt(byte[] data, byte[] key,
+                                  byte[] cipherState, boolean encrypt) throws KrbException {
+        Cipher cipher = null;
+        try {
+            cipher = Cipher.getInstance("AES/CTS/NoPadding");
+        } catch (GeneralSecurityException e) {
+            KrbException ke = new KrbException("JCE provider may not be installed. "
+                    + e.getMessage());
+            ke.initCause(e);
+            throw ke;
+        }
+
+        try {
+            SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
+            IvParameterSpec param = new IvParameterSpec(cipherState);
+
+            cipher.init(encrypt ?
+                    Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, param);
+            byte[] output = cipher.doFinal(data);
+            System.arraycopy(output, 0, data, 0, output.length);
+        } catch (GeneralSecurityException e) {
+            KrbException ke = new KrbException(e.getMessage());
+            ke.initCause(e);
+            throw ke;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
new file mode 100644
index 0000000..3e8efaa
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia128Provider.java
@@ -0,0 +1,8 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+public class Camellia128Provider extends CamelliaProvider {
+
+    public Camellia128Provider() {
+        super(16, 16, 16);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
new file mode 100644
index 0000000..66efdb7
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Camellia256Provider.java
@@ -0,0 +1,8 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+public class Camellia256Provider extends CamelliaProvider {
+
+    public Camellia256Provider() {
+        super(16, 32, 32);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
new file mode 100644
index 0000000..0e8e7b6
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
@@ -0,0 +1,39 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.crypto.Camellia;
+import org.apache.kerberos.kerb.KrbException;
+
+public abstract class CamelliaProvider extends AbstractEncryptProvider {
+
+    public CamelliaProvider(int blockSize, int keyInputSize, int keySize) {
+        super(blockSize, keyInputSize, keySize);
+    }
+
+    @Override
+    protected void doEncrypt(byte[] data, byte[] key,
+                             byte[] cipherState, boolean encrypt) throws KrbException {
+
+        Camellia cipher = new Camellia();
+        cipher.setKey(encrypt, key);
+        if (encrypt) {
+            cipher.encrypt(data, cipherState);
+        } else {
+            cipher.decrypt(data, cipherState);
+        }
+    }
+
+    @Override
+    public boolean supportCbcMac() {
+        return true;
+    }
+
+    @Override
+    public byte[] cbcMac(byte[] key, byte[] cipherState, byte[] data) {
+        Camellia cipher = new Camellia();
+        cipher.setKey(true, key);
+
+        int blocksNum = data.length / blockSize();
+        cipher.cbcEnc(data, 0, blocksNum, cipherState);
+        return data;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Des3Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Des3Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Des3Provider.java
new file mode 100644
index 0000000..a2b7e28
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Des3Provider.java
@@ -0,0 +1,46 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.GeneralSecurityException;
+import java.security.spec.KeySpec;
+
+public class Des3Provider extends AbstractEncryptProvider {
+
+    public Des3Provider() {
+        super(8, 21, 24);
+    }
+
+    @Override
+    protected void doEncrypt(byte[] input, byte[] key,
+                             byte[] cipherState, boolean encrypt) throws KrbException {
+
+        Cipher cipher = null;
+        try {
+            cipher = Cipher.getInstance("DESede/CBC/NoPadding");
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("Failed to init cipher", e);
+        }
+
+        try {
+            IvParameterSpec params = new IvParameterSpec(cipherState);
+            KeySpec skSpec = new DESedeKeySpec(key, 0);
+
+            SecretKeyFactory skf = SecretKeyFactory.getInstance("desede");
+            SecretKey secretKey = skf.generateSecret(skSpec);
+
+            cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, params);
+
+            byte[] output = cipher.doFinal(input);
+            System.arraycopy(output, 0, input, 0, output.length);
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("Failed to doEncrypt", e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/DesProvider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/DesProvider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/DesProvider.java
new file mode 100644
index 0000000..9a35500
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/DesProvider.java
@@ -0,0 +1,79 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public class DesProvider extends AbstractEncryptProvider {
+
+    public DesProvider() {
+        super(8, 7, 8);
+    }
+
+    @Override
+    protected void doEncrypt(byte[] input, byte[] key,
+                                 byte[] cipherState, boolean encrypt) throws KrbException {
+
+        Cipher cipher = null;
+        try {
+            cipher = Cipher.getInstance("DES/CBC/NoPadding");
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("Failed to init cipher", e);
+        }
+        IvParameterSpec params = new IvParameterSpec(cipherState);
+        SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
+        try {
+            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
+            SecretKey sk = (SecretKey) skSpec;
+
+            cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, sk, params);
+
+            byte[] output = cipher.doFinal(input);
+            System.arraycopy(output, 0, input, 0, output.length);
+        } catch (GeneralSecurityException e) {
+            KrbException ke = new KrbException(e.getMessage());
+            ke.initCause(e);
+            throw ke;
+        }
+    }
+
+    @Override
+    public byte[] cbcMac(byte[] key, byte[] cipherState, byte[] data) throws KrbException {
+        Cipher cipher = null;
+        try {
+            cipher = Cipher.getInstance("DES/CBC/NoPadding");
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("Failed to init cipher", e);
+        }
+        IvParameterSpec params = new IvParameterSpec(cipherState);
+        SecretKeySpec skSpec = new SecretKeySpec(key, "DES");
+
+        byte[] output = null;
+        try {
+            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
+            // SecretKey sk = skf.generateSecret(skSpec);
+            SecretKey sk = (SecretKey) skSpec;
+            cipher.init(Cipher.ENCRYPT_MODE, sk, params);
+            for (int i = 0; i < data.length / 8; i++) {
+                output = cipher.doFinal(data, i * 8, 8);
+                cipher.init(Cipher.ENCRYPT_MODE, sk, (new IvParameterSpec(output)));
+            }
+        }
+        catch (GeneralSecurityException e) {
+            KrbException ke = new KrbException(e.getMessage());
+            ke.initCause(e);
+            throw ke;
+        }
+        return output;
+    }
+
+    @Override
+    public boolean supportCbcMac() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Rc4Provider.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
new file mode 100644
index 0000000..3fbfece
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/enc/provider/Rc4Provider.java
@@ -0,0 +1,30 @@
+package org.apache.kerberos.kerb.crypto.enc.provider;
+
+import org.apache.kerberos.kerb.KrbException;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.GeneralSecurityException;
+
+public class Rc4Provider extends AbstractEncryptProvider {
+
+    public Rc4Provider() {
+        super(1, 16, 16);
+    }
+
+    @Override
+    protected void doEncrypt(byte[] data, byte[] key,
+                             byte[] cipherState, boolean encrypt) throws KrbException {
+        try {
+            Cipher cipher = Cipher.getInstance("ARCFOUR");
+            SecretKeySpec secretKey = new SecretKeySpec(key, "ARCFOUR");
+            cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey);
+            byte[] output = cipher.doFinal(data);
+            System.arraycopy(output, 0, data, 0, output.length);
+        } catch (GeneralSecurityException e) {
+            KrbException ke = new KrbException(e.getMessage());
+            ke.initCause(e);
+            throw ke;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AbstractKeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AbstractKeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AbstractKeyMaker.java
new file mode 100644
index 0000000..5e12151
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AbstractKeyMaker.java
@@ -0,0 +1,67 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerberos.kerb.KrbException;
+
+import java.io.UnsupportedEncodingException;
+
+public abstract class AbstractKeyMaker implements KeyMaker {
+
+    protected static final byte[] KERBEROS_CONSTANT = "kerberos".getBytes();
+
+    private EncryptProvider encProvider;
+
+    public AbstractKeyMaker(EncryptProvider encProvider) {
+        this.encProvider = encProvider;
+    }
+
+    protected EncryptProvider encProvider() {
+        return encProvider;
+    }
+
+    @Override
+    public byte[] random2Key(byte[] randomBits) throws KrbException {
+        return new byte[0];
+    }
+
+    protected static char[] makePasswdSalt(String password, String salt) {
+        char[] result = new char[password.length() + salt.length()];
+        System.arraycopy(password.toCharArray(), 0, result, 0, password.length());
+        System.arraycopy(salt.toCharArray(), 0, result, password.length(), salt.length());
+
+        return result;
+    }
+
+    protected static int getIterCount(byte[] param, int defCount) {
+        int iterCount = defCount;
+
+        if (param != null) {
+            if (param.length != 4) {
+                throw new IllegalArgumentException("Invalid param to str2Key");
+            }
+            iterCount = BytesUtil.bytes2int(param, 0, true);
+        }
+
+        return iterCount;
+    }
+
+    protected static byte[] getSaltBytes(String salt, String pepper)
+            throws UnsupportedEncodingException {
+        byte[] saltBytes = salt.getBytes("UTF-8");
+        if (pepper != null && ! pepper.isEmpty()) {
+            byte[] pepperBytes = pepper.getBytes("UTF-8");
+            int len = saltBytes.length;
+            len += 1 + pepperBytes.length;
+            byte[] results = new byte[len];
+            System.arraycopy(pepperBytes, 0, results, 0, pepperBytes.length);
+            results[pepperBytes.length] = (byte) 0;
+            System.arraycopy(saltBytes, 0,
+                    results, pepperBytes.length + 1, saltBytes.length);
+
+            return results;
+        } else {
+            return saltBytes;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AesKeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AesKeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AesKeyMaker.java
new file mode 100644
index 0000000..7317657
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/AesKeyMaker.java
@@ -0,0 +1,46 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerberos.kerb.crypto.enc.provider.AesProvider;
+
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+
+public class AesKeyMaker extends DkKeyMaker {
+
+    public AesKeyMaker(AesProvider encProvider) {
+        super(encProvider);
+    }
+
+    @Override
+    public byte[] random2Key(byte[] randomBits) throws KrbException {
+        return randomBits;
+    }
+
+    @Override
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+        int iterCount = getIterCount(param, 4096);
+
+        byte[] saltBytes = null;
+        try {
+            saltBytes = getSaltBytes(salt, null);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+        int keySize = encProvider().keySize();
+        byte[] random = new byte[0];
+        try {
+            random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("PBKDF2 failed", e);
+        }
+
+        byte[] tmpKey = random2Key(random);
+        byte[] result = dk(tmpKey, KERBEROS_CONSTANT);
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/CamelliaKeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
new file mode 100644
index 0000000..2d89178
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
@@ -0,0 +1,102 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerberos.kerb.crypto.Cmac;
+import org.apache.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerberos.kerb.crypto.enc.provider.CamelliaProvider;
+import org.apache.kerberos.kerb.KrbException;
+
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+
+public class CamelliaKeyMaker extends DkKeyMaker {
+
+    public CamelliaKeyMaker(CamelliaProvider encProvider) {
+        super(encProvider);
+    }
+
+    @Override
+    public byte[] random2Key(byte[] randomBits) throws KrbException {
+        return randomBits;
+    }
+
+    @Override
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+        int iterCount = getIterCount(param, 32768);
+
+        byte[] saltBytes = null;
+        try {
+            saltBytes = getSaltBytes(salt, getPepper());
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+        int keySize = encProvider().keySize();
+        byte[] random = new byte[0];
+        try {
+            random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
+        } catch (GeneralSecurityException e) {
+            throw new KrbException("PBKDF2 failed", e);
+        }
+
+        byte[] tmpKey = random2Key(random);
+        byte[] result = dk(tmpKey, KERBEROS_CONSTANT);
+
+        return result;
+    }
+
+    private String getPepper() {
+        int keySize = encProvider().keySize();
+        String pepper = keySize == 16 ? "camellia128-cts-cmac" : "camellia256-cts-cmac";
+        return pepper;
+    }
+
+    /*
+     * NIST SP800-108 KDF in feedback mode (section 5.2).
+     */
+    @Override
+    protected byte[] dr(byte[] key, byte[] constant) throws KrbException {
+
+        int blocksize = encProvider().blockSize();
+        int keyInuptSize = encProvider().keyInputSize();
+        byte[] keyBytes = new byte[keyInuptSize];
+        byte[] Ki;
+
+        int len = 0;
+        // K(i-1): the previous block of PRF output, initially all-zeros.
+        len += blocksize;
+        // four-byte big-endian binary string giving the block counter
+        len += 4;
+        // the fixed derived-key input
+        len += constant.length;
+        // 0x00: separator byte
+        len += 1;
+        // four-byte big-endian binary string giving the output length
+        len += 4;
+
+        Ki = new byte[len];
+        System.arraycopy(constant, 0, Ki, blocksize + 4, constant.length);
+        BytesUtil.int2bytes(keyInuptSize * 8, Ki, len - 4, true);
+
+        int i, n = 0;
+        byte[] tmp;
+        for (i = 1, n = 0; n < keyInuptSize; i++) {
+            // Update the block counter
+            BytesUtil.int2bytes(i, Ki, blocksize, true);
+
+            // Compute a CMAC checksum, update Ki with the result
+            tmp = Cmac.cmac(encProvider(), key, Ki);
+            System.arraycopy(tmp, 0, Ki, 0, blocksize);
+
+            if (n + blocksize >= keyInuptSize) {
+                System.arraycopy(Ki, 0, keyBytes, n, keyInuptSize - n);
+                break;
+            }
+
+            System.arraycopy(Ki, 0, keyBytes, n, blocksize);
+            n += blocksize;
+        }
+
+        return keyBytes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Des3KeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Des3KeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Des3KeyMaker.java
new file mode 100644
index 0000000..533f551
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Des3KeyMaker.java
@@ -0,0 +1,67 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.Des;
+import org.apache.kerberos.kerb.crypto.Nfold;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+
+import java.io.UnsupportedEncodingException;
+
+public class Des3KeyMaker extends DkKeyMaker {
+
+    public Des3KeyMaker(EncryptProvider encProvider) {
+        super(encProvider);
+    }
+
+    @Override
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+        char[] passwdSalt = makePasswdSalt(string, salt);
+        int keyInputSize = encProvider().keyInputSize();
+        try {
+            byte[] utf8Bytes = new String(passwdSalt).getBytes("UTF-8");
+            byte[] tmpKey = random2Key(Nfold.nfold(utf8Bytes, keyInputSize));
+            return dk(tmpKey, KERBEROS_CONSTANT);
+        } catch (UnsupportedEncodingException e) {
+            throw new KrbException("str2key failed", e);
+        }
+    }
+
+    @Override
+    public byte[] random2Key(byte[] randomBits) throws KrbException {
+        if (randomBits.length != encProvider().keyInputSize()) {
+            throw new KrbException("Invalid random bits, not of correct bytes size");
+        }
+        /**
+         * Ref. k5_rand2key_des3 in random_to_key.c in MIT krb5
+         * Take the seven bytes, move them around into the top 7 bits of the
+         * 8 key bytes, then compute the parity bits.  Do this three times.
+         */
+        byte[] key = new byte[encProvider().keySize()];
+        int nthByte;
+        int tmp;
+        for (int i = 0; i < 3; i++) {
+            System.arraycopy(randomBits, i * 7, key, i * 8, 7);
+            nthByte = i * 8;
+
+            key[nthByte + 7] = (byte) (((key[nthByte + 0] & 1) << 1) |
+                    ((key[nthByte + 1] & 1) << 2) |
+                    ((key[nthByte + 2] & 1) << 3) |
+                    ((key[nthByte + 3] & 1) << 4) |
+                    ((key[nthByte + 4] & 1) << 5) |
+                    ((key[nthByte + 5] & 1) << 6) |
+                    ((key[nthByte + 6] & 1) << 7));
+
+            for (int j = 0; j < 8; j++) {
+                tmp = key[nthByte + j] & 0xfe;
+                tmp |= (Integer.bitCount(tmp) & 1) ^ 1;
+                key[nthByte + j] = (byte) tmp;
+            }
+        }
+
+        for (int i = 0; i < 3; i++) {
+            Des.fixKey(key, i * 8, 8);
+        }
+
+        return key;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DesKeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DesKeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DesKeyMaker.java
new file mode 100644
index 0000000..4a8dc56
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DesKeyMaker.java
@@ -0,0 +1,260 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerberos.kerb.crypto.Des;
+import org.apache.kerberos.kerb.crypto.Util;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+
+public class DesKeyMaker extends AbstractKeyMaker {
+
+    public DesKeyMaker(EncryptProvider encProvider) {
+        super(encProvider);
+    }
+
+    @Override
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+        String error = null;
+        int type = 0;
+
+        if (param != null) {
+            if (param.length != 1) {
+                error = "Invalid param to S2K";
+            }
+            type = param[0];
+            if (type != 0 && type != 1) {
+                error = "Invalid param to S2K";
+            }
+        }
+        if (type == 1) {
+            error = "AFS not supported yet";
+        }
+
+        if (error != null) {
+            throw new KrbException(error);
+        }
+
+        char[] passwdSalt = makePasswdSalt(string, salt);
+        byte[] key = toKey(passwdSalt);
+        return key;
+    }
+
+    /**
+     mit_des_string_to_key(string,salt) {
+       odd = 1;
+       s = string | salt;
+       tempstring = 0; // 56-bit string
+       pad(s); // with nulls to 8 byte boundary
+       for (8byteblock in s) {
+         56bitstring = removeMSBits(8byteblock);
+         if (odd == 0) reverse(56bitstring);
+         odd = ! odd;
+         tempstring = tempstring XOR 56bitstring;
+       }
+       tempkey = key_correction(add_parity_bits(tempstring));
+       key = key_correction(DES-CBC-check(s,tempkey));
+       return(key);
+     }
+     */
+    private byte[] toKey(char[] passwdChars) throws KrbException {
+        int keySize = encProvider().keySize();
+
+        byte[] bytes = (new String(passwdChars)).getBytes();
+
+        // padded with zero-valued octets to a multiple of eight octets.
+        byte[] paddedBytes = BytesUtil.padding(bytes, keySize);
+
+        int blocksOfbytes8 = paddedBytes.length / keySize;
+        boolean odd = true;
+        byte[] bits56 = new byte[8];
+        byte[] tempString = new byte[8];
+        for (int i = 0; i < blocksOfbytes8; ++i) {
+            System.arraycopy(paddedBytes, 8 * i, bits56, 0, 8);
+            removeMSBits(bits56);
+            if (odd) {
+                reverse(bits56);
+            }
+            odd = ! odd;
+            Util.xor(bits56, 0, tempString);
+        }
+
+        byte[] keyBytes = addParityBits(tempString);
+        keyCorrection(keyBytes);
+
+        byte[] resultKey = null;
+        if (encProvider().supportCbcMac()) {
+            resultKey = encProvider().cbcMac(keyBytes, keyBytes, paddedBytes);
+        } else {
+            throw new KrbException("cbcMac should be supported by the provider: "
+                    + encProvider().getClass());
+        }
+
+        keyCorrection(resultKey);
+
+        return resultKey;
+    }
+
+    /**
+     * Note this isn't hit any test yet, and very probably problematic
+     */
+    @Override
+    public byte[] random2Key(byte[] randomBits) throws KrbException {
+        if (randomBits.length != encProvider().keyInputSize()) {
+            throw new KrbException("Invalid random bits, not of correct bytes size");
+        }
+
+        /**
+         * Ref. k5_rand2key_des in random_to_key.c in MIT krb5
+         * Take the seven bytes, move them around into the top 7 bits of the
+         * 8 key bytes, then compute the parity bits.  Do this three times.
+         */
+        byte[] key = new byte[encProvider().keySize()];
+        int tmp;
+        System.arraycopy(randomBits, 0, key, 0, 7);
+
+        key[7] = (byte) (((key[0] & 1) << 1) |
+                ((key[1] & 1) << 2) |
+                ((key[2] & 1) << 3) |
+                ((key[3] & 1) << 4) |
+                ((key[4] & 1) << 5) |
+                ((key[5] & 1) << 6) |
+                ((key[6] & 1) << 7));
+
+        for (int i = 0; i < 8; i++) {
+            tmp = key[i] & 0xfe;
+            tmp |= (Integer.bitCount(tmp) & 1) ^ 1;
+            key[i] = (byte) tmp;
+        }
+
+        Des.fixKey(key, 0, 8);
+
+        return key;
+    }
+
+    // Processing an 8bytesblock
+    private static byte[] removeMSBits(byte[] bits56) {
+        /**
+         Treats a 64 bit block as 8 octets and removes the MSB in
+         each octet (in big endian mode) and concatenates the result.
+         E.g., the input octet string:
+         01110000 01100001 11110011  01110011 11110111 01101111 11110010 01100100
+         =>
+         1110000 1100001 1110011  1110011 1110111 1101111 1110010 1100100
+         */
+
+        /**
+         * We probably do nothing here, just pretending the MSB bit to be discarded,
+         * and ensure the MSB will not be used in the following processing.
+         */
+
+        return bits56;
+    }
+
+    // Processing an 56bitblock
+    private static void reverse(byte[] bits56) {
+        /**
+         Treats a 56-bit block as a binary string and reverses it.
+         E.g., the input string:
+         1000001 1010100 1001000 1000101 1001110 1000001 0101110 1001101
+         =>
+         1000001 0010101 0001001 1010001 0111001 1000001 0101110 1011001
+         =>
+         1011001 0111010 1000001  0111001 1010001 0001001 0010101 1000001
+         */
+
+        // Reversing in a 7bit
+        int t1, t2;
+        byte bt;
+        for (int i = 0; i < 8; ++i) {
+            bt = bits56[i];
+
+            t1 = (bt >> 6) & 1;
+            t2 = (bt >> 0) & 1;
+            if (t1 != t2) bt ^= (1 << 6 | 1 << 0);
+
+            t1 = (bt >> 5) & 1;
+            t2 = (bt >> 1) & 1;
+            if (t1 != t2) bt ^= (1 << 5 | 1 << 1);
+
+            t1 = (bt >> 4) & 1;
+            t2 = (bt >> 2) & 1;
+            if (t1 != t2) bt ^= (1 << 4 | 1 << 2);
+
+            bits56[i] = bt;
+        }
+
+        // Reversing the 8 7bit
+        bt = bits56[7];
+        bits56[7] = bits56[0];
+        bits56[0] = bt;
+
+        bt = bits56[6];
+        bits56[6] = bits56[1];
+        bits56[1] = bt;
+
+        bt = bits56[5];
+        bits56[5] = bits56[2];
+        bits56[2] = bt;
+
+        bt = bits56[4];
+        bits56[4] = bits56[3];
+        bits56[3] = bt;
+    }
+
+    private static byte[] addParityBits(byte[] bits56) {
+        /**
+         Copies a 56-bit block into a 64-bit block, left shifts
+         content in each octet, and add DES parity bit.
+         E.g., the input string:
+         1100000 0001111 0011100  0110100 1000101 1100100 0110110 0010111
+         =>
+         11000001 00011111 00111000  01101000 10001010 11001000 01101101 00101111
+         */
+        byte bt;
+        for (int i = 0; i < 8; i++) {
+            bits56[i] <<= 1;
+        }
+        addParity(bits56);
+
+        return bits56;
+    }
+
+    private static void keyCorrection(byte[] key) {
+        addParity(key);
+        if (Des.isWeakKey(key, 0, key.length)) {
+            Des.fixKey(key, 0, key.length);
+        }
+    }
+
+    private static int smask(int step) {
+        return (1 << step) - 1;
+    }
+
+    private static byte pstep(byte x, int step) {
+        return (byte) ((x & smask(step)) ^ ((x >> step) & smask(step)));
+    }
+
+    private static byte parityChar(byte abyte) {
+        //#define smask(step) ((1<<step)-1)
+        //#define pstep(x,step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+        //#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
+        return pstep(pstep(pstep(abyte, 4), 2), 1);
+    }
+
+    private static void addParity(byte[] key) {
+        for (int i = 0; i < key.length; ++i) {
+            key[i] &= 0xfe;
+            key[i] |= 1 ^ parityChar(key[i]);
+        }
+    }
+
+    // Returns true if the key has correct des parity
+    private static boolean checkKeyParity(byte[] key) {
+        for (int i = 0; i < key.length; ++i) {
+            if ((key[i] & 1) == parityChar((byte) (key[i] & 0xfe))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DkKeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DkKeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DkKeyMaker.java
new file mode 100644
index 0000000..a29e0e1
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/DkKeyMaker.java
@@ -0,0 +1,54 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.Nfold;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+
+public abstract class DkKeyMaker extends AbstractKeyMaker {
+
+    public DkKeyMaker(EncryptProvider encProvider) {
+        super(encProvider);
+    }
+
+    // DK(Key, Constant) = random-to-key(DR(Key, Constant))
+    public byte[] dk(byte[] key, byte[] constant) throws KrbException {
+        return random2Key(dr(key, constant));
+    }
+
+    /*
+     * K1 = E(Key, n-fold(Constant), initial-cipher-state)
+     * K2 = E(Key, K1, initial-cipher-state)
+     * K3 = E(Key, K2, initial-cipher-state)
+     * K4 = ...
+     * DR(Key, Constant) = k-truncate(K1 | K2 | K3 | K4 ...)
+     */
+    protected byte[] dr(byte[] key, byte[] constant) throws KrbException {
+
+        int blocksize = encProvider().blockSize();
+        int keyInuptSize = encProvider().keyInputSize();
+        byte[] keyBytes = new byte[keyInuptSize];
+        byte[] Ki;
+
+        if (constant.length != blocksize) {
+            Ki = Nfold.nfold(constant, blocksize);
+        } else {
+            Ki = new byte[constant.length];
+            System.arraycopy(constant, 0, Ki, 0, constant.length);
+        }
+
+        int n = 0, len;
+        while (n < keyInuptSize) {
+            encProvider().encrypt(key, Ki);
+
+            if (n + blocksize >= keyInuptSize) {
+                System.arraycopy(Ki, 0, keyBytes, n, keyInuptSize - n);
+                break;
+            }
+
+            System.arraycopy(Ki, 0, keyBytes, n, blocksize);
+            n += blocksize;
+        }
+
+        return keyBytes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/KeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/KeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/KeyMaker.java
new file mode 100644
index 0000000..a0789d9
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/KeyMaker.java
@@ -0,0 +1,10 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.KrbException;
+
+public interface KeyMaker {
+
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException;
+
+    public byte[] random2Key(byte[] randomBits) throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Rc4KeyMaker.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Rc4KeyMaker.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Rc4KeyMaker.java
new file mode 100644
index 0000000..e64ffe3
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/key/Rc4KeyMaker.java
@@ -0,0 +1,33 @@
+package org.apache.kerberos.kerb.crypto.key;
+
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerberos.kerb.KrbException;
+import sun.security.provider.MD4;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+
+public class Rc4KeyMaker extends AbstractKeyMaker {
+
+    public Rc4KeyMaker(EncryptProvider encProvider) {
+        super(encProvider);
+    }
+
+    @Override
+    public byte[] str2key(String string, String salt, byte[] param) throws KrbException {
+
+        if (param != null && param.length > 0) {
+            throw new RuntimeException("Invalid param to str2Key");
+        }
+
+        try {
+            byte[] passwd = string.getBytes("UTF-16LE"); // to unicode
+            MessageDigest md = MD4.getInstance();
+            md.update(passwd);
+            return md.digest();
+        } catch (UnsupportedEncodingException e) {
+            throw new KrbException("str2key failed", e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf b/haox-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
new file mode 100644
index 0000000..d118dd1
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/resources/kdc-krb5.conf
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+[libdefaults]
+    default_realm = {0}
+    udp_preference_limit = 1
+
+[realms]
+    {0} = '{'
+        kdc = {1}:{2}
+    '}'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/main/resources/kdc.ldiff
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/resources/kdc.ldiff b/haox-kerb/kerb-crypto/src/main/resources/kdc.ldiff
new file mode 100644
index 0000000..e344131
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/main/resources/kdc.ldiff
@@ -0,0 +1,30 @@
+dn: ou=users,dc=${0},dc=${1}
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: secret
+krb5PrincipalName: ldap/${4}@${2}.${3}
+krb5KeyVersionNumber: 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CamelliaEncTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CamelliaEncTest.java b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CamelliaEncTest.java
new file mode 100644
index 0000000..41bab8f
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CamelliaEncTest.java
@@ -0,0 +1,93 @@
+package org.apache.kerberos.kerb.crypto;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerberos.kerb.crypto.enc.provider.Camellia128Provider;
+import org.apache.kerberos.kerb.crypto.enc.provider.Camellia256Provider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CamelliaEncTest {
+
+    private List<String> outputs = new ArrayList<String>();
+    private int keySize;
+
+    private byte[] plain = new byte[16];
+    private byte[] cipher = new byte[16];
+    private EncryptProvider encProvider;
+
+    private List<String> getExpectedLines() throws IOException {
+        InputStream res = CamelliaEncTest.class.getResourceAsStream("/camellia-expect-vt.txt");
+        BufferedReader br = new BufferedReader(new InputStreamReader(res));
+
+        List<String> results = new ArrayList<String>();
+        String line;
+        while ((line = br.readLine()) != null) {
+            line = line.trim();
+            if (! line.isEmpty()) {
+                results.add(line);
+            }
+        }
+        return results;
+    }
+
+    @Test
+    public void testEnc() throws IOException, KrbException {
+        List<String> expectedLines = getExpectedLines();
+
+        testWith(16);
+        outputs.add("==========");
+        testWith(32);
+        outputs.add("==========");
+
+        List<String> newLines = expectedLines;
+        Assert.assertEquals("Comparing new lines with expected lines",
+                expectedLines, outputs);
+    }
+
+    private void testWith(int keySize) throws KrbException {
+        this.keySize = keySize;
+        outputs.add("KEYSIZE=" + (keySize * 8));
+
+        encProvider = keySize == 16 ?
+                new Camellia128Provider() : new Camellia256Provider();
+
+        byte[] key = new byte[keySize];
+        Arrays.fill(key, (byte) 0);
+        hexDump("KEY", key);
+
+        for (int i = 0; i < 16 * 8; ++i) {
+            Arrays.fill(plain, (byte) 0);
+            setBit(plain, i);
+            outputs.add("I=" + (i + 1));
+            hexDump("PT", plain);
+            encWith(key);
+            hexDump("CT", cipher);
+        }
+    }
+
+    private void hexDump(String label, byte[] bytes) {
+        String line = label + "=" + TestUtil.bytesToHex(bytes);
+        outputs.add(line);
+    }
+
+    private static void setBit(byte[] bytes, int bitnum) {
+        int bytenum = bitnum / 8;
+        bitnum %= 8;
+        // First bit is the high bit!
+        bytes[bytenum] = (byte) (1 << (7 - bitnum));
+    }
+
+    private void encWith(byte[] key) throws KrbException {
+        System.arraycopy(plain, 0, cipher, 0, plain.length);
+        encProvider.encrypt(key, cipher);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumTest.java b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumTest.java
new file mode 100644
index 0000000..caa501d
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumTest.java
@@ -0,0 +1,89 @@
+package org.apache.kerberos.kerb.crypto;
+
+import org.apache.kerberos.kerb.spec.common.*;
+import org.junit.Test;
+
+/**
+ * Only used to test for rsa-md4-des and rsa-md5-des
+ */
+public class CheckSumTest {
+
+    static class CksumTest {
+        CheckSumType cksumType;
+        String plainText;
+        String knownChecksum;
+
+        CksumTest(CheckSumType cksumType, String plainText, String knownChecksum) {
+            this.cksumType = cksumType;
+            this.plainText = plainText;
+            this.knownChecksum = knownChecksum;
+        }
+    }
+
+    static CksumTest[] testCases = new CksumTest[] {
+            new CksumTest(
+                    CheckSumType.RSA_MD4_DES,
+                    "this is a test",
+                    "e3f76a07f3401e3536b43a3f54226c39422c35682c354835"
+            ),
+            new CksumTest(
+                    CheckSumType.RSA_MD5_DES,
+                    "this is a test",
+                    "e3f76a07f3401e351143ee6f4c09be1edb4264d55015db53"
+            )
+    };
+
+    static byte[] TESTKEY = { (byte)0x45, (byte)0x01, (byte)0x49, (byte)0x61, (byte)0x58,
+            (byte)0x19, (byte)0x1a, (byte)0x3d };
+
+    @Test
+    public void testCheckSums() {
+        for (CksumTest tc : testCases) {
+            System.err.println("Checksum testing for " + tc.cksumType.getName());
+            try {
+                testWith(tc);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void testWith(CksumTest testCase) throws Exception {
+        byte[] knownChecksum = TestUtil.hex2bytes(testCase.knownChecksum);
+        byte[] plainData = testCase.plainText.getBytes();
+        CheckSum newCksum;
+
+        if (! CheckSumHandler.isImplemented(testCase.cksumType)) {
+            System.err.println("Checksum type not supported yet: "
+                    + testCase.cksumType.getName());
+            return;
+        }
+
+        EncryptionKey key = new EncryptionKey(EncryptionType.DES_CBC_CRC, TESTKEY);
+
+        newCksum = CheckSumHandler.checksumWithKey(testCase.cksumType, plainData, key.getKeyData(), KeyUsage.NONE);
+
+        if (CheckSumHandler.verifyWithKey(newCksum, plainData, key.getKeyData(), KeyUsage.NONE)) {
+            System.err.println("Checksum verifying is OK for " + testCase.cksumType.getName());
+        } else {
+            System.err.println("Checksum verifying failed for " + testCase.cksumType.getName());
+        }
+
+        // corrupt and verify again
+        byte[] cont = newCksum.getChecksum();
+        cont[0]++;
+        newCksum.setChecksum(cont);
+        if (CheckSumHandler.verifyWithKey(newCksum, plainData, key.getKeyData(), KeyUsage.NONE)) {
+            System.err.println("Checksum verifying failed with corrupt data for " + testCase.cksumType.getName());
+        } else {
+            System.err.println("Checksum verifying is OK with corrupt data for " + testCase.cksumType.getName());
+        }
+
+        CheckSum knwnCksum = new CheckSum(testCase.cksumType, knownChecksum);
+        if (CheckSumHandler.verifyWithKey(knwnCksum, plainData, key.getKeyData(), KeyUsage.NONE)) {
+            System.err.println("Checksum verifying is OK with known checksum for " + testCase.cksumType.getName());
+        } else {
+            System.err.println("Checksum verifying failed with known checksum for " + testCase.cksumType.getName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumsTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumsTest.java b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumsTest.java
new file mode 100644
index 0000000..5941b29
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CheckSumsTest.java
@@ -0,0 +1,163 @@
+package org.apache.kerberos.kerb.crypto;
+
+import org.apache.kerberos.kerb.spec.common.CheckSum;
+import org.apache.kerberos.kerb.spec.common.CheckSumType;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.junit.Test;
+
+/**
+ * These are to test the checksums of good answers, and the checksums
+ * are deterministic. For other cases, look at CheckSumTest.
+ */
+public class CheckSumsTest {
+
+    static class CksumTest {
+        String plainText;
+        CheckSumType cksumType;
+        EncryptionType encType;
+        String key;
+        int keyUsage;
+        String answer;
+
+        CksumTest(String plainText, CheckSumType cksumType, EncryptionType encType,
+                  int keyUsage, String key, String answer) {
+            this.plainText = plainText;
+            this.cksumType = cksumType;
+            this.encType = encType;
+            this.key = key;
+            this.keyUsage = keyUsage;
+            this.answer = answer;
+        }
+    }
+
+    static CksumTest[] testCases = new CksumTest[] {
+            new CksumTest(
+                    "abc",
+                    CheckSumType.CRC32, EncryptionType.NONE, 0, "",
+                    "D09865CA"
+            ),
+            new CksumTest(
+                    "one",
+                    CheckSumType.RSA_MD4, EncryptionType.NONE, 0, "",
+                    "305DCC2C0FDD5339969552C7B8996348"
+            ),
+            new CksumTest(
+                    "two three four five",
+                    CheckSumType.RSA_MD5, EncryptionType.NONE, 0, "",
+                    "BAB5321551E1084490869635B3C26815"
+            ),
+            new CksumTest(
+                    "",
+                    CheckSumType.NIST_SHA, EncryptionType.NONE, 0, "",
+                    "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
+            ),
+            new CksumTest(
+                    "six seven",
+                    CheckSumType.HMAC_SHA1_DES3, EncryptionType.DES3_CBC_SHA1, 2,
+                    "7A25DF8992296DCEDA0E135BC4046E2375B3C14C98FBC162",
+                    "0EEFC9C3E049AABC1BA5C401677D9AB699082BB4"
+            ),
+            new CksumTest(
+                    "eight nine ten eleven twelve thirteen",
+                    CheckSumType.HMAC_SHA1_96_AES128, EncryptionType.AES128_CTS_HMAC_SHA1_96, 3,
+                    "9062430C8CDA3388922E6D6A509F5B7A",
+                    "01A4B088D45628F6946614E3"
+            ),
+            new CksumTest(
+                    "fourteen",
+                    CheckSumType.HMAC_SHA1_96_AES256, EncryptionType.AES256_CTS_HMAC_SHA1_96, 4,
+                    "B1AE4CD8462AFF1677053CC9279AAC30B796FB81CE21474DD3DDBCFEA4EC76D7",
+                    "E08739E3279E2903EC8E3836"
+            ),
+            new CksumTest(
+                    "fifteen sixteen",
+                    CheckSumType.MD5_HMAC_ARCFOUR, EncryptionType.ARCFOUR_HMAC, 5,
+                    "F7D3A155AF5E238A0B7A871A96BA2AB2",
+                    "9F41DF304907DE735447001FD2A197B9"
+            ),
+            new CksumTest(
+                    "seventeen eighteen nineteen twenty",
+                    CheckSumType.HMAC_MD5_ARCFOUR, EncryptionType.ARCFOUR_HMAC, 6,
+                    "F7D3A155AF5E238A0B7A871A96BA2AB2",
+                    "EB38CC97E2230F59DA4117DC5859D7EC"
+            ),
+            new CksumTest(
+                    "abcdefghijk",
+                    CheckSumType.CMAC_CAMELLIA128, EncryptionType.CAMELLIA128_CTS_CMAC, 7,
+                    "1DC46A8D763F4F93742BCBA3387576C3",
+                    "1178E6C5C47A8C1AE0C4B9C7D4EB7B6B"
+            ),
+            new CksumTest(
+                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                    CheckSumType.CMAC_CAMELLIA128, EncryptionType.CAMELLIA128_CTS_CMAC, 8,
+                    "5027BC231D0F3A9D23333F1CA6FDBE7C",
+                    "D1B34F7004A731F23A0C00BF6C3F753A"
+            ),
+            new CksumTest(
+                    "123456789",
+                    CheckSumType.CMAC_CAMELLIA256, EncryptionType.CAMELLIA256_CTS_CMAC, 9,
+                    "B61C86CC4E5D2757545AD423399FB7031ECAB913CBB900BD7A3C6DD8BF92015B",
+                    "87A12CFD2B96214810F01C826E7744B1"
+            ),
+            new CksumTest(
+                    "!@#$%^&*()!@#$%^&*()!@#$%^&*()",
+                    CheckSumType.CMAC_CAMELLIA256, EncryptionType.CAMELLIA256_CTS_CMAC, 10,
+                    "32164C5B434D1D1538E4CFD9BE8040FE8C4AC7ACC4B93D3314D2133668147A05",
+                    "3FA0B42355E52B189187294AA252AB64"
+            )
+    };
+
+    @Test
+    public void testCheckSums() {
+        for (CksumTest tc : testCases) {
+            System.err.println("Checksum testing for " + tc.cksumType.getName());
+            try {
+                testWith(tc);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void testWith(CksumTest testCase) throws Exception {
+        byte[] answer = TestUtil.hex2bytes(testCase.answer);
+        byte[] plainData = testCase.plainText.getBytes();
+        CheckSum newCksum;
+
+        if (! CheckSumHandler.isImplemented(testCase.cksumType)) {
+            System.err.println("Checksum type not supported yet: "
+                    + testCase.cksumType.getName());
+            return;
+        }
+
+        if (testCase.encType != EncryptionType.NONE) {
+            if (! EncryptionHandler.isImplemented(testCase.encType)) {
+                System.err.println("Key type not supported yet: " + testCase.encType.getName());
+                return;
+            }
+
+            byte[] key = TestUtil.hex2bytes(testCase.key);
+            KeyUsage keyUsage = KeyUsage.fromValue(testCase.keyUsage);
+            newCksum = CheckSumHandler.checksumWithKey(testCase.cksumType, plainData, key, keyUsage);
+            if (CheckSumHandler.verifyWithKey(newCksum, plainData, key, keyUsage)) {
+                System.err.println("Checksum test OK for " + testCase.cksumType.getName());
+            } else {
+                System.err.println("Checksum test failed for " + testCase.cksumType.getName());
+            }
+        } else {
+            newCksum = CheckSumHandler.checksum(testCase.cksumType, plainData);
+            if (CheckSumHandler.verify(newCksum, plainData)) {
+                System.err.println("Checksum and verifying OK for " + testCase.cksumType.getName());
+            } else {
+                System.err.println("Checksum and verifying failed for " + testCase.cksumType.getName());
+            }
+        }
+
+        if (! newCksum.isEqual(answer)) {
+            System.err.println("Checksum test failed for " + testCase.cksumType.getName());
+        } else {
+            System.err.println("Checksum test OK for " + testCase.cksumType.getName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CmacTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CmacTest.java b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CmacTest.java
new file mode 100644
index 0000000..99a26af
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/CmacTest.java
@@ -0,0 +1,65 @@
+package org.apache.kerberos.kerb.crypto;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerberos.kerb.crypto.enc.provider.Camellia128Provider;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CmacTest {
+
+    /* All examples use the following Camellia-128 key. */
+    static String keyBytes = "2b7e151628aed2a6" +
+            "abf7158809cf4f3c";
+
+    /* Example inputs are this message truncated to 0, 16, 40, and 64 bytes. */
+    static String inputBytes = "6bc1bee22e409f96" +
+            "e93d7e117393172a" +
+            "ae2d8a571e03ac9c" +
+            "9eb76fac45af8e51" +
+            "30c81c46a35ce411" +
+            "e5fbc1191a0a52ef" +
+            "f69f2445df4f9b17" +
+            "ad2b417be66c3710";
+
+    /* Expected result of CMAC on empty inputBytes. */
+    static String cmac1 = "ba925782aaa1f5d9" +
+            "a00f89648094fc71";
+
+    /* Expected result of CMAC on first 16 bytes of inputBytes. */
+    static String cmac2 = "6d962854a3b9fda5" +
+            "6d7d45a95ee17993";
+
+    /* Expected result of CMAC on first 40 bytes of inputBytes. */
+    static String cmac3 = "5c18d119ccd67661" +
+            "44ac1866131d9f22";
+
+    /* Expected result of CMAC on all 64 bytes of inputBytes. */
+    static String cmac4 = "c2699a6eba55ce9d" +
+            "939a8a4e19466ee9";
+
+
+    @Test
+    public void testCmac() throws KrbException, KrbException {
+        byte[] key = TestUtil.hex2bytes(keyBytes);
+        byte[] input = TestUtil.hex2bytes(inputBytes);
+        EncryptProvider encProvider = new Camellia128Provider();
+        byte[] result;
+
+        // test 1
+        result = Cmac.cmac(encProvider, key, input, 0, 0);
+        Assert.assertArrayEquals("Test 1", TestUtil.hex2bytes(cmac1), result);
+
+        // test 2
+        result = Cmac.cmac(encProvider, key, input, 0, 16);
+        Assert.assertArrayEquals("Test 2", TestUtil.hex2bytes(cmac2), result);
+
+        // test 3
+        result = Cmac.cmac(encProvider, key, input, 0, 40);
+        Assert.assertArrayEquals("Test 3", TestUtil.hex2bytes(cmac3), result);
+
+        // test 4
+        result = Cmac.cmac(encProvider, key, input, 0, 64);
+        Assert.assertArrayEquals("Test 4", TestUtil.hex2bytes(cmac4), result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/Crc32Test.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/Crc32Test.java b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/Crc32Test.java
new file mode 100644
index 0000000..f9b6b5d
--- /dev/null
+++ b/haox-kerb/kerb-crypto/src/test/java/org/apache/kerberos/kerb/crypto/Crc32Test.java
@@ -0,0 +1,99 @@
+package org.apache.kerberos.kerb.crypto;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class Crc32Test {
+
+    static class TestCase {
+        String data;
+        long answer;
+
+        public TestCase(String data, long answer) {
+            this.data = data;
+            this.answer = answer;
+        }
+    }
+
+    static TestCase[] testCases = new TestCase[] {
+            new TestCase("01", 0x77073096),
+            new TestCase("02", 0xee0e612c),
+            new TestCase("04", 0x076dc419),
+            new TestCase("08", 0x0edb8832),
+            new TestCase("10", 0x1db71064),
+            new TestCase("20", 0x3b6e20c8),
+            new TestCase("40", 0x76dc4190),
+            new TestCase("80", 0xedb88320),
+            new TestCase("0100", 0x191b3141),
+            new TestCase("0200", 0x32366282),
+            new TestCase("0400", 0x646cc504),
+            new TestCase("0800", 0xc8d98a08),
+            new TestCase("1000", 0x4ac21251),
+            new TestCase("2000", 0x958424a2),
+            new TestCase("4000", 0xf0794f05),
+            new TestCase("8000", 0x3b83984b),
+            new TestCase("0001", 0x77073096),
+            new TestCase("0002", 0xee0e612c),
+            new TestCase("0004", 0x076dc419),
+            new TestCase("0008", 0x0edb8832),
+            new TestCase("0010", 0x1db71064),
+            new TestCase("0020", 0x3b6e20c8),
+            new TestCase("0040", 0x76dc4190),
+            new TestCase("0080", 0xedb88320),
+            new TestCase("01000000", 0xb8bc6765),
+            new TestCase("02000000", 0xaa09c88b),
+            new TestCase("04000000", 0x8f629757),
+            new TestCase("08000000", 0xc5b428ef),
+            new TestCase("10000000", 0x5019579f),
+            new TestCase("20000000", 0xa032af3e),
+            new TestCase("40000000", 0x9b14583d),
+            new TestCase("80000000", 0xed59b63b),
+            new TestCase("00010000", 0x01c26a37),
+            new TestCase("00020000", 0x0384d46e),
+            new TestCase("00040000", 0x0709a8dc),
+            new TestCase("00080000", 0x0e1351b8),
+            new TestCase("00100000", 0x1c26a370),
+            new TestCase("00200000", 0x384d46e0),
+            new TestCase("00400000", 0x709a8dc0),
+            new TestCase("00800000", 0xe1351b80),
+            new TestCase("00000100", 0x191b3141),
+            new TestCase("00000200", 0x32366282),
+            new TestCase("00000400", 0x646cc504),
+            new TestCase("00000800", 0xc8d98a08),
+            new TestCase("00001000", 0x4ac21251),
+            new TestCase("00002000", 0x958424a2),
+            new TestCase("00004000", 0xf0794f05),
+            new TestCase("00008000", 0x3b83984b),
+            new TestCase("00000001", 0x77073096),
+            new TestCase("00000002", 0xee0e612c),
+            new TestCase("00000004", 0x076dc419),
+            new TestCase("00000008", 0x0edb8832),
+            new TestCase("00000010", 0x1db71064),
+            new TestCase("00000020", 0x3b6e20c8),
+            new TestCase("00000040", 0x76dc4190),
+            new TestCase("00000080", 0xedb88320),
+            new TestCase("666F6F", 0x7332bc33),
+            new TestCase("7465737430313233343536373839", 0xb83e88d6),
+            new TestCase("4D4153534143485653455454532049" +
+                    "4E53544954565445204F4620544543484E4F4C4F4759", 0xe34180f7)
+    };
+
+    @Test
+    public void testCrc32() {
+        boolean isOk = true;
+        for (TestCase tc : testCases) {
+            if (! testWith(tc)) {
+                isOk = false;
+                System.err.println("Test with data " + tc.data + " failed");
+            }
+        }
+
+        Assert.assertTrue(isOk);
+    }
+
+    private boolean testWith(TestCase testCase) {
+        byte[] data = TestUtil.hex2bytes(testCase.data);
+        long value = Crc32.crc(0, data, 0, data.length);
+        return value == testCase.answer;
+    }
+}


Mime
View raw message