RFR: 8298865: Excessive memory allocation in CipherOutputStream AEAD decryption

Daniel Jeliński djelinski at openjdk.org
Thu Dec 15 14:24:59 UTC 2022


This patch modifies `CipherOutputStream` to avoid pointless memory allocations when decrypting data using AEAD ciphers. This is related to #11597, which fixed a similar issue in `CipherInputStream`.

`Cipher.update` does not output any data when doing AEAD decryption; all data is buffered, and is later returned in one shot from `doFinal`. `Cipher.getOutputSize` returns the buffer size required by `doFinal`, which increases after every `update`, triggering new allocation in `ensureCapacity`.

This patch addresses the issue by calling the `update` overload that returns the output buffer until one of the update calls returns some data. When that happens, we know that the cipher does not buffer everything until `doFinal`, and revert to original behavior.

This PR adds a new benchmark for AES/GCM encryption and decryption using `CipherOutputStream`.

Benchmark results before:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   27949,624 ±  301,408  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40      20,730 ±    0,875  ops/s
AESGCMCipherOutputStream.encrypt       16384          128              thrpt   40  175358,641 ± 4235,808  ops/s
AESGCMCipherOutputStream.encrypt     1048576          128              thrpt   40    2588,111 ±   35,469  ops/s


after:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   69644,217 ± 1081,032  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40     949,667 ±    9,431  ops/s
AESGCMCipherOutputStream.encrypt       16384          128              thrpt   40  173144,038 ± 3279,149  ops/s
AESGCMCipherOutputStream.encrypt     1048576          128              thrpt   40    2514,840 ±   87,935  ops/s

-------------

Commit messages:
 - Reduce allocation
 - CipherOutputStream benchmark

Changes: https://git.openjdk.org/jdk/pull/11693/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11693&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8298865
  Stats: 154 lines in 2 files changed: 150 ins; 0 del; 4 mod
  Patch: https://git.openjdk.org/jdk/pull/11693.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/11693/head:pull/11693

PR: https://git.openjdk.org/jdk/pull/11693



More information about the security-dev mailing list