8000415: Add support for SHA-3
Summary: Add SHA-3 support to SUN and OracleUcrypto provider
Reviewed-by: ascarpino, jnimeh
--- a/jdk/make/mapfiles/libj2ucrypto/mapfile-vers Fri May 13 18:58:32 2016 +0000
+++ b/jdk/make/mapfiles/libj2ucrypto/mapfile-vers Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, 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
@@ -30,28 +30,35 @@
JNI_OnLoad;
Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries;
Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList;
- Java_com_oracle_security_ucrypto_NativeDigest_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate;
+ Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest;
+ Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone;
+ Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeInit;
Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
- Java_com_oracle_security_ucrypto_NativeDigest_nativeClone;
Java_com_oracle_security_ucrypto_NativeDigest_nativeFree;
- Java_com_oracle_security_ucrypto_NativeCipher_nativeInit;
- Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
- Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
Java_com_oracle_security_ucrypto_NativeKey_nativeFree;
Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit;
Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
- Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
- Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
- Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
- Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
- Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
-
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+ Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree;
JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit;
JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
- JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone;
JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree;
JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit;
JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
@@ -60,10 +67,10 @@
JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit;
JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
- JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
- JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
- JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
- JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
local:
--- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -441,17 +441,89 @@
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
- len += outOfs;
- while (outOfs < len) {
- long i = in[inOfs++];
- out[outOfs++] = (byte)(i >> 56);
- out[outOfs++] = (byte)(i >> 48);
- out[outOfs++] = (byte)(i >> 40);
- out[outOfs++] = (byte)(i >> 32);
- out[outOfs++] = (byte)(i >> 24);
- out[outOfs++] = (byte)(i >> 16);
- out[outOfs++] = (byte)(i >> 8);
- out[outOfs++] = (byte)(i );
+ if (littleEndianUnaligned) {
+ outOfs += byteArrayOfs;
+ len += outOfs;
+ while (outOfs < len) {
+ unsafe.putLong(out, (long)outOfs, reverseBytes(in[inOfs++]));
+ outOfs += 8;
+ }
+ } else {
+ len += outOfs;
+ while (outOfs < len) {
+ long i = in[inOfs++];
+ out[outOfs++] = (byte)(i >> 56);
+ out[outOfs++] = (byte)(i >> 48);
+ out[outOfs++] = (byte)(i >> 40);
+ out[outOfs++] = (byte)(i >> 32);
+ out[outOfs++] = (byte)(i >> 24);
+ out[outOfs++] = (byte)(i >> 16);
+ out[outOfs++] = (byte)(i >> 8);
+ out[outOfs++] = (byte)(i );
+ }
+ }
+ }
+
+ /**
+ * byte[] to long[] conversion, little endian byte order
+ */
+ static void b2lLittle(byte[] in, int inOfs, long[] out, int outOfs, int len) {
+ if ((inOfs < 0) || ((in.length - inOfs) < len) ||
+ ((outOfs < 0) || (out.length - outOfs) < len/8)) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ if (littleEndianUnaligned) {
+ inOfs += byteArrayOfs;
+ len += inOfs;
+ while (inOfs < len) {
+ out[outOfs++] = unsafe.getLong(in, (long)inOfs);
+ inOfs += 8;
+ }
+ } else {
+ len += inOfs;
+ while (inOfs < len) {
+ out[outOfs++] = ((in[inOfs ] & 0xffL)
+ | ((in[inOfs + 1] & 0xffL) << 8)
+ | ((in[inOfs + 2] & 0xffL) << 16)
+ | ((in[inOfs + 3] & 0xffL) << 24)
+ | ((in[inOfs + 4] & 0xffL) << 32)
+ | ((in[inOfs + 5] & 0xffL) << 40)
+ | ((in[inOfs + 6] & 0xffL) << 48)
+ | ((in[inOfs + 7] & 0xffL) << 56));
+ inOfs += 8;
+ }
+ }
+ }
+
+
+ /**
+ * long[] to byte[] conversion, little endian byte order
+ */
+ static void l2bLittle(long[] in, int inOfs, byte[] out, int outOfs, int len) {
+ if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
+ (outOfs < 0) || ((out.length - outOfs) < len)) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ if (littleEndianUnaligned) {
+ outOfs += byteArrayOfs;
+ len += outOfs;
+ while (outOfs < len) {
+ unsafe.putLong(out, (long)outOfs, in[inOfs++]);
+ outOfs += 8;
+ }
+ } else {
+ len += outOfs;
+ while (outOfs < len) {
+ long i = in[inOfs++];
+ out[outOfs++] = (byte)(i );
+ out[outOfs++] = (byte)(i >> 8);
+ out[outOfs++] = (byte)(i >> 16);
+ out[outOfs++] = (byte)(i >> 24);
+ out[outOfs++] = (byte)(i >> 32);
+ out[outOfs++] = (byte)(i >> 40);
+ out[outOfs++] = (byte)(i >> 48);
+ out[outOfs++] = (byte)(i >> 56);
+ }
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SHA3.java Sat May 14 03:44:30 2016 +0000
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2016, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.provider;
+
+import static sun.security.provider.ByteArrayAccess.*;
+import java.nio.*;
+import java.util.*;
+import java.security.*;
+
+/**
+ * This class implements the Secure Hash Algorithm SHA-3 developed by
+ * the National Institute of Standards and Technology along with the
+ * National Security Agency as defined in FIPS PUB 202.
+ *
+ * <p>It implements java.security.MessageDigestSpi, and can be used
+ * through Java Cryptography Architecture (JCA), as a pluggable
+ * MessageDigest implementation.
+ *
+ * @since 9
+ * @author Valerie Peng
+ */
+abstract class SHA3 extends DigestBase {
+
+ private static final int WIDTH = 200; // in bytes, e.g. 1600 bits
+ private static final int DM = 5; // dimension of lanes
+
+ private static final int NR = 24; // number of rounds
+
+ // precomputed round constants needed by the step mapping Iota
+ private static final long[] RC_CONSTANTS = {
+ 0x01L, 0x8082L, 0x800000000000808aL,
+ 0x8000000080008000L, 0x808bL, 0x80000001L,
+ 0x8000000080008081L, 0x8000000000008009L, 0x8aL,
+ 0x88L, 0x80008009L, 0x8000000aL,
+ 0x8000808bL, 0x800000000000008bL, 0x8000000000008089L,
+ 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L,
+ 0x800aL, 0x800000008000000aL, 0x8000000080008081L,
+ 0x8000000000008080L, 0x80000001L, 0x8000000080008008L,
+ };
+
+ private byte[] state;
+
+ /**
+ * Creates a new SHA-3 object.
+ */
+ SHA3(String name, int digestLength) {
+ super(name, digestLength, (WIDTH - (2 * digestLength)));
+ implReset();
+ }
+
+ /**
+ * Core compression function. Processes blockSize bytes at a time
+ * and updates the state of this object.
+ */
+ void implCompress(byte[] b, int ofs) {
+ for (int i = 0; i < buffer.length; i++) {
+ state[i] ^= b[ofs++];
+ }
+ state = keccak(state);
+ }
+
+ /**
+ * Return the digest. Subclasses do not need to reset() themselves,
+ * DigestBase calls implReset() when necessary.
+ */
+ void implDigest(byte[] out, int ofs) {
+ int numOfPadding =
+ setPaddingBytes(buffer, (int)(bytesProcessed % buffer.length));
+ if (numOfPadding < 1) {
+ throw new ProviderException("Incorrect pad size: " + numOfPadding);
+ }
+ for (int i = 0; i < buffer.length; i++) {
+ state[i] ^= buffer[i];
+ }
+ state = keccak(state);
+ System.arraycopy(state, 0, out, ofs, engineGetDigestLength());
+ }
+
+ /**
+ * Resets the internal state to start a new hash.
+ */
+ void implReset() {
+ state = new byte[WIDTH];
+ }
+
+ /**
+ * Utility function for circular shift the specified long
+ * value to the left for n bits.
+ */
+ private static long circularShiftLeft(long lane, int n) {
+ return ((lane << n) | (lane >>> (64 - n)));
+ }
+
+ /**
+ * Utility function for padding the specified data based on the
+ * pad10*1 algorithm (section 5.1) and the 2-bit suffix "01" required
+ * for SHA-3 hash (section 6.1).
+ */
+ private static int setPaddingBytes(byte[] in, int len) {
+ if (len != in.length) {
+ // erase leftover values
+ Arrays.fill(in, len, in.length, (byte)0);
+ // directly store the padding bytes into the input
+ // as the specified buffer is allocated w/ size = rateR
+ in[len] |= (byte) 0x06;
+ in[in.length - 1] |= (byte) 0x80;
+ }
+ return (in.length - len);
+ }
+
+ /**
+ * Utility function for transforming the specified state from
+ * the byte array format into array of lanes as defined in
+ * section 3.1.2.
+ */
+ private static long[][] bytes2Lanes(byte[] s) {
+ if (s.length != WIDTH) {
+ throw new ProviderException("Error: incorrect input size " +
+ s.length);
+ }
+ // The conversion traverses along x-axis before y-axis. So, y is the
+ // first dimension and x is the second dimension.
+ long[][] s2 = new long[DM][DM];
+ int sOfs = 0;
+ for (int y = 0; y < DM; y++, sOfs += 40) {
+ b2lLittle(s, sOfs, s2[y], 0, 40);
+ }
+ return s2;
+ }
+
+ /**
+ * Utility function for transforming the specified arrays of
+ * lanes into a byte array as defined in section 3.1.3.
+ */
+ private static byte[] lanes2Bytes(long[][] m) {
+ byte[] s = new byte[WIDTH];
+ int sOfs = 0;
+ // The conversion traverses along x-axis before y-axis. So, y is the
+ // first dimension and x is the second dimension.
+ for (int y = 0; y < DM; y++, sOfs += 40) {
+ l2bLittle(m[y], 0, s, sOfs, 40);
+ }
+ return s;
+ }
+
+ /**
+ * Step mapping Theta as defined in section 3.2.1 .
+ */
+ private static long[][] smTheta(long[][] a) {
+ long[] c = new long[DM];
+ for (int i = 0; i < DM; i++) {
+ c[i] = a[0][i]^a[1][i]^a[2][i]^a[3][i]^a[4][i];
+ }
+ long[] d = new long[DM];
+ for (int i = 0; i < DM; i++) {
+ long c1 = c[(i + 4) % DM];
+ // left shift and wrap the leftmost bit into the rightmost bit
+ long c2 = circularShiftLeft(c[(i + 1) % DM], 1);
+ d[i] = c1^c2;
+ }
+ for (int y = 0; y < DM; y++) {
+ for (int x = 0; x < DM; x++) {
+ a[y][x] ^= d[x];
+ }
+ }
+ return a;
+ }
+
+ /**
+ * Step mapping Rho as defined in section 3.2.2.
+ */
+ private static long[][] smRho(long[][] a) {
+ long[][] a2 = new long[DM][DM];
+ a2[0][0] = a[0][0];
+ int xNext, yNext;
+ for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) {
+ int numberOfShift = ((t + 1)*(t + 2)/2) % 64;
+ a2[y][x] = circularShiftLeft(a[y][x], numberOfShift);
+ xNext = y;
+ yNext = (2 * x + 3 * y) % DM;
+ }
+ return a2;
+ }
+
+ /**
+ * Step mapping Pi as defined in section 3.2.3.
+ */
+ private static long[][] smPi(long[][] a) {
+ long[][] a2 = new long[DM][DM];
+ for (int y = 0; y < DM; y++) {
+ for (int x = 0; x < DM; x++) {
+ a2[y][x] = a[x][(x + 3 * y) % DM];
+ }
+ }
+ return a2;
+ }
+
+ /**
+ * Step mapping Chi as defined in section 3.2.4.
+ */
+ private static long[][] smChi(long[][] a) {
+ long[][] a2 = new long[DM][DM];
+ for (int y = 0; y < DM; y++) {
+ for (int x = 0; x < DM; x++) {
+ a2[y][x] = a[y][x] ^
+ ((a[y][(x + 1) % DM] ^ 0xFFFFFFFFFFFFFFFFL) &
+ a[y][(x + 2) % DM]);
+ }
+ }
+ return a2;
+ }
+
+ /**
+ * Step mapping Iota as defined in section 3.2.5.
+ *
+ * @return the processed state array
+ * @param state the state array to be processed
+ */
+ private static long[][] smIota(long[][] a, int rndIndex) {
+ a[0][0] ^= RC_CONSTANTS[rndIndex];
+ return a;
+ }
+
+ /**
+ * The function Keccak as defined in section 5.2 with
+ * rate r = 1600 and capacity c = (digest length x 2).
+ */
+ private static byte[] keccak(byte[] state) {
+ long[][] lanes = bytes2Lanes(state);
+ for (int ir = 0; ir < NR; ir++) {
+ lanes = smIota(smChi(smPi(smRho(smTheta(lanes)))), ir);
+ }
+ return lanes2Bytes(lanes);
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ SHA3 copy = (SHA3) super.clone();
+ copy.state = copy.state.clone();
+ return copy;
+ }
+
+ /**
+ * SHA3-224 implementation class.
+ */
+ public static final class SHA224 extends SHA3 {
+ public SHA224() {
+ super("SHA3-224", 28);
+ }
+ }
+
+ /**
+ * SHA3-256 implementation class.
+ */
+ public static final class SHA256 extends SHA3 {
+ public SHA256() {
+ super("SHA3-256", 32);
+ }
+ }
+
+ /**
+ * SHAs-384 implementation class.
+ */
+ public static final class SHA384 extends SHA3 {
+ public SHA384() {
+ super("SHA3-384", 48);
+ }
+ }
+
+ /**
+ * SHA3-512 implementation class.
+ */
+ public static final class SHA512 extends SHA3 {
+ public SHA512() {
+ super("SHA3-512", 64);
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Sat May 14 03:44:30 2016 +0000
@@ -211,6 +211,25 @@
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.6",
"SHA-512/256");
+ map.put("MessageDigest.SHA3-224", "sun.security.provider.SHA3$SHA224");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.7", "SHA3-224");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.7",
+ "SHA3-224");
+
+ map.put("MessageDigest.SHA3-256", "sun.security.provider.SHA3$SHA256");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.8", "SHA3-256");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.8",
+ "SHA3-256");
+ map.put("MessageDigest.SHA3-384", "sun.security.provider.SHA3$SHA384");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.9", "SHA3-384");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.9",
+ "SHA3-384");
+ map.put("MessageDigest.SHA3-512", "sun.security.provider.SHA3$SHA512");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.10", "SHA3-512");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.10",
+ "SHA3-512");
+
+
/*
* Algorithm Parameter Generator engines
*/
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -108,7 +108,7 @@
* a hash for the certificate verify message is required.
*/
HandshakeHash(boolean needCertificateVerify) {
- clonesNeeded = needCertificateVerify ? 3 : 2;
+ clonesNeeded = needCertificateVerify ? 4 : 3;
}
void reserve(ByteBuffer input) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java Sat May 14 03:44:30 2016 +0000
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2016, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.oracle.security.ucrypto;
+
+/**
+ * Enum for representing the ucrypto mechanisms.
+ *
+ * @since 9
+ */
+public enum LibMDMech {
+
+ MD5(new ServiceDesc[]
+ { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigestMD$MD5")
+ }),
+ SHA_1(new ServiceDesc[]
+ { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigestMD$SHA1",
+ "SHA-1", "SHA1")
+ }),
+ SHA_256(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigestMD$SHA256",
+ "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1")
+ }),
+ SHA_384(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigestMD$SHA384",
+ "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2")
+ }),
+ SHA_512(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigestMD$SHA512",
+ "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3")
+ });
+
+ ServiceDesc[] serviceDescs;
+
+ private static ServiceDesc sd(String type, String algo, String cn, String... aliases) {
+ return new ServiceDesc(type, algo, cn, aliases);
+ }
+
+ LibMDMech(ServiceDesc[] serviceDescs) {
+ this.serviceDescs = serviceDescs;
+ }
+
+ public ServiceDesc[] getServiceDescriptions() { return serviceDescs; }
+}
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -33,23 +33,67 @@
import java.security.*;
/**
- * MessageDigest implementation class. This class currently supports
- * MD5, SHA1, SHA256, SHA384, and SHA512
+ * MessageDigest implementation class using native Ucrypto API.
+ * This class currently supports: MD5, SHA-2 (224, 256, 384, 512)
+ * and SHA-3 (224, 256, 384, 512) digests
*
* @since 9
*/
-public abstract class NativeDigest extends MessageDigestSpi
- implements Cloneable {
+abstract class NativeDigest extends MessageDigestSpi {
- private static final int MECH_MD5 = 1;
- private static final int MECH_SHA1 = 2;
- private static final int MECH_SHA256 = 3;
- private static final int MECH_SHA224 = 4;
- private static final int MECH_SHA384 = 5;
- private static final int MECH_SHA512 = 6;
+ public static final class MD5 extends NativeDigest {
+ public MD5() {
+ super(UcryptoMech.CRYPTO_MD5, 16);
+ }
+ }
+ public static final class SHA1 extends NativeDigest {
+ public SHA1() {
+ super(UcryptoMech.CRYPTO_SHA1, 20);
+ }
+ }
+ public static final class SHA224 extends NativeDigest {
+ public SHA224() {
+ super(UcryptoMech.CRYPTO_SHA224, 28);
+ }
+ }
+ public static final class SHA256 extends NativeDigest {
+ public SHA256() {
+ super(UcryptoMech.CRYPTO_SHA256, 32);
+ }
+ }
+ public static final class SHA384 extends NativeDigest {
+ public SHA384() {
+ super(UcryptoMech.CRYPTO_SHA384, 48);
+ }
+ }
+ public static final class SHA512 extends NativeDigest {
+ public SHA512() {
+ super(UcryptoMech.CRYPTO_SHA512, 64);
+ }
+ }
+ public static final class SHA3_224 extends NativeDigest {
+ public SHA3_224() {
+ super(UcryptoMech.CRYPTO_SHA3_224, 28);
+ }
+ }
+ public static final class SHA3_256 extends NativeDigest {
+ public SHA3_256() {
+ super(UcryptoMech.CRYPTO_SHA3_256, 32);
+ }
+ }
+ public static final class SHA3_384 extends NativeDigest {
+ public SHA3_384() {
+ super(UcryptoMech.CRYPTO_SHA3_384, 48);
+ }
+ }
+ public static final class SHA3_512 extends NativeDigest {
+ public SHA3_512() {
+ super(UcryptoMech.CRYPTO_SHA3_512, 64);
+ }
+ }
private final int digestLen;
- private final int mech;
+ private final UcryptoMech mech;
// field for ensuring native memory is freed
private DigestContextRef pCtxt = null;
@@ -64,10 +108,9 @@
// referents are GC'ed so we can do post-mortem processing
private static Set<DigestContextRef> refList =
new ConcurrentSkipListSet<DigestContextRef>();
- // Collections.synchronizedSortedSet(new TreeSet<DigestContextRef>());
private final long id;
- private final int mech;
+ private final UcryptoMech mech;
private static void drainRefQueueBounded() {
while (true) {
@@ -77,7 +120,7 @@
}
}
- DigestContextRef(NativeDigest nc, long id, int mech) {
+ DigestContextRef(NativeDigest nc, long id, UcryptoMech mech) {
super(nc, refQueue);
this.id = id;
this.mech = mech;
@@ -98,18 +141,22 @@
refList.remove(this);
try {
if (needFree) {
- UcryptoProvider.debug("Resource: free Digest Ctxt " + this.id);
- NativeDigest.nativeFree(mech, id);
- } else UcryptoProvider.debug("Resource: stop tracking Digest Ctxt " + this.id);
+ UcryptoProvider.debug("Resource: free Digest Ctxt " +
+ this.id);
+ NativeDigest.nativeFree(mech.value(), id);
+ } else {
+ UcryptoProvider.debug("Resource: discard Digest Ctxt " +
+ this.id);
+ }
} finally {
this.clear();
}
}
}
- NativeDigest(int mech, int digestLen) {
+ NativeDigest(UcryptoMech mech, int digestLen) {
+ this.mech = mech;
this.digestLen = digestLen;
- this.mech = mech;
}
// see JCA spec
@@ -153,10 +200,10 @@
}
if (pCtxt == null) {
- pCtxt = new DigestContextRef(this, nativeInit(mech), mech);
+ pCtxt = new DigestContextRef(this, nativeInit(mech.value()), mech);
}
try {
- int status = nativeDigest(mech, pCtxt.id, out, ofs, digestLen);
+ int status = nativeDigest(mech.value(), pCtxt.id, out, ofs, digestLen);
if (status != 0) {
throw new DigestException("Internal error: " + status);
}
@@ -183,64 +230,24 @@
+ len + ". in.length: " + in.length);
}
if (pCtxt == null) {
- pCtxt = new DigestContextRef(this, nativeInit(mech), mech);
+ pCtxt = new DigestContextRef(this, nativeInit(mech.value()), mech);
}
- nativeUpdate(mech, pCtxt.id, in, ofs, len);
+ nativeUpdate(mech.value(), pCtxt.id, in, ofs, len);
}
/**
* Clone this digest.
*/
public synchronized Object clone() throws CloneNotSupportedException {
- NativeDigest copy = (NativeDigest) super.clone();
- // re-work the fields that cannot be copied over
- if (pCtxt != null) {
- copy.pCtxt = new DigestContextRef(this, nativeClone(mech, pCtxt.id), mech);
- }
- return copy;
+ throw new CloneNotSupportedException("Clone is not supported");
}
// return pointer to the context
- protected static native long nativeInit(int mech);
- // return status code; always 0
- protected static native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen);
+ protected static final native long nativeInit(int mech);
// return status code; always 0
- protected static native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen);
- // return pointer to the duplicated context
- protected static native long nativeClone(int mech, long pCtxt);
+ protected static final native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen);
+ // return status code; always 0
+ protected static final native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen);
// free the specified context
- private native static void nativeFree(int mech, long id);
-
-
- public static final class MD5 extends NativeDigest {
- public MD5() {
- super(MECH_MD5, 16);
- }
- }
-
- public static final class SHA1 extends NativeDigest {
- public SHA1() {
- super(MECH_SHA1, 20);
- }
- }
-
- public static final class SHA256 extends NativeDigest {
- public SHA256() {
- super(MECH_SHA256, 32);
- }
- }
-
-
- public static final class SHA384 extends NativeDigest {
- public SHA384() {
- super(MECH_SHA384, 48);
- }
- }
-
-
- public static final class SHA512 extends NativeDigest {
- public SHA512() {
- super(MECH_SHA512, 64);
- }
- }
+ private static final native void nativeFree(int mech, long id);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java Sat May 14 03:44:30 2016 +0000
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.oracle.security.ucrypto;
+
+import java.lang.ref.*;
+
+import java.io.ByteArrayOutputStream;
+import java.util.*;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.security.*;
+
+/**
+ * MessageDigest implementation class for libMD API. This class currently supports
+ * MD5, SHA1, SHA256, SHA384, and SHA512
+ *
+ * @since 9
+ */
+public abstract class NativeDigestMD extends MessageDigestSpi
+ implements Cloneable {
+
+ private static final int MECH_MD5 = 1;
+ private static final int MECH_SHA1 = 2;
+ private static final int MECH_SHA256 = 3;
+ private static final int MECH_SHA224 = 4;
+ private static final int MECH_SHA384 = 5;
+ private static final int MECH_SHA512 = 6;
+
+ private final int digestLen;
+ private final int mech;
+
+ // field for ensuring native memory is freed
+ private DigestContextRef pCtxt = null;
+
+ private static class DigestContextRef extends PhantomReference<NativeDigestMD>
+ implements Comparable<DigestContextRef> {
+
+ private static ReferenceQueue<NativeDigestMD> refQueue =
+ new ReferenceQueue<NativeDigestMD>();
+
+ // Needed to keep these references from being GC'ed until when their
+ // referents are GC'ed so we can do post-mortem processing
+ private static Set<DigestContextRef> refList =
+ new ConcurrentSkipListSet<DigestContextRef>();
+ // Collections.synchronizedSortedSet(new TreeSet<DigestContextRef>());
+
+ private final long id;
+ private final int mech;
+
+ private static void drainRefQueueBounded() {
+ while (true) {
+ DigestContextRef next = (DigestContextRef) refQueue.poll();
+ if (next == null) break;
+ next.dispose(true);
+ }
+ }
+
+ DigestContextRef(NativeDigestMD nc, long id, int mech) {
+ super(nc, refQueue);
+ this.id = id;
+ this.mech = mech;
+ refList.add(this);
+ UcryptoProvider.debug("Resource: track Digest Ctxt " + this.id);
+ drainRefQueueBounded();
+ }
+
+ public int compareTo(DigestContextRef other) {
+ if (this.id == other.id) {
+ return 0;
+ } else {
+ return (this.id < other.id) ? -1 : 1;
+ }
+ }
+
+ void dispose(boolean needFree) {
+ refList.remove(this);
+ try {
+ if (needFree) {
+ UcryptoProvider.debug("Resource: free Digest Ctxt " + this.id);
+ NativeDigestMD.nativeFree(mech, id);
+ } else UcryptoProvider.debug("Resource: stop tracking Digest Ctxt " + this.id);
+ } finally {
+ this.clear();
+ }
+ }
+ }
+
+ NativeDigestMD(int mech, int digestLen) {
+ this.digestLen = digestLen;
+ this.mech = mech;
+ }
+
+ // see JCA spec
+ protected int engineGetDigestLength() {
+ return digestLen;
+ }
+
+ // see JCA spec
+ protected synchronized void engineReset() {
+ if (pCtxt != null) {
+ pCtxt.dispose(true);
+ pCtxt = null;
+ }
+ }
+
+ // see JCA spec
+ protected synchronized byte[] engineDigest() {
+ byte[] digest = new byte[digestLen];
+ try {
+ int len = engineDigest(digest, 0, digestLen);
+ if (len != digestLen) {
+ throw new UcryptoException("Digest length mismatch." +
+ " Len: " + len + ". digestLen: " + digestLen);
+ }
+ return digest;
+ } catch (DigestException de) {
+ throw new UcryptoException("Internal error", de);
+ }
+ }
+
+ // see JCA spec
+ protected synchronized int engineDigest(byte[] out, int ofs, int len)
+ throws DigestException {
+ if (len < digestLen) {
+ throw new DigestException("Output buffer must be at least " +
+ digestLen + " bytes long. Got: " + len);
+ }
+ if ((ofs < 0) || (len < 0) || (ofs > out.length - len)) {
+ throw new DigestException("Buffer too short to store digest. " +
+ "ofs: " + ofs + ". len: " + len + ". out.length: " + out.length);
+ }
+
+ if (pCtxt == null) {
+ pCtxt = new DigestContextRef(this, nativeInit(mech), mech);
+ }
+ try {
+ int status = nativeDigest(mech, pCtxt.id, out, ofs, digestLen);
+ if (status != 0) {
+ throw new DigestException("Internal error: " + status);
+ }
+ } finally {
+ pCtxt.dispose(false);
+ pCtxt = null;
+ }
+ return digestLen;
+ }
+
+ // see JCA spec
+ protected synchronized void engineUpdate(byte in) {
+ byte[] temp = { in };
+ engineUpdate(temp, 0, 1);
+ }
+
+ // see JCA spec
+ protected synchronized void engineUpdate(byte[] in, int ofs, int len) {
+ if (len == 0) {
+ return;
+ }
+ if ((ofs < 0) || (len < 0) || (ofs > in.length - len)) {
+ throw new ArrayIndexOutOfBoundsException("ofs: " + ofs + ". len: "
+ + len + ". in.length: " + in.length);
+ }
+ if (pCtxt == null) {
+ pCtxt = new DigestContextRef(this, nativeInit(mech), mech);
+ }
+ nativeUpdate(mech, pCtxt.id, in, ofs, len);
+ }
+
+ /**
+ * Clone this digest.
+ */
+ public synchronized Object clone() throws CloneNotSupportedException {
+ NativeDigestMD copy = (NativeDigestMD) super.clone();
+ // re-work the fields that cannot be copied over
+ if (pCtxt != null) {
+ copy.pCtxt = new DigestContextRef(this, nativeClone(mech, pCtxt.id), mech);
+ }
+ return copy;
+ }
+
+ // return pointer to the context
+ protected static final native long nativeInit(int mech);
+ // return status code; always 0
+ protected static final native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen);
+ // return status code; always 0
+ protected static final native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen);
+ // return pointer to the duplicated context
+ protected static final native long nativeClone(int mech, long pCtxt);
+ // free the specified context
+ private static final native void nativeFree(int mech, long id);
+
+
+ public static final class MD5 extends NativeDigestMD {
+ public MD5() {
+ super(MECH_MD5, 16);
+ }
+ }
+
+ public static final class SHA1 extends NativeDigestMD {
+ public SHA1() {
+ super(MECH_SHA1, 20);
+ }
+ }
+
+ public static final class SHA256 extends NativeDigestMD {
+ public SHA256() {
+ super(MECH_SHA256, 32);
+ }
+ }
+
+
+ public static final class SHA384 extends NativeDigestMD {
+ public SHA384() {
+ super(MECH_SHA384, 48);
+ }
+ }
+
+
+ public static final class SHA512 extends NativeDigestMD {
+ public SHA512() {
+ super(MECH_SHA512, 64);
+ }
+ }
+}
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -25,8 +25,6 @@
package com.oracle.security.ucrypto;
-import java.util.HashMap;
-
/**
* Enum for representing the ucrypto mechanisms.
*
@@ -35,78 +33,126 @@
// Check /usr/include/libsoftcrypto.h for updates
public enum UcryptoMech {
- CRYPTO_AES_ECB(1, new ServiceDesc[]
+ CRYPTO_AES_ECB(new ServiceDesc[]
{ sd("Cipher", "AES/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"),
sd("Cipher", "AES/ECB/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5",
"AES"),
- sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128EcbNoPadding",
+ sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding",
"2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
- sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192EcbNoPadding",
+ sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding",
"2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
- sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256EcbNoPadding",
+ sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding",
"2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41")
}),
- CRYPTO_AES_CBC(2, new ServiceDesc[]
+ CRYPTO_AES_CBC(new ServiceDesc[]
{ sd("Cipher", "AES/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"),
sd("Cipher", "AES/CBC/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5"),
- sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128CbcNoPadding",
+ sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding",
"2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
- sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192CbcNoPadding",
+ sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding",
"2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
- sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256CbcNoPadding",
+ sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding",
"2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42")
}),
- CRYPTO_AES_CBC_PAD(3, null), // No support from Solaris yet
- CRYPTO_AES_CTR(4, new ServiceDesc[]
+// CRYPTO_AES_CBC_PAD(null), // Support added since S11.1; however we still use CRYPTO_AES_CBC due to known bug
+ CRYPTO_AES_CTR(new ServiceDesc[]
{ sd("Cipher", "AES/CTR/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCtrNoPadding") }),
- CRYPTO_AES_CCM(5, null), // Cannot support due to lack of Java API which corresponds to CK_AES_CCM_PARAMS
- CRYPTO_AES_GCM(6, new ServiceDesc[]
+// CRYPTO_AES_CCM(null), // Need Java API for CK_AES_CCM_PARAMS
+ CRYPTO_AES_GCM(new ServiceDesc[]
{ sd("Cipher", "AES/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"),
- sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes128GcmNoPadding",
+ sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding",
"2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"),
- sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes192GcmNoPadding",
+ sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding",
"2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"),
- sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes256GcmNoPadding",
+ sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding",
"2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46")
}),
- CRYPTO_AES_GMAC(7, null), // No support from Solaris yet
- CRYPTO_AES_CFB128(8, new ServiceDesc[]
+// CRYPTO_AES_GMAC(null), // No support from Solaris
+ CRYPTO_AES_CFB128(new ServiceDesc[]
{ sd("Cipher", "AES/CFB128/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCfb128NoPadding"),
- sd("Cipher", "AES/CFB128/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5") }),
- CRYPTO_RSA_PKCS(31, new ServiceDesc[]
+ sd("Cipher", "AES/CFB128/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5")
+ }),
+
+ CRYPTO_RSA_PKCS(new ServiceDesc[]
{ sd("Cipher", "RSA/ECB/PKCS1Padding", "com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding",
- "RSA") }),
- CRYPTO_RSA_X_509(32, new ServiceDesc[]
+ "RSA")
+ }),
+ CRYPTO_RSA_X_509(new ServiceDesc[]
{ sd("Cipher", "RSA/ECB/NoPadding", "com.oracle.security.ucrypto.NativeRSACipher$NoPadding") }),
- CRYPTO_MD5_RSA_PKCS(33, new ServiceDesc[]
+ CRYPTO_MD5_RSA_PKCS(new ServiceDesc[]
{ sd("Signature", "MD5withRSA", "com.oracle.security.ucrypto.NativeRSASignature$MD5",
- "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") }),
- CRYPTO_SHA1_RSA_PKCS(34, new ServiceDesc[]
+ "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4")
+ }),
+ CRYPTO_SHA1_RSA_PKCS(new ServiceDesc[]
{ sd("Signature", "SHA1withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA1",
"1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
- "1.3.14.3.2.29") }),
- CRYPTO_SHA256_RSA_PKCS(35, new ServiceDesc[]
+ "1.3.14.3.2.29")
+ }),
+ CRYPTO_SHA256_RSA_PKCS(new ServiceDesc[]
{ sd("Signature", "SHA256withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA256",
- "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") }),
- CRYPTO_SHA384_RSA_PKCS(36, new ServiceDesc[]
+ "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11")
+ }),
+ CRYPTO_SHA384_RSA_PKCS(new ServiceDesc[]
{ sd("Signature", "SHA384withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA384",
- "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") }),
- CRYPTO_SHA512_RSA_PKCS(37, new ServiceDesc[]
+ "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12")
+ }),
+ CRYPTO_SHA512_RSA_PKCS(new ServiceDesc[]
{ sd("Signature", "SHA512withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA512",
- "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") });
+ "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13")
+ }),
- private final int mech;
+ CRYPTO_MD5(new ServiceDesc[]
+ { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") }),
+ CRYPTO_SHA1(new ServiceDesc[]
+ { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigest$SHA1", "SHA-1", "SHA1") }),
+ CRYPTO_SHA224(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-224", "com.oracle.security.ucrypto.NativeDigest$SHA224",
+ "2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4")
+ }),
+ CRYPTO_SHA256(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigest$SHA256",
+ "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1")
+ }),
+ CRYPTO_SHA384(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigest$SHA384",
+ "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2")
+ }),
+ CRYPTO_SHA512(new ServiceDesc[]
+ { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigest$SHA512",
+ "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3")
+ }),
+ CRYPTO_SHA3_224(new ServiceDesc[]
+ { sd("MessageDigest", "SHA3-224", "com.oracle.security.ucrypto.NativeDigest$SHA3_224",
+ "2.16.840.1.101.3.4.2.7", "OID.2.16.840.1.101.3.4.2.7")
+ }),
+ CRYPTO_SHA3_256(new ServiceDesc[]
+ { sd("MessageDigest", "SHA3-256", "com.oracle.security.ucrypto.NativeDigest$SHA3_256",
+ "2.16.840.1.101.3.4.2.8", "OID.2.16.840.1.101.3.4.2.8")
+ }),
+ CRYPTO_SHA3_384(new ServiceDesc[]
+ { sd("MessageDigest", "SHA3-384", "com.oracle.security.ucrypto.NativeDigest$SHA3_384",
+ "2.16.840.1.101.3.4.2.9", "OID.2.16.840.1.101.3.4.2.9")
+ }),
+ CRYPTO_SHA3_512(new ServiceDesc[]
+ { sd("MessageDigest", "SHA3-512", "com.oracle.security.ucrypto.NativeDigest$SHA3_512",
+ "2.16.840.1.101.3.4.2.10", "OID.2.16.840.1.101.3.4.2.10")
+ });
+
+ private int mech = 0;
private final ServiceDesc[] serviceDescs;
private static ServiceDesc sd(String type, String algo, String cn, String... aliases) {
return new ServiceDesc(type, algo, cn, aliases);
}
- UcryptoMech(int mech, ServiceDesc[] serviceDescs) {
- this.mech = mech;
+ UcryptoMech(ServiceDesc[] serviceDescs) {
this.serviceDescs = serviceDescs;
}
+ public void setValue(int nativeMechValue) {
+ this.mech = nativeMechValue;
+ }
+
public int value() { return mech; }
public ServiceDesc[] getServiceDescriptions() { return serviceDescs; }
}
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -27,6 +27,7 @@
import java.io.IOException;
import java.io.File;
+import java.lang.reflect.Constructor;
import java.util.*;
import java.security.*;
@@ -74,48 +75,52 @@
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
- if (result[0]) { // successfully loaded libmd
- provProp.put("MessageDigest.MD5",
- sd("MessageDigest", "MD5",
- "com.oracle.security.ucrypto.NativeDigest$MD5"));
- provProp.put("MessageDigest.SHA",
- sd("MessageDigest", "SHA",
- "com.oracle.security.ucrypto.NativeDigest$SHA1",
- "SHA-1", "SHA1"));
- provProp.put("MessageDigest.SHA-256",
- sd("MessageDigest", "SHA-256",
- "com.oracle.security.ucrypto.NativeDigest$SHA256",
- "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"));
-
- provProp.put("MessageDigest.SHA-384",
- sd("MessageDigest", "SHA-384",
- "com.oracle.security.ucrypto.NativeDigest$SHA384",
- "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"));
-
- provProp.put("MessageDigest.SHA-512",
- sd("MessageDigest", "SHA-512",
- "com.oracle.security.ucrypto.NativeDigest$SHA512",
- "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"));
- };
- if (result[1]) { // successfully loaded libsoftcrypto
+ // true when libsoftcrypto or libucrypto(S12) has been successfully loaded
+ if (result[1]) {
String supportedMechs = getMechList();
debug("Prov: supported mechs = " + supportedMechs);
- for (UcryptoMech m : UcryptoMech.values()) {
- if (supportedMechs.indexOf(m.name() + ",") != -1) {
+ StringTokenizer st = new StringTokenizer(supportedMechs, ":,;");
+ // format: numOfSupportedMechs:[mechName,mechValue;]+
+ // skip the first one which is numberOfSupportedMechs
+ st.nextToken();
+ while (st.hasMoreTokens()) {
+ String mechName = st.nextToken();
+ int nativeMechVal = Integer.parseInt(st.nextToken());
+ try {
+ UcryptoMech m = Enum.valueOf(UcryptoMech.class, mechName);
+ m.setValue(nativeMechVal);
ServiceDesc[] services = m.getServiceDescriptions();
- // skip unsupported UcryptoMech
- if (services == null || services.length == 0) continue;
+ // defined in UcryptoMech as unsupported
+ if (services == null || services.length == 0) {
+ debug("Skip Unsupported Algorithm: " + mechName);
+ continue;
+ }
for (int p = 0; p < services.length; p++) {
ServiceDesc entry = services[p];
provProp.put(entry.getType() + "." + entry.getAlgorithm(),
entry);
}
+ } catch (IllegalArgumentException iae) {
+ // not defined in UcryptoMech
+ debug("Skip Unrecognized Algorithm: " + mechName);
}
}
// NOTE: GCM support is only available since jdk 7
provProp.put("AlgorithmParameters.GCM",
- sd("AlgorithmParameters", "GCM", "com.oracle.security.ucrypto.GCMParameters"));
+ sd("AlgorithmParameters", "GCM",
+ "com.oracle.security.ucrypto.GCMParameters"));
}
+ // true when libmd is needed and has been successfully loaded
+ if (result[0]) {
+ for (LibMDMech m : LibMDMech.values()) {
+ ServiceDesc[] services = m.getServiceDescriptions();
+ for (ServiceDesc entry : services) {
+ String sKey = entry.getType() + "." + entry.getAlgorithm();
+ // only register if none has been registered
+ provProp.putIfAbsent(sKey, entry);
+ }
+ }
+ };
} else {
debug("Prov: unexpected ucrypto library loading error, got " + result.length);
}
@@ -138,6 +143,7 @@
sd.getAliases(), null);
}
+ @SuppressWarnings("deprecation")
@Override
public Object newInstance(Object ctrParamObj)
throws NoSuchAlgorithmException {
@@ -152,53 +158,19 @@
int keySize = -1;
if (algo.charAt(3) == '_') {
keySize = Integer.parseInt(algo.substring(4, 7))/8;
- algo = algo.substring(0, 3) + algo.substring(7);
- }
- if (algo.equals("AES/ECB/NoPadding")) {
- return new NativeCipher.AesEcbNoPadding(keySize);
- } else if (algo.equals("AES/ECB/PKCS5Padding")) {
- return new NativeCipherWithJavaPadding.AesEcbPKCS5();
- } else if (algo.equals("AES/CBC/NoPadding")) {
- return new NativeCipher.AesCbcNoPadding(keySize);
- } else if (algo.equals("AES/CBC/PKCS5Padding")) {
- return new NativeCipherWithJavaPadding.AesCbcPKCS5();
- } else if (algo.equals("AES/CTR/NoPadding")) {
- return new NativeCipher.AesCtrNoPadding();
- } else if (algo.equals("AES/GCM/NoPadding")) {
- return new NativeGCMCipher.AesGcmNoPadding(keySize);
- } else if (algo.equals("AES/CFB128/NoPadding")) {
- return new NativeCipher.AesCfb128NoPadding();
- } else if (algo.equals("AES/CFB128/PKCS5Padding")) {
- return new NativeCipherWithJavaPadding.AesCfb128PKCS5();
- } else if (algo.equals("RSA/ECB/NoPadding")) {
- return new NativeRSACipher.NoPadding();
- } else if (algo.equals("RSA/ECB/PKCS1Padding")) {
- return new NativeRSACipher.PKCS1Padding();
}
- } else if (type.equals("Signature")) {
- if (algo.equals("SHA1withRSA")) {
- return new NativeRSASignature.SHA1();
- } else if (algo.equals("SHA256withRSA")) {
- return new NativeRSASignature.SHA256();
- } else if (algo.equals("SHA384withRSA")) {
- return new NativeRSASignature.SHA384();
- } else if (algo.equals("SHA512withRSA")) {
- return new NativeRSASignature.SHA512();
- } else if (algo.equals("MD5withRSA")) {
- return new NativeRSASignature.MD5();
+ String implClass = getClassName();
+ Class<?> clz = Class.forName(implClass);
+ if (keySize != -1) {
+ Constructor<?> ctr = clz.getConstructor(int.class);
+ return ctr.newInstance(keySize);
+ } else {
+ return clz.newInstance();
}
- } else if (type.equals("MessageDigest")) {
- if (algo.equals("SHA")) {
- return new NativeDigest.SHA1();
- } else if (algo.equals("SHA-256")) {
- return new NativeDigest.SHA256();
- } else if (algo.equals("SHA-384")) {
- return new NativeDigest.SHA384();
- } else if (algo.equals("SHA-512")) {
- return new NativeDigest.SHA512();
- } else if (algo.equals("MD5")) {
- return new NativeDigest.MD5();
- }
+ } else if (type.equals("Signature") || type.equals("MessageDigest")) {
+ String implClass = getClassName();
+ Class<?> clz = Class.forName(implClass);
+ return clz.newInstance();
} else if (type.equals("AlgorithmParameters")) {
if (algo.equals("GCM")) {
return new GCMParameters();
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/libsoftcrypto.h Fri May 13 18:58:32 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2014, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#ifndef _LIBSOFTCRYPTO_H
-#define _LIBSOFTCRYPTO_H
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <strings.h>
-
-typedef enum ucrypto_mech {
- CRYPTO_AES_ECB = 1,
- CRYPTO_AES_CBC,
- CRYPTO_AES_CBC_PAD,
- CRYPTO_AES_CTR,
- CRYPTO_AES_CCM,
- CRYPTO_AES_GCM,
- CRYPTO_AES_GMAC,
- CRYPTO_AES_CFB128,
- CRYPTO_RSA_PKCS = 31,
- CRYPTO_RSA_X_509,
- CRYPTO_MD5_RSA_PKCS,
- CRYPTO_SHA1_RSA_PKCS,
- CRYPTO_SHA256_RSA_PKCS,
- CRYPTO_SHA384_RSA_PKCS,
- CRYPTO_SHA512_RSA_PKCS
-} ucrypto_mech_t;
-
-typedef struct crypto_ctx {
- void *cc_provider;
- uint_t cc_session;
- void *cc_provider_private; /* owned by provider */
- void *cc_framework_private; /* owned by framework */
- uint32_t cc_flags; /* flags */
- void *cc_opstate; /* state */
-} crypto_ctx_t;
-
-extern int ucrypto_encrypt_init(crypto_ctx_t *context,
- ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len,
- void *iv, size_t iv_len);
-
-extern int ucrypto_encrypt_update(crypto_ctx_t *context, uchar_t *in,
- size_t in_len, uchar_t *out, size_t *out_len);
-
-extern int ucrypto_encrypt_final(crypto_ctx_t *context, uchar_t *out,
- size_t *out_len);
-
-/* Encrypt atomic */
-extern int ucrypto_encrypt(ucrypto_mech_t mech_type, uchar_t *key_str,
- size_t key_len, void *iv, size_t iv_len, uchar_t *in,
- size_t in_len, uchar_t *out, size_t *out_len);
-
-/* Decrypt multi-part */
-extern int ucrypto_decrypt_init(crypto_ctx_t *context,
- ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len,
- void *iv, size_t iv_len);
-
-extern int ucrypto_decrypt_update(crypto_ctx_t *context, uchar_t *in,
- size_t in_len, uchar_t *out, size_t *out_len);
-
-extern int ucrypto_decrypt_final(crypto_ctx_t *context, uchar_t *out,
- size_t *out_len);
-
-/* Decrypt atomic */
-extern int ucrypto_decrypt(ucrypto_mech_t mech_type, uchar_t *key_str,
- size_t key_len, void *iv, size_t iv_len, uchar_t *in,
- size_t in_len, uchar_t *out, size_t *out_len);
-
-/* Sign multi-part */
-extern int ucrypto_sign_init(crypto_ctx_t *context, ucrypto_mech_t mech_type,
- uchar_t *key_str, size_t key_len, void *iv, size_t iv_len);
-
-extern int ucrypto_sign_update(crypto_ctx_t *context,
- uchar_t *data_str, size_t data_len);
-
-extern int ucrypto_sign_final(crypto_ctx_t *context,
- uchar_t *sig_str, size_t *sig_len);
-
-/* Sign atomic */
-extern int ucrypto_sign(ucrypto_mech_t mech_type,
- uchar_t *key_str, size_t key_len, void *iv, size_t iv_len,
- uchar_t *data_str, size_t data_len, uchar_t *sig_str, size_t *sig_len);
-
-/* Verify multi-part */
-extern int ucrypto_verify_init(crypto_ctx_t *context, ucrypto_mech_t mech_type,
- uchar_t *key_str, size_t key_len, void *iv, size_t iv_len);
-
-extern int ucrypto_verify_update(crypto_ctx_t *context,
- uchar_t *data_str, size_t data_len);
-
-extern int ucrypto_verify_final(crypto_ctx_t *context,
- uchar_t *sig_str, size_t *sig_len);
-
-/* Verify atomic */
-extern int ucrypto_verify(ucrypto_mech_t mech_type,
- uchar_t *key_str, size_t key_len, void *iv, size_t iv_len,
- uchar_t *data_str, size_t data_len, uchar_t *sig, size_t *sig_len);
-
-extern int ucrypto_get_mechlist(char *str);
-
-extern const char *ucrypto_id2mech(ucrypto_mech_t mech_type);
-
-extern ucrypto_mech_t ucrypto_mech2id(const char *str);
-
-extern int ucrypto_version();
-
-typedef struct CK_AES_CTR_PARAMS {
- ulong_t ulCounterBits;
- uint8_t cb[16];
-} CK_AES_CTR_PARAMS;
-
-typedef struct CK_AES_GCM_PARAMS {
- uchar_t *pIv;
- ulong_t ulIvLen;
- ulong_t ulIvBits;
- uchar_t *pAAD;
- ulong_t ulAADLen;
- ulong_t ulTagBits;
-} CK_AES_GCM_PARAMS;
-
-typedef struct crypto_object_attribute {
- uint64_t oa_type; /* attribute type */
- caddr_t oa_value; /* attribute value */
- ssize_t oa_value_len; /* length of attribute value */
-} crypto_object_attribute_t;
-
-/* Attribute types to use for passing a RSA public key or a private key. */
-#define SUN_CKA_MODULUS 0x00000120
-#define SUN_CKA_MODULUS_BITS 0x00000121
-#define SUN_CKA_PUBLIC_EXPONENT 0x00000122
-#define SUN_CKA_PRIVATE_EXPONENT 0x00000123
-#define SUN_CKA_PRIME_1 0x00000124
-#define SUN_CKA_PRIME_2 0x00000125
-#define SUN_CKA_EXPONENT_1 0x00000126
-#define SUN_CKA_EXPONENT_2 0x00000127
-#define SUN_CKA_COEFFICIENT 0x00000128
-#define SUN_CKA_PRIME 0x00000130
-#define SUN_CKA_SUBPRIME 0x00000131
-#define SUN_CKA_BASE 0x00000132
-
-#define CKK_EC 0x00000003
-#define CKK_GENERIC_SECRET 0x00000010
-#define CKK_RC4 0x00000012
-#define CKK_AES 0x0000001F
-#define CKK_DES 0x00000013
-#define CKK_DES2 0x00000014
-#define CKK_DES3 0x00000015
-
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKA_CLASS 0x00000000
-#define CKA_VALUE 0x00000011
-#define CKA_KEY_TYPE 0x00000100
-#define CKA_VALUE_LEN 0x00000161
-#define CKA_EC_PARAMS 0x00000180
-#define CKA_EC_POINT 0x00000181
-
-#endif /* _LIBSOFTCRYPTO_H */
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -35,6 +35,22 @@
/*
* Dumps out byte array in hex with and name and length info
*/
+void printError(char* header, int mech, int rv) {
+ if (mech != -1) {
+ printf("%s, mech = %d, rv = 0x%0x\n", header, mech, rv);
+ } else {
+ printf("%s, rv = 0x%0x\n", header, rv);
+ }
+ if (*ftab->ucryptoStrerror != NULL) {
+ char * reason = (*ftab->ucryptoStrerror)(rv);
+ printf("\tcause = %s\n", reason);
+ free(reason);
+ }
+}
+
+/*
+ * Dumps out byte array in hex with and name and length info
+ */
void printBytes(char* header, unsigned char* bytes, int len) {
int i;
@@ -60,6 +76,16 @@
(*env)->DeleteLocalRef(env, jExClass);
}
+/*
+ * De-allocates all memory associated with crypto_ctx_t
+ */
+void freeContext(crypto_ctx_t *context) {
+ if (ftab->ucryptoFreeContext != NULL) {
+ (*ftab->ucryptoFreeContext)(context);
+ }
+ free(context);
+}
+
JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_4;
}
@@ -203,10 +229,10 @@
}
if (encrypt) {
rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
- if (rv != 0 && DEBUG) printf("ucryptoEncryptInit: ret = 0x%x\n", rv);
+ if (rv != 0 && DEBUG) printError("ucryptoEncryptInit", mech, rv);
} else {
rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
- if (rv != 0 && DEBUG) printf("ucryptoDecryptInit: ret = 0x%x\n", rv);
+ if (rv != 0 && DEBUG) printError("ucryptoDecryptInit", mech, rv);
}
if (iv != jIv) {
@@ -234,15 +260,15 @@
}
if (encrypt) {
rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
- if (rv != 0) {
- if (DEBUG) printf("ucryptoEncryptUpdate: ret = 0x%x\n", rv);
+ if (rv) {
+ if (DEBUG) printError("ucryptoEncryptUpdate", -1, rv);
} else {
*outLen = (int)outLength;
}
} else {
rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
- if (rv != 0) {
- if (DEBUG) printf("ucryptoDecryptUpdate: ret = 0x%x\n", rv);
+ if (rv) {
+ if (DEBUG) printError("ucryptoDecryptUpdate", -1, rv);
} else {
if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
*outLen = (int)outLength;
@@ -263,16 +289,16 @@
if (DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen);
if (encrypt) {
rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
- if (rv != 0) {
- if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv);
+ if (rv) {
+ if (DEBUG) printError("ucryptoDecryptFinal", -1, rv);
} else {
if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
*outLen = (int)outLength;
}
} else {
rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
- if (rv != 0) {
- if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv);
+ if (rv) {
+ if (DEBUG) printError("ucryptoDecryptFinal", -1, rv);
} else {
if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
*outLen = (int)outLength;
@@ -285,102 +311,61 @@
// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION
////////////////////////////////////////////////////////
jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(jint mech) {
- void *pContext = NULL;
+ crypto_ctx_t *context = NULL;
+ int rv;
- switch (mech) {
- case com_oracle_security_ucrypto_NativeDigest_MECH_SHA1:
- pContext = (SHA1_CTX *) malloc(sizeof(SHA1_CTX));
- if (pContext != NULL) {
- (*ftab->sha1Init)((SHA1_CTX *)pContext);
- }
- break;
- case com_oracle_security_ucrypto_NativeDigest_MECH_MD5:
- pContext = (MD5_CTX *) malloc(sizeof(MD5_CTX));
- if (pContext != NULL) {
- (*ftab->md5Init)((MD5_CTX *)pContext);
+ context = malloc(sizeof(crypto_ctx_t));
+ if (context != NULL) {
+ rv = (*ftab->ucryptoDigestInit)(context, (ucrypto_mech_t) mech, NULL, 0);
+ if (rv) {
+ freeContext(context);
+ if (DEBUG) printError("ucryptoDigestInit", mech, rv);
+ return 0L;
}
- break;
- case com_oracle_security_ucrypto_NativeDigest_MECH_SHA256:
- pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX));
- if (pContext != NULL) {
- (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext);
- }
- break;
- case com_oracle_security_ucrypto_NativeDigest_MECH_SHA384:
- pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX));
- if (pContext != NULL) {
- (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext);
- }
- break;
- case com_oracle_security_ucrypto_NativeDigest_MECH_SHA512:
- pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX));
- if (pContext != NULL) {
- (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext);
- }
- break;
- default:
- if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech);
}
- return (jlong) pContext;
+ return (jlong) context;
}
jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate
(jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) {
- if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) {
- (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len);
- } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) {
- (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len);
- } else { // SHA-2 family
- (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len);
+ crypto_ctx_t *context;
+ jint rv = 0;
+
+ context = (crypto_ctx_t *) pContext;
+ rv = (*ftab->ucryptoDigestUpdate)(context, (const unsigned char*)(in + ofs),
+ (size_t) len);
+
+ if (rv) {
+ freeContext(context);
+ if (DEBUG) printError("ucryptoDigestUpdate", mech, rv);
}
- return 0;
+
+ return -rv; // use negative value to indicate error
}
-// Do digest and free the context immediately
jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest
(jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) {
-
- if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) {
- (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext);
- free((SHA1_CTX *)pContext);
- } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) {
- (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext);
- free((MD5_CTX *)pContext);
- } else { // SHA-2 family
- (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext);
- free((SHA2_CTX *)pContext);
- }
- return 0;
-}
+ crypto_ctx_t *context;
+ jint rv = 0;
+ size_t digest_len = digestLen;
-jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone
- (jint mech, jlong pContext) {
- void *copy = NULL;
- size_t len = 0;
+ context = (crypto_ctx_t *) pContext;
+ rv = (*ftab->ucryptoDigestFinal)(context, (unsigned char*)(out + ofs),
+ &digest_len);
+ if (rv) {
+ freeContext(context);
+ if (DEBUG) printError("ucryptoDigestFinal", mech, rv);
+ }
- if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) {
- len = sizeof(SHA1_CTX);
- } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) {
- len = sizeof(MD5_CTX);
- } else { // SHA-2 family
- len = sizeof(SHA2_CTX);
- }
- copy = (void*) malloc(len);
- if (copy != NULL) {
- bcopy((void *)pContext, copy, len);
- }
- return (jlong) copy;
+ return -rv; // use negative value to indicate error
}
void JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree
(jint mech, jlong pContext) {
- if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) {
- free((SHA1_CTX*) pContext);
- } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) {
- free((MD5_CTX*) pContext);
- } else { // SHA-2 family
- free((SHA2_CTX*) pContext);
- }
+ crypto_ctx_t *context;
+
+ context = (crypto_ctx_t *) pContext;
+ freeContext(context);
}
// AES
@@ -395,7 +380,7 @@
rv = CipherInit(context, encrypt, (ucrypto_mech_t) mech, bufKey, keyLen,
bufIv, ivLen, tagLen, bufAad, aadLen);
if (rv) {
- free(context);
+ freeContext(context);
return 0L;
}
}
@@ -417,8 +402,7 @@
context = (crypto_ctx_t *) pContext;
rv = CipherUpdate(context, encrypt, (unsigned char*)bufIn, inOfs, inLen, (unsigned char*)bufOut, outOfs, &outLen);
if (rv) {
- free(context);
- context = 0;
+ freeContext(context);
return -rv; // use negative value to indicate error!
}
@@ -443,7 +427,7 @@
outLen = 0;
}
rv = CipherFinal(context, encrypt, bufOut, outOfs, &outLen);
- free(context);
+ freeContext(context);
if (rv) {
return -rv; // use negative value to indicate error!
}
@@ -451,8 +435,6 @@
return outLen;
}
-
-
/*
* Class: com_oracle_security_ucrypto_NativeDigest
* Method: nativeInit
@@ -475,13 +457,15 @@
JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate
(JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) {
unsigned char *bufIn;
+ jint rv = 0;
+
bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen);
if (!(*env)->ExceptionCheck(env)) {
- JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen);
+ rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen);
free(bufIn);
}
- return 0;
+ return rv;
}
/*
@@ -492,6 +476,7 @@
JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest
(JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) {
unsigned char *bufOut;
+ jint rv = 0;
bufOut = (unsigned char *) malloc(digestLen);
if (bufOut == NULL) {
@@ -499,21 +484,12 @@
return 0;
}
- JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen);
-
- (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut);
+ rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen);
+ if (rv == 0) {
+ (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut);
+ }
free(bufOut);
- return 0;
-}
-
-/*
- * Class: com_oracle_security_ucrypto_NativeDigest
- * Method: nativeClone
- * Signature: (IJ)J
- */
-JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeClone
- (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
- return JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone(mech, pContext);
+ return rv;
}
/*
@@ -582,7 +558,7 @@
cleanup:
if ((result == 0L) && (context != NULL)) {
- free(context);
+ freeContext(context);
}
if (bufKey != NULL) {
(*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0);
@@ -626,7 +602,7 @@
rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen);
if (rv) {
- free(context);
+ freeContext(context);
free(bufIn);
free(bufOut);
return -rv;
@@ -683,6 +659,7 @@
return rc;
}
+
/*
* Class: com_oracle_security_ucrypto_NativeKey
* Method: nativeFree
@@ -984,9 +961,9 @@
}
if (DEBUG) {
- printf("RSAPublicKey Init: keyValue=%ld, keyLen=2\n", pKey);
- printBytes("RSA PublicKey mod: ", (unsigned char*) mod, modLen);
- printBytes("RSA PublicKey pubExp: ", (unsigned char*) pub, pubLen);
+ printf("RSAPublicKey.nativeInit: keyValue=%ld, keyLen=2\n", pKey);
+ printBytes("\tmod: ", (unsigned char*) mod, modLen);
+ printBytes("\tpubExp: ", (unsigned char*) pub, pubLen);
}
pKey[0].oa_type = SUN_CKA_MODULUS;
@@ -1062,7 +1039,7 @@
if (DEBUG) {
printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n",
context, mech, sign, pKey, keyLength);
- printf("SignatureInit, ret => 0x%x\n", rv);
+ printError("SignatureInit", mech, rv);
}
return rv;
}
@@ -1083,7 +1060,7 @@
pKey = (uchar_t *) jKey;
rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength);
if (rv) {
- free(context);
+ freeContext(context);
return 0L;
}
}
@@ -1105,7 +1082,7 @@
pKey = (uchar_t *) jKey;
rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength);
if (rv) {
- free(context);
+ freeContext(context);
throwUCExceptionUsingRV(env, rv);
return 0L;
}
@@ -1125,7 +1102,7 @@
context = (crypto_ctx_t *) pCtxt;
if (DEBUG) {
- printf("Signature update: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n",
+ printf("NativeRSASignature.nativeUpdate: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n",
context, sign, jIn, jInOfs, jInLen);
}
if (sign) {
@@ -1133,9 +1110,9 @@
} else {
rv = (*ftab->ucryptoVerifyUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen);
}
- if (DEBUG) printf("Signature update, ret => 0x%x\n", rv);
if (rv) {
- free(context);
+ freeContext(context);
+ if (DEBUG) printError("NativeRSASignature.nativeUpdate", -1, rv);
return -rv; // use negative value to indicate error!
}
@@ -1194,9 +1171,9 @@
context = (crypto_ctx_t *) pCtxt;
if (DEBUG) {
- printf("Signature final: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n",
+ printf("NativeRSASignature.nativeFinal: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n",
context, sign, bufSig, sigOfs, jSigLen);
- printBytes("Before Final: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
+ printBytes("Before: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
}
if (sign) {
rv = (*ftab->ucryptoSignFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength);
@@ -1204,18 +1181,17 @@
rv = (*ftab->ucryptoVerifyFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength);
}
- if (DEBUG) {
- printf("Signature nativeFinal, ret => 0x%x\n", rv);
- if (sigLength != jSigLen) {
- printf("SIG actual output len=%d\n", sigLength);
+ freeContext(context);
+ if (rv) {
+ if (DEBUG) {
+ printError("NativeRSASignature.nativeFinal", -1, rv);
+ if (sigLength != jSigLen) {
+ printf("NativeRSASignature.nativeFinal out sig len=%d\n", sigLength);
+ }
+ if (sign) {
+ printBytes("After: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
+ }
}
- if (sign) {
- printBytes("After nativeFinal: ", (unsigned char*) (bufSig + sigOfs), jSigLen);
- }
- }
-
- free(context);
- if (rv) {
return -rv;
} else return 0;
}
@@ -1273,10 +1249,10 @@
pKey = (uchar_t *) keyValue;
if (DEBUG) {
- printf("Cipher nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n",
+ printf("NativeRSACipher.nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n",
mech, encrypt, pKey, keyLength);
- printBytes("Before nativeAtomic: in: ", (unsigned char*) bufIn, jInLen);
- printBytes("Before nativeAtomic: out: ", (unsigned char*) (bufOut + jOutOfs), jOutLen);
+ printBytes("Before: in = ", (unsigned char*) bufIn, jInLen);
+ printBytes("Before: out = ", (unsigned char*) (bufOut + jOutOfs), jOutLen);
}
if (encrypt) {
@@ -1289,11 +1265,11 @@
(uchar_t *)(bufOut + jOutOfs), &outLength);
}
if (DEBUG) {
- printf("Cipher nativeAtomic, ret => 0x%x\n", rv);
+ printError("NativeRSACipher.nativeAtomic", mech, rv);
if (outLength != jOutLen) {
- printf("CIP actual output len=%d\n", outLength);
+ printf("NativeRSACipher.nativeAtomic out len=%d\n", outLength);
}
- printBytes("After nativeAtomic: ", (unsigned char*) (bufOut + jOutOfs), outLength);
+ printBytes("After: ", (unsigned char*) (bufOut + jOutOfs), outLength);
}
if (rv) {
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -29,18 +29,18 @@
extern "C" {
#endif
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_MD5
-#define com_oracle_security_ucrypto_NativeDigest_MECH_MD5 1L
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA1
-#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA1 2L
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA256
-#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA256 3L
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA224
-#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA224 4L
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA384
-#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA384 5L
-#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA512
-#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA512 6L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5 1L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1 2L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256 3L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA224
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA224 4L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384 5L
+#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512
+#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512 6L
#define DEBUG 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c Sat May 14 03:44:30 2016 +0000
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2016, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <jni.h>
+#include "jni_util.h"
+#include <libsoftcrypto.h>
+#include "nativeCrypto.h"
+#include "nativeFunc.h"
+
+
+extern void throwOutOfMemoryError(JNIEnv *env, const char *msg);
+extern jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len);
+
+///////////////////////////////////////////////////////
+// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION
+////////////////////////////////////////////////////////
+jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(jint mech) {
+ void *pContext = NULL;
+
+ switch (mech) {
+ case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1:
+ pContext = malloc(sizeof(SHA1_CTX));
+ if (pContext != NULL) {
+ (*ftab->sha1Init)((SHA1_CTX *)pContext);
+ }
+ break;
+ case com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5:
+ pContext = malloc(sizeof(MD5_CTX));
+ if (pContext != NULL) {
+ (*ftab->md5Init)((MD5_CTX *)pContext);
+ }
+ break;
+ case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256:
+ pContext = malloc(sizeof(SHA2_CTX));
+ if (pContext != NULL) {
+ (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext);
+ }
+ break;
+ case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384:
+ pContext = malloc(sizeof(SHA2_CTX));
+ if (pContext != NULL) {
+ (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext);
+ }
+ break;
+ case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512:
+ pContext = malloc(sizeof(SHA2_CTX));
+ if (pContext != NULL) {
+ (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext);
+ }
+ break;
+ default:
+ if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech);
+ }
+ return (jlong) pContext;
+}
+
+jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate
+ (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) {
+ if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
+ (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len);
+ } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
+ (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len);
+ } else { // SHA-2 family
+ (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len);
+ }
+ return 0;
+}
+
+// Do digest and free the context immediately
+jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest
+ (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) {
+
+ if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
+ (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext);
+ free((SHA1_CTX *)pContext);
+ } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
+ (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext);
+ free((MD5_CTX *)pContext);
+ } else { // SHA-2 family
+ (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext);
+ free((SHA2_CTX *)pContext);
+ }
+ return 0;
+}
+
+jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone
+ (jint mech, jlong pContext) {
+ void *copy = NULL;
+ size_t len = 0;
+
+ if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
+ len = sizeof(SHA1_CTX);
+ } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
+ len = sizeof(MD5_CTX);
+ } else { // SHA-2 family
+ len = sizeof(SHA2_CTX);
+ }
+ copy = malloc(len);
+ if (copy != NULL) {
+ bcopy((void *)pContext, copy, len);
+ }
+ return (jlong) copy;
+}
+
+void JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree
+ (jint mech, jlong pContext) {
+ if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
+ free((SHA1_CTX*) pContext);
+ } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
+ free((MD5_CTX*) pContext);
+ } else { // SHA-2 family
+ free((SHA2_CTX*) pContext);
+ }
+}
+
+
+/*
+ * Class: com_oracle_security_ucrypto_NativeDigestMD
+ * Method: nativeInit
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit
+ (JNIEnv *env, jclass jcls, jint mech) {
+ jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(mech);
+ if (result == NULL) {
+ throwOutOfMemoryError(env, NULL);
+ }
+ return result;
+}
+
+/*
+ * Class: com_oracle_security_ucrypto_NativeDigestMD
+ * Method: nativeUpdate
+ * Signature: (IJ[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate
+ (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) {
+ unsigned char *bufIn;
+
+ bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen);
+ if (!(*env)->ExceptionCheck(env)) {
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen);
+ free(bufIn);
+ }
+ return 0;
+}
+
+/*
+ * Class: com_oracle_security_ucrypto_NativeDigestMD
+ * Method: nativeDigest
+ * Signature: (IJ[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest
+ (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) {
+ unsigned char *bufOut;
+
+ bufOut = (unsigned char *) malloc(digestLen);
+ if (bufOut == NULL) {
+ throwOutOfMemoryError(env, NULL);
+ return 0;
+ }
+
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen);
+
+ (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut);
+ free(bufOut);
+ return 0;
+}
+
+/*
+ * Class: com_oracle_security_ucrypto_NativeDigestMD
+ * Method: nativeClone
+ * Signature: (IJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone
+ (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
+ return JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone(mech, pContext);
+}
+
+/*
+ * Class: com_oracle_security_ucrypto_NativeDigestMD
+ * Method: nativeFree
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree
+ (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
+ JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree(mech, pContext);
+}
+
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -42,21 +42,33 @@
static const char SHA2_FINAL[] = "SHA2Final";
static const char UCRYPTO_VERSION[] = "ucrypto_version";
static const char UCRYPTO_GET_MECHLIST[] = "ucrypto_get_mechlist";
+
static const char UCRYPTO_ENCRYPT_INIT[] = "ucrypto_encrypt_init";
static const char UCRYPTO_ENCRYPT_UPDATE[] = "ucrypto_encrypt_update";
static const char UCRYPTO_ENCRYPT_FINAL[] = "ucrypto_encrypt_final";
static const char UCRYPTO_ENCRYPT[] = "ucrypto_encrypt";
+
static const char UCRYPTO_DECRYPT_INIT[] = "ucrypto_decrypt_init";
static const char UCRYPTO_DECRYPT_UPDATE[] = "ucrypto_decrypt_update";
static const char UCRYPTO_DECRYPT_FINAL[] = "ucrypto_decrypt_final";
static const char UCRYPTO_DECRYPT[] = "ucrypto_decrypt";
+
static const char UCRYPTO_SIGN_INIT[] = "ucrypto_sign_init";
static const char UCRYPTO_SIGN_UPDATE[] = "ucrypto_sign_update";
static const char UCRYPTO_SIGN_FINAL[] = "ucrypto_sign_final";
+
static const char UCRYPTO_VERIFY_INIT[] = "ucrypto_verify_init";
static const char UCRYPTO_VERIFY_UPDATE[] = "ucrypto_verify_update";
static const char UCRYPTO_VERIFY_FINAL[] = "ucrypto_verify_final";
+static const char UCRYPTO_DIGEST_INIT[] = "ucrypto_digest_init";
+static const char UCRYPTO_DIGEST_UPDATE[] = "ucrypto_digest_update";
+static const char UCRYPTO_DIGEST_FINAL[] = "ucrypto_digest_final";
+
+static const char UCRYPTO_FREE_CONTEXT[] = "ucrypto_free_context";
+
+static const char UCRYPTO_STRERROR[] = "ucrypto_strerror";
+
/**
* Initialize native T4 crypto function pointers
*/
@@ -73,28 +85,6 @@
return NULL;
}
- lib = dlopen("libmd.so", RTLD_NOW);
- if (lib != NULL) {
- ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT);
- ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE);
- ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL);
- ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT);
- ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE);
- ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL);
- ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT);
- ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE);
- ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL);
- if (ftab->md5Init != NULL && ftab->md5Update != NULL &&
- ftab->md5Final != NULL && ftab->sha1Init != NULL &&
- ftab->sha1Update != NULL && ftab->sha1Final != NULL &&
- ftab->sha2Init != NULL && ftab->sha2Update != NULL &&
- ftab->sha2Final != NULL) {
- buf[0] = JNI_TRUE;
- } else {
- dlclose(lib);
- }
- }
-
lib = dlopen("libsoftcrypto.so", RTLD_NOW);
if (lib != NULL) {
// These APIs aren't available for v0 lib on Solaris 10
@@ -102,7 +92,6 @@
dlsym(lib, UCRYPTO_VERSION);
ftab->ucryptoGetMechList = (UCRYPTO_GET_MECHLIST_FN_PTR)
dlsym(lib, UCRYPTO_GET_MECHLIST);
- //??
ftab->ucryptoSignInit = (UCRYPTO_SIGN_INIT_FN_PTR)
dlsym(lib, UCRYPTO_SIGN_INIT);
ftab->ucryptoSignUpdate = (UCRYPTO_SIGN_UPDATE_FN_PTR)
@@ -116,6 +105,21 @@
ftab->ucryptoVerifyFinal = (UCRYPTO_VERIFY_FINAL_FN_PTR)
dlsym(lib, UCRYPTO_VERIFY_FINAL);
+ // These APS are added starting S12
+ ftab->ucryptoDigestInit = (UCRYPTO_DIGEST_INIT_FN_PTR)
+ dlsym(lib, UCRYPTO_DIGEST_INIT);
+ ftab->ucryptoDigestUpdate = (UCRYPTO_DIGEST_UPDATE_FN_PTR)
+ dlsym(lib, UCRYPTO_DIGEST_UPDATE);
+ ftab->ucryptoDigestFinal = (UCRYPTO_DIGEST_FINAL_FN_PTR)
+ dlsym(lib, UCRYPTO_DIGEST_FINAL);
+
+ ftab->ucryptoFreeContext = (UCRYPTO_FREE_CONTEXT_FN_PTR)
+ dlsym(lib, UCRYPTO_FREE_CONTEXT);
+
+ ftab->ucryptoStrerror = (UCRYPTO_STRERROR_FN_PTR)
+ dlsym(lib, UCRYPTO_STRERROR);
+
+
// These should be avilable for all libsoftcrypto libs
ftab->ucryptoEncryptInit = (UCRYPTO_ENCRYPT_INIT_FN_PTR)
dlsym(lib, UCRYPTO_ENCRYPT_INIT);
@@ -147,6 +151,34 @@
} else {
dlclose(lib);
}
+
+ // proceed with libmd when libucrypto does not support digest operations
+ if (ftab->ucryptoDigestInit == NULL ||
+ ftab->ucryptoDigestUpdate == NULL ||
+ ftab->ucryptoDigestFinal == NULL) {
+
+ lib = dlopen("libmd.so", RTLD_NOW);
+ if (lib != NULL) {
+ ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT);
+ ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE);
+ ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL);
+ ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT);
+ ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE);
+ ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL);
+ ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT);
+ ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE);
+ ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL);
+ if (ftab->md5Init != NULL && ftab->md5Update != NULL &&
+ ftab->md5Final != NULL && ftab->sha1Init != NULL &&
+ ftab->sha1Update != NULL && ftab->sha1Final != NULL &&
+ ftab->sha2Init != NULL && ftab->sha2Update != NULL &&
+ ftab->sha2Final != NULL) {
+ buf[0] = JNI_TRUE;
+ } else {
+ dlclose(lib);
+ }
+ }
+ }
}
return buf;
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h Fri May 13 18:58:32 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -69,15 +69,12 @@
(crypto_ctx_t *context, ucrypto_mech_t mech_type,
uchar_t *key_str, size_t key_len,
void *iv, size_t iv_len);
-
typedef int (*UCRYPTO_ENCRYPT_UPDATE_FN_PTR)
(crypto_ctx_t *context, uchar_t *in,
size_t in_len, uchar_t *out, size_t *out_len);
-
typedef int (*UCRYPTO_ENCRYPT_FINAL_FN_PTR)
(crypto_ctx_t *context, uchar_t *out,
size_t *out_len);
-
typedef int (*UCRYPTO_ENCRYPT_FN_PTR)
(ucrypto_mech_t mech_type, uchar_t *key_str,
size_t key_len, void *iv, size_t iv_len, uchar_t *in,
@@ -87,15 +84,12 @@
(crypto_ctx_t *context,
ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len,
void *iv, size_t iv_len);
-
typedef int (*UCRYPTO_DECRYPT_UPDATE_FN_PTR)
(crypto_ctx_t *context, uchar_t *in,
size_t in_len, uchar_t *out, size_t *out_len);
-
typedef int (*UCRYPTO_DECRYPT_FINAL_FN_PTR)
(crypto_ctx_t *context, uchar_t *out,
size_t *out_len);
-
typedef int (*UCRYPTO_DECRYPT_FN_PTR)
(ucrypto_mech_t mech_type, uchar_t *key_str,
size_t key_len, void *iv, size_t iv_len, uchar_t *in,
@@ -105,10 +99,8 @@
(crypto_ctx_t *context, ucrypto_mech_t mech_type,
uchar_t *key_str, size_t key_len,
void *iv, size_t iv_len);
-
typedef int (*UCRYPTO_SIGN_UPDATE_FN_PTR)
(crypto_ctx_t *context, uchar_t *data_str, size_t data_len);
-
typedef int (*UCRYPTO_SIGN_FINAL_FN_PTR)
(crypto_ctx_t *context, uchar_t *sig_str, size_t *sig_len);
@@ -116,13 +108,24 @@
(crypto_ctx_t *context, ucrypto_mech_t mech_type,
uchar_t *key_str, size_t key_len,
void *iv, size_t iv_len);
-
typedef int (*UCRYPTO_VERIFY_UPDATE_FN_PTR)
(crypto_ctx_t *context, uchar_t *data_str, size_t data_len);
-
typedef int (*UCRYPTO_VERIFY_FINAL_FN_PTR)
(crypto_ctx_t *context, uchar_t *sig_str, size_t *sig_len);
+typedef int (*UCRYPTO_DIGEST_INIT_FN_PTR)
+ (crypto_ctx_t *context, ucrypto_mech_t mech_type,
+ void *param, size_t param_len);
+typedef int (*UCRYPTO_DIGEST_UPDATE_FN_PTR)
+ (crypto_ctx_t *context, const uchar_t *data, size_t data_len);
+typedef int (*UCRYPTO_DIGEST_FINAL_FN_PTR)
+ (crypto_ctx_t *context, uchar_t *digest, size_t *digest_len);
+
+typedef void (*UCRYPTO_FREE_CONTEXT_FN_PTR)
+ (crypto_ctx_t *context);
+
+typedef char* (*UCRYPTO_STRERROR_FN_PTR)(int rv);
+
/* dynamically resolved functions from libmd, and libsoftcrypto
@@ -153,6 +156,11 @@
UCRYPTO_VERIFY_INIT_FN_PTR ucryptoVerifyInit;
UCRYPTO_VERIFY_UPDATE_FN_PTR ucryptoVerifyUpdate;
UCRYPTO_VERIFY_FINAL_FN_PTR ucryptoVerifyFinal;
+ UCRYPTO_DIGEST_INIT_FN_PTR ucryptoDigestInit;
+ UCRYPTO_DIGEST_UPDATE_FN_PTR ucryptoDigestUpdate;
+ UCRYPTO_DIGEST_FINAL_FN_PTR ucryptoDigestFinal;
+ UCRYPTO_FREE_CONTEXT_FN_PTR ucryptoFreeContext;
+ UCRYPTO_STRERROR_FN_PTR ucryptoStrerror;
} T4CRYPTO_FUNCTION_TABLE;
typedef T4CRYPTO_FUNCTION_TABLE *T4CRYPTO_FUNCTION_TABLE_PTR;
--- a/jdk/test/com/oracle/security/ucrypto/TestDigest.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestDigest.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7088989
+ * @bug 7088989 8000415
* @summary Ensure the various message digests works correctly
* @key randomness
*/
@@ -40,84 +40,106 @@
private static final String[] MD_ALGOS = {
"MD5",
"SHA",
+ "SHA-224",
"SHA-256",
"SHA-384",
- "SHA-512"
+ "SHA-512",
+ "SHA3-224",
+ "SHA3-256",
+ "SHA3-384",
+ "SHA3-512"
};
public static void main(String[] args) throws Exception {
main(new TestDigest(), null);
}
- public void doTest(Provider p) {
+ public void doTest(Provider p) throws Exception {
boolean testPassed = true;
byte[] msg = new byte[200];
(new SecureRandom()).nextBytes(msg);
String interopProvName = "SUN";
+ MessageDigest md, md2;
+
for (String a : MD_ALGOS) {
+ System.out.println("Testing " + a);
try {
- MessageDigest md, md2;
- try {
- md = MessageDigest.getInstance(a, p);
- } catch (NoSuchAlgorithmException nsae) {
- System.out.println("Skipping Unsupported MD algo: " + a);
- continue;
- }
+ md = MessageDigest.getInstance(a, p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("=> Skip, unsupported");
+ continue;
+ }
+ try {
md2 = MessageDigest.getInstance(a, interopProvName);
- // Test Interoperability for update+digest calls
- for (int i = 0; i < 3; i++) {
- md.update(msg);
- byte[] digest = md.digest();
- md2.update(msg);
- byte[] digest2 = md2.digest();
- if (!Arrays.equals(digest, digest2)) {
- System.out.println("DIFF1 FAILED for: " + a + " at iter " + i);
- testPassed = false;
- }
- }
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("=> Skip, no interop provider found");
+ continue;
+ }
- // Test Interoperability for digest calls
- md = MessageDigest.getInstance(a, p);
- md2 = MessageDigest.getInstance(a, interopProvName);
+ // Test Interoperability for update+digest calls
+ for (int i = 0; i < 3; i++) {
+ md.update(msg);
+ byte[] digest = md.digest();
+ md2.update(msg);
+ byte[] digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF1 FAILED at iter " + i);
+ testPassed = false;
+ } else {
+ System.out.println("...diff1 test passed");
+ }
+ }
- for (int i = 0; i < 3; i++) {
- byte[] digest = md.digest();
- byte[] digest2 = md2.digest();
- if (!Arrays.equals(digest, digest2)) {
- System.out.println("DIFF2 FAILED for: " + a + " at iter " + i);
- testPassed = false;
- }
- }
+ // Test Interoperability for digest calls
+ md = MessageDigest.getInstance(a, p);
+ md2 = MessageDigest.getInstance(a, interopProvName);
- // Test Cloning functionality
- md = MessageDigest.getInstance(a, p);
- md2 = (MessageDigest) md.clone(); // clone right after construction
+ for (int i = 0; i < 3; i++) {
byte[] digest = md.digest();
byte[] digest2 = md2.digest();
if (!Arrays.equals(digest, digest2)) {
- System.out.println("DIFF-3.1 FAILED for: " + a);
+ System.out.println("DIFF2 FAILED at iter " + i);
testPassed = false;
- }
- md.update(msg);
- md2 = (MessageDigest) md.clone(); // clone again after update call
- digest = md.digest();
- digest2 = md2.digest();
- if (!Arrays.equals(digest, digest2)) {
- System.out.println("DIFF-3.2 FAILED for: " + a);
- testPassed = false;
+ } else {
+ System.out.println("...diff2 test passed");
}
- md2 = (MessageDigest) md.clone(); // clone after digest
- digest = md.digest();
- digest2 = md2.digest();
- if (!Arrays.equals(digest, digest2)) {
- System.out.println("DIFF-3.3 FAILED for: " + a);
- testPassed = false;
- }
- } catch(Exception ex) {
- System.out.println("Unexpected Exception: " + a);
- ex.printStackTrace();
+ }
+
+ // Test Cloning functionality if supported
+ md = MessageDigest.getInstance(a, p);
+ try {
+ md2 = (MessageDigest) md.clone(); // clone right after construction
+ } catch (CloneNotSupportedException cnse) {
+ System.out.println("...no clone support");
+ continue;
+ }
+ byte[] digest = md.digest();
+ byte[] digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.1 FAILED");
testPassed = false;
+ } else {
+ System.out.println("...diff3.1 tests passed");
+ }
+ md.update(msg);
+ md2 = (MessageDigest) md.clone(); // clone again after update call
+ digest = md.digest();
+ digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.2 FAILED");
+ testPassed = false;
+ } else {
+ System.out.println("...diff3.2 tests passed");
+ }
+ md2 = (MessageDigest) md.clone(); // clone after digest
+ digest = md.digest();
+ digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.3 FAILED");
+ testPassed = false;
+ } else {
+ System.out.println("...diff3.3 tests passed");
}
}
if (!testPassed) {
--- a/jdk/test/sun/security/provider/MessageDigest/Offsets.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/test/sun/security/provider/MessageDigest/Offsets.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -84,6 +84,10 @@
test("SHA-256", 0, 64, 0, 128);
test("SHA-384", 0, 128, 0, 256);
test("SHA-512", 0, 128, 0, 256);
+ test("SHA3-224", 0, 64, 0, 128);
+ test("SHA3-256", 0, 64, 0, 128);
+ test("SHA3-384", 0, 128, 0, 256);
+ test("SHA3-512", 0, 128, 0, 256);
}
}
--- a/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java Fri May 13 18:58:32 2016 +0000
+++ b/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java Sat May 14 03:44:30 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -32,8 +32,13 @@
public class TestSHAClone {
+ // OracleUcrypto provider gets its digest impl from either
+ // libucrypto (starting S12 with SHA-3 support added) and
+ // libmd (pre-S12, no SHA-3 at all).
+ // The impls from libucrypto does not support clone but ones
+ // from libmd do.
private static final String[] ALGOS = {
- "SHA", "SHA-224", "SHA-256", "SHA-512", "SHA-384"
+ "SHA", "SHA-224", "SHA-256", "SHA-384", "SHA-512"
};
private static byte[] input1 = {
@@ -52,7 +57,13 @@
private void run() throws Exception {
md.update(input1);
- MessageDigest md2 = (MessageDigest) md.clone();
+ MessageDigest md2;
+ try {
+ md2 = (MessageDigest) md.clone();
+ } catch (CloneNotSupportedException cnse) {
+ System.out.println(md.getAlgorithm() + ": clone unsupported");
+ return;
+ }
md.update(input2);
md2.update(input2);
if (!Arrays.equals(md.digest(), md2.digest())) {