jdk/test/java/security/MessageDigest/TestSameValue.java
changeset 38761 e31b47204f64
parent 30046 cf2c86e1819e
child 45288 58be10a068c2
equal deleted inserted replaced
38760:bd8975d946b8 38761:e31b47204f64
       
     1 
     1 /*
     2 /*
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * 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  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  * published by the Free Software Foundation.
    20  * or visit www.oracle.com if you need additional information or have any
    21  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  * questions.
    22  */
    23  */
    23 
    24 
    24 import static java.lang.System.out;
    25 import static java.lang.System.out;
    25 
       
    26 import java.nio.ByteBuffer;
    26 import java.nio.ByteBuffer;
    27 import java.security.DigestException;
    27 import java.security.DigestException;
    28 import java.security.MessageDigest;
    28 import java.security.MessageDigest;
    29 import java.util.Random;
    29 import java.security.NoSuchAlgorithmException;
       
    30 import java.security.Security;
       
    31 import jdk.testlibrary.RandomFactory;
    30 
    32 
    31 /**
    33 /**
    32  * @test
    34  * @test
    33  * @bug 8050371
    35  * @bug 8050371 8156059
    34  * @summary Check md.digest(data) value whether same with digest output value
    36  * @summary Check md.digest(data) value whether same with digest output value
    35  *          with various update/digest methods.
    37  *          with various update/digest methods.
    36  * @author Kevin Liu
    38  * @author Kevin Liu
    37  * @key randomness
    39  * @key randomness
       
    40  * @library /lib/testlibrary
    38  */
    41  */
    39 
    42 
    40 public class TestSameValue {
    43 public class TestSameValue {
    41 
    44 
    42     public static void main(String[] args) throws Exception {
    45     public static void main(String[] args) throws Exception {
    47     private void run() throws Exception {
    50     private void run() throws Exception {
    48 
    51 
    49         byte[] data = new byte[6706];
    52         byte[] data = new byte[6706];
    50         MessageDigest md = null;
    53         MessageDigest md = null;
    51         // Initialize input data
    54         // Initialize input data
    52         new Random().nextBytes(data);
    55         RandomFactory.getRandom().nextBytes(data);
    53 
    56 
    54         String[] providers = {
    57         String[] algorithmArr = { "SHA", "Sha", "MD5", "md5", "SHA-224",
    55                 null, "SUN"
    58                 "SHA-256", "SHA-384", "SHA-512", "SHA3-224", "SHA3-256",
    56         };
    59                 "SHA3-384", "SHA3-512" };
    57         String[] algorithmArr = {
    60 
    58                 "SHA", "Sha", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384",
    61         for (String algorithm : algorithmArr) {
    59                 "SHA-512"
    62             try {
    60         };
    63                 md = MessageDigest.getInstance(algorithm);
    61 
    64 
    62         for (String algorithm: algorithmArr) {
    65                 for (UpdateDigestMethod updateMethod : UpdateDigestMethod
    63             for (String provider: providers) {
       
    64                 if (provider != null) {
       
    65                     md = MessageDigest.getInstance(algorithm, provider);
       
    66                 } else {
       
    67                     md = MessageDigest.getInstance(algorithm);
       
    68                 }
       
    69                 for (UpdateDigestMethod updateMethod: UpdateDigestMethod
       
    70                         .values()) {
    66                         .values()) {
    71                     byte[] output = updateMethod.updateDigest(data, md);
    67                     byte[] output = updateMethod.updateDigest(data, md);
    72                     // Get the output and the "correct" one
    68                     // Get the output and the "correct" one
    73                     byte[] standard = md.digest(data);
    69                     byte[] standard = md.digest(data);
    74                     // Compare input and output
    70                     // Compare input and output
    75                     if (!MessageDigest.isEqual(output, standard)) {
    71                     if (!MessageDigest.isEqual(output, standard)) {
    76                         throw new RuntimeException(
    72                         throw new RuntimeException(
    77                                 "Test failed at algorithm/provider/numUpdate:"
    73                                 "Test failed at algorithm/provider/numUpdate:"
    78                                         + algorithm + "/" + provider + "/"
    74                                         + algorithm + "/" + md.getProvider()
    79                                         + updateMethod);
    75                                         + "/" + updateMethod);
    80                     }
    76                     }
    81                 }
    77                 }
       
    78             } catch (NoSuchAlgorithmException nae) {
       
    79                 if (algorithm.startsWith("SHA3") && !isSHA3supported()) {
       
    80                     continue;
       
    81                 } else {
       
    82                     throw nae;
       
    83                 }
    82             }
    84             }
    83         }
    85         }
    84 
    86 
    85         out.println("All " + algorithmArr.length
    87         out.println("All "
    86                 * UpdateDigestMethod.values().length * providers.length
    88                 + algorithmArr.length * UpdateDigestMethod.values().length
    87                 + " tests Passed");
    89                 + " tests Passed");
    88     }
    90     }
    89 
    91 
       
    92     // SHA-3 hash algorithms are only supported by "SUN" provider
       
    93     // and "OracleUcrypto" provider on Solaris 12.0 or later
       
    94     // This method checks if system supports SHA-3
       
    95     private boolean isSHA3supported() {
       
    96         if (Security.getProvider("SUN") != null) {
       
    97             return true;
       
    98         }
       
    99         if (Security.getProvider("OracleUcrypto") != null
       
   100                 && "SunOS".equals(System.getProperty("os.name"))
       
   101                 && System.getProperty("os.version").compareTo("5.12") >= 0) {
       
   102             return true;
       
   103         }
       
   104         return false;
       
   105     }
       
   106 
    90     private static enum UpdateDigestMethod {
   107     private static enum UpdateDigestMethod {
    91 
   108 
    92         /*
   109         /*
    93          * update the data one by one using method update(byte input) then
   110          * update the data one by one using method update(byte input) then do
    94          * do digest (giving the output buffer, offset, and the number of
   111          * digest (giving the output buffer, offset, and the number of bytes to
    95          * bytes to put in the output buffer)
   112          * put in the output buffer)
    96          */
   113          */
    97         UPDATE_DIGEST_BUFFER {
   114         UPDATE_DIGEST_BUFFER {
    98             @Override
   115             @Override
    99             public byte[] updateDigest(byte[] data, MessageDigest md)
   116             public byte[] updateDigest(byte[] data, MessageDigest md)
   100                     throws DigestException {
   117                     throws DigestException {
   101                 for (byte element: data) {
   118                 for (byte element : data) {
   102                     md.update(element);
   119                     md.update(element);
   103                 }
   120                 }
   104                 byte[] output = new byte[md.getDigestLength()];
   121                 byte[] output = new byte[md.getDigestLength()];
   105                 int len = md.digest(output, 0, output.length);
   122                 int len = md.digest(output, 0, output.length);
   106                 if (len != output.length) {
   123                 if (len != output.length) {
   107                     throw new RuntimeException(
   124                     throw new RuntimeException(
   108                         "ERROR" + ": digest length differs!");
   125                             "ERROR" + ": digest length differs!");
   109                 }
   126                 }
   110                 return output;
   127                 return output;
   111             }
   128             }
   112         },
   129         },
   113 
   130 
   114         /*
   131         /*
   115          * update the data one by one using method update(byte input)
   132          * update the data one by one using method update(byte input) then do
   116          * then do digest
   133          * digest
   117          */
   134          */
   118         UPDATE_DIGEST {
   135         UPDATE_DIGEST {
   119             @Override
   136             @Override
   120             public byte[] updateDigest(byte[] data, MessageDigest md) {
   137             public byte[] updateDigest(byte[] data, MessageDigest md) {
   121                 for (byte element: data) {
   138                 for (byte element : data) {
   122                     md.update(element);
   139                     md.update(element);
   123                 }
   140                 }
   124                 return md.digest();
   141                 return md.digest();
   125             }
   142             }
   126         },
   143         },
   137                 md.update(data);
   154                 md.update(data);
   138                 byte[] output = new byte[md.getDigestLength()];
   155                 byte[] output = new byte[md.getDigestLength()];
   139                 int len = md.digest(output, 0, output.length);
   156                 int len = md.digest(output, 0, output.length);
   140                 if (len != output.length) {
   157                 if (len != output.length) {
   141                     throw new RuntimeException(
   158                     throw new RuntimeException(
   142                         "ERROR" + ": digest length differs!");
   159                             "ERROR" + ": digest length differs!");
   143                 }
   160                 }
   144                 return output;
   161                 return output;
   145             }
   162             }
   146         },
   163         },
   147 
   164 
   153                 return md.digest();
   170                 return md.digest();
   154             }
   171             }
   155         },
   172         },
   156 
   173 
   157         /*
   174         /*
   158          * update the leading bytes (length is "data.length-LASTNBYTES")
   175          * update the leading bytes (length is "data.length-LASTNBYTES") at once
   159          * at once as a block, then do digest (do a final update using
   176          * as a block, then do digest (do a final update using the left
   160          * the left LASTNBYTES bytes which is passed as a parameter for
   177          * LASTNBYTES bytes which is passed as a parameter for the digest
   161          * the digest method, then complete the digest)
   178          * method, then complete the digest)
   162          */
   179          */
   163         UPDATE_LEADING_BLOCK_DIGEST_REMAIN {
   180         UPDATE_LEADING_BLOCK_DIGEST_REMAIN {
   164             @Override
   181             @Override
   165             public byte[] updateDigest(byte[] data, MessageDigest md) {
   182             public byte[] updateDigest(byte[] data, MessageDigest md) {
   166                 byte[] mainPart = new byte[data.length - LASTNBYTES];
   183                 byte[] mainPart = new byte[data.length - LASTNBYTES];
   174                 return md.digest(REMAIN);
   191                 return md.digest(REMAIN);
   175             }
   192             }
   176         },
   193         },
   177 
   194 
   178         /*
   195         /*
   179          * update the data 2 bytes each time, after finishing updating,
   196          * update the data 2 bytes each time, after finishing updating, do
   180          * do digest (giving the output buffer, offset, and the number
   197          * digest (giving the output buffer, offset, and the number of bytes to
   181          * of bytes to put in the output buffer)
   198          * put in the output buffer)
   182          */
   199          */
   183         UPDATE_BYTES_DIGEST_BUFFER {
   200         UPDATE_BYTES_DIGEST_BUFFER {
   184             @Override
   201             @Override
   185             public byte[] updateDigest(byte[] data, MessageDigest md)
   202             public byte[] updateDigest(byte[] data, MessageDigest md)
   186                     throws DigestException {
   203                     throws DigestException {
   190                 }
   207                 }
   191                 byte[] output = new byte[md.getDigestLength()];
   208                 byte[] output = new byte[md.getDigestLength()];
   192                 int len = md.digest(output, 0, output.length);
   209                 int len = md.digest(output, 0, output.length);
   193                 if (len != output.length) {
   210                 if (len != output.length) {
   194                     throw new RuntimeException(
   211                     throw new RuntimeException(
   195                         "ERROR" + ": digest length differs!");
   212                             "ERROR" + ": digest length differs!");
   196                 }
   213                 }
   197                 return output;
   214                 return output;
   198             }
   215             }
   199         },
   216         },
   200 
   217 
   201         /*
   218         /*
   202          * update the data 2 bytes each time, after finishing updating,
   219          * update the data 2 bytes each time, after finishing updating, do
   203          * do digest
   220          * digest
   204          */
   221          */
   205         UPDATE_BYTES_DIGEST {
   222         UPDATE_BYTES_DIGEST {
   206             @Override
   223             @Override
   207             public byte[] updateDigest(byte[] data, MessageDigest md) {
   224             public byte[] updateDigest(byte[] data, MessageDigest md) {
   208                 for (int i=0;i<data.length/2;i++){
   225                 for (int i = 0; i < data.length / 2; i++) {
   209                     md.update(data,i*2,2);
   226                     md.update(data, i * 2, 2);
   210                 }
   227                 }
   211                 return md.digest();
   228                 return md.digest();
   212             }
   229             }
   213         },
   230         },
   214 
   231 
   215         /*
   232         /*
   216          * update the data one by one using method update(byte[] input,
   233          * update the data one by one using method update(byte[] input, int
   217          * int offset, int len) for the leading bytes (length is
   234          * offset, int len) for the leading bytes (length is
   218          * "data.length-LASTNBYTES"), then do digest (do a final
   235          * "data.length-LASTNBYTES"), then do digest (do a final update using
   219          * update using the left LASTNBYTES bytes which is passed
   236          * the left LASTNBYTES bytes which is passed as a parameter for digest
   220          * as a parameter for digest method then complete the digest)
   237          * method then complete the digest)
   221          */
   238          */
   222         UPDATE_BUFFER_LEADING_DIGEST_REMAIN {
   239         UPDATE_BUFFER_LEADING_DIGEST_REMAIN {
   223             @Override
   240             @Override
   224             public byte[] updateDigest(byte[] data, MessageDigest md) {
   241             public byte[] updateDigest(byte[] data, MessageDigest md) {
   225                 for (int i = 0; i < data.length - LASTNBYTES; i++) {
   242                 for (int i = 0; i < data.length - LASTNBYTES; i++) {
   231                 return md.digest(REMAIN);
   248                 return md.digest(REMAIN);
   232             }
   249             }
   233         },
   250         },
   234 
   251 
   235         /*
   252         /*
   236          * update the data one by one using method update(byte input)
   253          * update the data one by one using method update(byte input) for the
   237          * for the leading bytes (length is "data.length-LASTNBYTES"),
   254          * leading bytes (length is "data.length-LASTNBYTES"), then do digest
   238          * then do digest (do a final update using the left LASTNBYTES
   255          * (do a final update using the left LASTNBYTES bytes which is passed as
   239          * bytes which is passed as a parameter for digest method,
   256          * a parameter for digest method, then complete the digest)
   240          * then complete the digest)
       
   241          */
   257          */
   242         UPDATE_LEADING_DIGEST_REMAIN {
   258         UPDATE_LEADING_DIGEST_REMAIN {
   243             @Override
   259             @Override
   244             public byte[] updateDigest(byte[] data, MessageDigest md) {
   260             public byte[] updateDigest(byte[] data, MessageDigest md) {
   245                 for (int i = 0; i < data.length - LASTNBYTES; i++) {
   261                 for (int i = 0; i < data.length - LASTNBYTES; i++) {
   251                 return md.digest(REMAIN);
   267                 return md.digest(REMAIN);
   252             }
   268             }
   253         },
   269         },
   254 
   270 
   255         /*
   271         /*
   256          * update all the data at once as a ByteBuffer, then do digest
   272          * update all the data at once as a ByteBuffer, then do digest (giving
   257          * (giving the output buffer, offset, and the number of bytes
   273          * the output buffer, offset, and the number of bytes to put in the
   258          * to put in the output buffer)
   274          * output buffer)
   259          */
   275          */
   260         UPDATE_BYTE_BUFFER_DIGEST_BUFFER {
   276         UPDATE_BYTE_BUFFER_DIGEST_BUFFER {
   261             @Override
   277             @Override
   262             public byte[] updateDigest(byte[] data, MessageDigest md)
   278             public byte[] updateDigest(byte[] data, MessageDigest md)
   263                     throws DigestException {
   279                     throws DigestException {
   264                 md.update(ByteBuffer.wrap(data));
   280                 md.update(ByteBuffer.wrap(data));
   265                 byte[] output = new byte[md.getDigestLength()];
   281                 byte[] output = new byte[md.getDigestLength()];
   266                 int len = md.digest(output, 0, output.length);
   282                 int len = md.digest(output, 0, output.length);
   267                 if (len != output.length) {
   283                 if (len != output.length) {
   268                     throw new RuntimeException(
   284                     throw new RuntimeException(
   269                           "ERROR" + ": digest length differs!");
   285                             "ERROR" + ": digest length differs!");
   270                 }
   286                 }
   271                 return output;
   287                 return output;
   272             }
   288             }
   273         },
   289         },
   274 
   290 
   280                 return md.digest();
   296                 return md.digest();
   281             }
   297             }
   282         },
   298         },
   283 
   299 
   284         /*
   300         /*
   285          * update the leading bytes (length is "data.length-LASTNBYTES")
   301          * update the leading bytes (length is "data.length-LASTNBYTES") at once
   286          * at once as a ByteBuffer, then do digest (do a final update
   302          * as a ByteBuffer, then do digest (do a final update using the left
   287          * using the left LASTNBYTES bytes which is passed as a parameter
   303          * LASTNBYTES bytes which is passed as a parameter for the digest
   288          * for the digest method, then complete the digest)
   304          * method, then complete the digest)
   289          */
   305          */
   290         UPDATE_BYTE_BUFFER_LEADING_DIGEST_REMAIN {
   306         UPDATE_BYTE_BUFFER_LEADING_DIGEST_REMAIN {
   291             @Override
   307             @Override
   292             public byte[] updateDigest(byte[] data, MessageDigest md) {
   308             public byte[] updateDigest(byte[] data, MessageDigest md) {
   293                 byte[] mainPart = new byte[data.length - LASTNBYTES];
   309                 byte[] mainPart = new byte[data.length - LASTNBYTES];