Home | History | Annotate | Download | only in digest
      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