FileDocCategorySizeDatePackage
HMac.javaAPI DocAndroid 1.5 API4684Wed May 06 22:41:06 BST 2009org.bouncycastle.crypto.macs

HMac

public class HMac extends Object implements org.bouncycastle.crypto.Mac
HMAC implementation based on RFC2104 H(K XOR opad, H(K XOR ipad, text))

Fields Summary
private static final byte
IPAD
private static final byte
OPAD
private org.bouncycastle.crypto.Digest
digest
private int
digestSize
private int
blockLength
private byte[]
inputPad
private byte[]
outputPad
private static Hashtable
blockLengths
Constructors Summary
public HMac(org.bouncycastle.crypto.Digest digest)
Base constructor for one of the standard digest algorithms that the byteLength of the algorithm is know for.

param
digest the digest.

        this(digest, getByteLength(digest));
    
private HMac(org.bouncycastle.crypto.Digest digest, int byteLength)

        this.digest = digest;
        digestSize = digest.getDigestSize();

        this.blockLength = byteLength;

        inputPad = new byte[blockLength];
        outputPad = new byte[blockLength];
    
Methods Summary
public intdoFinal(byte[] out, int outOff)

        byte[] tmp = new byte[digestSize];
        digest.doFinal(tmp, 0);

        digest.update(outputPad, 0, outputPad.length);
        digest.update(tmp, 0, tmp.length);

        int     len = digest.doFinal(out, outOff);

        reset();

        return len;
    
public java.lang.StringgetAlgorithmName()

        return digest.getAlgorithmName() + "/HMAC";
    
private static intgetByteLength(org.bouncycastle.crypto.Digest digest)

    
    
    
        blockLengths = new Hashtable();
        
        blockLengths.put("GOST3411", new Integer(32));
        
        blockLengths.put("MD2", new Integer(16));
        blockLengths.put("MD4", new Integer(64));
        blockLengths.put("MD5", new Integer(64));
        
        blockLengths.put("RIPEMD128", new Integer(64));
        blockLengths.put("RIPEMD160", new Integer(64));
        
        blockLengths.put("SHA-1", new Integer(64));
        blockLengths.put("SHA-224", new Integer(64));
        blockLengths.put("SHA-256", new Integer(64));
        blockLengths.put("SHA-384", new Integer(128));
        blockLengths.put("SHA-512", new Integer(128));
        
        blockLengths.put("Tiger", new Integer(64));
        blockLengths.put("Whirlpool", new Integer(64));
    
        if (digest instanceof ExtendedDigest)
        {
            return ((ExtendedDigest)digest).getByteLength();
        }
        
        Integer  b = (Integer)blockLengths.get(digest.getAlgorithmName());
        
        if (b == null)
        {       
            throw new IllegalArgumentException("unknown digest passed: " + digest.getAlgorithmName());
        }
        
        return b.intValue();
    
public intgetMacSize()

        return digestSize;
    
public org.bouncycastle.crypto.DigestgetUnderlyingDigest()

        return digest;
    
public voidinit(org.bouncycastle.crypto.CipherParameters params)

        digest.reset();

        byte[] key = ((KeyParameter)params).getKey();

        if (key.length > blockLength)
        {
            digest.update(key, 0, key.length);
            digest.doFinal(inputPad, 0);
            for (int i = digestSize; i < inputPad.length; i++)
            {
                inputPad[i] = 0;
            }
        }
        else
        {
            System.arraycopy(key, 0, inputPad, 0, key.length);
            for (int i = key.length; i < inputPad.length; i++)
            {
                inputPad[i] = 0;
            }
        }

        outputPad = new byte[inputPad.length];
        System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length);

        for (int i = 0; i < inputPad.length; i++)
        {
            inputPad[i] ^= IPAD;
        }

        for (int i = 0; i < outputPad.length; i++)
        {
            outputPad[i] ^= OPAD;
        }

        digest.update(inputPad, 0, inputPad.length);
    
public voidreset()
Reset the mac generator.

        /*
         * reset the underlying digest.
         */
        digest.reset();

        /*
         * reinitialize the digest.
         */
        digest.update(inputPad, 0, inputPad.length);
    
public voidupdate(byte in)

        digest.update(in);
    
public voidupdate(byte[] in, int inOff, int len)

        digest.update(in, inOff, len);