001: package org.bouncycastle.crypto.macs;
002:
003: import org.bouncycastle.crypto.CipherParameters;
004: import org.bouncycastle.crypto.Digest;
005: import org.bouncycastle.crypto.Mac;
006: import org.bouncycastle.crypto.params.KeyParameter;
007:
008: /**
009: * HMAC implementation based on RFC2104
010: *
011: * H(K XOR opad, H(K XOR ipad, text))
012: */
013: public class OldHMac implements Mac {
014: private final static int BLOCK_LENGTH = 64;
015:
016: private final static byte IPAD = (byte) 0x36;
017: private final static byte OPAD = (byte) 0x5C;
018:
019: private Digest digest;
020: private int digestSize;
021: private byte[] inputPad = new byte[BLOCK_LENGTH];
022: private byte[] outputPad = new byte[BLOCK_LENGTH];
023:
024: /**
025: * @deprecated uses incorrect pad for SHA-512 and SHA-384 use HMac.
026: */
027: public OldHMac(Digest digest) {
028: this .digest = digest;
029: digestSize = digest.getDigestSize();
030: }
031:
032: public String getAlgorithmName() {
033: return digest.getAlgorithmName() + "/HMAC";
034: }
035:
036: public Digest getUnderlyingDigest() {
037: return digest;
038: }
039:
040: public void init(CipherParameters params) {
041: digest.reset();
042:
043: byte[] key = ((KeyParameter) params).getKey();
044:
045: if (key.length > BLOCK_LENGTH) {
046: digest.update(key, 0, key.length);
047: digest.doFinal(inputPad, 0);
048: for (int i = digestSize; i < inputPad.length; i++) {
049: inputPad[i] = 0;
050: }
051: } else {
052: System.arraycopy(key, 0, inputPad, 0, key.length);
053: for (int i = key.length; i < inputPad.length; i++) {
054: inputPad[i] = 0;
055: }
056: }
057:
058: outputPad = new byte[inputPad.length];
059: System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length);
060:
061: for (int i = 0; i < inputPad.length; i++) {
062: inputPad[i] ^= IPAD;
063: }
064:
065: for (int i = 0; i < outputPad.length; i++) {
066: outputPad[i] ^= OPAD;
067: }
068:
069: digest.update(inputPad, 0, inputPad.length);
070: }
071:
072: public int getMacSize() {
073: return digestSize;
074: }
075:
076: public void update(byte in) {
077: digest.update(in);
078: }
079:
080: public void update(byte[] in, int inOff, int len) {
081: digest.update(in, inOff, len);
082: }
083:
084: public int doFinal(byte[] out, int outOff) {
085: byte[] tmp = new byte[digestSize];
086: digest.doFinal(tmp, 0);
087:
088: digest.update(outputPad, 0, outputPad.length);
089: digest.update(tmp, 0, tmp.length);
090:
091: int len = digest.doFinal(out, outOff);
092:
093: reset();
094:
095: return len;
096: }
097:
098: /**
099: * Reset the mac generator.
100: */
101: public void reset() {
102: /*
103: * reset the underlying digest.
104: */
105: digest.reset();
106:
107: /*
108: * reinitialize the digest.
109: */
110: digest.update(inputPad, 0, inputPad.length);
111: }
112: }
|