src/java.base/share/classes/sun/security/ssl/MAC.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 56541 92cbbfc996f3
child 56543 2352538d2f6e
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
     1 /*
       
     2  * Copyright (c) 1996, 2015, 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 sun.security.ssl;
       
    27 
       
    28 import java.security.InvalidKeyException;
       
    29 import java.security.NoSuchAlgorithmException;
       
    30 
       
    31 import java.nio.ByteBuffer;
       
    32 
       
    33 import javax.crypto.Mac;
       
    34 import javax.crypto.SecretKey;
       
    35 
       
    36 import sun.security.ssl.CipherSuite.MacAlg;
       
    37 import static sun.security.ssl.CipherSuite.*;
       
    38 import static sun.security.ssl.CipherSuite.MacAlg.*;
       
    39 
       
    40 /**
       
    41  * This class computes the "Message Authentication Code" (MAC) for each
       
    42  * SSL stream and block cipher message.  This is essentially a shared-secret
       
    43  * signature, used to provide integrity protection for SSL messages.  The
       
    44  * MAC is actually one of several keyed hashes, as associated with the cipher
       
    45  * suite and protocol version. (SSL v3.0 uses one construct, TLS uses another.)
       
    46  *
       
    47  * @author David Brownell
       
    48  * @author Andreas Sterbenz
       
    49  */
       
    50 final class MAC extends Authenticator {
       
    51 
       
    52     static final MAC TLS_NULL = new MAC(false);
       
    53 
       
    54     // Value of the null MAC is fixed
       
    55     private static final byte[] nullMAC = new byte[0];
       
    56 
       
    57     // internal identifier for the MAC algorithm
       
    58     private final MacAlg macAlg;
       
    59 
       
    60     // JCE Mac object
       
    61     private final Mac mac;
       
    62 
       
    63     MAC(boolean isDTLS) {
       
    64         super(isDTLS);
       
    65 
       
    66         macAlg = M_NULL;
       
    67         mac = null;
       
    68     }
       
    69 
       
    70     /**
       
    71      * Set up, configured for the given MAC type and version.
       
    72      */
       
    73     MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
       
    74             throws NoSuchAlgorithmException, InvalidKeyException {
       
    75         super(protocolVersion);
       
    76         this.macAlg = macAlg;
       
    77 
       
    78         String algorithm;
       
    79 
       
    80         // using SSL MAC computation?
       
    81         boolean useSSLMac = (protocolVersion.v < ProtocolVersion.TLS10.v);
       
    82 
       
    83         if (macAlg == M_MD5) {
       
    84             algorithm = useSSLMac ? "SslMacMD5" : "HmacMD5";
       
    85         } else if (macAlg == M_SHA) {
       
    86             algorithm = useSSLMac ? "SslMacSHA1" : "HmacSHA1";
       
    87         } else if (macAlg == M_SHA256) {
       
    88             algorithm = "HmacSHA256";    // TLS 1.2+
       
    89         } else if (macAlg == M_SHA384) {
       
    90             algorithm = "HmacSHA384";    // TLS 1.2+
       
    91         } else {
       
    92             throw new RuntimeException("Unknown Mac " + macAlg);
       
    93         }
       
    94 
       
    95         mac = JsseJce.getMac(algorithm);
       
    96         mac.init(key);
       
    97     }
       
    98 
       
    99     /**
       
   100      * Returns the length of the MAC.
       
   101      */
       
   102     int MAClen() {
       
   103         return macAlg.size;
       
   104     }
       
   105 
       
   106     /**
       
   107      * Returns the hash function block length of the MAC alorithm.
       
   108      */
       
   109     int hashBlockLen() {
       
   110         return macAlg.hashBlockSize;
       
   111     }
       
   112 
       
   113     /**
       
   114      * Returns the hash function minimal padding length of the MAC alorithm.
       
   115      */
       
   116     int minimalPaddingLen() {
       
   117         return macAlg.minimalPaddingSize;
       
   118     }
       
   119 
       
   120     /**
       
   121      * Computes and returns the MAC for the data in this byte array.
       
   122      *
       
   123      * @param type record type
       
   124      * @param buf compressed record on which the MAC is computed
       
   125      * @param offset start of compressed record data
       
   126      * @param len the size of the compressed record
       
   127      * @param isSimulated if true, simulate the MAC computation
       
   128      *
       
   129      * @return the MAC result
       
   130      */
       
   131     final byte[] compute(byte type, byte buf[],
       
   132             int offset, int len, boolean isSimulated) {
       
   133         if (macAlg.size == 0) {
       
   134             return nullMAC;
       
   135         }
       
   136 
       
   137         if (!isSimulated) {
       
   138             // Uses the implicit sequence number for the computation.
       
   139             byte[] additional = acquireAuthenticationBytes(type, len, null);
       
   140             mac.update(additional);
       
   141         }
       
   142         mac.update(buf, offset, len);
       
   143 
       
   144         return mac.doFinal();
       
   145     }
       
   146 
       
   147     /**
       
   148      * Compute and returns the MAC for the remaining data
       
   149      * in this ByteBuffer.
       
   150      *
       
   151      * On return, the bb position == limit, and limit will
       
   152      * have not changed.
       
   153      *
       
   154      * @param type record type
       
   155      * @param bb a ByteBuffer in which the position and limit
       
   156      *          demarcate the data to be MAC'd.
       
   157      * @param isSimulated if true, simulate the MAC computation
       
   158      * @param sequence the explicit sequence number, or null if using
       
   159      *        the implicit sequence number for the computation
       
   160      *
       
   161      * @return the MAC result
       
   162      */
       
   163     final byte[] compute(byte type, ByteBuffer bb,
       
   164             byte[] sequence, boolean isSimulated) {
       
   165 
       
   166         if (macAlg.size == 0) {
       
   167             return nullMAC;
       
   168         }
       
   169 
       
   170         if (!isSimulated) {
       
   171             // Uses the explicit sequence number for the computation.
       
   172             byte[] additional =
       
   173                     acquireAuthenticationBytes(type, bb.remaining(), sequence);
       
   174             mac.update(additional);
       
   175         }
       
   176         mac.update(bb);
       
   177 
       
   178         return mac.doFinal();
       
   179     }
       
   180 
       
   181     /**
       
   182      * Compute and returns the MAC for the remaining data
       
   183      * in this ByteBuffer.
       
   184      *
       
   185      * On return, the bb position == limit, and limit will
       
   186      * have not changed.
       
   187      *
       
   188      * @param type record type
       
   189      * @param bb a ByteBuffer in which the position and limit
       
   190      *        demarcate the data to be MAC'd.
       
   191      * @param isSimulated if true, simulate the MAC computation
       
   192      *
       
   193      * @return the MAC result
       
   194      */
       
   195     final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
       
   196         // Uses the implicit sequence number for the computation.
       
   197         return compute(type, bb, null, isSimulated);
       
   198     }
       
   199 }