1 2 /* 3 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 import static java.lang.System.out; 26 import java.nio.ByteBuffer; 27 import java.security.MessageDigest; 28 import java.security.NoSuchAlgorithmException; 29 import java.security.Security; 30 import jdk.testlibrary.RandomFactory; 31 32 /** 33 * @test 34 * @bug 8050371 8156059 35 * @summary Check md.getDigestLength() equal digest output length with various 36 * algorithm/dataLen/(update,digest methods). 37 * @author Kevin Liu 38 * @key randomness 39 * @library /lib/testlibrary 40 */ 41 42 public class TestSameLength { 43 44 public static void main(String[] args) throws Exception { 45 TestSameLength test = new TestSameLength(); 46 test.run(); 47 } 48 49 private void run() throws Exception { 50 String[] algorithmArr = { "SHA", "Sha", "SHA-1", "sha-1", "SHA1", 51 "sha1", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384", 52 "SHA-512", "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512" }; 53 int[] nUpdatesArr = { 0, 1, 2, 3 }; 54 int[] dataLenArr = { 1, 50, 2500, 125000, 6250000 }; 55 56 for (String algorithm : algorithmArr) { 57 for (UpdateMethod update : UpdateMethod.values()) { 58 for (int dataLen : dataLenArr) { 59 if (!runTest(algorithm, dataLen, update)) { 60 throw new RuntimeException( 61 "Test failed at algorithm/dataLen/numUpdate:" 62 + algorithm + "/" + dataLen + "/" 63 + update.toString()); 64 } 65 } 66 } 67 } 68 69 out.println("All " 70 + algorithmArr.length * nUpdatesArr.length * dataLenArr.length 71 + " tests Passed"); 72 } 73 74 private boolean runTest(String algo, long dataLen, UpdateMethod whichUpdate) 75 throws Exception { 76 try { 77 // Do initialization 78 byte[] data = new byte[(int) dataLen]; 79 RandomFactory.getRandom().nextBytes(data); 80 MessageDigest md = MessageDigest.getInstance(algo); 81 int outputLen = md.getDigestLength(); 82 83 // Perform the update using all available/possible update methods 84 whichUpdate.updateDigest(data, md, dataLen); 85 // Get the output 86 byte[] output = md.digest(); 87 88 // Compare input and output 89 return outputLen == output.length; 90 } catch (NoSuchAlgorithmException nae) { 91 if (algo.startsWith("SHA3") && !isSHA3supported()) { 92 return true; 93 } 94 throw nae; 95 } catch (Exception ex) { 96 System.err.println("Testing: " + algo + "/" + dataLen + "/" 97 + whichUpdate.toString() 98 + " failed with unexpected exception"); 99 ex.printStackTrace(); 100 throw ex; 101 } 102 } 103 104 // SHA-3 hash algorithms are only supported by "SUN" provider 105 // and "OracleUcrypto" provider on Solaris 12.0 or later 106 // This method checks if system supports SHA-3 107 private boolean isSHA3supported() { 108 if (Security.getProvider("SUN") != null) { 109 return true; 110 } 111 if (Security.getProvider("OracleUcrypto") != null 112 && "SunOS".equals(System.getProperty("os.name")) 113 && System.getProperty("os.version").compareTo("5.12") >= 0) { 114 return true; 115 } 116 return false; 117 } 118 119 private static enum UpdateMethod { 120 UPDATE_BYTE { 121 @Override 122 public void updateDigest(byte[] data, MessageDigest md, 123 long dataLen) { 124 125 for (int i = 0; i < dataLen; i++) { 126 md.update(data[i]); 127 } 128 } 129 }, 130 131 UPDATE_BUFFER { 132 @Override 133 public void updateDigest(byte[] data, MessageDigest md, 134 long dataLen) { 135 136 md.update(data); 137 } 138 }, 139 140 UPDATE_BUFFER_LEN { 141 @Override 142 public void updateDigest(byte[] data, MessageDigest md, 143 long dataLen) { 144 145 for (int i = 0; i < dataLen; i++) { 146 md.update(data, i, 1); 147 } 148 } 149 }, 150 151 UPDATE_BYTE_BUFFER { 152 @Override 153 public void updateDigest(byte[] data, MessageDigest md, 154 long dataLen) { 155 156 md.update(ByteBuffer.wrap(data)); 157 } 158 }; 159 160 public abstract void updateDigest(byte[] data, MessageDigest md, 161 long dataLen); 162 } 163 }