提交 794a6b45 编写于 作者: A andrew

8223511: Extended AES support

Reviewed-by: phh, mbalao, bae
上级 5024c671
...@@ -38,6 +38,7 @@ package com.sun.crypto.provider; ...@@ -38,6 +38,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.Objects;
/** /**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
...@@ -346,6 +347,14 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -346,6 +347,14 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
* Encrypt exactly one block of plaintext. * Encrypt exactly one block of plaintext.
*/ */
void encryptBlock(byte[] in, int inOffset, void encryptBlock(byte[] in, int inOffset,
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) byte[] out, int outOffset)
{ {
int keyOffset = 0; int keyOffset = 0;
...@@ -412,11 +421,18 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -412,11 +421,18 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
} }
/** /**
* Decrypt exactly one block of plaintext. * Decrypt exactly one block of plaintext.
*/ */
void decryptBlock(byte[] in, int inOffset, void decryptBlock(byte[] in, int inOffset,
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) byte[] out, int outOffset)
{ {
int keyOffset = 4; int keyOffset = 4;
...@@ -572,6 +588,25 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -572,6 +588,25 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); 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. * Expand a user-supplied key material into a session key.
......
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import java.util.Objects;
/** /**
...@@ -138,18 +139,24 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -138,18 +139,24 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset) {
{
if (plainLen <= 0) { if (plainLen <= 0) {
return plainLen; return plainLen;
} }
if ((plainLen % blockSize) != 0) { cryptBlockSizeCheck(plainLen);
throw new ProviderException("Internal error in input buffering"); 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; int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex; for (; plainOffset < endIndex;
plainOffset+=blockSize, cipherOffset += blockSize) { plainOffset += blockSize, cipherOffset += blockSize) {
for (int i = 0; i < blockSize; i++) { for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i + plainOffset] ^ r[i]); k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
} }
...@@ -182,14 +189,19 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -182,14 +189,19 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the decrypted data * @return the length of the decrypted data
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset) {
{
if (cipherLen <= 0) { if (cipherLen <= 0) {
return cipherLen; return cipherLen;
} }
if ((cipherLen % blockSize) != 0) { cryptBlockSizeCheck(cipherLen);
throw new ProviderException("Internal error in input buffering"); 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; int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex; for (; cipherOffset < endIndex;
...@@ -202,4 +214,23 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -202,4 +214,23 @@ class CipherBlockChaining extends FeedbackCipher {
} }
return cipherLen; 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);
}
}
} }
...@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi; ...@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi;
import java.security.DigestException; import java.security.DigestException;
import java.security.ProviderException; import java.security.ProviderException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
/** /**
* Common base message digest implementation for the Sun provider. * Common base message digest implementation for the Sun provider.
...@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable { ...@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
// compress complete blocks // compress complete blocks
private int implCompressMultiBlock(byte[] b, int ofs, int limit) { 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) { for (; ofs <= limit; ofs += blockSize) {
implCompress(b, ofs); implCompress(b, ofs);
} }
return 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. // reset this object. See JCA doc.
protected final void engineReset() { protected final void engineReset() {
if (bytesProcessed == 0) { if (bytesProcessed == 0) {
......
...@@ -27,6 +27,8 @@ package sun.security.provider; ...@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
/** /**
...@@ -123,8 +125,26 @@ public final class SHA extends DigestBase { ...@@ -123,8 +125,26 @@ public final class SHA extends DigestBase {
* "old" NIST Secure Hash Algorithm. * "old" NIST Secure Hash Algorithm.
*/ */
void implCompress(byte[] buf, int ofs) { 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); 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 first 16 ints have the byte stream, compute the rest of
// the buffer // the buffer
for (int t = 16; t <= 79; t++) { for (int t = 16; t <= 79; t++) {
......
...@@ -27,6 +27,8 @@ package sun.security.provider; ...@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
/** /**
...@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase { ...@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase {
* Process the current block to update the state variable state. * Process the current block to update the state variable state.
*/ */
void implCompress(byte[] buf, int ofs) { 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); 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 first 16 ints are from the byte stream, compute the rest of
// the W[]'s // the W[]'s
for (int t = 16; t < ITERATION; t++) { for (int t = 16; t < ITERATION; t++) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package sun.security.provider; package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
...@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase { ...@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase {
* "old" NIST Secure Hash Algorithm. * "old" NIST Secure Hash Algorithm.
*/ */
final void implCompress(byte[] buf, int ofs) { 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); 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 first 16 longs are from the byte stream, compute the rest of
// the W[]'s // the W[]'s
for (int t = 16; t < ITERATION; t++) { for (int t = 16; t < ITERATION; t++) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册