Home | History | Annotate | Download | only in macs
      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      */
     29     public OldHMac(
     30         Digest digest)
     31     {
     32         this.digest = digest;
     33         digestSize = digest.getDigestSize();
     34     }
     35 
     36     public String getAlgorithmName()
     37     {
     38         return digest.getAlgorithmName() + "/HMAC";
     39     }
     40 
     41     public Digest getUnderlyingDigest()
     42     {
     43         return digest;
     44     }
     45 
     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 
     87     public int getMacSize()
     88     {
     89         return digestSize;
     90     }
     91 
     92     public void update(
     93         byte in)
     94     {
     95         digest.update(in);
     96     }
     97 
     98     public void update(
     99         byte[] in,
    100         int inOff,
    101         int len)
    102     {
    103         digest.update(in, inOff, len);
    104     }
    105 
    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      */
    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