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

8223511: Extended AES support

Reviewed-by: phh, mbalao, bae
上级 5024c671
......@@ -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,6 +347,14 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
* Encrypt exactly one block of plaintext.
*/
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)
{
int keyOffset = 0;
......@@ -412,11 +421,18 @@ 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) {
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;
......@@ -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.
......
......@@ -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);
}
}
}
......@@ -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) {
......
......@@ -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++) {
......
......@@ -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++) {
......
......@@ -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++) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册