From e7e2dc05a24a018223b6daa1bb80a2a8ee1a8f41 Mon Sep 17 00:00:00 2001 From: Matthew Donovan Date: Wed, 10 Sep 2025 09:52:09 -0400 Subject: [PATCH] updated additional Cipher tests for MemorySegment-backed ByteBuffers --- .../provider/Cipher/AEAD/AEADBufferTest.java | 449 +++++++++++------- .../provider/Cipher/AEAD/GCMShortBuffer.java | 5 + .../provider/Cipher/AEAD/GCMShortInput.java | 4 + .../Cipher/AEAD/OverlapByteBuffer.java | 181 +++---- .../provider/Cipher/AEAD/SameBuffer.java | 31 +- .../provider/Cipher/AES/TestKATForGCM.java | 161 ++++--- .../provider/Cipher/ChaCha20/ChaCha20KAT.java | 104 ++-- .../provider/Cipher/PBE/PBMacBuffer.java | 31 +- 8 files changed, 587 insertions(+), 379 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java index a3b9064cb8a..23a420d26db 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java @@ -37,6 +37,7 @@ import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; @@ -48,7 +49,7 @@ import java.util.List; public class AEADBufferTest implements Cloneable { // Data type for the operation - enum dtype { BYTE, HEAP, DIRECT }; + enum dtype { BYTE, HEAP, DIRECT, MEMORY_SEGMENT }; // Data map static HashMap> datamap = new HashMap<>(); // List of enum values for order of operation @@ -60,6 +61,7 @@ public class AEADBufferTest implements Cloneable { static final int REMAINDER = -1; String algo; + Arena arena; boolean same = true; int[] sizes; boolean incremental = false; @@ -153,6 +155,14 @@ public class AEADBufferTest implements Cloneable { * specified, the last is a doFinal, the others are updates. */ AEADBufferTest(String algo, List ops) { + this(algo, ops, null); + } + + AEADBufferTest(String algo, List ops, Arena arena) { + if (arena == null && ops.contains(dtype.MEMORY_SEGMENT)) { + throw new RuntimeException("Arena must not be null if ops contains MEMORY_SEGMENT"); + } + this.arena = arena; this.algo = algo; this.ops = ops; theoreticalCheck = true; @@ -433,6 +443,21 @@ public class AEADBufferTest implements Cloneable { rlen = cipher.update(b, out); ba.write(out.array(), outOfs, rlen); } + case MEMORY_SEGMENT -> { + ByteBuffer b = arena.allocate(plen + outOfs).asByteBuffer(); + b.position(outOfs); + b.put(pt, dataoffset + inOfs, plen); + b.flip(); + b.position(outOfs); + ByteBuffer out = arena.allocate(olen).asByteBuffer(); + out.position(outOfs); + rlen = cipher.update(b, out); + byte[] o = new byte[rlen]; + out.flip(); + out.position(outOfs); + out.get(o, 0, rlen); + ba.write(o); + } case DIRECT -> { ByteBuffer b = ByteBuffer.allocateDirect(plen + outOfs); b.position(outOfs); @@ -488,6 +513,23 @@ public class AEADBufferTest implements Cloneable { rlen = cipher.doFinal(b, out); ba.write(out.array(), outOfs, rlen); } + case MEMORY_SEGMENT -> { + ByteBuffer b = arena.allocate(plen+inOfs).asByteBuffer(); + b.limit(b.capacity()); + b.position(inOfs); + b.put(pt, dataoffset + inOfs, plen); + b.flip(); + b.position(inOfs); + ByteBuffer out = arena.allocate(olen).asByteBuffer(); + out.limit(out.capacity()); + out.position(outOfs); + rlen = cipher.doFinal(b, out); + byte[] o = new byte[rlen]; + out.flip(); + out.position(outOfs); + out.get(o, 0, rlen); + ba.write(o); + } case DIRECT -> { ByteBuffer b = ByteBuffer.allocateDirect(plen + inOfs); b.limit(b.capacity()); @@ -577,6 +619,12 @@ public class AEADBufferTest implements Cloneable { bbin.put(data, 0, input.length + inOfs); bbin.flip(); } + case MEMORY_SEGMENT -> { + bbin = arena.allocate(data.length).asByteBuffer(); + bbout = bbin.duplicate(); + bbin.put(data, 0, input.length + inOfs); + bbin.flip(); + } } // Set data limits for bytebuffers @@ -594,7 +642,7 @@ public class AEADBufferTest implements Cloneable { rlen = cipher.update(data, dataoffset + inOfs, plen, data, len + outOfs); } - case HEAP, DIRECT -> { + case HEAP, DIRECT, MEMORY_SEGMENT -> { theorticallen = bbin.remaining() - (d.blockSize > 0 ? bbin.remaining() % d.blockSize : 0); rlen = cipher.update(bbin, bbout); @@ -623,7 +671,7 @@ public class AEADBufferTest implements Cloneable { plen, data, len + outOfs); out = Arrays.copyOfRange(data, 0,len + rlen + outOfs); } - case HEAP, DIRECT -> { + case HEAP, DIRECT, MEMORY_SEGMENT -> { rlen = cipher.doFinal(bbin, bbout); bbout.flip(); out = new byte[bbout.remaining()]; @@ -660,193 +708,252 @@ public class AEADBufferTest implements Cloneable { initTest(); - // **** GCM Tests + try(Arena arena = Arena.ofConfined()) { + // **** GCM Tests - // Test single byte array - new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE))); - // Test update-doFinal with byte arrays - new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE))); - // Test update-update-doFinal with byte arrays - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE))); + // Test single byte array + new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE))); + // Test update-doFinal with byte arrays + new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE))); + // Test update-update-doFinal with byte arrays + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE))); - // Test single heap bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP))); - // Test update-doFinal with heap bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.HEAP, dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP))); - // Test update-update-doFinal with heap bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP))); + // Test single heap bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP))); + // Test update-doFinal with heap bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.HEAP, dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP))); + // Test update-update-doFinal with heap bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP))); - // Test single direct bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT))); - // Test update-doFinal with direct bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT))); - // Test update-update-doFinal with direct bytebuffer - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT))); + // Test single direct bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT))); + // Test update-doFinal with direct bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT))); + // Test update-update-doFinal with direct bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT))); - // Test update-update-doFinal with byte arrays and preset data sizes - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments( - new int[] { 1, 1, AEADBufferTest.REMAINDER}); - t.clone().test(); - offsetTests(t.clone()); + // Test single memory segment bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.MEMORY_SEGMENT), arena)); + // Test update-doFinal with direct bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena)); + // Test update-update-doFinal with direct bytebuffer + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena)); - // Test update-doFinal with a byte array and a direct bytebuffer - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); - // Test update-doFinal with a byte array and heap and direct bytebuffer - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); + // Test update-update-doFinal with byte arrays and preset data sizes + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments( + new int[]{1, 1, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); - // Test update-doFinal with a direct bytebuffer and a byte array. - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); + // Test update-doFinal with a byte array and a direct bytebuffer + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); + // Test update-doFinal with a byte array and heap and direct bytebuffer + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); + // Test update-doFinal with a byte array and heap and direct and memory segment bytebuffer + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT, dtype.MEMORY_SEGMENT), arena).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); - // Test update-doFinal with a direct bytebuffer and a byte array with - // preset data sizes. - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(). - dataSegments(new int[] { 20, AEADBufferTest.REMAINDER }); - t.clone().test(); - offsetTests(t.clone()); - // Test update-update-doFinal with a direct and heap bytebuffer and a - // byte array with preset data sizes. - t = new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)). - differentBufferOnly().dataSet(5). - dataSegments(new int[] { 5000, 1000, AEADBufferTest.REMAINDER }); - t.clone().test(); - offsetTests(t.clone()); + // Test update-doFinal with a direct bytebuffer and a byte array. + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); - // Test update-update-doFinal with byte arrays, incrementing through - // every data size combination for the Data set 0 - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments(). - dataSet(0).test(); - // Test update-update-doFinal with direct bytebuffers, incrementing through - // every data size combination for the Data set 0 - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). - incrementalSegments().dataSet(0).test(); + // Test update-doFinal with a direct bytebuffer and a byte array with + // preset data sizes. + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(). + dataSegments(new int[]{20, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); + // Test update-update-doFinal with a direct and heap bytebuffer and a + // byte array with preset data sizes. + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)). + differentBufferOnly().dataSet(5). + dataSegments(new int[]{5000, 1000, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); + // Test update-update-doFinal with a direct and heap and memory segment + // bytebuffer and a byte array with preset data sizes. + t = new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP, dtype.MEMORY_SEGMENT), arena). + differentBufferOnly().dataSet(5). + dataSegments(new int[]{5000, 1000, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); - new AEADBufferTest("AES/GCM/NoPadding", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). - dataSegments(new int[] { 49, 0, 2 }).dataSet(0).test(); + // Test update-update-doFinal with byte arrays, incrementing through + // every data size combination for the Data set 0 + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments(). + dataSet(0).test(); + // Test update-update-doFinal with direct bytebuffers, incrementing through + // every data size combination for the Data set 0 + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). + incrementalSegments().dataSet(0).test(); - // **** CC20P1305 Tests + new AEADBufferTest("AES/GCM/NoPadding", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). + dataSegments(new int[]{49, 0, 2}).dataSet(0).test(); - // Test single byte array - new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE))); - // Test update-doFinal with byte arrays - new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE))); - // Test update-update-doFinal with byte arrays - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE))); + // **** CC20P1305 Tests - // Test single heap bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP))); - // Test update-doFinal with heap bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.HEAP, dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP))); - // Test update-update-doFinal with heap bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP))); + // Test single byte array + new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE))); + // Test update-doFinal with byte arrays + new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE))); + // Test update-update-doFinal with byte arrays + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE))); - // Test single direct bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT))); - // Test update-doFinal with direct bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT))); - // Test update-update-doFinal with direct bytebuffer - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test(); - offsetTests(new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT))); + // Test single heap bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP))); + // Test update-doFinal with heap bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.HEAP, dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP))); + // Test update-update-doFinal with heap bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP))); - // Test update-update-doFinal with byte arrays and preset data sizes - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments( - new int[] { 1, 1, AEADBufferTest.REMAINDER}); - t.clone().test(); - offsetTests(t.clone()); + // Test single direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT))); + // Test update-doFinal with direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT))); + // Test update-update-doFinal with direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT))); - // Test update-doFinal with a byte array and a direct bytebuffer - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); - // Test update-doFinal with a byte array and heap and direct bytebuffer - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); + // Test single direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.MEMORY_SEGMENT), arena)); + // Test update-doFinal with direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena)); + // Test update-update-doFinal with direct bytebuffer + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena).test(); + offsetTests(new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT, dtype.MEMORY_SEGMENT), arena)); - // Test update-doFinal with a direct bytebuffer and a byte array. - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(); - t.clone().test(); - offsetTests(t.clone()); + // Test update-update-doFinal with byte arrays and preset data sizes + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments( + new int[]{1, 1, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); - // Test update-doFinal with a direct bytebuffer and a byte array with - // preset data sizes. - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(). - dataSegments(new int[] { 20, AEADBufferTest.REMAINDER }); - t.clone().test(); - offsetTests(t.clone()); - // Test update-update-doFinal with a direct and heap bytebuffer and a - // byte array with preset data sizes. - t = new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)). - differentBufferOnly().dataSet(1). - dataSegments(new int[] { 5000, 1000, AEADBufferTest.REMAINDER }); - t.clone().test(); - offsetTests(t.clone()); + // Test update-doFinal with a byte array and a direct bytebuffer + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); + // Test update-doFinal with a byte array and heap and direct bytebuffer + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); - // Test update-update-doFinal with byte arrays, incrementing through - // every data size combination for the Data set 0 - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments(). - dataSet(0).test(); - // Test update-update-doFinal with direct bytebuffers, incrementing through - // every data size combination for the Data set 0 - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). - incrementalSegments().dataSet(0).test(); + // Test update-doFinal with a byte array and heap and direct and memory segment bytebuffer + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT, dtype.MEMORY_SEGMENT), arena). + differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); - new AEADBufferTest("ChaCha20-Poly1305", - List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). - dataSegments(new int[] { 49, 0, 2 }).dataSet(0).test(); + // Test update-doFinal with a direct bytebuffer and a byte array. + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(); + t.clone().test(); + offsetTests(t.clone()); + + // Test update-doFinal with a direct bytebuffer and a byte array with + // preset data sizes. + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly(). + dataSegments(new int[]{20, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); + // Test update-update-doFinal with a direct and heap bytebuffer and a + // byte array with preset data sizes. + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)). + differentBufferOnly().dataSet(1). + dataSegments(new int[]{5000, 1000, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); + + // Test update-update-doFinal with a direct and heap and memory segment + // bytebuffer and a byte array with preset data sizes. + t = new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP, dtype.MEMORY_SEGMENT), arena). + differentBufferOnly().dataSet(1). + dataSegments(new int[]{5000, 1000, AEADBufferTest.REMAINDER}); + t.clone().test(); + offsetTests(t.clone()); + + // Test update-update-doFinal with byte arrays, incrementing through + // every data size combination for the Data set 0 + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments(). + dataSet(0).test(); + // Test update-update-doFinal with direct bytebuffers, incrementing through + // every data size combination for the Data set 0 + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). + incrementalSegments().dataSet(0).test(); + + new AEADBufferTest("ChaCha20-Poly1305", + List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)). + dataSegments(new int[]{49, 0, 2}).dataSet(0).test(); + } } // Test data diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java index 73140c5a668..a5269284054 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java @@ -25,6 +25,7 @@ import javax.crypto.Cipher; import javax.crypto.ShortBufferException; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.HexFormat; @@ -117,6 +118,10 @@ public class GCMShortBuffer { new GCMShortBuffer(new byte[50]); new GCMShortBuffer(ByteBuffer.allocate(13)); new GCMShortBuffer(ByteBuffer.allocate(50)); + try(Arena arena = Arena.ofConfined()) { + new GCMShortBuffer(arena.allocate(13).asByteBuffer()); + new GCMShortBuffer(arena.allocate(50).asByteBuffer()); + } } diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java index d01cbfb1e19..98e387780ee 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortInput.java @@ -27,6 +27,7 @@ * @summary ArithmeticException in GaloisCounterMode */ +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import javax.crypto.AEADBadTagException; @@ -50,6 +51,9 @@ public class GCMShortInput { cipher.init(Cipher.DECRYPT_MODE, keySpec, params); try { cipher.doFinal(ByteBuffer.allocate(0), ByteBuffer.allocate(0)); + try (Arena arena = Arena.ofConfined()) { + cipher.doFinal(arena.allocate(0).asByteBuffer(), arena.allocate(0).asByteBuffer()); + } throw new AssertionError("AEADBadTagException expected"); } catch (AEADBadTagException e) { // expected diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java index 9c62556d88b..c0e73c56d9b 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java @@ -25,6 +25,7 @@ import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.security.spec.AlgorithmParameterSpec; @@ -77,97 +78,115 @@ public class OverlapByteBuffer { void test() throws Exception { // Output offset from the baseBuf - for (int i = 0; i < 3; i++) { - for (outOfs = -1; outOfs <= 1; outOfs++) { + try(Arena arena = Arena.ofConfined()) { + for (int i = 0; i < 4; i++) { + for (outOfs = -1; outOfs <= 1; outOfs++) { - Cipher cipher = Cipher.getInstance(algorithm); - cipher.init(Cipher.ENCRYPT_MODE, key, params); + Cipher cipher = Cipher.getInstance(algorithm); + cipher.init(Cipher.ENCRYPT_MODE, key, params); - // Offset on the particular ByteBuffer (aka position()) - int inOfsInBuf = 1; - int outOfsInBuf = inOfsInBuf + outOfs; - int sliceLen = cipher.getOutputSize(baseBuf.length); - int bufferSize = sliceLen + Math.max(inOfsInBuf, outOfsInBuf); - byte[] buffer; - // Create overlapping input and output buffers - switch (i) { - case 0 -> { - buffer = new byte[bufferSize]; - output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen). - slice(); - input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen). - slice(); - System.out.println("Using array-backed ByteBuffer"); - in = input.duplicate(); + // Offset on the particular ByteBuffer (aka position()) + int inOfsInBuf = 1; + int outOfsInBuf = inOfsInBuf + outOfs; + int sliceLen = cipher.getOutputSize(baseBuf.length); + int bufferSize = sliceLen + Math.max(inOfsInBuf, outOfsInBuf); + byte[] buffer; + // Create overlapping input and output buffers + switch (i) { + case 0 -> { + buffer = new byte[bufferSize]; + output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen). + slice(); + input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen). + slice(); + System.out.println("Using array-backed ByteBuffer"); + in = input.duplicate(); + } + case 1 -> { + buffer = new byte[bufferSize]; + output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen). + slice(); + input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen). + slice(); + + System.out.println("Using read-only array-backed " + + "ByteBuffer"); + in = input.asReadOnlyBuffer(); + } + case 2 -> { + System.out.println("Using direct ByteBuffer"); + ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize); + output = buf.duplicate(); + output.position(outOfsInBuf); + output.limit(sliceLen + outOfsInBuf); + output = output.slice(); + + input = buf.duplicate(); + input.position(inOfsInBuf); + input.limit(sliceLen + inOfsInBuf); + input = input.slice(); + + in = input.duplicate(); + } + + case 3 -> { + System.out.println("Using memory-segment ByteBuffer"); + ByteBuffer buf = arena.allocate(bufferSize).asByteBuffer(); + output = buf.duplicate(); + output.position(outOfsInBuf); + output.limit(sliceLen + outOfsInBuf); + output = output.slice(); + + input = buf.duplicate(); + input.position(inOfsInBuf); + input.limit(sliceLen + inOfsInBuf); + input = input.slice(); + + in = input.duplicate(); + } + default -> throw new Exception("Unknown index " + i); } - case 1 -> { - buffer = new byte[bufferSize]; - output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen). - slice(); - input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen). - slice(); - System.out.println("Using read-only array-backed " + - "ByteBuffer"); - in = input.asReadOnlyBuffer(); - } - case 2 -> { - System.out.println("Using direct ByteBuffer"); - ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize); - output = buf.duplicate(); - output.position(outOfsInBuf); - output.limit(sliceLen + outOfsInBuf); - output = output.slice(); + System.out.println("inOfsInBuf = " + inOfsInBuf); + System.out.println("outOfsInBuf = " + outOfsInBuf); - input = buf.duplicate(); - input.position(inOfsInBuf); - input.limit(sliceLen + inOfsInBuf); - input = input.slice(); - - in = input.duplicate(); - } - default -> throw new Exception("Unknown index " + i); - } - - System.out.println("inOfsInBuf = " + inOfsInBuf); - System.out.println("outOfsInBuf = " + outOfsInBuf); - - // Copy data into shared buffer - input.put(baseBuf); - input.flip(); - in.limit(input.limit()); - - try { - int ctSize = cipher.doFinal(in, output); - - // Get ready to decrypt - byte[] tmp = new byte[ctSize]; - output.flip(); - output.get(tmp); - output.clear(); - - input.clear(); - input.put(tmp); + // Copy data into shared buffer + input.put(baseBuf); input.flip(); - - in.clear(); in.limit(input.limit()); - cipher.init(Cipher.DECRYPT_MODE, key, params); - cipher.doFinal(in, output); + try { + int ctSize = cipher.doFinal(in, output); - output.flip(); - ByteBuffer b = ByteBuffer.wrap(baseBuf); - if (b.compareTo(output) != 0) { - System.err.println( - "\nresult (" + output + "):\n" + - byteToHex(output) + - "\nexpected (" + b + "):\n" + - byteToHex(b)); - throw new Exception("Mismatch"); + // Get ready to decrypt + byte[] tmp = new byte[ctSize]; + output.flip(); + output.get(tmp); + output.clear(); + + input.clear(); + input.put(tmp); + input.flip(); + + in.clear(); + in.limit(input.limit()); + + cipher.init(Cipher.DECRYPT_MODE, key, params); + cipher.doFinal(in, output); + + output.flip(); + ByteBuffer b = ByteBuffer.wrap(baseBuf); + if (b.compareTo(output) != 0) { + System.err.println( + "\nresult (" + output + "):\n" + + byteToHex(output) + + "\nexpected (" + b + "):\n" + + byteToHex(b)); + throw new Exception("Mismatch"); + } + } catch (Exception e) { + throw new Exception("Error with base offset " + outOfs, e); } - } catch (Exception e) { - throw new Exception("Error with base offset " + outOfs, e); } } } diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java index 3e3fa3d77b1..ab4313196c9 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java @@ -21,6 +21,7 @@ * questions. */ +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.security.AlgorithmParameters; import java.security.Provider; @@ -217,17 +218,27 @@ public class SameBuffer { // prepare byte buffer contained AAD and plain text int bufSize = AADLength + offset + outputLength; byte[] AAD_and_Text = Helper.generateBytes(bufSize); - ByteBuffer AAD_and_Text_Buf = ByteBuffer.allocate(bufSize); - AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length); - // do test - runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset, - textLength, params); - int tagLength = c.getParameters() - .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; - AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength); - runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset, - textLength + tagLength, params); + try (Arena arena = Arena.ofConfined()) { + for (int i = 0; i < 2; ++i) { + ByteBuffer AAD_and_Text_Buf = switch (i) { + case 0 -> ByteBuffer.allocate(bufSize); + case 1 -> arena.allocate(bufSize).asByteBuffer(); + default -> throw new RuntimeException("Unknown test case"); + }; + + AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length); + + // do test + runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset, + textLength, params); + int tagLength = c.getParameters() + .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; + AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength); + runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset, + textLength + tagLength, params); + } + } } diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java index 70db7b166e8..c8b4e75b38d 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java @@ -33,6 +33,7 @@ */ +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.security.*; import javax.crypto.*; @@ -43,6 +44,8 @@ import java.util.*; public class TestKATForGCM { + enum BufferType { DIRECT, HEAP, MEMORY_SEGMENT }; + // Utility methods private static byte[] HexToBytes(String hexVal) { if (hexVal == null) return new byte[0]; @@ -320,7 +323,7 @@ public class TestKATForGCM { } } - void executeByteBuffer(TestVector tv, boolean direct, int offset) throws Exception { + void executeByteBuffer(TestVector tv, BufferType bufferType, int offset) throws Exception { Cipher c = Cipher.getInstance("AES/GCM/NoPadding", System.getProperty("test.provider.name", "SunJCE")); @@ -328,76 +331,92 @@ public class TestKATForGCM { ByteBuffer ctdst; ByteBuffer ptdst; - if (direct) { - System.out.print("Test #" + tv.id + ": ByteBuffer Direct."); - src = ByteBuffer.allocateDirect(tv.plainText.length + offset); - ctdst = ByteBuffer.allocateDirect(tv.cipherText.length + tv.tag.length + offset); - ptdst = ByteBuffer.allocateDirect(tv.plainText.length + offset); - } else { - System.out.print("Test #" + tv.id + ": ByteBuffer Heap."); - src = ByteBuffer.allocate(tv.plainText.length + offset); - ctdst = ByteBuffer.allocate(tv.cipherText.length + tv.tag.length + offset); - ptdst = ByteBuffer.allocate(tv.plainText.length + offset); - } - - byte[] plainText; - - if (offset > 0) { - System.out.println(" offset = " + offset); - plainText = new byte[tv.plainText.length + offset]; - System.arraycopy(tv.plainText, 0, plainText, offset, - tv.plainText.length); - } else { - System.out.println(); - plainText = tv.plainText; - } - - src.put(plainText); - src.position(offset); - ctdst.position(offset); - ctdst.mark(); - ptdst.position(offset); - ptdst.mark(); - - try { - c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec); - c.updateAAD(tv.aad); - c.doFinal(src, ctdst); - - ctdst.reset(); - ByteBuffer tag = ctdst.duplicate(); - tag.position(tag.limit() - tv.tag.length); - - c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec); - c.updateAAD(tv.aad); - c.doFinal(ctdst, ptdst); // should fail if tag mismatched - - ptdst.reset(); - // check encryption/decryption results just to be sure - if (ptdst.compareTo(ByteBuffer.wrap(tv.plainText)) != 0) { - System.out.println("\t PlainText diff failed for test# " + tv.id); - testFailed = true; + try (Arena arena = Arena.ofConfined()) { + switch (bufferType) { + case DIRECT: { + System.out.print("Test #" + tv.id + ": ByteBuffer Direct."); + src = ByteBuffer.allocateDirect(tv.plainText.length + offset); + ctdst = ByteBuffer.allocateDirect(tv.cipherText.length + tv.tag.length + offset); + ptdst = ByteBuffer.allocateDirect(tv.plainText.length + offset); + } + break; + case HEAP: { + System.out.print("Test #" + tv.id + ": ByteBuffer Heap."); + src = ByteBuffer.allocate(tv.plainText.length + offset); + ctdst = ByteBuffer.allocate(tv.cipherText.length + tv.tag.length + offset); + ptdst = ByteBuffer.allocate(tv.plainText.length + offset); + } + break; + case MEMORY_SEGMENT: { + System.out.print("Test #" + tv.id + ": ByteBuffer MemorySegment."); + src = arena.allocate(tv.plainText.length + offset).asByteBuffer(); + ctdst = arena.allocate(tv.cipherText.length + tv.tag.length + offset).asByteBuffer(); + ptdst = arena.allocate(tv.plainText.length + offset).asByteBuffer(); + } + break; + default: + throw new RuntimeException("Unsupported buffer type " + bufferType); } - ctdst.reset(); - ctdst.limit(ctdst.limit() - tv.tag.length); - if (ctdst.compareTo(ByteBuffer.wrap(tv.cipherText)) != 0) { - System.out.println("\t CipherText diff failed for test# " + tv.id); - testFailed = true; + byte[] plainText; + + if (offset > 0) { + System.out.println(" offset = " + offset); + plainText = new byte[tv.plainText.length + offset]; + System.arraycopy(tv.plainText, 0, plainText, offset, + tv.plainText.length); + } else { + System.out.println(); + plainText = tv.plainText; } - int mismatch = 0; - for (int i = 0; i < tv.tag.length; i++) { - mismatch |= tag.get() ^ tv.tag[i]; + src.put(plainText); + src.position(offset); + ctdst.position(offset); + ctdst.mark(); + ptdst.position(offset); + ptdst.mark(); + + try { + c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec); + c.updateAAD(tv.aad); + c.doFinal(src, ctdst); + + ctdst.reset(); + ByteBuffer tag = ctdst.duplicate(); + tag.position(tag.limit() - tv.tag.length); + + c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec); + c.updateAAD(tv.aad); + c.doFinal(ctdst, ptdst); // should fail if tag mismatched + + ptdst.reset(); + // check encryption/decryption results just to be sure + if (ptdst.compareTo(ByteBuffer.wrap(tv.plainText)) != 0) { + System.out.println("\t PlainText diff failed for test# " + tv.id); + testFailed = true; + } + + ctdst.reset(); + ctdst.limit(ctdst.limit() - tv.tag.length); + if (ctdst.compareTo(ByteBuffer.wrap(tv.cipherText)) != 0) { + System.out.println("\t CipherText diff failed for test# " + tv.id); + testFailed = true; + } + + int mismatch = 0; + for (int i = 0; i < tv.tag.length; i++) { + mismatch |= tag.get() ^ tv.tag[i]; + } + if (mismatch != 0) { + System.out.println("\t Tag diff failed for test# " + tv.id); + testFailed = true; + } + } catch (Exception ex) { + // continue testing other test vectors + System.out.println("\t Failed Test Vector ( #" + tv.id + ") : " + tv); + ex.printStackTrace(); } - if (mismatch != 0) { - System.out.println("\t Tag diff failed for test# " + tv.id); - testFailed = true; - } - } catch (Exception ex) { - // continue testing other test vectors - System.out.println("\t Failed Test Vector ( #" + tv.id + ") : " + tv); - ex.printStackTrace(); } } @@ -405,10 +424,12 @@ public class TestKATForGCM { TestKATForGCM test = new TestKATForGCM(); for (TestVector tv : testValues) { test.executeArray(tv); - test.executeByteBuffer(tv, false, 0); - test.executeByteBuffer(tv, true, 0); - test.executeByteBuffer(tv, false, 2); - test.executeByteBuffer(tv, true, 2); + test.executeByteBuffer(tv, BufferType.HEAP, 0); + test.executeByteBuffer(tv, BufferType.DIRECT, 0); + test.executeByteBuffer(tv, BufferType.MEMORY_SEGMENT, 0); + test.executeByteBuffer(tv, BufferType.HEAP, 2); + test.executeByteBuffer(tv, BufferType.DIRECT, 2); + test.executeByteBuffer(tv, BufferType.MEMORY_SEGMENT, 2); } if (!testFailed) { System.out.println("Tests passed"); diff --git a/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/ChaCha20KAT.java b/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/ChaCha20KAT.java index c54cf0c7097..b225fcc7946 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/ChaCha20KAT.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/ChaCha20KAT.java @@ -30,6 +30,7 @@ * @summary ChaCha20 Cipher Implementation (KAT) */ +import java.lang.foreign.Arena; import java.util.*; import java.security.GeneralSecurityException; import javax.crypto.Cipher; @@ -200,7 +201,13 @@ public class ChaCha20KAT { for (TestData test : testList) { System.out.println("*** Test " + ++testNumber + ": " + test.testName); - if (runByteBuffer(test)) { + if (runByteBuffer(test, true)) { + testsPassed++; + } + + System.out.println("*** Test " + ++testNumber + ": " + + test.testName); + if (runByteBuffer(test, false)) { testsPassed++; } } @@ -360,7 +367,7 @@ public class ChaCha20KAT { System.out.println(); } - private static boolean runByteBuffer(TestData testData) + private static boolean runByteBuffer(TestData testData, boolean heap) throws GeneralSecurityException { boolean encRes = false; boolean decRes = false; @@ -372,48 +379,63 @@ public class ChaCha20KAT { testData.nonce, testData.counter); mambo.init(Cipher.ENCRYPT_MODE, mamboKey, mamboSpec); - ByteBuffer bbIn = ByteBuffer.wrap(testData.input); - ByteBuffer bbEncOut = ByteBuffer.allocate( - mambo.getOutputSize(testData.input.length)); - ByteBuffer bbExpOut = ByteBuffer.wrap(testData.expOutput); + try (Arena arena = Arena.ofConfined()) { + ByteBuffer bbIn = ByteBuffer.wrap(testData.input); + ByteBuffer bbEncOut; + ByteBuffer bbExpOut = ByteBuffer.wrap(testData.expOutput); + if (heap) { + bbEncOut = ByteBuffer.allocate( + mambo.getOutputSize(testData.input.length)); + } else { + bbEncOut = arena.allocate( + mambo.getOutputSize(testData.input.length)) + .asByteBuffer(); + } - mambo.doFinal(bbIn, bbEncOut); - bbIn.rewind(); - bbEncOut.rewind(); + mambo.doFinal(bbIn, bbEncOut); + bbIn.rewind(); + bbEncOut.rewind(); - if (bbEncOut.compareTo(bbExpOut) != 0) { - System.out.println("ERROR - Output Mismatch!"); - System.out.println("Expected:\n" + - dumpHexBytes(bbExpOut, 16, "\n", " ")); - System.out.println("Actual:\n" + - dumpHexBytes(bbEncOut, 16, "\n", " ")); - System.out.println(); - } else { - encRes = true; + if (bbEncOut.compareTo(bbExpOut) != 0) { + System.out.println("ERROR - Output Mismatch!"); + System.out.println("Expected:\n" + + dumpHexBytes(bbExpOut, 16, "\n", " ")); + System.out.println("Actual:\n" + + dumpHexBytes(bbEncOut, 16, "\n", " ")); + System.out.println(); + } else { + encRes = true; + } + + // Decrypt the result of the encryption operation + mambo = Cipher.getInstance("ChaCha20"); + mambo.init(Cipher.DECRYPT_MODE, mamboKey, mamboSpec); + System.out.print("Decrypt - "); + ByteBuffer bbDecOut; + if (heap) { + bbDecOut = ByteBuffer.allocate( + mambo.getOutputSize(bbEncOut.remaining())); + } else { + bbDecOut = arena.allocate( + mambo.getOutputSize(bbEncOut.remaining())) + .asByteBuffer(); + } + + mambo.doFinal(bbEncOut, bbDecOut); + bbEncOut.rewind(); + bbDecOut.rewind(); + + if (bbDecOut.compareTo(bbIn) != 0) { + System.out.println("ERROR - Output Mismatch!"); + System.out.println("Expected:\n" + + dumpHexBytes(bbIn, 16, "\n", " ")); + System.out.println("Actual:\n" + + dumpHexBytes(bbDecOut, 16, "\n", " ")); + System.out.println(); + } else { + decRes = true; + } } - - // Decrypt the result of the encryption operation - mambo = Cipher.getInstance("ChaCha20"); - mambo.init(Cipher.DECRYPT_MODE, mamboKey, mamboSpec); - System.out.print("Decrypt - "); - ByteBuffer bbDecOut = ByteBuffer.allocate( - mambo.getOutputSize(bbEncOut.remaining())); - - mambo.doFinal(bbEncOut, bbDecOut); - bbEncOut.rewind(); - bbDecOut.rewind(); - - if (bbDecOut.compareTo(bbIn) != 0) { - System.out.println("ERROR - Output Mismatch!"); - System.out.println("Expected:\n" + - dumpHexBytes(bbIn, 16, "\n", " ")); - System.out.println("Actual:\n" + - dumpHexBytes(bbDecOut, 16, "\n", " ")); - System.out.println(); - } else { - decRes = true; - } - return (encRes && decRes); } diff --git a/test/jdk/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java index 5d4b102fb88..2f812c381ef 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java @@ -21,12 +21,14 @@ * questions. */ +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Random; +import java.util.function.Function; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; @@ -119,17 +121,33 @@ public class PBMacBuffer { theMac.init(key); // Do large ByteBuffer test case - if (!largeByteBufferTest(theMac)) { + if (!largeByteBufferTest(theMac, this::generateRandomByteBuffer)) { System.out.println("Large ByteBuffer test case failed."); return false; } // Do empty ByteBuffer test case - if (!emptyByteBufferTest(theMac)) { + if (!emptyByteBufferTest(theMac, this::generateRandomByteBuffer)) { System.out.println("Empty ByteBuffer test case failed."); return false; } + try(Arena arena = Arena.ofConfined()) { + // Do large ByteBuffer test case + if (!largeByteBufferTest(theMac, + (size) -> arena.allocate(size).asByteBuffer())) { + System.out.println("Large MemorySegment ByteBuffer test case failed."); + return false; + } + + // Do empty ByteBuffer test case + if (!emptyByteBufferTest(theMac, + (size) -> arena.allocate(size).asByteBuffer())) { + System.out.println("Empty MemorySegment ByteBuffer test case failed."); + return false; + } + } + // Do null ByteBuffer test case if (!nullByteBufferTest(theMac)) { System.out.println("NULL ByteBuffer test case failed."); @@ -148,8 +166,9 @@ public class PBMacBuffer { * @param theMac MAC object to test. * @return true - test case passed; false - otherwise; */ - protected boolean largeByteBufferTest(Mac theMac) { - ByteBuffer buf = generateRandomByteBuffer(LARGE_SIZE); + protected boolean largeByteBufferTest(Mac theMac, + Function createBuffer) { + ByteBuffer buf = createBuffer.apply(LARGE_SIZE); int limitBefore = buf.limit(); theMac.update(buf); @@ -179,8 +198,8 @@ public class PBMacBuffer { * @param theMac * @return true - test case pass; exception otherwise */ - protected boolean emptyByteBufferTest(Mac theMac) { - ByteBuffer buf = generateRandomByteBuffer(0); + protected boolean emptyByteBufferTest(Mac theMac, Function createBuffer) { + ByteBuffer buf = createBuffer.apply(0); theMac.update(buf); theMac.doFinal(); return true;