1 /*
   2  * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.crypto.provider;
  27 
  28 import java.nio.ByteBuffer;
  29 
  30 import javax.crypto.MacSpi;
  31 import javax.crypto.SecretKey;
  32 import java.security.*;
  33 import java.security.spec.*;
  34 
  35 /**
  36  * This is an implementation of the HMAC-MD5 algorithm.
  37  *
  38  * @author Jan Luehe
  39  */
  40 public final class HmacMD5 extends MacSpi implements Cloneable {
  41 
  42     private HmacCore hmac;
  43     private static final int MD5_BLOCK_LENGTH = 64;
  44 
  45     /**
  46      * Standard constructor, creates a new HmacMD5 instance.
  47      */
  48     public HmacMD5() throws NoSuchAlgorithmException {
  49         hmac = new HmacCore(MessageDigest.getInstance("MD5"),
  50                             MD5_BLOCK_LENGTH);
  51     }
  52 
  53     /**
  54      * Returns the length of the HMAC in bytes.
  55      *
  56      * @return the HMAC length in bytes.
  57      */
  58     protected int engineGetMacLength() {
  59         return hmac.getDigestLength();
  60     }
  61 
  62     /**
  63      * Initializes the HMAC with the given secret key and algorithm parameters.
  64      *
  65      * @param key the secret key.
  66      * @param params the algorithm parameters.
  67      *
  68      * @exception InvalidKeyException if the given key is inappropriate for
  69      * initializing this MAC.
  70      * @exception InvalidAlgorithmParameterException if the given algorithm
  71      * parameters are inappropriate for this MAC.
  72      */
  73     protected void engineInit(Key key, AlgorithmParameterSpec params)
  74         throws InvalidKeyException, InvalidAlgorithmParameterException {
  75         hmac.init(key, params);
  76     }
  77 
  78     /**
  79      * Processes the given byte.
  80      *
  81      * @param input the input byte to be processed.
  82      */
  83     protected void engineUpdate(byte input) {
  84         hmac.update(input);
  85     }
  86 
  87     /**
  88      * Processes the first <code>len</code> bytes in <code>input</code>,
  89      * starting at <code>offset</code>.
  90      *
  91      * @param input the input buffer.
  92      * @param offset the offset in <code>input</code> where the input starts.
  93      * @param len the number of bytes to process.
  94      */
  95     protected void engineUpdate(byte input[], int offset, int len) {
  96         hmac.update(input, offset, len);
  97     }
  98 
  99     protected void engineUpdate(ByteBuffer input) {
 100         hmac.update(input);
 101     }
 102 
 103     /**
 104      * Completes the HMAC computation and resets the HMAC for further use,
 105      * maintaining the secret key that the HMAC was initialized with.
 106      *
 107      * @return the HMAC result.
 108      */
 109     protected byte[] engineDoFinal() {
 110         return hmac.doFinal();
 111     }
 112 
 113     /**
 114      * Resets the HMAC for further use, maintaining the secret key that the
 115      * HMAC was initialized with.
 116      */
 117     protected void engineReset() {
 118         hmac.reset();
 119     }
 120 
 121     /*
 122      * Clones this object.
 123      */
 124     public Object clone() {
 125         HmacMD5 that = null;
 126         try {
 127             that = (HmacMD5) super.clone();
 128             that.hmac = (HmacCore) this.hmac.clone();
 129         } catch (CloneNotSupportedException e) {
 130         }
 131         return that;
 132     }
 133 }