package org.apache.kerberos.kerb.crypto;
import org.apache.kerberos.kerb.crypto.cksum.HashProvider;
import org.apache.kerberos.kerb.KrbException;
import java.util.Arrays;
/**
* Based on MIT krb5 hmac.c
*/
public class Hmac {
public static byte[] hmac(HashProvider hashProvider, byte[] key,
byte[] data, int outputSize) throws KrbException {
return hmac(hashProvider, key, data, 0, data.length, outputSize);
}
public static byte[] hmac(HashProvider hashProvider, byte[] key, byte[] data,
int start, int len, int outputSize) throws KrbException {
byte[] hash = Hmac.hmac(hashProvider, key, data, start, len);
byte[] output = new byte[outputSize];
System.arraycopy(hash, 0, output, 0, outputSize);
return output;
}
public static byte[] hmac(HashProvider hashProvider,
byte[] key, byte[] data) throws KrbException {
return hmac(hashProvider, key, data, 0, data.length);
}
public static byte[] hmac(HashProvider hashProvider,
byte[] key, byte[] data, int start, int len) throws KrbException {
int blockLen = hashProvider.blockSize();
byte[] innerPaddedKey = new byte[blockLen];
byte[] outerPaddedKey = new byte[blockLen];
// Create the inner padded key
Arrays.fill(innerPaddedKey, (byte)0x36);
for (int i = 0; i < key.length; i++) {
innerPaddedKey[i] ^= key[i];
}
// Create the outer padded key
Arrays.fill(outerPaddedKey, (byte)0x5c);
for (int i = 0; i < key.length; i++) {
outerPaddedKey[i] ^= key[i];
}
hashProvider.hash(innerPaddedKey);
hashProvider.hash(data, start, len);
byte[] tmp = hashProvider.output();
hashProvider.hash(outerPaddedKey);
hashProvider.hash(tmp);
tmp = hashProvider.output();
return tmp;
}
}