From 2f05cc1674ce4c2445c80480e7a4234beeaacc5a Mon Sep 17 00:00:00 2001 From: kevinw Date: Thu, 31 Jan 2019 04:49:46 -0800 Subject: [PATCH] 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 | 4 +- .../TestCipherBlockChainingEncrypt.java | 136 ++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 test/compiler/8209951/TestCipherBlockChainingEncrypt.java diff --git a/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/src/cpu/sparc/vm/stubGenerator_sparc.cpp index e4cc113c2..6ad0b1a41 100644 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -4483,7 +4483,7 @@ class StubGenerator: public StubCodeGenerator { // save F48:F54 in temp registers __ movdtox(F54,G2); __ movdtox(F52,G3); - __ movdtox(F50,G6); + __ movdtox(F50,L6); __ movdtox(F48,G1); for ( int i = 46; i >= 14; i -= 8 ) { __ aes_dround23(as_FloatRegister(i), F0, F2, F4); @@ -4511,7 +4511,7 @@ class StubGenerator: public StubCodeGenerator { // re-init F48:F54 with their original values __ movxtod(G2,F54); __ movxtod(G3,F52); - __ movxtod(G6,F50); + __ movxtod(L6,F50); __ movxtod(G1,F48); __ movxtod(L0,F6); diff --git a/test/compiler/8209951/TestCipherBlockChainingEncrypt.java b/test/compiler/8209951/TestCipherBlockChainingEncrypt.java new file mode 100644 index 000000000..649135eea --- /dev/null +++ b/test/compiler/8209951/TestCipherBlockChainingEncrypt.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8209951 + * @summary SIGBUS in com.sun.crypto.provider.CipherBlockChaining + * @run main/othervm/timeout=300 -Xbatch + * compiler.codegen.aes.TestCipherBlockChainingEncrypt + */ + +package compiler.codegen.aes; + +import java.io.PrintStream; +import java.security.*; +import java.util.Random; +import java.lang.reflect.Method; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +public class TestCipherBlockChainingEncrypt { + private static String algorithm = "PBEWithHmacSHA1AndAES_256"; + private static final String PBEPASS = "Hush, it's supposed to be a secret!"; + + private static final int INPUT_LENGTH = 800; + private static final int[] OFFSETS = {0}; + private static final int NUM_PAD_BYTES = 8; + private static final int PBKDF2_ADD_PAD_BYTES = 8; + + private static SecretKey key; + private static Cipher ci; + + public static void main(String[] args) throws Exception { + for(int i=0; i<5_000; i++) { + if (!(new TestCipherBlockChainingEncrypt().test(args))) { + throw new RuntimeException("TestCipherBlockChainingEncrypt test failed"); + } + } + } + + public boolean test(String[] args) throws Exception { + boolean result = true; + + Provider p = Security.getProvider("SunJCE"); + ci = Cipher.getInstance(algorithm, p); + key = SecretKeyFactory.getInstance(algorithm, p).generateSecret( + new PBEKeySpec(PBEPASS.toCharArray())); + + // generate input data + byte[] inputText = new byte[INPUT_LENGTH + NUM_PAD_BYTES + + PBKDF2_ADD_PAD_BYTES]; + new Random().nextBytes(inputText); + + try { + // Encrypt + execute(Cipher.ENCRYPT_MODE, + inputText, + 0, + INPUT_LENGTH); + + // PBKDF2 required 16 byte padding + int padLength = NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES; + + // Decrypt + // Note: inputText is implicitly padded by the above encrypt + // operation so decrypt operation can safely proceed + execute(Cipher.DECRYPT_MODE, + inputText, + 0, + INPUT_LENGTH + padLength); + + } catch (Exception ex) { + ex.printStackTrace(System.out); + result = false; + } + return result; + } + + private void execute(int edMode, byte[] inputText, int offset, int len) { + try { + // init Cipher + if (Cipher.ENCRYPT_MODE == edMode) { + ci.init(Cipher.ENCRYPT_MODE, this.key); + } else { + ci.init(Cipher.DECRYPT_MODE, this.key, ci.getParameters()); + } + + // First, generate the cipherText at an allocated buffer + byte[] outputText = ci.doFinal(inputText, offset, len); + + // Second, generate cipherText again at the same buffer of plainText + int myoff = offset / 2; + int off = ci.update(inputText, offset, len, inputText, myoff); + ci.doFinal(inputText, myoff + off); + + // Compare to see whether the two results are the same or not + boolean e = equalsBlock(inputText, myoff, outputText, 0, + outputText.length); + } catch (Exception ex) { + System.out.println("Got unexpected exception for " + algorithm); + ex.printStackTrace(System.out); + } + } + + private boolean equalsBlock(byte[] b1, int off1, + byte[] b2, int off2, int len) { + for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) { + if (b1[i] != b2[j]) { + return false; + } + } + return true; + } +} -- GitLab