8344144: AES/CBC slow at big payloads

Reviewed-by: sviswanathan, abarashev, ascarpino
This commit is contained in:
Volodymyr Paprotski 2024-11-21 19:17:57 +00:00 committed by Anthony Scarpino
parent 93d4ad4dd4
commit d6b40d3033
2 changed files with 51 additions and 5 deletions

View File

@ -59,10 +59,15 @@ class CipherBlockChaining extends FeedbackCipher {
// variables for save/restore calls
private byte[] rSave = null;
// chunkSize is a multiple of block size and used to divide up
// input data to trigger the intrinsic.
private final int chunkSize;
CipherBlockChaining(SymmetricCipher embeddedCipher) {
super(embeddedCipher);
k = new byte[blockSize];
r = new byte[blockSize];
chunkSize = blockSize * 6400;
}
/**
@ -148,8 +153,18 @@ class CipherBlockChaining extends FeedbackCipher {
ArrayUtil.blockSizeCheck(plainLen, blockSize);
ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
return implEncrypt(plain, plainOffset, plainLen,
cipher, cipherOffset);
int processed = 0;
for (; plainLen > chunkSize; cipherOffset += chunkSize,
plainOffset += chunkSize, plainLen -= chunkSize) {
processed +=
implEncrypt(plain, plainOffset, chunkSize, cipher, cipherOffset);
}
// note: above loop always leaves some data to process (more than zero,
// less than or equal to chunkSize) so this last call can be
// unconditional
processed +=
implEncrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
return processed;
}
@IntrinsicCandidate
@ -199,7 +214,18 @@ class CipherBlockChaining extends FeedbackCipher {
ArrayUtil.blockSizeCheck(cipherLen, blockSize);
ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen);
ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen);
return implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
int processed = 0;
for (; cipherLen > chunkSize; cipherOffset += chunkSize,
plainOffset += chunkSize, cipherLen -= chunkSize) {
processed +=
implDecrypt(cipher, cipherOffset, chunkSize, plain, plainOffset);
}
// note: above loop always leaves some data to process (more than zero,
// less than or equal to chunkSize) so this last call can be
// unconditional
processed +=
implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
return processed;
}
@IntrinsicCandidate

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,9 @@ package org.openjdk.bench.javax.crypto.full;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.infra.Blackhole;
import java.security.GeneralSecurityException;
import org.openjdk.jmh.annotations.Fork;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@ -36,9 +39,10 @@ import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
@Fork(jvmArgsAppend = {"-Xms20g", "-Xmx20g", "-XX:+UseZGC"})
public class AESBench extends CryptoBase {
public static final int SET_SIZE = 128;
public static final int SET_SIZE = 8;
@Param({"AES/ECB/NoPadding", "AES/ECB/PKCS5Padding", "AES/CBC/NoPadding", "AES/CBC/PKCS5Padding"})
private String algorithm;
@ -53,6 +57,7 @@ public class AESBench extends CryptoBase {
byte[][] encryptedData;
private Cipher encryptCipher;
private Cipher decryptCipher;
private byte[] outBuffer;
int index = 0;
@Setup
@ -66,6 +71,7 @@ public class AESBench extends CryptoBase {
decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters());
data = fillRandom(new byte[SET_SIZE][dataSize]);
encryptedData = fillEncrypted(data, encryptCipher);
outBuffer = new byte[dataSize + 128]; // extra space for tag, etc
}
@Benchmark
@ -75,6 +81,13 @@ public class AESBench extends CryptoBase {
return encryptCipher.doFinal(d);
}
@Benchmark
public void encrypt2(Blackhole bh) throws GeneralSecurityException {
byte[] d = data[index];
index = (index +1) % SET_SIZE;
bh.consume(encryptCipher.doFinal(d, 0, d.length, outBuffer));
}
@Benchmark
public byte[] decrypt() throws BadPaddingException, IllegalBlockSizeException {
byte[] e = encryptedData[index];
@ -82,4 +95,11 @@ public class AESBench extends CryptoBase {
return decryptCipher.doFinal(e);
}
@Benchmark
public void decrypt2(Blackhole bh) throws GeneralSecurityException {
byte[] e = encryptedData[index];
index = (index +1) % SET_SIZE;
bh.consume(decryptCipher.doFinal(e, 0, e.length, outBuffer));
}
}