--- old/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java 2017-04-21 13:00:43.480124068 -0700 +++ new/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java 2017-04-21 13:00:43.352124063 -0700 @@ -38,7 +38,7 @@ import java.security.InvalidKeyException; import java.security.MessageDigest; -import java.util.Arrays; +import java.security.ProviderException; import java.util.Objects; import jdk.internal.HotSpotIntrinsicCandidate; @@ -356,6 +356,18 @@ implEncryptBlock(in, inOffset, out, outOffset); } + @Override + void encryptBlocks(byte[] in, int inOffset, byte[] out, int outOffset, int len) { + if ((len % AES_BLOCK_SIZE) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + Objects.checkFromIndexSize(inOffset , len, in.length); + Objects.checkFromIndexSize(outOffset, len, out.length); + for (int i = 0; i < len; i += AES_BLOCK_SIZE) { + implEncryptBlock(in, inOffset + i, out, outOffset + i); + } + } + // Encryption operation. Possibly replaced with a compiler intrinsic. @HotSpotIntrinsicCandidate private void implEncryptBlock(byte[] in, int inOffset, @@ -435,6 +447,19 @@ implDecryptBlock(in, inOffset, out, outOffset); } + @Override + void decryptBlocks(byte[] in, int inOffset, byte[] out, int outOffset, int len) { + if ((len % AES_BLOCK_SIZE) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + Objects.checkFromIndexSize(inOffset, len, in.length); + Objects.checkFromIndexSize(outOffset, len, out.length); + for (int i = 0; i < len; i += AES_BLOCK_SIZE) { + implDecryptBlock(in, inOffset + i, out, outOffset + i); + } + } + + // Decrypt operation. Possibly replaced with a compiler intrinsic. @HotSpotIntrinsicCandidate private void implDecryptBlock(byte[] in, int inOffset, --- old/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java 2017-04-21 13:00:43.956124089 -0700 +++ new/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java 2017-04-21 13:00:43.828124084 -0700 @@ -112,14 +112,7 @@ * @return the length of the encrypted data */ int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { - if ((len % blockSize) != 0) { - throw new ProviderException("Internal error in input buffering"); - } - for (int i = len; i >= blockSize; i -= blockSize) { - embeddedCipher.encryptBlock(in, inOff, out, outOff); - inOff += blockSize; - outOff += blockSize; - } + embeddedCipher.encryptBlocks(in, inOff, out, outOff, len); return len; } @@ -141,14 +134,7 @@ * @return the length of the decrypted data */ int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { - if ((len % blockSize) != 0) { - throw new ProviderException("Internal error in input buffering"); - } - for (int i = len; i >= blockSize; i -= blockSize) { - embeddedCipher.decryptBlock(in, inOff, out, outOff); - inOff += blockSize; - outOff += blockSize; - } + embeddedCipher.decryptBlocks(in, inOff, out, outOff, len); return len; } } --- old/src/java.base/share/classes/com/sun/crypto/provider/SymmetricCipher.java 2017-04-21 13:00:44.420124110 -0700 +++ new/src/java.base/share/classes/com/sun/crypto/provider/SymmetricCipher.java 2017-04-21 13:00:44.292124104 -0700 @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; /** * This abstract class represents the core of all block ciphers. It allows to @@ -84,6 +85,17 @@ abstract void encryptBlock(byte[] plain, int plainOffset, byte[] cipher, int cipherOffset); + void encryptBlocks(byte[] plain, int plainOffset, byte[] cipher, int cipherOffset, int len) { + int blockSize = getBlockSize(); + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + for (int i = 0; i < len; i += blockSize) { + encryptBlock(plain, plainOffset + i, cipher, cipherOffset + i); + } + } + + /** * Decrypt one cipher block. * @@ -99,4 +111,15 @@ */ abstract void decryptBlock(byte[] cipher, int cipherOffset, byte[] plain, int plainOffset); + + void decryptBlocks(byte[] cipher, int cipherOffset, byte[] plain, int plainOffset, int len) { + int blockSize = getBlockSize(); + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + for (int i = 0; i < len; i += blockSize) { + decryptBlock(cipher, cipherOffset + i, plain, plainOffset + i); + } + } + }