Thu, 31 Jan 2019 04:49:46 -0800
8209951: Problematic sparc intrinsic: com.sun.crypto.provider.CipherBlockChaining
Reviewed-by: kvn, thartmann
Contributed-by: fairoz.matte@oracle.com
src/cpu/sparc/vm/stubGenerator_sparc.cpp | file | annotate | diff | comparison | revisions | |
test/compiler/8209951/TestCipherBlockChainingEncrypt.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jan 23 23:24:10 2019 -0800 1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Jan 31 04:49:46 2019 -0800 1.3 @@ -4483,7 +4483,7 @@ 1.4 // save F48:F54 in temp registers 1.5 __ movdtox(F54,G2); 1.6 __ movdtox(F52,G3); 1.7 - __ movdtox(F50,G6); 1.8 + __ movdtox(F50,L6); 1.9 __ movdtox(F48,G1); 1.10 for ( int i = 46; i >= 14; i -= 8 ) { 1.11 __ aes_dround23(as_FloatRegister(i), F0, F2, F4); 1.12 @@ -4511,7 +4511,7 @@ 1.13 // re-init F48:F54 with their original values 1.14 __ movxtod(G2,F54); 1.15 __ movxtod(G3,F52); 1.16 - __ movxtod(G6,F50); 1.17 + __ movxtod(L6,F50); 1.18 __ movxtod(G1,F48); 1.19 1.20 __ movxtod(L0,F6);
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/8209951/TestCipherBlockChainingEncrypt.java Thu Jan 31 04:49:46 2019 -0800 2.3 @@ -0,0 +1,136 @@ 2.4 +/* 2.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * @test 2.29 + * @bug 8209951 2.30 + * @summary SIGBUS in com.sun.crypto.provider.CipherBlockChaining 2.31 + * @run main/othervm/timeout=300 -Xbatch 2.32 + * compiler.codegen.aes.TestCipherBlockChainingEncrypt 2.33 + */ 2.34 + 2.35 +package compiler.codegen.aes; 2.36 + 2.37 +import java.io.PrintStream; 2.38 +import java.security.*; 2.39 +import java.util.Random; 2.40 +import java.lang.reflect.Method; 2.41 +import javax.crypto.Cipher; 2.42 +import javax.crypto.SecretKey; 2.43 +import javax.crypto.SecretKeyFactory; 2.44 +import javax.crypto.spec.PBEKeySpec; 2.45 + 2.46 +public class TestCipherBlockChainingEncrypt { 2.47 + private static String algorithm = "PBEWithHmacSHA1AndAES_256"; 2.48 + private static final String PBEPASS = "Hush, it's supposed to be a secret!"; 2.49 + 2.50 + private static final int INPUT_LENGTH = 800; 2.51 + private static final int[] OFFSETS = {0}; 2.52 + private static final int NUM_PAD_BYTES = 8; 2.53 + private static final int PBKDF2_ADD_PAD_BYTES = 8; 2.54 + 2.55 + private static SecretKey key; 2.56 + private static Cipher ci; 2.57 + 2.58 + public static void main(String[] args) throws Exception { 2.59 + for(int i=0; i<5_000; i++) { 2.60 + if (!(new TestCipherBlockChainingEncrypt().test(args))) { 2.61 + throw new RuntimeException("TestCipherBlockChainingEncrypt test failed"); 2.62 + } 2.63 + } 2.64 + } 2.65 + 2.66 + public boolean test(String[] args) throws Exception { 2.67 + boolean result = true; 2.68 + 2.69 + Provider p = Security.getProvider("SunJCE"); 2.70 + ci = Cipher.getInstance(algorithm, p); 2.71 + key = SecretKeyFactory.getInstance(algorithm, p).generateSecret( 2.72 + new PBEKeySpec(PBEPASS.toCharArray())); 2.73 + 2.74 + // generate input data 2.75 + byte[] inputText = new byte[INPUT_LENGTH + NUM_PAD_BYTES 2.76 + + PBKDF2_ADD_PAD_BYTES]; 2.77 + new Random().nextBytes(inputText); 2.78 + 2.79 + try { 2.80 + // Encrypt 2.81 + execute(Cipher.ENCRYPT_MODE, 2.82 + inputText, 2.83 + 0, 2.84 + INPUT_LENGTH); 2.85 + 2.86 + // PBKDF2 required 16 byte padding 2.87 + int padLength = NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES; 2.88 + 2.89 + // Decrypt 2.90 + // Note: inputText is implicitly padded by the above encrypt 2.91 + // operation so decrypt operation can safely proceed 2.92 + execute(Cipher.DECRYPT_MODE, 2.93 + inputText, 2.94 + 0, 2.95 + INPUT_LENGTH + padLength); 2.96 + 2.97 + } catch (Exception ex) { 2.98 + ex.printStackTrace(System.out); 2.99 + result = false; 2.100 + } 2.101 + return result; 2.102 + } 2.103 + 2.104 + private void execute(int edMode, byte[] inputText, int offset, int len) { 2.105 + try { 2.106 + // init Cipher 2.107 + if (Cipher.ENCRYPT_MODE == edMode) { 2.108 + ci.init(Cipher.ENCRYPT_MODE, this.key); 2.109 + } else { 2.110 + ci.init(Cipher.DECRYPT_MODE, this.key, ci.getParameters()); 2.111 + } 2.112 + 2.113 + // First, generate the cipherText at an allocated buffer 2.114 + byte[] outputText = ci.doFinal(inputText, offset, len); 2.115 + 2.116 + // Second, generate cipherText again at the same buffer of plainText 2.117 + int myoff = offset / 2; 2.118 + int off = ci.update(inputText, offset, len, inputText, myoff); 2.119 + ci.doFinal(inputText, myoff + off); 2.120 + 2.121 + // Compare to see whether the two results are the same or not 2.122 + boolean e = equalsBlock(inputText, myoff, outputText, 0, 2.123 + outputText.length); 2.124 + } catch (Exception ex) { 2.125 + System.out.println("Got unexpected exception for " + algorithm); 2.126 + ex.printStackTrace(System.out); 2.127 + } 2.128 + } 2.129 + 2.130 + private boolean equalsBlock(byte[] b1, int off1, 2.131 + byte[] b2, int off2, int len) { 2.132 + for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) { 2.133 + if (b1[i] != b2[j]) { 2.134 + return false; 2.135 + } 2.136 + } 2.137 + return true; 2.138 + } 2.139 +}