1 /* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5 package ch.ethz.ssh2.crypto.digest; 6 7 /** 8 * HMAC. 9 * 10 * @author Christian Plattner 11 * @version 2.50, 03/15/10 12 */ 13 public final class HMAC implements Digest 14 { 15 Digest md; 16 byte[] k_xor_ipad; 17 byte[] k_xor_opad; 18 19 byte[] tmp; 20 21 int size; 22 23 public HMAC(Digest md, byte[] key, int size) 24 { 25 this.md = md; 26 this.size = size; 27 28 tmp = new byte[md.getDigestLength()]; 29 30 int blocksize = 64; 31 32 k_xor_ipad = new byte[blocksize]; 33 k_xor_opad = new byte[blocksize]; 34 35 if (key.length > blocksize) 36 { 37 md.reset(); 38 md.update(key); 39 md.digest(tmp); 40 key = tmp; 41 } 42 43 System.arraycopy(key, 0, k_xor_ipad, 0, key.length); 44 System.arraycopy(key, 0, k_xor_opad, 0, key.length); 45 46 for (int i = 0; i < blocksize; i++) 47 { 48 k_xor_ipad[i] ^= 0x36; 49 k_xor_opad[i] ^= 0x5C; 50 } 51 md.update(k_xor_ipad); 52 } 53 54 public int getDigestLength() 55 { 56 return size; 57 } 58 59 public void update(byte b) 60 { 61 md.update(b); 62 } 63 64 public void update(byte[] b) 65 { 66 md.update(b); 67 } 68 69 public void update(byte[] b, int off, int len) 70 { 71 md.update(b, off, len); 72 } 73 74 public void reset() 75 { 76 md.reset(); 77 md.update(k_xor_ipad); 78 } 79 80 public void digest(byte[] out) 81 { 82 digest(out, 0); 83 } 84 85 public void digest(byte[] out, int off) 86 { 87 md.digest(tmp); 88 89 md.update(k_xor_opad); 90 md.update(tmp); 91 92 md.digest(tmp); 93 94 System.arraycopy(tmp, 0, out, off, size); 95 96 md.update(k_xor_ipad); 97 } 98 } 99