You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/02/09 07:27:53 UTC

[12/30] directory-kerberos git commit: Cleaned some bit and refactored some codes in kerb-crypto

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Random.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Random.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Random.java
deleted file mode 100644
index cd6bf71..0000000
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Random.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- *  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. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.crypto;
-
-import java.security.SecureRandom;
-
-public final class Random {
-
-    private static SecureRandom srand = new SecureRandom();
-
-    public static byte[] makeBytes(int size) {
-        byte[] data = new byte[size];
-        srand.nextBytes(data);
-        return data;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Rc4.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Rc4.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Rc4.java
deleted file mode 100644
index b45c4eb..0000000
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/Rc4.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- *  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. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.crypto;
-
-/**
- * Based on MIT krb5 enc_rc4.c
- */
-public class Rc4 {
-
-    private static byte[] L40 = "fortybits".getBytes();
-
-    public static byte[] getSalt(int usage, boolean exportable) {
-        int newUsage = convertUsage(usage);
-        byte[] salt;
-
-        if (exportable) {
-            salt = new byte[14];
-            System.arraycopy(L40, 0, salt, 0, 9);
-            BytesUtil.int2bytes(newUsage, salt, 10, false);
-        } else {
-            salt = new byte[4];
-            BytesUtil.int2bytes(newUsage, salt, 0, false);
-        }
-
-        return salt;
-    }
-
-    private static int convertUsage(int usage) {
-        switch (usage) {
-            case 1:  return 1;   /* AS-REQ PA-ENC-TIMESTAMP padata timestamp,  */
-            case 2:  return 2;   /* ticket from kdc */
-            case 3:  return 8;   /* as-rep encrypted part */
-            case 4:  return 4;   /* tgs-req authz data */
-            case 5:  return 5;   /* tgs-req authz data in subkey */
-            case 6:  return 6;   /* tgs-req authenticator cksum */
-            case 7:  return 7;   /* tgs-req authenticator */
-            case 8:  return 8;
-            case 9:  return 9;   /* tgs-rep encrypted with subkey */
-            case 10: return 10;  /* ap-rep authentication cksum (never used by MS) */
-            case 11: return 11;  /* app-req authenticator */
-            case 12: return 12;  /* app-rep encrypted part */
-            case 23: return 13;  /* sign wrap token*/
-            default: return usage;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractCheckSumTypeHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractCheckSumTypeHandler.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractCheckSumTypeHandler.java
index 49a62c7..6f01c38 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractCheckSumTypeHandler.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractCheckSumTypeHandler.java
@@ -30,7 +30,8 @@ public abstract class AbstractCheckSumTypeHandler
     private int computeSize;
     private int outputSize;
 
-    public AbstractCheckSumTypeHandler(EncryptProvider encProvider, HashProvider hashProvider,
+    public AbstractCheckSumTypeHandler(EncryptProvider encProvider,
+                                       HashProvider hashProvider,
                                        int computeSize, int outputSize) {
         super(encProvider, hashProvider);
         this.computeSize = computeSize;
@@ -89,7 +90,8 @@ public abstract class AbstractCheckSumTypeHandler
     }
 
     @Override
-    public boolean verify(byte[] data, int start, int size, byte[] checksum) throws KrbException {
+    public boolean verify(byte[] data, int start, int size,
+                          byte[] checksum) throws KrbException {
         throw new UnsupportedOperationException();
     }
 
@@ -106,7 +108,8 @@ public abstract class AbstractCheckSumTypeHandler
     }
     @Override
     public boolean verifyWithKey(byte[] data,
-                                 byte[] key, int usage, byte[] checksum) throws KrbException {
+                                 byte[] key, int usage,
+                                 byte[] checksum) throws KrbException {
         throw new UnsupportedOperationException();
     }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractKeyedCheckSumTypeHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractKeyedCheckSumTypeHandler.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractKeyedCheckSumTypeHandler.java
index 3f17454..81bfa0a 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractKeyedCheckSumTypeHandler.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/AbstractKeyedCheckSumTypeHandler.java
@@ -23,11 +23,13 @@ import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 import org.apache.kerby.kerberos.kerb.crypto.key.KeyMaker;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
-public abstract class AbstractKeyedCheckSumTypeHandler extends AbstractCheckSumTypeHandler {
+public abstract class AbstractKeyedCheckSumTypeHandler
+        extends AbstractCheckSumTypeHandler {
 
     private KeyMaker keyMaker;
 
-    public AbstractKeyedCheckSumTypeHandler(EncryptProvider encProvider, HashProvider hashProvider,
+    public AbstractKeyedCheckSumTypeHandler(EncryptProvider encProvider,
+                                            HashProvider hashProvider,
                                             int computeSize, int outputSize) {
         super(encProvider, hashProvider, computeSize, outputSize);
     }

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/CmacKcCheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/CmacKcCheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/CmacKcCheckSum.java
index 16122d2..6a51d29 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/CmacKcCheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/CmacKcCheckSum.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.Cmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Cmac;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/ConfounderedDesCheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/ConfounderedDesCheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/ConfounderedDesCheckSum.java
index 8259849..5f6a3d6 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/ConfounderedDesCheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/ConfounderedDesCheckSum.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.util.Confounder;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.DesProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HashProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HashProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HashProvider.java
index 1586fb1..1eb32db 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HashProvider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HashProvider.java
@@ -22,7 +22,12 @@ package org.apache.kerby.kerberos.kerb.crypto.cksum;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
 /**
- * krb5_hash_provider
+ * Ref. MIT Krb5: krb5_hash_provider
+ */
+
+/**
+ * Hash provider that provides hash function
+ * for implementing a checksum type defined by Kerberos RFC3961.
  */
 public interface HashProvider {
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacKcCheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacKcCheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacKcCheckSum.java
index 84d9031..03b8c0b 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacKcCheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacKcCheckSum.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Hmac;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Sha1Provider;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacMd5Rc4CheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacMd5Rc4CheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacMd5Rc4CheckSum.java
index 1ef5489..3123f71 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacMd5Rc4CheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/HmacMd5Rc4CheckSum.java
@@ -19,8 +19,8 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.Hmac;
-import org.apache.kerby.kerberos.kerb.crypto.Rc4;
+import org.apache.kerby.kerberos.kerb.crypto.util.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Rc4;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md5Provider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.spec.common.CheckSumType;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/KcCheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/KcCheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/KcCheckSum.java
index ee8faea..2e7db3b 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/KcCheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/KcCheckSum.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 import org.apache.kerby.kerberos.kerb.crypto.key.DkKeyMaker;
 import org.apache.kerby.kerberos.kerb.KrbException;
@@ -44,5 +44,6 @@ public abstract class KcCheckSum extends AbstractKeyedCheckSumTypeHandler {
         return mac;
     }
 
-    protected abstract byte[] mac(byte[] Kc, byte[] data, int start, int len) throws KrbException;
+    protected abstract byte[] mac(byte[] Kc, byte[] data, int start,
+                                  int len) throws KrbException;
 }

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/Md5HmacRc4CheckSum.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/Md5HmacRc4CheckSum.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/Md5HmacRc4CheckSum.java
index 4939027..038631e 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/Md5HmacRc4CheckSum.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/Md5HmacRc4CheckSum.java
@@ -19,8 +19,8 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum;
 
-import org.apache.kerby.kerberos.kerb.crypto.Hmac;
-import org.apache.kerby.kerberos.kerb.crypto.Rc4;
+import org.apache.kerby.kerberos.kerb.crypto.util.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Rc4;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md5Provider;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.Rc4Provider;
 import org.apache.kerby.kerberos.kerb.KrbException;
@@ -55,7 +55,6 @@ public class Md5HmacRc4CheckSum extends AbstractKeyedCheckSumTypeHandler {
     @Override
     protected byte[] doChecksumWithKey(byte[] data, int start, int len,
                                        byte[] key, int usage) throws KrbException {
-
         byte[] Ksign = key;
 
         byte[] salt = Rc4.getSalt(usage, false);

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Crc32Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Crc32Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Crc32Provider.java
index de30eca..40e4fa8 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Crc32Provider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Crc32Provider.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum.provider;
 
-import org.apache.kerby.kerberos.kerb.crypto.Crc32;
+import org.apache.kerby.kerberos.kerb.crypto.util.Crc32;
 
 public class Crc32Provider extends AbstractHashProvider {
     private byte[] output;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Md4Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Md4Provider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Md4Provider.java
index e00977c..441ad74 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Md4Provider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/cksum/provider/Md4Provider.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.cksum.provider;
 
-import org.apache.kerby.kerberos.kerb.crypto.Md4;
+import org.apache.kerby.kerberos.kerb.crypto.util.Md4;
 
 public class Md4Provider extends MessageDigestHashProvider {
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcEnc.java
index e3aa7d8..a639d56 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcEnc.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/DesCbcEnc.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.crypto.enc;
 
 import org.apache.kerby.kerberos.kerb.KrbErrorCode;
-import org.apache.kerby.kerberos.kerb.crypto.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.util.Confounder;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.HashProvider;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.DesProvider;
 import org.apache.kerby.kerberos.kerb.crypto.key.DesKeyMaker;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
index 47168cb..87960f4 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/EncryptProvider.java
@@ -22,7 +22,12 @@ package org.apache.kerby.kerberos.kerb.crypto.enc;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
 /**
- * krb5_enc_provider
+ * Ref. MIT Krb5:krb5_enc_provider
+ */
+
+/**
+ * Encryption provider that provides encryption/decryption functions
+ * for implementing an encryption type defined by Kerberos RFC3961.
  */
 public interface EncryptProvider {
 
@@ -37,7 +42,4 @@ public interface EncryptProvider {
     public byte[] cbcMac(byte[] key, byte[] iv, byte[] data) throws KrbException;
     public boolean supportCbcMac();
 
-    public byte[] initState(byte[] key, int keyUsage);
-    public void cleanState();
-    public void cleanKey();
 }

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
index 890c7ca..efe3abf 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiCmacEnc.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.enc;
 
-import org.apache.kerby.kerberos.kerb.crypto.Cmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Cmac;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
 public abstract class KeKiCmacEnc extends KeKiEnc {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
index 9e562c7..b1bc7dc 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiEnc.java
@@ -20,8 +20,8 @@
 package org.apache.kerby.kerberos.kerb.crypto.enc;
 
 import org.apache.kerby.kerberos.kerb.KrbErrorCode;
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
-import org.apache.kerby.kerberos.kerb.crypto.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.Confounder;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.HashProvider;
 import org.apache.kerby.kerberos.kerb.crypto.key.DkKeyMaker;
 import org.apache.kerby.kerberos.kerb.KrbException;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
index 70f49c0..0220830 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/KeKiHmacSha1Enc.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.enc;
 
-import org.apache.kerby.kerberos.kerb.crypto.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Hmac;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.HashProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
index 126edaf..9d9e90d 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/Rc4HmacEnc.java
@@ -20,10 +20,10 @@
 package org.apache.kerby.kerberos.kerb.crypto.enc;
 
 import org.apache.kerby.kerberos.kerb.KrbErrorCode;
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
-import org.apache.kerby.kerberos.kerb.crypto.Confounder;
-import org.apache.kerby.kerberos.kerb.crypto.Rc4;
-import org.apache.kerby.kerberos.kerb.crypto.Hmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.Confounder;
+import org.apache.kerby.kerberos.kerb.crypto.util.Rc4;
+import org.apache.kerby.kerberos.kerb.crypto.util.Hmac;
 import org.apache.kerby.kerberos.kerb.crypto.cksum.provider.Md5Provider;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.Rc4Provider;
 import org.apache.kerby.kerberos.kerb.crypto.key.Rc4KeyMaker;

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
index 2fcca14..660ffb6 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/AbstractEncryptProvider.java
@@ -49,11 +49,6 @@ public abstract class AbstractEncryptProvider implements EncryptProvider {
     }
 
     @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);
     }
@@ -87,13 +82,4 @@ public abstract class AbstractEncryptProvider implements EncryptProvider {
         return false;
     }
 
-    @Override
-    public void cleanState() {
-
-    }
-
-    @Override
-    public void cleanKey() {
-
-    }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
index d3b69a6..6e16734 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/enc/provider/CamelliaProvider.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.enc.provider;
 
-import org.apache.kerby.kerberos.kerb.crypto.Camellia;
+import org.apache.kerby.kerberos.kerb.crypto.util.Camellia;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
 public abstract class CamelliaProvider extends AbstractEncryptProvider {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
index 3c2cf9c..f31aeb3 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AbstractKeyMaker.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
index 8b385da..f777a12 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/AesKeyMaker.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerby.kerberos.kerb.crypto.util.Pbkdf;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.AesProvider;
 
 import java.io.UnsupportedEncodingException;
@@ -49,7 +49,7 @@ public class AesKeyMaker extends DkKeyMaker {
         }
 
         int keySize = encProvider().keySize();
-        byte[] random = new byte[0];
+        byte[] random;
         try {
             random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
         } catch (GeneralSecurityException e) {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
index 4feb7c5..a790a38 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/CamelliaKeyMaker.java
@@ -19,9 +19,9 @@
  */
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
-import org.apache.kerby.kerberos.kerb.crypto.Cmac;
-import org.apache.kerby.kerberos.kerb.crypto.Pbkdf;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.Cmac;
+import org.apache.kerby.kerberos.kerb.crypto.util.Pbkdf;
 import org.apache.kerby.kerberos.kerb.crypto.enc.provider.CamelliaProvider;
 import org.apache.kerby.kerberos.kerb.KrbException;
 
@@ -51,7 +51,7 @@ public class CamelliaKeyMaker extends DkKeyMaker {
         }
 
         int keySize = encProvider().keySize();
-        byte[] random = new byte[0];
+        byte[] random;
         try {
             random = Pbkdf.PBKDF2(string.toCharArray(), saltBytes, iterCount, keySize);
         } catch (GeneralSecurityException e) {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
index 06caeb8..363eb29 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/Des3KeyMaker.java
@@ -20,8 +20,8 @@
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.crypto.Des;
-import org.apache.kerby.kerberos.kerb.crypto.Nfold;
+import org.apache.kerby.kerberos.kerb.crypto.util.Des;
+import org.apache.kerby.kerberos.kerb.crypto.util.Nfold;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 
 public class Des3KeyMaker extends DkKeyMaker {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
index 2528b0d..daf15c2 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DesKeyMaker.java
@@ -20,8 +20,8 @@
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.crypto.BytesUtil;
-import org.apache.kerby.kerberos.kerb.crypto.Des;
+import org.apache.kerby.kerberos.kerb.crypto.util.BytesUtil;
+import org.apache.kerby.kerberos.kerb.crypto.util.Des;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 
 public class DesKeyMaker extends AbstractKeyMaker {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
index a1a515d..ad38932 100644
--- a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/key/DkKeyMaker.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.crypto.key;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.crypto.Nfold;
+import org.apache.kerby.kerberos.kerb.crypto.util.Nfold;
 import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
 
 public abstract class DkKeyMaker extends AbstractKeyMaker {

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/BytesUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/BytesUtil.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/BytesUtil.java
new file mode 100644
index 0000000..1c58293
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/BytesUtil.java
@@ -0,0 +1,183 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+public class BytesUtil {
+
+    public static short bytes2short(byte[] bytes, int offset, boolean bigEndian) {
+        short val = 0;
+
+        if (bigEndian) {
+            val += (bytes[offset + 0] & 0xff) << 8;
+            val += (bytes[offset + 1] & 0xff);
+        } else {
+            val += (bytes[offset + 1] & 0xff) << 8;
+            val += (bytes[offset + 0] & 0xff);
+        }
+
+        return val;
+    }
+
+    public static short bytes2short(byte[] bytes, boolean bigEndian) {
+        return bytes2short(bytes, 0, bigEndian);
+    }
+
+    public static byte[] short2bytes(int val, boolean bigEndian) {
+        byte[] bytes = new byte[2];
+
+        short2bytes(val, bytes, 0, bigEndian);
+
+        return bytes;
+    }
+
+    public static void short2bytes(int val, byte[] bytes, int offset, boolean bigEndian) {
+        if (bigEndian) {
+            bytes[offset + 0] = (byte) ((val >> 8) & 0xff);
+            bytes[offset + 1] = (byte) ((val) & 0xff);
+        } else {
+            bytes[offset + 1] = (byte) ((val >>  8) & 0xff);
+            bytes[offset + 0] = (byte) ((val      ) & 0xff);
+        }
+    }
+
+    public static int bytes2int(byte[] bytes, boolean bigEndian) {
+        return bytes2int(bytes, 0, bigEndian);
+    }
+
+    public static int bytes2int(byte[] bytes, int offset, boolean bigEndian) {
+        int val = 0;
+
+        if (bigEndian) {
+            val += (bytes[offset + 0] & 0xff) << 24;
+            val += (bytes[offset + 1] & 0xff) << 16;
+            val += (bytes[offset + 2] & 0xff) << 8;
+            val += (bytes[offset + 3] & 0xff);
+        } else {
+            val += (bytes[offset + 3] & 0xff) << 24;
+            val += (bytes[offset + 2] & 0xff) << 16;
+            val += (bytes[offset + 1] & 0xff) << 8;
+            val += (bytes[offset + 0] & 0xff);
+        }
+
+        return val;
+    }
+
+    public static byte[] int2bytes(int val, boolean bigEndian) {
+        byte[] bytes = new byte[4];
+
+        int2bytes(val, bytes, 0, bigEndian);
+
+        return bytes;
+    }
+
+    public static void int2bytes(int val, byte[] bytes, int offset, boolean bigEndian) {
+        if (bigEndian) {
+            bytes[offset + 0] = (byte) ((val >> 24) & 0xff);
+            bytes[offset + 1] = (byte) ((val >> 16) & 0xff);
+            bytes[offset + 2] = (byte) ((val >> 8) & 0xff);
+            bytes[offset + 3] = (byte) ((val) & 0xff);
+        } else {
+            bytes[offset + 3] = (byte) ((val >> 24) & 0xff);
+            bytes[offset + 2] = (byte) ((val >> 16) & 0xff);
+            bytes[offset + 1] = (byte) ((val >> 8) & 0xff);
+            bytes[offset + 0] = (byte) ((val) & 0xff);
+        }
+    }
+
+    public static byte[] long2bytes(long val, boolean bigEndian) {
+        byte[] bytes = new byte[8];
+        long2bytes(val, bytes, 0, bigEndian);
+        return bytes;
+    }
+
+    public static void long2bytes(long val, byte[] bytes, int offset, boolean bigEndian) {
+        if (bigEndian) {
+            for (int i = 0; i < 8; i++) {
+                bytes[i + offset] = (byte) ((val >> ((7 - i) * 8)) & 0xffL);
+            }
+        } else {
+            for (int i = 0; i < 8; i++) {
+                bytes[i + offset] = (byte) ((val >> (i * 8)) & 0xffL);
+            }
+        }
+    }
+
+    public static long bytes2long(byte[] bytes, boolean bigEndian) {
+        return bytes2long(bytes, 0, bigEndian);
+    }
+
+    public static long bytes2long(byte[] bytes, int offset, boolean bigEndian) {
+        long val = 0;
+
+        if (bigEndian) {
+            for (int i = 0; i < 8; i++) {
+                val |= (((long) bytes[i + offset]) & 0xffL) << ((7 - i) * 8);
+            }
+        } else {
+            for (int i = 0; i < 8; i++) {
+                val |= (((long) bytes[i + offset]) & 0xffL) << (i * 8);
+            }
+        }
+
+        return val;
+    }
+
+    public static byte[] padding(byte[] data, int block) {
+        int len = data.length;
+        int paddingLen = len % block != 0 ? 8 - len % block : 0;
+        if (paddingLen == 0) {
+            return data;
+        }
+
+        byte[] result = new byte[len + + paddingLen];
+        System.arraycopy(data, 0, result, 0, len);
+        return result;
+    }
+
+    public static byte[] duplicate(byte[] bytes) {
+        return duplicate(bytes, 0, bytes.length);
+    }
+
+    public static byte[] duplicate(byte[] bytes, int offset, int len) {
+        byte[] dup = new byte[len];
+        System.arraycopy(bytes, offset, dup, 0, len);
+        return dup;
+    }
+
+    public static void xor(byte[] input, int offset, byte[] output) {
+        int a, b;
+        for (int i = 0; i < output.length / 4; ++i) {
+            a = BytesUtil.bytes2int(input, offset + i * 4, true);
+            b = BytesUtil.bytes2int(output, i * 4, true);
+            b = a ^ b;
+            BytesUtil.int2bytes(b, output, i * 4, true);
+        }
+    }
+
+    public static void xor(byte[] a, byte[] b, byte[] output) {
+        int av, bv, v;
+        for (int i = 0; i < a.length / 4; ++i) {
+            av = BytesUtil.bytes2int(a, i * 4, true);
+            bv = BytesUtil.bytes2int(b, i * 4, true);
+            v = av ^ bv;
+            BytesUtil.int2bytes(v, output, i * 4, true);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Camellia.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Camellia.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Camellia.java
new file mode 100644
index 0000000..3e96c53
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Camellia.java
@@ -0,0 +1,250 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+/**
+ * Camellia - based on RFC 3713, about half the size of CamelliaEngine.
+ *
+ * This is based on CamelliaEngine.java from bouncycastle library.
+ */
+
+public class Camellia {
+    private static final int BLOCK_SIZE = 16;
+    private int[] state = new int[4]; // for encryption and decryption
+
+    private CamelliaKey camKey;
+
+    public void setKey(boolean forEncryption, byte[] key) {
+        camKey = new CamelliaKey(key, forEncryption);
+    }
+
+    private void process128Block(byte[] in, int inOff,
+                                byte[] out, int outOff) {
+        for (int i = 0; i < 4; i++) {
+            state[i] = BytesUtil.bytes2int(in, inOff + (i * 4), true);
+            state[i] ^= camKey.kw[i];
+        }
+
+        camKey.f2(state, camKey.subkey, 0);
+        camKey.f2(state, camKey.subkey, 4);
+        camKey.f2(state, camKey.subkey, 8);
+        camKey.fls(state, camKey.ke, 0);
+        camKey.f2(state, camKey.subkey, 12);
+        camKey.f2(state, camKey.subkey, 16);
+        camKey.f2(state, camKey.subkey, 20);
+        camKey.fls(state, camKey.ke, 4);
+        camKey.f2(state, camKey.subkey, 24);
+        camKey.f2(state, camKey.subkey, 28);
+        camKey.f2(state, camKey.subkey, 32);
+
+        state[2] ^= camKey.kw[4];
+        state[3] ^= camKey.kw[5];
+        state[0] ^= camKey.kw[6];
+        state[1] ^= camKey.kw[7];
+
+        BytesUtil.int2bytes(state[2], out, outOff, true);
+        BytesUtil.int2bytes(state[3], out, outOff + 4, true);
+        BytesUtil.int2bytes(state[0], out, outOff + 8, true);
+        BytesUtil.int2bytes(state[1], out, outOff + 12, true);
+    }
+
+    private void processBlockLargerBlock(byte[] in, int inOff,
+                                        byte[] out, int outOff) {
+        for (int i = 0; i < 4; i++) {
+            state[i] = BytesUtil.bytes2int(in, inOff + (i * 4), true);
+            state[i] ^= camKey.kw[i];
+        }
+
+        camKey.f2(state, camKey.subkey, 0);
+        camKey.f2(state, camKey.subkey, 4);
+        camKey.f2(state, camKey.subkey, 8);
+        camKey.fls(state, camKey.ke, 0);
+        camKey.f2(state, camKey.subkey, 12);
+        camKey.f2(state, camKey.subkey, 16);
+        camKey.f2(state, camKey.subkey, 20);
+        camKey.fls(state, camKey.ke, 4);
+        camKey.f2(state, camKey.subkey, 24);
+        camKey.f2(state, camKey.subkey, 28);
+        camKey.f2(state, camKey.subkey, 32);
+        camKey.fls(state, camKey.ke, 8);
+        camKey.f2(state, camKey.subkey, 36);
+        camKey.f2(state, camKey.subkey, 40);
+        camKey.f2(state, camKey.subkey, 44);
+
+        state[2] ^= camKey.kw[4];
+        state[3] ^= camKey.kw[5];
+        state[0] ^= camKey.kw[6];
+        state[1] ^= camKey.kw[7];
+
+        BytesUtil.int2bytes(state[2], out, outOff, true);
+        BytesUtil.int2bytes(state[3], out, outOff + 4, true);
+        BytesUtil.int2bytes(state[0], out, outOff + 8, true);
+        BytesUtil.int2bytes(state[1], out, outOff + 12, true);
+    }
+
+    public void processBlock(byte[] in, int inOff) {
+        byte[] out = new byte[BLOCK_SIZE];
+
+        if (camKey.is128()) {
+            process128Block(in, inOff, out, 0);
+        } else {
+            processBlockLargerBlock(in, inOff, out, 0);
+        }
+
+        System.arraycopy(out, 0, in, inOff, BLOCK_SIZE);
+    }
+
+    public void encrypt(byte[] data, byte[] iv) {
+        byte[] cipher = new byte[BLOCK_SIZE];
+        byte[] cipherState = new byte[BLOCK_SIZE];
+
+        int blocksNum = (data.length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        int lastBlockLen = data.length - (blocksNum - 1) * BLOCK_SIZE;
+        if (blocksNum == 1) {
+            cbcEnc(data, 0, 1, cipherState);
+            return;
+        }
+
+        if (iv != null) {
+            System.arraycopy(iv, 0, cipherState, 0, BLOCK_SIZE);
+        }
+
+        int contBlocksNum, offset = 0;
+        while (blocksNum > 2) {
+            contBlocksNum = (data.length - offset) / BLOCK_SIZE;
+            if (contBlocksNum > 0) {
+                // Encrypt a series of contiguous blocks in place if we can, but
+                // don't touch the last two blocks.
+                contBlocksNum = (contBlocksNum > blocksNum - 2) ? blocksNum - 2 : contBlocksNum;
+                cbcEnc(data, offset, contBlocksNum, cipherState);
+                offset += contBlocksNum * BLOCK_SIZE;
+                blocksNum -= contBlocksNum;
+            } else {
+                cbcEnc(data, offset, 1, cipherState);
+                offset += BLOCK_SIZE;
+                blocksNum--;
+            }
+        }
+
+        // Encrypt the last two blocks and store the results in reverse order
+        byte[] blockN2 = new byte[BLOCK_SIZE];
+        byte[] blockN1 = new byte[BLOCK_SIZE];
+
+        System.arraycopy(data, offset, blockN2, 0, BLOCK_SIZE);
+        cbcEnc(blockN2, 0, 1, cipherState);
+        System.arraycopy(data, offset + BLOCK_SIZE, blockN1, 0, lastBlockLen);
+        cbcEnc(blockN1, 0, 1, cipherState);
+
+        System.arraycopy(blockN1, 0, data, offset, BLOCK_SIZE);
+        System.arraycopy(blockN2, 0, data, offset + BLOCK_SIZE, lastBlockLen);
+
+        if (iv != null) {
+            System.arraycopy(cipherState, 0, iv, 0, BLOCK_SIZE);
+        }
+    }
+
+    public void decrypt(byte[] data, byte[] iv) {
+        byte[] cipher = new byte[BLOCK_SIZE];
+        byte[] cipherState = new byte[BLOCK_SIZE];
+
+        int blocksNum = (data.length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        int lastBlockLen = data.length - (blocksNum - 1) * BLOCK_SIZE;
+        if (blocksNum == 1) {
+            cbcDec(data, 0, 1, cipherState);
+            return;
+        }
+
+        if (iv != null) {
+            System.arraycopy(iv, 0, cipherState, 0, BLOCK_SIZE);
+        }
+
+        int contBlocksNum, offset = 0;
+        while (blocksNum > 2) {
+            contBlocksNum = (data.length - offset) / BLOCK_SIZE;
+            if (contBlocksNum > 0) {
+                // Decrypt a series of contiguous blocks in place if we can, but
+                // don't touch the last two blocks.
+                contBlocksNum = (contBlocksNum > blocksNum - 2) ? blocksNum - 2 : contBlocksNum;
+                cbcDec(data, offset, contBlocksNum, cipherState);
+                offset += contBlocksNum * BLOCK_SIZE;
+                blocksNum -= contBlocksNum;
+            } else {
+                cbcDec(data, offset, 1, cipherState);
+                offset += BLOCK_SIZE;
+                blocksNum--;
+            }
+        }
+
+        // Decrypt the last two blocks
+        byte[] blockN2 = new byte[BLOCK_SIZE];
+        byte[] blockN1 = new byte[BLOCK_SIZE];
+        System.arraycopy(data, offset, blockN2, 0, BLOCK_SIZE);
+        System.arraycopy(data, offset + BLOCK_SIZE, blockN1, 0, lastBlockLen);
+        if (iv != null) {
+            System.arraycopy(blockN2, 0, iv, 0, BLOCK_SIZE);
+        }
+
+        byte[] tmpCipherState = new byte[BLOCK_SIZE];
+        System.arraycopy(blockN1, 0, tmpCipherState, 0, BLOCK_SIZE);
+        cbcDec(blockN2, 0, 1, tmpCipherState);
+        System.arraycopy(blockN2, lastBlockLen, blockN1, lastBlockLen, BLOCK_SIZE - lastBlockLen);
+        cbcDec(blockN1, 0, 1, cipherState);
+
+        System.arraycopy(blockN1, 0, data, offset, BLOCK_SIZE);
+        System.arraycopy(blockN2, 0, data, offset + BLOCK_SIZE, lastBlockLen);
+    }
+
+    /**
+     * CBC encrypt nblocks blocks of data in place, using and updating iv.
+     */
+    public void cbcEnc(byte[] data, int offset, int blocksNum, byte[] cipherState) {
+        byte[] cipher = new byte[BLOCK_SIZE];
+        for (int i = 0; i < blocksNum; ++i) {
+            System.arraycopy(data, offset + i * BLOCK_SIZE, cipher, 0, BLOCK_SIZE);
+            BytesUtil.xor(cipherState, 0, cipher);
+            processBlock(cipher, 0);
+            System.arraycopy(cipher, 0, data, offset + i * BLOCK_SIZE, BLOCK_SIZE);
+            System.arraycopy(cipher, 0, cipherState, 0, BLOCK_SIZE);
+        }
+    }
+
+    /**
+     * CBC encrypt nblocks blocks of data in place, using and updating iv.
+     */
+    public void cbcDec(byte[] data, int offset, int blocksNum, byte[] cipherState) {
+        byte[] lastBlock = new byte[BLOCK_SIZE];
+        byte[] cipher = new byte[BLOCK_SIZE];
+
+        System.arraycopy(data, offset + (blocksNum - 1) * BLOCK_SIZE, lastBlock, 0, BLOCK_SIZE);
+        for (int i = blocksNum; i > 0; i--) {
+            System.arraycopy(data, offset + (i - 1) * BLOCK_SIZE, cipher, 0, BLOCK_SIZE);
+            processBlock(cipher, 0);
+
+            if (i == 1) {
+                BytesUtil.xor(cipherState, 0, cipher);
+            } else {
+                BytesUtil.xor(data, offset + (i - 2) * BLOCK_SIZE, cipher);
+            }
+
+            System.arraycopy(cipher, 0, data, offset + (i - 1) * BLOCK_SIZE, BLOCK_SIZE);
+        }
+        System.arraycopy(lastBlock, 0, cipherState, 0, BLOCK_SIZE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/CamelliaKey.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/CamelliaKey.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/CamelliaKey.java
new file mode 100644
index 0000000..3a640a8
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/CamelliaKey.java
@@ -0,0 +1,433 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+/**
+ * Camellia - based on RFC 3713, about half the size of CamelliaEngine.
+ *
+ * This is based on CamelliaEngine.java from bouncycastle library.
+ */
+
+public class CamelliaKey {
+    private int keySize;
+
+    protected int[] subkey = new int[24 * 4];
+    protected int[] kw = new int[4 * 2]; // for whitening
+    protected int[] ke = new int[6 * 2]; // for FL and FL^(-1)
+
+    private static final int SIGMA[] = {
+            0xa09e667f, 0x3bcc908b,
+            0xb67ae858, 0x4caa73b2,
+            0xc6ef372f, 0xe94f82be,
+            0x54ff53a5, 0xf1d36f1c,
+            0x10e527fa, 0xde682d1d,
+            0xb05688c2, 0xb3e6c1fd
+    };
+
+    // S-box data
+    protected static final byte SBOX1[] = {
+            (byte)112, (byte)130, (byte)44, (byte)236,
+            (byte)179, (byte)39, (byte)192, (byte)229,
+            (byte)228, (byte)133, (byte)87, (byte)53,
+            (byte)234, (byte)12, (byte)174, (byte)65,
+            (byte)35, (byte)239, (byte)107, (byte)147,
+            (byte)69, (byte)25, (byte)165, (byte)33,
+            (byte)237, (byte)14, (byte)79, (byte)78,
+            (byte)29, (byte)101, (byte)146, (byte)189,
+            (byte)134, (byte)184, (byte)175, (byte)143,
+            (byte)124, (byte)235, (byte)31, (byte)206,
+            (byte)62, (byte)48, (byte)220, (byte)95,
+            (byte)94, (byte)197, (byte)11, (byte)26,
+            (byte)166, (byte)225, (byte)57, (byte)202,
+            (byte)213, (byte)71, (byte)93, (byte)61,
+            (byte)217, (byte)1, (byte)90, (byte)214,
+            (byte)81, (byte)86, (byte)108, (byte)77,
+            (byte)139, (byte)13, (byte)154, (byte)102,
+            (byte)251, (byte)204, (byte)176, (byte)45,
+            (byte)116, (byte)18, (byte)43, (byte)32,
+            (byte)240, (byte)177, (byte)132, (byte)153,
+            (byte)223, (byte)76, (byte)203, (byte)194,
+            (byte)52, (byte)126, (byte)118, (byte)5,
+            (byte)109, (byte)183, (byte)169, (byte)49,
+            (byte)209, (byte)23, (byte)4, (byte)215,
+            (byte)20, (byte)88, (byte)58, (byte)97,
+            (byte)222, (byte)27, (byte)17, (byte)28,
+            (byte)50, (byte)15, (byte)156, (byte)22,
+            (byte)83, (byte)24, (byte)242, (byte)34,
+            (byte)254, (byte)68, (byte)207, (byte)178,
+            (byte)195, (byte)181, (byte)122, (byte)145,
+            (byte)36, (byte)8, (byte)232, (byte)168,
+            (byte)96, (byte)252, (byte)105, (byte)80,
+            (byte)170, (byte)208, (byte)160, (byte)125,
+            (byte)161, (byte)137, (byte)98, (byte)151,
+            (byte)84, (byte)91, (byte)30, (byte)149,
+            (byte)224, (byte)255, (byte)100, (byte)210,
+            (byte)16, (byte)196, (byte)0, (byte)72,
+            (byte)163, (byte)247, (byte)117, (byte)219,
+            (byte)138, (byte)3, (byte)230, (byte)218,
+            (byte)9, (byte)63, (byte)221, (byte)148,
+            (byte)135, (byte)92, (byte)131, (byte)2,
+            (byte)205, (byte)74, (byte)144, (byte)51,
+            (byte)115, (byte)103, (byte)246, (byte)243,
+            (byte)157, (byte)127, (byte)191, (byte)226,
+            (byte)82, (byte)155, (byte)216, (byte)38,
+            (byte)200, (byte)55, (byte)198, (byte)59,
+            (byte)129, (byte)150, (byte)111, (byte)75,
+            (byte)19, (byte)190, (byte)99, (byte)46,
+            (byte)233, (byte)121, (byte)167, (byte)140,
+            (byte)159, (byte)110, (byte)188, (byte)142,
+            (byte)41, (byte)245, (byte)249, (byte)182,
+            (byte)47, (byte)253, (byte)180, (byte)89,
+            (byte)120, (byte)152, (byte)6, (byte)106,
+            (byte)231, (byte)70, (byte)113, (byte)186,
+            (byte)212, (byte)37, (byte)171, (byte)66,
+            (byte)136, (byte)162, (byte)141, (byte)250,
+            (byte)114, (byte)7, (byte)185, (byte)85,
+            (byte)248, (byte)238, (byte)172, (byte)10,
+            (byte)54, (byte)73, (byte)42, (byte)104,
+            (byte)60, (byte)56, (byte)241, (byte)164,
+            (byte)64, (byte)40, (byte)211, (byte)123,
+            (byte)187, (byte)201, (byte)67, (byte)193,
+            (byte)21, (byte)227, (byte)173, (byte)244,
+            (byte)119, (byte)199, (byte)128, (byte)158
+    };
+
+    public CamelliaKey(byte[] key, boolean isEncrypt) {
+        init(key, isEncrypt);
+    }
+
+    protected boolean is128() {
+        return keySize == 16;
+    }
+
+    private static int rightRotate(int x, int s) {
+        return (((x) >>> (s)) + ((x) << (32 - s)));
+    }
+
+    private static int leftRotate(int x, int s) {
+        return ((x) << (s)) + ((x) >>> (32 - s));
+    }
+
+    private static void roldq(int rot, int[] ki, int ioff,
+                              int[] ko, int ooff) {
+        ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot));
+        ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot));
+        ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot));
+        ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot));
+        ki[0 + ioff] = ko[0 + ooff];
+        ki[1 + ioff] = ko[1 + ooff];
+        ki[2 + ioff] = ko[2 + ooff];
+        ki[3 + ioff] = ko[3 + ooff];
+    }
+
+    private static void decroldq(int rot, int[] ki, int ioff,
+                                 int[] ko, int ooff) {
+        ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >>> (32 - rot));
+        ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >>> (32 - rot));
+        ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >>> (32 - rot));
+        ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >>> (32 - rot));
+        ki[0 + ioff] = ko[2 + ooff];
+        ki[1 + ioff] = ko[3 + ooff];
+        ki[2 + ioff] = ko[0 + ooff];
+        ki[3 + ioff] = ko[1 + ooff];
+    }
+
+    private static void roldqo32(int rot, int[] ki, int ioff,
+                                 int[] ko, int ooff)
+    {
+        ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot));
+        ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot));
+        ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot));
+        ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot));
+        ki[0 + ioff] = ko[0 + ooff];
+        ki[1 + ioff] = ko[1 + ooff];
+        ki[2 + ioff] = ko[2 + ooff];
+        ki[3 + ioff] = ko[3 + ooff];
+    }
+
+    private static void decroldqo32(int rot, int[] ki, int ioff,
+                                    int[] ko, int ooff) {
+        ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >>> (64 - rot));
+        ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >>> (64 - rot));
+        ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >>> (64 - rot));
+        ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >>> (64 - rot));
+        ki[0 + ioff] = ko[2 + ooff];
+        ki[1 + ioff] = ko[3 + ooff];
+        ki[2 + ioff] = ko[0 + ooff];
+        ki[3 + ioff] = ko[1 + ooff];
+    }
+
+    private byte lRot8(byte v, int rot)
+    {
+        return (byte)((v << rot) | ((v & 0xff) >>> (8 - rot)));
+    }
+
+    private int sbox2(int x)
+    {
+        return (lRot8(SBOX1[x], 1) & 0xff);
+    }
+
+    private int sbox3(int x)
+    {
+        return (lRot8(SBOX1[x], 7) & 0xff);
+    }
+
+    private int sbox4(int x)
+    {
+        return (SBOX1[((int)lRot8((byte)x, 1) & 0xff)] & 0xff);
+    }
+
+    protected void fls(int[] s, int[] fkey, int keyoff) {
+        s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1);
+        s[0] ^= fkey[1 + keyoff] | s[1];
+
+        s[2] ^= fkey[3 + keyoff] | s[3];
+        s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1);
+    }
+
+    protected void f2(int[] s, int[] skey, int keyoff) {
+        int t1, t2, u, v;
+
+        t1 = s[0] ^ skey[0 + keyoff];
+        u = sbox4((t1 & 0xff));
+        u |= (sbox3(((t1 >>> 8) & 0xff)) << 8);
+        u |= (sbox2(((t1 >>> 16) & 0xff)) << 16);
+        u |= ((int)(SBOX1[((t1 >>> 24) & 0xff)] & 0xff) << 24);
+
+        t2 = s[1] ^ skey[1 + keyoff];
+        v = (int)SBOX1[(t2 & 0xff)] & 0xff;
+        v |= (sbox4(((t2 >>> 8) & 0xff)) << 8);
+        v |= (sbox3(((t2 >>> 16) & 0xff)) << 16);
+        v |= (sbox2(((t2 >>> 24) & 0xff)) << 24);
+
+        v = leftRotate(v, 8);
+        u ^= v;
+        v = leftRotate(v, 8) ^ u;
+        u = rightRotate(u, 8) ^ v;
+        s[2] ^= leftRotate(v, 16) ^ u;
+        s[3] ^= leftRotate(u, 8);
+
+        t1 = s[2] ^ skey[2 + keyoff];
+        u = sbox4((t1 & 0xff));
+        u |= sbox3(((t1 >>> 8) & 0xff)) << 8;
+        u |= sbox2(((t1 >>> 16) & 0xff)) << 16;
+        u |= ((int)SBOX1[((t1 >>> 24) & 0xff)] & 0xff) << 24;
+
+        t2 = s[3] ^ skey[3 + keyoff];
+        v = ((int)SBOX1[(t2 & 0xff)] & 0xff);
+        v |= sbox4(((t2 >>> 8) & 0xff)) << 8;
+        v |= sbox3(((t2 >>> 16) & 0xff)) << 16;
+        v |= sbox2(((t2 >>> 24) & 0xff)) << 24;
+
+        v = leftRotate(v, 8);
+        u ^= v;
+        v = leftRotate(v, 8) ^ u;
+        u = rightRotate(u, 8) ^ v;
+        s[0] ^= leftRotate(v, 16) ^ u;
+        s[1] ^= leftRotate(u, 8);
+    }
+
+    private void init(byte[] key, boolean isEncrypt) {
+        keySize = key.length;
+
+        int[] k = new int[8];
+        int[] ka = new int[4];
+        int[] kb = new int[4];
+        int[] t = new int[4];
+
+        switch (key.length) {
+            case 16:
+                k[0] = BytesUtil.bytes2int(key, 0, true);
+                k[1] = BytesUtil.bytes2int(key, 4, true);
+                k[2] = BytesUtil.bytes2int(key, 8, true);
+                k[3] = BytesUtil.bytes2int(key, 12, true);
+                k[4] = k[5] = k[6] = k[7] = 0;
+                break;
+            case 24:
+                k[0] = BytesUtil.bytes2int(key, 0, true);
+                k[1] = BytesUtil.bytes2int(key, 4, true);
+                k[2] = BytesUtil.bytes2int(key, 8, true);
+                k[3] = BytesUtil.bytes2int(key, 12, true);
+                k[4] = BytesUtil.bytes2int(key, 16, true);
+                k[5] = BytesUtil.bytes2int(key, 20, true);
+                k[6] = ~k[4];
+                k[7] = ~k[5];
+                break;
+            case 32:
+                k[0] = BytesUtil.bytes2int(key, 0, true);
+                k[1] = BytesUtil.bytes2int(key, 4, true);
+                k[2] = BytesUtil.bytes2int(key, 8, true);
+                k[3] = BytesUtil.bytes2int(key, 12, true);
+                k[4] = BytesUtil.bytes2int(key, 16, true);
+                k[5] = BytesUtil.bytes2int(key, 20, true);
+                k[6] = BytesUtil.bytes2int(key, 24, true);
+                k[7] = BytesUtil.bytes2int(key, 28, true);
+                break;
+            default:
+                throw new
+                        IllegalArgumentException("Invalid key size, only support 16/24/32 bytes");
+        }
+
+        for (int i = 0; i < 4; i++) {
+            ka[i] = k[i] ^ k[i + 4];
+        }
+
+        /* compute KA */
+        f2(ka, SIGMA, 0);
+        for (int i = 0; i < 4; i++) {
+            ka[i] ^= k[i];
+        }
+        f2(ka, SIGMA, 4);
+
+        if (keySize == 16) {
+            if (isEncrypt) {
+                /* KL dependant keys */
+                kw[0] = k[0];
+                kw[1] = k[1];
+                kw[2] = k[2];
+                kw[3] = k[3];
+                roldq(15, k, 0, subkey, 4);
+                roldq(30, k, 0, subkey, 12);
+                roldq(15, k, 0, t, 0);
+                subkey[18] = t[2];
+                subkey[19] = t[3];
+                roldq(17, k, 0, ke, 4);
+                roldq(17, k, 0, subkey, 24);
+                roldq(17, k, 0, subkey, 32);
+                /* KA dependant keys */
+                subkey[0] = ka[0];
+                subkey[1] = ka[1];
+                subkey[2] = ka[2];
+                subkey[3] = ka[3];
+                roldq(15, ka, 0, subkey, 8);
+                roldq(15, ka, 0, ke, 0);
+                roldq(15, ka, 0, t, 0);
+                subkey[16] = t[0];
+                subkey[17] = t[1];
+                roldq(15, ka, 0, subkey, 20);
+                roldqo32(34, ka, 0, subkey, 28);
+                roldq(17, ka, 0, kw, 4);
+
+            } else { // decryption
+                /* KL dependant keys */
+                kw[4] = k[0];
+                kw[5] = k[1];
+                kw[6] = k[2];
+                kw[7] = k[3];
+                decroldq(15, k, 0, subkey, 28);
+                decroldq(30, k, 0, subkey, 20);
+                decroldq(15, k, 0, t, 0);
+                subkey[16] = t[0];
+                subkey[17] = t[1];
+                decroldq(17, k, 0, ke, 0);
+                decroldq(17, k, 0, subkey, 8);
+                decroldq(17, k, 0, subkey, 0);
+                /* KA dependant keys */
+                subkey[34] = ka[0];
+                subkey[35] = ka[1];
+                subkey[32] = ka[2];
+                subkey[33] = ka[3];
+                decroldq(15, ka, 0, subkey, 24);
+                decroldq(15, ka, 0, ke, 4);
+                decroldq(15, ka, 0, t, 0);
+                subkey[18] = t[2];
+                subkey[19] = t[3];
+                decroldq(15, ka, 0, subkey, 12);
+                decroldqo32(34, ka, 0, subkey, 4);
+                roldq(17, ka, 0, kw, 0);
+            }
+        } else { // 192bit or 256bit
+            /* compute KB */
+            for (int i = 0; i < 4; i++) {
+                kb[i] = ka[i] ^ k[i + 4];
+            }
+            f2(kb, SIGMA, 8);
+
+            if (isEncrypt) {
+                /* KL dependant keys */
+                kw[0] = k[0];
+                kw[1] = k[1];
+                kw[2] = k[2];
+                kw[3] = k[3];
+                roldqo32(45, k, 0, subkey, 16);
+                roldq(15, k, 0, ke, 4);
+                roldq(17, k, 0, subkey, 32);
+                roldqo32(34, k, 0, subkey, 44);
+                /* KR dependant keys */
+                roldq(15, k, 4, subkey, 4);
+                roldq(15, k, 4, ke, 0);
+                roldq(30, k, 4, subkey, 24);
+                roldqo32(34, k, 4, subkey, 36);
+                /* KA dependant keys */
+                roldq(15, ka, 0, subkey, 8);
+                roldq(30, ka, 0, subkey, 20);
+                /* 32bit rotation */
+                ke[8] = ka[1];
+                ke[9] = ka[2];
+                ke[10] = ka[3];
+                ke[11] = ka[0];
+                roldqo32(49, ka, 0, subkey, 40);
+
+                /* KB dependant keys */
+                subkey[0] = kb[0];
+                subkey[1] = kb[1];
+                subkey[2] = kb[2];
+                subkey[3] = kb[3];
+                roldq(30, kb, 0, subkey, 12);
+                roldq(30, kb, 0, subkey, 28);
+                roldqo32(51, kb, 0, kw, 4);
+
+            } else { // decryption
+                /* KL dependant keys */
+                kw[4] = k[0];
+                kw[5] = k[1];
+                kw[6] = k[2];
+                kw[7] = k[3];
+                decroldqo32(45, k, 0, subkey, 28);
+                decroldq(15, k, 0, ke, 4);
+                decroldq(17, k, 0, subkey, 12);
+                decroldqo32(34, k, 0, subkey, 0);
+                /* KR dependant keys */
+                decroldq(15, k, 4, subkey, 40);
+                decroldq(15, k, 4, ke, 8);
+                decroldq(30, k, 4, subkey, 20);
+                decroldqo32(34, k, 4, subkey, 8);
+                /* KA dependant keys */
+                decroldq(15, ka, 0, subkey, 36);
+                decroldq(30, ka, 0, subkey, 24);
+                /* 32bit rotation */
+                ke[2] = ka[1];
+                ke[3] = ka[2];
+                ke[0] = ka[3];
+                ke[1] = ka[0];
+                decroldqo32(49, ka, 0, subkey, 4);
+
+                /* KB dependant keys */
+                subkey[46] = kb[0];
+                subkey[47] = kb[1];
+                subkey[44] = kb[2];
+                subkey[45] = kb[3];
+                decroldq(30, kb, 0, subkey, 32);
+                decroldq(30, kb, 0, subkey, 16);
+                roldqo32(51, kb, 0, kw, 0);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Cmac.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Cmac.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Cmac.java
new file mode 100644
index 0000000..36397f1
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Cmac.java
@@ -0,0 +1,178 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+import org.apache.kerby.kerberos.kerb.crypto.enc.EncryptProvider;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.util.Arrays;
+
+/**
+ * Based on MIT krb5 cmac.c
+ */
+public class Cmac {
+
+    private static byte[] constRb = {
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x87
+    };
+
+    public static byte[] cmac(EncryptProvider encProvider, byte[] key,
+                       byte[] data, int outputSize) throws KrbException {
+        return cmac(encProvider, key, data, 0, data.length, outputSize);
+    }
+
+    public static byte[] cmac(EncryptProvider encProvider, byte[] key, byte[] data,
+                       int start, int len, int outputSize) throws KrbException {
+        byte[] hash = Cmac.cmac(encProvider, key, data, start, len);
+        if (hash.length > outputSize) {
+            byte[] output = new byte[outputSize];
+            System.arraycopy(hash, 0, output, 0, outputSize);
+            return output;
+        } else {
+            return hash;
+        }
+    }
+
+    public static byte[] cmac(EncryptProvider encProvider,
+                              byte[] key, byte[] data) throws KrbException {
+        return cmac(encProvider, key, data, 0, data.length);
+    }
+
+    public static byte[] cmac(EncryptProvider encProvider,
+                              byte[] key, byte[] data, int start, int len) throws KrbException {
+
+        int blockSize = encProvider.blockSize();
+
+        byte[] Y = new byte[blockSize];
+        byte[] mLast = new byte[blockSize];
+        byte[] padded = new byte[blockSize];
+        byte[] K1 = new byte[blockSize];
+        byte[] K2 = new byte[blockSize];
+
+        // step 1
+        makeSubkey(encProvider, key, K1, K2);
+
+        // step 2
+        int n = (len + blockSize - 1) / blockSize;
+
+        // step 3
+        boolean lastIsComplete;
+        if (n == 0) {
+            n = 1;
+            lastIsComplete = false;
+        } else {
+            lastIsComplete = ((len % blockSize) == 0);
+        }
+
+        // Step 6 (all but last block)
+        byte[] cipherState = new byte[blockSize];
+        byte[] cipher = new byte[blockSize];
+        for (int i = 0; i < n - 1; i++) {
+            System.arraycopy(data, i * blockSize, cipher, 0, blockSize);
+            encryptBlock(encProvider, key, cipherState, cipher);
+            System.arraycopy(cipher, 0, cipherState, 0, blockSize);
+        }
+
+        // step 5
+        System.arraycopy(cipher, 0, Y, 0, blockSize);
+
+        // step 4
+        int lastPos = (n - 1) * blockSize;
+        int lastLen = lastIsComplete ? blockSize : len % blockSize;
+        byte[] lastBlock = new byte[lastLen];
+        System.arraycopy(data, lastPos, lastBlock, 0, lastLen);
+        if (lastIsComplete) {
+            BytesUtil.xor(lastBlock, K1, mLast);
+        } else {
+            padding(lastBlock, padded);
+            BytesUtil.xor(padded, K2, mLast);
+        }
+
+        // Step 6 (last block)
+        encryptBlock(encProvider, key, cipherState, mLast);
+
+        return mLast;
+    }
+
+    // Generate subkeys K1 and K2 as described in RFC 4493 figure 2.2.
+    private static void makeSubkey(EncryptProvider encProvider,
+                              byte[] key, byte[] K1, byte[] K2) throws KrbException {
+
+        // L := encrypt(K, const_Zero)
+        byte[] L = new byte[K1.length];
+        Arrays.fill(L, (byte) 0);
+        encryptBlock(encProvider, key, null, L);
+
+        // K1 := (MSB(L) == 0) ? L << 1 : (L << 1) XOR const_Rb
+        if ((L[0] & 0x80) == 0) {
+            leftShiftByOne(L, K1);
+        } else {
+            byte[] tmp = new byte[K1.length];
+            leftShiftByOne(L, tmp);
+            BytesUtil.xor(tmp, constRb, K1);
+        }
+
+        // K2 := (MSB(K1) == 0) ? K1 << 1 : (K1 << 1) XOR const_Rb
+        if ((K1[0] & 0x80) == 0) {
+            leftShiftByOne(K1, K2);
+        } else {
+            byte[] tmp = new byte[K1.length];
+            leftShiftByOne(K1, tmp);
+            BytesUtil.xor(tmp, constRb, K2);
+        }
+    }
+
+    private static void encryptBlock(EncryptProvider encProvider,
+                                     byte[] key, byte[] cipherState, byte[] block) throws KrbException {
+        if (cipherState == null) {
+            cipherState = new byte[encProvider.blockSize()];
+        }
+        if (encProvider.supportCbcMac()) {
+            encProvider.cbcMac(key, cipherState, block);
+        } else {
+            encProvider.encrypt(key, cipherState, block);
+        }
+    }
+
+    private static void leftShiftByOne(byte[] input, byte[] output) {
+        byte overflow = 0;
+
+        for (int i = input.length - 1; i >= 0; i--) {
+            output[i] = (byte) (input[i] << 1);
+            output[i] |= overflow;
+            overflow = (byte) ((input[i] & 0x80) != 0 ? 1 : 0);
+        }
+    }
+
+    // Padding out data with a 1 bit followed by 0 bits, placing the result in pad
+    private static void padding(byte[] data, byte[] padded) {
+        int len = data.length;
+
+        // original last block
+        System.arraycopy(data, 0, padded, 0, len);
+
+        padded[len] = (byte) 0x80;
+
+        for (int i = len + 1; i < padded.length; i++) {
+            padded[i] = 0x00;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Confounder.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Confounder.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Confounder.java
new file mode 100644
index 0000000..b776f6a
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Confounder.java
@@ -0,0 +1,33 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+import java.security.SecureRandom;
+
+public final class Confounder {
+
+    private static SecureRandom instance = new SecureRandom();
+
+    public static byte[] makeBytes(int size) {
+        byte[] data = new byte[size];
+        instance.nextBytes(data);
+        return data;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Crc32.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Crc32.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Crc32.java
new file mode 100644
index 0000000..5807429
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Crc32.java
@@ -0,0 +1,78 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+/**
+ * Reference: http://introcs.cs.princeton.edu/java/51data/CRC32.java
+ */
+public class Crc32 {
+
+    private static long[] table = {
+            0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+            0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+            0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+            0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+            0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+            0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+            0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+            0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+            0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+            0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+            0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+            0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+            0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+            0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+            0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+            0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+            0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+            0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+            0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+            0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+            0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+            0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+            0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+            0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+            0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+            0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+            0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+            0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+            0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+            0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+            0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+            0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+    };
+
+    public static byte[] crc(byte[] data, int start, int size) {
+        long c = crc(0, data, start, size);
+        return BytesUtil.int2bytes((int) c, false);
+    }
+
+    public static long crc(long initial, byte[] data, int start, int len) {
+        long c = initial;
+
+        int idx;
+        for (int i = 0; i < len; i++) {
+            idx = (int) ((data[start + i] ^ c) & 0xff);
+            c = ((c & 0xffffffffL) >>> 8) ^ table[idx]; // why?
+        }
+
+        return c;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/f504a173/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Des.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Des.java b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Des.java
new file mode 100644
index 0000000..f7997fa
--- /dev/null
+++ b/kerby-kerb/kerb-crypto/src/main/java/org/apache/kerby/kerberos/kerb/crypto/util/Des.java
@@ -0,0 +1,84 @@
+/**
+ *  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. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.crypto.util;
+
+/**
+ * Ref. MIT krb5 weak_key.c
+ */
+public class Des {
+
+    /*
+     * The following are the weak DES keys:
+     */
+    static byte[][] WEAK_KEYS = {
+    /* weak keys */
+            {(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01},
+            {(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe},
+            {(byte) 0x1f,(byte) 0x1f,(byte) 0x1f,(byte) 0x1f,(byte) 0x0e,(byte) 0x0e,(byte) 0x0e,(byte) 0x0e},
+            {(byte) 0xe0,(byte) 0xe0,(byte) 0xe0,(byte) 0xe0,(byte) 0xf1,(byte) 0xf1,(byte) 0xf1,(byte) 0xf1},
+
+    /* semi-weak */
+            {(byte) 0x01,(byte) 0xfe,(byte) 0x01,(byte) 0xfe,(byte) 0x01,(byte) 0xfe,(byte) 0x01,(byte) 0xfe},
+            {(byte) 0xfe,(byte) 0x01,(byte) 0xfe,(byte) 0x01,(byte) 0xfe,(byte) 0x01,(byte) 0xfe,(byte) 0x01},
+
+            {(byte) 0x1f,(byte) 0xe0,(byte) 0x1f,(byte) 0xe0,(byte) 0x0e,(byte) 0xf1,(byte) 0x0e,(byte) 0xf1},
+            {(byte) 0xe0,(byte) 0x1f,(byte) 0xe0,(byte) 0x1f,(byte) 0xf1,(byte) 0x0e,(byte) 0xf1,(byte) 0x0e},
+
+            {(byte) 0x01,(byte) 0xe0,(byte) 0x01,(byte) 0xe0,(byte) 0x01,(byte) 0xf1,(byte) 0x01,(byte) 0xf1},
+            {(byte) 0xe0,(byte) 0x01,(byte) 0xe0,(byte) 0x01,(byte) 0xf1,(byte) 0x01,(byte) 0xf1,(byte) 0x01},
+
+            {(byte) 0x1f,(byte) 0xfe,(byte) 0x1f,(byte) 0xfe,(byte) 0x0e,(byte) 0xfe,(byte) 0x0e,(byte) 0xfe},
+            {(byte) 0xfe,(byte) 0x1f,(byte) 0xfe,(byte) 0x1f,(byte) 0xfe,(byte) 0x0e,(byte) 0xfe,(byte) 0x0e},
+
+            {(byte) 0x01,(byte) 0x1f,(byte) 0x01,(byte) 0x1f,(byte) 0x01,(byte) 0x0e,(byte) 0x01,(byte) 0x0e},
+            {(byte) 0x1f,(byte) 0x01,(byte) 0x1f,(byte) 0x01,(byte) 0x0e,(byte) 0x01,(byte) 0x0e,(byte) 0x01},
+
+            {(byte) 0xe0,(byte) 0xfe,(byte) 0xe0,(byte) 0xfe,(byte) 0xf1,(byte) 0xfe,(byte) 0xf1,(byte) 0xfe},
+            {(byte) 0xfe,(byte) 0xe0,(byte) 0xfe,(byte) 0xe0,(byte) 0xfe,(byte) 0xf1,(byte) 0xfe,(byte) 0xf1}
+    };
+
+    public static boolean isWeakKey(byte[] key, int offset, int len) {
+        boolean match;
+        for (byte[] weakKey : WEAK_KEYS) {
+            match = true;
+            if (weakKey.length == len) {
+                for (int i = 0; i < len; i++) {
+                    if (weakKey[i] != key[i]) {
+                        match = false;
+                        break;
+                    }
+                }
+            }
+            if (match) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * MIT krb5 FIXUP(k) in s2k_des.c
+     */
+    public static void fixKey(byte[] key, int offset, int len) {
+        if (isWeakKey(key, offset, len)) {
+            key[offset + 7] ^= (byte) 0xf0;
+        }
+    }
+}