--- old/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java 2015-06-25 12:09:44.638654333 +0200 +++ new/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java 2015-06-25 12:09:44.038654304 +0200 @@ -38,6 +38,9 @@ import java.security.InvalidKeyException; import java.util.Arrays; +import java.util.Objects; + +import jdk.internal.HotSpotIntrinsicCandidate; /** * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit @@ -346,7 +349,16 @@ * Encrypt exactly one block of plaintext. */ void encryptBlock(byte[] in, int inOffset, - byte[] out, int outOffset) + byte[] out, int outOffset) { + cryptBlockCheck(in, inOffset); + cryptBlockCheck(out, outOffset); + encryptBlockImpl(in, inOffset, out, outOffset); + } + + // Encryption operation. Possibly replaced with a compiler intrinsic. + @HotSpotIntrinsicCandidate + private void encryptBlockImpl(byte[] in, int inOffset, + byte[] out, int outOffset) { int keyOffset = 0; int t0 = ((in[inOffset++] ) << 24 | @@ -412,12 +424,20 @@ out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); } - /** * Decrypt exactly one block of plaintext. */ void decryptBlock(byte[] in, int inOffset, - byte[] out, int outOffset) + byte[] out, int outOffset) { + cryptBlockCheck(in, inOffset); + cryptBlockCheck(out, outOffset); + decryptBlockImpl(in, inOffset, out, outOffset); + } + + // Decrypt operation. Possibly replaced with a compiler intrinsic. + @HotSpotIntrinsicCandidate + private void decryptBlockImpl(byte[] in, int inOffset, + byte[] out, int outOffset) { int keyOffset = 4; int t0 = ((in[inOffset++] ) << 24 | @@ -572,6 +592,25 @@ out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); } + // Used to perform all checks required by the Java semantics + // (i.e., null checks and bounds checks) on the input parameters + // to encryptBlock and to decryptBlock. + // Normally, the Java Runtime performs these checks, however, as + // encryptBlock and decryptBlock are possibly replaced with + // compiler intrinsics, the JDK performs the required checks instead. + // Does not check accesses to class-internal (private) arrays. + private static void cryptBlockCheck(byte[] array, int offset) { + Objects.requireNonNull(array); + + if (offset < 0 || offset >= array.length) { + throw new ArrayIndexOutOfBoundsException(offset); + } + + int largestIndex = offset + AES_BLOCK_SIZE - 1; + if (largestIndex < 0 || largestIndex >= array.length) { + throw new ArrayIndexOutOfBoundsException(largestIndex); + } + } /** * Expand a user-supplied key material into a session key.