8000415: Add support for SHA-3
Add SHA-3 support to SUN and OracleUcrypto provider Reviewed-by: ascarpino, jnimeh
This commit is contained in:
parent
6c51be077a
commit
b40b6a2e8e
jdk
make/mapfiles/libj2ucrypto
src
java.base/share/classes/sun/security
jdk.crypto.ucrypto/solaris
classes/com/oracle/security/ucrypto
native/libj2ucrypto
test
com/oracle/security/ucrypto
sun/security/provider/MessageDigest
@ -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 @@ SUNWprivate_1.1 {
|
||||
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 @@ SUNWprivate_1.1 {
|
||||
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:
|
||||
|
@ -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 @@ final class ByteArrayAccess {
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
300
jdk/src/java.base/share/classes/sun/security/provider/SHA3.java
Normal file
300
jdk/src/java.base/share/classes/sun/security/provider/SHA3.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -211,6 +211,25 @@ final class SunEntries {
|
||||
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
|
||||
*/
|
||||
|
@ -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 @@ final class HandshakeHash {
|
||||
* a hash for the certificate verify message is required.
|
||||
*/
|
||||
HandshakeHash(boolean needCertificateVerify) {
|
||||
clonesNeeded = needCertificateVerify ? 3 : 2;
|
||||
clonesNeeded = needCertificateVerify ? 4 : 3;
|
||||
}
|
||||
|
||||
void reserve(ByteBuffer input) {
|
||||
|
66
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java
Normal file
66
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java
Normal file
@ -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; }
|
||||
}
|
@ -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.util.concurrent.ConcurrentSkipListSet;
|
||||
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 @@ public abstract class NativeDigest extends MessageDigestSpi
|
||||
// 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 @@ public abstract class NativeDigest extends MessageDigestSpi
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public abstract class NativeDigest extends MessageDigestSpi
|
||||
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) {
|
||||
this.digestLen = digestLen;
|
||||
NativeDigest(UcryptoMech mech, int digestLen) {
|
||||
this.mech = mech;
|
||||
this.digestLen = digestLen;
|
||||
}
|
||||
|
||||
// see JCA spec
|
||||
@ -153,10 +200,10 @@ public abstract class NativeDigest extends MessageDigestSpi
|
||||
}
|
||||
|
||||
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 @@ public abstract class NativeDigest extends MessageDigestSpi
|
||||
+ 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);
|
||||
protected static final 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 int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen);
|
||||
// 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 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);
|
||||
}
|
||||
|
246
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java
Normal file
246
jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 @@ import java.util.HashMap;
|
||||
// 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; }
|
||||
}
|
||||
|
@ -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 @@ package com.oracle.security.ucrypto;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
|
||||
@ -74,48 +75,52 @@ public final class UcryptoProvider extends Provider {
|
||||
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 @@ public final class UcryptoProvider extends Provider {
|
||||
sd.getAliases(), null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Object newInstance(Object ctrParamObj)
|
||||
throws NoSuchAlgorithmException {
|
||||
@ -152,53 +158,19 @@ public final class UcryptoProvider extends Provider {
|
||||
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();
|
||||
}
|
||||
} 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();
|
||||
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("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();
|
||||
|
@ -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 */
|
@ -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
|
||||
@ -32,6 +32,22 @@
|
||||
#include "nativeCrypto.h"
|
||||
#include "nativeFunc.h"
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -60,6 +76,16 @@ void throwOutOfMemoryError(JNIEnv *env, const char *msg)
|
||||
(*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 @@ CipherInit(crypto_ctx_t *context, int encrypt, ucrypto_mech_t mech,
|
||||
}
|
||||
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 @@ CipherUpdate(crypto_ctx_t *context, int encrypt, unsigned char *bufIn, int inOfs
|
||||
}
|
||||
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 @@ CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOf
|
||||
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 @@ CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOf
|
||||
// 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);
|
||||
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_MD5:
|
||||
pContext = (MD5_CTX *) malloc(sizeof(MD5_CTX));
|
||||
if (pContext != NULL) {
|
||||
(*ftab->md5Init)((MD5_CTX *)pContext);
|
||||
}
|
||||
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) {
|
||||
crypto_ctx_t *context;
|
||||
jint rv = 0;
|
||||
size_t digest_len = 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);
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone
|
||||
(jint mech, jlong pContext) {
|
||||
void *copy = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
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 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal
|
||||
return outLen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_oracle_security_ucrypto_NativeDigest
|
||||
* Method: nativeInit
|
||||
@ -475,13 +457,15 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit
|
||||
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_nativeUpdat
|
||||
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 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDiges
|
||||
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 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit
|
||||
|
||||
cleanup:
|
||||
if ((result == 0L) && (context != NULL)) {
|
||||
free(context);
|
||||
freeContext(context);
|
||||
}
|
||||
if (bufKey != NULL) {
|
||||
(*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0);
|
||||
@ -626,7 +602,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdat
|
||||
|
||||
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 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: com_oracle_security_ucrypto_NativeKey
|
||||
* Method: nativeFree
|
||||
@ -984,9 +961,9 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeIn
|
||||
}
|
||||
|
||||
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 @@ SignatureInit(crypto_ctx_t *context, jint mechVal, jboolean sign,
|
||||
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 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit
|
||||
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 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nati
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__J
|
||||
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__J
|
||||
} 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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal
|
||||
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal
|
||||
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);
|
||||
}
|
||||
if (sign) {
|
||||
printBytes("After nativeFinal: ", (unsigned char*) (bufSig + sigOfs), jSigLen);
|
||||
}
|
||||
}
|
||||
|
||||
free(context);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return -rv;
|
||||
} else return 0;
|
||||
}
|
||||
@ -1273,10 +1249,10 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic
|
||||
|
||||
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 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic
|
||||
(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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_UPDATE[] = "SHA2Update";
|
||||
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 @@ jboolean* loadNative() {
|
||||
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 @@ jboolean* loadNative() {
|
||||
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 @@ jboolean* loadNative() {
|
||||
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 @@ jboolean* loadNative() {
|
||||
} 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;
|
||||
|
@ -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 @@ typedef int (*UCRYPTO_ENCRYPT_INIT_FN_PTR)
|
||||
(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 @@ typedef int (*UCRYPTO_DECRYPT_INIT_FN_PTR)
|
||||
(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 @@ typedef int (*UCRYPTO_SIGN_INIT_FN_PTR)
|
||||
(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 @@ typedef int (*UCRYPTO_VERIFY_INIT_FN_PTR)
|
||||
(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 @@ typedef struct T4CRYPTO_FUNCTION_TABLE {
|
||||
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;
|
||||
|
@ -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 @@ public class TestDigest extends UcryptoTest {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Test Interoperability for digest calls
|
||||
md = MessageDigest.getInstance(a, p);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
System.out.println("=> Skip, unsupported");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
md2 = MessageDigest.getInstance(a, interopProvName);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
System.out.println("=> Skip, no interop provider found");
|
||||
continue;
|
||||
}
|
||||
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
|
||||
// Test Cloning functionality
|
||||
md = MessageDigest.getInstance(a, p);
|
||||
md2 = (MessageDigest) md.clone(); // clone right after construction
|
||||
// Test Interoperability for digest calls
|
||||
md = MessageDigest.getInstance(a, p);
|
||||
md2 = MessageDigest.getInstance(a, interopProvName);
|
||||
|
||||
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;
|
||||
} else {
|
||||
System.out.println("...diff2 test 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 for: " + a);
|
||||
testPassed = false;
|
||||
}
|
||||
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) {
|
||||
|
@ -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 @@ public class Offsets {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 @@ import java.util.*;
|
||||
|
||||
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 @@ public class TestSHAClone {
|
||||
|
||||
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())) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user