Skip to content

Commit 477a3dd

Browse files
committed
8371820: Further AES performance improvements for key schedule generation
1 parent 48c59fa commit 477a3dd

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

src/hotspot/share/opto/library_call.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7479,13 +7479,8 @@ Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object)
74797479
// MixColumns for decryption can be reduced by preprocessing MixColumns with round keys.
74807480
// Intel's extension is based on this optimization and AESCrypt generates round keys by preprocessing MixColumns.
74817481
// However, ppc64 vncipher processes MixColumns and requires the same round keys with encryption.
7482-
// The ppc64 and riscv64 stubs of encryption and decryption use the same round keys (sessionK[0]).
7483-
Node* objSessionK = load_field_from_object(aescrypt_object, "sessionK", "[[I");
7484-
assert (objSessionK != nullptr, "wrong version of com.sun.crypto.provider.AES_Crypt");
7485-
if (objSessionK == nullptr) {
7486-
return (Node *) nullptr;
7487-
}
7488-
Node* objAESCryptKey = load_array_element(objSessionK, intcon(0), TypeAryPtr::OOPS, /* set_ctrl */ true);
7482+
// The ppc64, s390 and riscv64 stubs of encryption and decryption use the same round keys.
7483+
Node* objAESCryptKey = load_field_from_object(aescrypt_object, "sessionKe", "[I");
74897484
#else
74907485
Node* objAESCryptKey = load_field_from_object(aescrypt_object, "K", "[I");
74917486
#endif // PPC64

src/java.base/share/classes/com/sun/crypto/provider/AES_Crypt.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ final class AES_Crypt extends SymmetricCipher {
5454
private int rounds;
5555
private byte[] prevKey = null;
5656

57-
// Following two attributes are specific to Intrinsics where sessionK is
58-
// used for PPC64, S390, and RISCV64 architectures, whereas K is used for
59-
// everything else.
60-
private int[][] sessionK = null;
61-
private int[] K = null;
57+
// Following attribute is specific to Intrinsics where the unprocessed
58+
// key is used for PPC64, S390, and RISCV64 architectures, whereas K is
59+
// used for everything else.
60+
private int[] sessionKe = null; // key for encryption
61+
private int[] sessionKd = null; // preprocessed key for decryption
62+
private int[] K = null; // preprocessed key in case of decryption
6263

6364
// Round constant
6465
private static final int[] RCON = {
@@ -904,7 +905,6 @@ static boolean isKeySizeValid(int len) {
904905
*/
905906
void init(boolean decrypting, String algorithm, byte[] key)
906907
throws InvalidKeyException {
907-
int decrypt = decrypting ? 1 : 0;
908908

909909
if (!algorithm.equalsIgnoreCase("AES")
910910
&& !algorithm.equalsIgnoreCase("Rijndael")) {
@@ -920,21 +920,30 @@ void init(boolean decrypting, String algorithm, byte[] key)
920920
throw new InvalidKeyException("Invalid key length (" + key.length
921921
+ ").");
922922
}
923+
923924
if (!MessageDigest.isEqual(prevKey, key)) {
924-
if (sessionK == null) {
925-
sessionK = new int[2][];
926-
} else {
927-
Arrays.fill(sessionK[0], 0);
928-
Arrays.fill(sessionK[1], 0);
925+
if (sessionKe != null) {
926+
Arrays.fill(sessionKe, 0);
927+
}
928+
sessionKe = genRoundKeys(key, rounds);
929+
if (sessionKd != null) {
930+
Arrays.fill(sessionKd, 0);
931+
sessionKd = null;
929932
}
930-
sessionK[0] = genRoundKeys(key, rounds);
931-
sessionK[1] = genInvRoundKeys(sessionK[0], rounds);
932933
if (prevKey != null) {
933934
Arrays.fill(prevKey, (byte) 0);
934935
}
935936
prevKey = key.clone();
936937
}
937-
K = sessionK[decrypt];
938+
939+
if (decrypting) {
940+
if (sessionKd == null) {
941+
sessionKd = genInvRoundKeys(sessionKe, rounds);
942+
}
943+
K = sessionKd;
944+
} else {
945+
K = sessionKe;
946+
}
938947
}
939948

940949
/**

0 commit comments

Comments
 (0)