aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrew <unknown>2019-07-04 18:20:08 +0100
committerbell-sw <liberica@bell-sw.com>2019-07-22 19:22:48 +0300
commit80628723229fbba69406a55c0de236cbb420dac1 (patch)
tree91f33062dd9b43a114a15df9437f65cbab0a9261
parentfea30b063042d87967029e3512bebcdd7f8eb9c9 (diff)
downloadjdk8u_jdk-80628723229fbba69406a55c0de236cbb420dac1.tar.gz
8223511: Extended AES support
Reviewed-by: phh, mbalao, bae
-rw-r--r--src/share/classes/com/sun/crypto/provider/AESCrypt.java41
-rw-r--r--src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java53
-rw-r--r--src/share/classes/sun/security/provider/DigestBase.java24
-rw-r--r--src/share/classes/sun/security/provider/SHA.java20
-rw-r--r--src/share/classes/sun/security/provider/SHA2.java20
-rw-r--r--src/share/classes/sun/security/provider/SHA5.java19
6 files changed, 163 insertions, 14 deletions
diff --git a/src/share/classes/com/sun/crypto/provider/AESCrypt.java b/src/share/classes/com/sun/crypto/provider/AESCrypt.java
index c85f715e96..0adb07092e 100644
--- a/src/share/classes/com/sun/crypto/provider/AESCrypt.java
+++ b/src/share/classes/com/sun/crypto/provider/AESCrypt.java
@@ -38,6 +38,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
+import java.util.Objects;
/**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
@@ -346,7 +347,15 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
* 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);
+ implEncryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Encryption operation. Possibly replaced with a compiler intrinsic.
+ private void implEncryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 0;
int t0 = ((in[inOffset++] ) << 24 |
@@ -412,12 +421,19 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
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);
+ implDecryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Decrypt operation. Possibly replaced with a compiler intrinsic.
+ private void implDecryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 4;
int t0 = ((in[inOffset++] ) << 24 |
@@ -572,6 +588,25 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
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.
diff --git a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
index 1d33117dd5..0f8040fe20 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import java.util.Objects;
/**
@@ -138,18 +139,24 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
- byte[] cipher, int cipherOffset)
- {
+ byte[] cipher, int cipherOffset) {
if (plainLen <= 0) {
return plainLen;
}
- if ((plainLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ cryptBlockSizeCheck(plainLen);
+ cryptNullAndBoundsCheck(plain, plainOffset, plainLen);
+ cryptNullAndBoundsCheck(cipher, cipherOffset, plainLen);
+ return implEncrypt(plain, plainOffset, plainLen,
+ cipher, cipherOffset);
+ }
+
+ private int implEncrypt(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset)
+ {
int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex;
- plainOffset+=blockSize, cipherOffset += blockSize) {
+ plainOffset += blockSize, cipherOffset += blockSize) {
for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
}
@@ -182,14 +189,19 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the decrypted data
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
- byte[] plain, int plainOffset)
- {
+ byte[] plain, int plainOffset) {
if (cipherLen <= 0) {
return cipherLen;
}
- if ((cipherLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ cryptBlockSizeCheck(cipherLen);
+ cryptNullAndBoundsCheck(cipher, cipherOffset, cipherLen);
+ cryptNullAndBoundsCheck(plain, plainOffset, cipherLen);
+ return implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
+ }
+
+ private int implDecrypt(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset)
+ {
int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex;
@@ -202,4 +214,23 @@ class CipherBlockChaining extends FeedbackCipher {
}
return cipherLen;
}
+
+ private void cryptBlockSizeCheck(int len) {
+ if ((len % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+ }
+
+ private static void cryptNullAndBoundsCheck(byte[] array, int offset, int len) {
+ Objects.requireNonNull(array);
+
+ if (offset < 0 || offset >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(offset);
+ }
+
+ int endIndex = offset + len - 1;
+ if (endIndex < 0 || endIndex >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
}
diff --git a/src/share/classes/sun/security/provider/DigestBase.java b/src/share/classes/sun/security/provider/DigestBase.java
index c3ac4ac36f..89b1d77f31 100644
--- a/src/share/classes/sun/security/provider/DigestBase.java
+++ b/src/share/classes/sun/security/provider/DigestBase.java
@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi;
import java.security.DigestException;
import java.security.ProviderException;
import java.util.Arrays;
+import java.util.Objects;
/**
* Common base message digest implementation for the Sun provider.
@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
// compress complete blocks
private int implCompressMultiBlock(byte[] b, int ofs, int limit) {
+ implCompressMultiBlockCheck(b, ofs, limit);
+ return implCompressMultiBlock0(b, ofs, limit);
+ }
+
+ private int implCompressMultiBlock0(byte[] b, int ofs, int limit) {
for (; ofs <= limit; ofs += blockSize) {
implCompress(b, ofs);
}
return ofs;
}
+ private void implCompressMultiBlockCheck(byte[] b, int ofs, int limit) {
+ if (limit < 0) {
+ return; // not an error because implCompressMultiBlockImpl won't execute if limit < 0
+ // and an exception is thrown if ofs < 0.
+ }
+
+ Objects.requireNonNull(b);
+
+ if (ofs < 0 || ofs >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(ofs);
+ }
+
+ int endIndex = (limit / blockSize) * blockSize + blockSize - 1;
+ if (endIndex >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
+
// reset this object. See JCA doc.
protected final void engineReset() {
if (bytesProcessed == 0) {
diff --git a/src/share/classes/sun/security/provider/SHA.java b/src/share/classes/sun/security/provider/SHA.java
index 24dc0b2897..dfa477adf2 100644
--- a/src/share/classes/sun/security/provider/SHA.java
+++ b/src/share/classes/sun/security/provider/SHA.java
@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
+
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -123,8 +125,26 @@ public final class SHA extends DigestBase {
* "old" NIST Secure Hash Algorithm.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints have the byte stream, compute the rest of
// the buffer
for (int t = 16; t <= 79; t++) {
diff --git a/src/share/classes/sun/security/provider/SHA2.java b/src/share/classes/sun/security/provider/SHA2.java
index 6f34c8d55d..25f13d0736 100644
--- a/src/share/classes/sun/security/provider/SHA2.java
+++ b/src/share/classes/sun/security/provider/SHA2.java
@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
+
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase {
* Process the current block to update the state variable state.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
diff --git a/src/share/classes/sun/security/provider/SHA5.java b/src/share/classes/sun/security/provider/SHA5.java
index 90c12526d8..ceba1fc2b2 100644
--- a/src/share/classes/sun/security/provider/SHA5.java
+++ b/src/share/classes/sun/security/provider/SHA5.java
@@ -26,6 +26,7 @@
package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*;
@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase {
* "old" NIST Secure Hash Algorithm.
*/
final void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig128'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2lBig128(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private final void implCompress0(byte[] buf, int ofs) {
// The first 16 longs are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {