8209951: Problematic sparc intrinsic: com.sun.crypto.provider.CipherBlockChaining

Thu, 31 Jan 2019 04:49:46 -0800

author
kevinw
date
Thu, 31 Jan 2019 04:49:46 -0800
changeset 9655
a49d6f06f0d5
parent 9654
6b67e2bcf2be
child 9656
35d9d8c13d30

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 +}

mercurial