1 package org.bouncycastle.crypto.macs; 2 3 import org.bouncycastle.crypto.CipherParameters; 4 import org.bouncycastle.crypto.Digest; 5 import org.bouncycastle.crypto.Mac; 6 import org.bouncycastle.crypto.params.KeyParameter; 7 8 /** 9 * HMAC implementation based on RFC2104 10 * 11 * H(K XOR opad, H(K XOR ipad, text)) 12 */ 13 public class OldHMac 14 implements Mac 15 { 16 private final static int BLOCK_LENGTH = 64; 17 18 private final static byte IPAD = (byte)0x36; 19 private final static byte OPAD = (byte)0x5C; 20 21 private Digest digest; 22 private int digestSize; 23 private byte[] inputPad = new byte[BLOCK_LENGTH]; 24 private byte[] outputPad = new byte[BLOCK_LENGTH]; 25 26 /** 27 * @deprecated uses incorrect pad for SHA-512 and SHA-384 use HMac. 28 */ OldHMac( Digest digest)29 public OldHMac( 30 Digest digest) 31 { 32 this.digest = digest; 33 digestSize = digest.getDigestSize(); 34 } 35 getAlgorithmName()36 public String getAlgorithmName() 37 { 38 return digest.getAlgorithmName() + "/HMAC"; 39 } 40 getUnderlyingDigest()41 public Digest getUnderlyingDigest() 42 { 43 return digest; 44 } 45 init( CipherParameters params)46 public void init( 47 CipherParameters params) 48 { 49 digest.reset(); 50 51 byte[] key = ((KeyParameter)params).getKey(); 52 53 if (key.length > BLOCK_LENGTH) 54 { 55 digest.update(key, 0, key.length); 56 digest.doFinal(inputPad, 0); 57 for (int i = digestSize; i < inputPad.length; i++) 58 { 59 inputPad[i] = 0; 60 } 61 } 62 else 63 { 64 System.arraycopy(key, 0, inputPad, 0, key.length); 65 for (int i = key.length; i < inputPad.length; i++) 66 { 67 inputPad[i] = 0; 68 } 69 } 70 71 outputPad = new byte[inputPad.length]; 72 System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length); 73 74 for (int i = 0; i < inputPad.length; i++) 75 { 76 inputPad[i] ^= IPAD; 77 } 78 79 for (int i = 0; i < outputPad.length; i++) 80 { 81 outputPad[i] ^= OPAD; 82 } 83 84 digest.update(inputPad, 0, inputPad.length); 85 } 86 getMacSize()87 public int getMacSize() 88 { 89 return digestSize; 90 } 91 update( byte in)92 public void update( 93 byte in) 94 { 95 digest.update(in); 96 } 97 update( byte[] in, int inOff, int len)98 public void update( 99 byte[] in, 100 int inOff, 101 int len) 102 { 103 digest.update(in, inOff, len); 104 } 105 doFinal( byte[] out, int outOff)106 public int doFinal( 107 byte[] out, 108 int outOff) 109 { 110 byte[] tmp = new byte[digestSize]; 111 digest.doFinal(tmp, 0); 112 113 digest.update(outputPad, 0, outputPad.length); 114 digest.update(tmp, 0, tmp.length); 115 116 int len = digest.doFinal(out, outOff); 117 118 reset(); 119 120 return len; 121 } 122 123 /** 124 * Reset the mac generator. 125 */ reset()126 public void reset() 127 { 128 /* 129 * reset the underlying digest. 130 */ 131 digest.reset(); 132 133 /* 134 * reinitialize the digest. 135 */ 136 digest.update(inputPad, 0, inputPad.length); 137 } 138 } 139