| package org.bouncycastle.crypto.macs; |
| |
| import org.bouncycastle.crypto.CipherParameters; |
| import org.bouncycastle.crypto.Digest; |
| import org.bouncycastle.crypto.Mac; |
| import org.bouncycastle.crypto.params.KeyParameter; |
| |
| /** |
| * HMAC implementation based on RFC2104 |
| * |
| * H(K XOR opad, H(K XOR ipad, text)) |
| */ |
| public class OldHMac |
| implements Mac |
| { |
| private final static int BLOCK_LENGTH = 64; |
| |
| private final static byte IPAD = (byte)0x36; |
| private final static byte OPAD = (byte)0x5C; |
| |
| private Digest digest; |
| private int digestSize; |
| private byte[] inputPad = new byte[BLOCK_LENGTH]; |
| private byte[] outputPad = new byte[BLOCK_LENGTH]; |
| |
| /** |
| * @deprecated uses incorrect pad for SHA-512 and SHA-384 use HMac. |
| */ |
| public OldHMac( |
| Digest digest) |
| { |
| this.digest = digest; |
| digestSize = digest.getDigestSize(); |
| } |
| |
| public String getAlgorithmName() |
| { |
| return digest.getAlgorithmName() + "/HMAC"; |
| } |
| |
| public Digest getUnderlyingDigest() |
| { |
| return digest; |
| } |
| |
| public void init( |
| CipherParameters params) |
| { |
| digest.reset(); |
| |
| byte[] key = ((KeyParameter)params).getKey(); |
| |
| if (key.length > BLOCK_LENGTH) |
| { |
| 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 int getMacSize() |
| { |
| return digestSize; |
| } |
| |
| public void update( |
| byte in) |
| { |
| digest.update(in); |
| } |
| |
| public void update( |
| byte[] in, |
| int inOff, |
| int len) |
| { |
| digest.update(in, inOff, len); |
| } |
| |
| public int doFinal( |
| 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; |
| } |
| |
| /** |
| * Reset the mac generator. |
| */ |
| public void reset() |
| { |
| /* |
| * reset the underlying digest. |
| */ |
| digest.reset(); |
| |
| /* |
| * reinitialize the digest. |
| */ |
| digest.update(inputPad, 0, inputPad.length); |
| } |
| } |