01: package ch.ethz.ssh2.crypto.digest;
02:
03: /**
04: * HMAC.
05: *
06: * @author Christian Plattner, plattner@inf.ethz.ch
07: * @version $Id: HMAC.java,v 1.2 2006/02/02 09:11:03 cplattne Exp $
08: */
09: public final class HMAC implements Digest {
10: Digest md;
11: byte[] k_xor_ipad;
12: byte[] k_xor_opad;
13:
14: byte[] tmp;
15:
16: int size;
17:
18: public HMAC(Digest md, byte[] key, int size) {
19: this .md = md;
20: this .size = size;
21:
22: tmp = new byte[md.getDigestLength()];
23:
24: int BLOCKSIZE = 64;
25:
26: k_xor_ipad = new byte[BLOCKSIZE];
27: k_xor_opad = new byte[BLOCKSIZE];
28:
29: if (key.length > BLOCKSIZE) {
30: md.reset();
31: md.update(key);
32: md.digest(tmp);
33: key = tmp;
34: }
35:
36: System.arraycopy(key, 0, k_xor_ipad, 0, key.length);
37: System.arraycopy(key, 0, k_xor_opad, 0, key.length);
38:
39: for (int i = 0; i < BLOCKSIZE; i++) {
40: k_xor_ipad[i] ^= 0x36;
41: k_xor_opad[i] ^= 0x5C;
42: }
43: md.update(k_xor_ipad);
44: }
45:
46: public final int getDigestLength() {
47: return size;
48: }
49:
50: public final void update(byte b) {
51: md.update(b);
52: }
53:
54: public final void update(byte[] b) {
55: md.update(b);
56: }
57:
58: public final void update(byte[] b, int off, int len) {
59: md.update(b, off, len);
60: }
61:
62: public final void reset() {
63: md.reset();
64: md.update(k_xor_ipad);
65: }
66:
67: public final void digest(byte[] out) {
68: digest(out, 0);
69: }
70:
71: public final void digest(byte[] out, int off) {
72: md.digest(tmp);
73:
74: md.update(k_xor_opad);
75: md.update(tmp);
76:
77: md.digest(tmp);
78:
79: System.arraycopy(tmp, 0, out, off, size);
80:
81: md.update(k_xor_ipad);
82: }
83: }
|