diff --git a/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.expected b/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.expected new file mode 100644 index 000000000000..38ba6187b595 --- /dev/null +++ b/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.expected @@ -0,0 +1,4 @@ +| Test.java:40:47:40:52 | Nonce | Reuse with nonce $@ | Test.java:49:47:49:52 | Nonce | Nonce | +| Test.java:49:47:49:52 | Nonce | Reuse with nonce $@ | Test.java:40:47:40:52 | Nonce | Nonce | +| Test.java:76:48:76:54 | Nonce | Reuse with nonce $@ | Test.java:82:49:82:55 | Nonce | Nonce | +| Test.java:82:49:82:55 | Nonce | Reuse with nonce $@ | Test.java:76:48:76:54 | Nonce | Nonce | diff --git a/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.qlref b/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.qlref new file mode 100644 index 000000000000..bfe67a6c2e8e --- /dev/null +++ b/java/ql/test/experimental/query-tests/quantum/NonceReuse/NonceReuse.qlref @@ -0,0 +1 @@ +experimental/quantum/Analysis/ReusedNonce.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/quantum/NonceReuse/Test.java b/java/ql/test/experimental/query-tests/quantum/NonceReuse/Test.java new file mode 100644 index 000000000000..1b65e324275b --- /dev/null +++ b/java/ql/test/experimental/query-tests/quantum/NonceReuse/Test.java @@ -0,0 +1,95 @@ +package com.example.crypto.artifacts; + +import java.security.*; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +public class Test { + + public static SecretKey generateAESKey() throws Exception { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + keyGen.init(256); + return keyGen.generateKey(); + } + + private static byte[] getRandomWrapper1() throws Exception { + byte[] val = new byte[16]; + new SecureRandom().nextBytes(val); + return val; + } + + private static byte[] getRandomWrapper2A() throws Exception { + byte[] val; + val = getRandomWrapper1(); + funcA1(val); + return val; + } + + private static byte[] getRandomWrapper2b() throws Exception { + byte[] val; + val = getRandomWrapper1(); + return val; + } + + private static void funcA1(byte[] iv) throws Exception { + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key = generateAESKey(); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // BAD: Reuse of `iv` in funcB1 + byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); + } + + private static void funcB1() throws Exception { + byte[] iv = getRandomWrapper2A(); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key = generateAESKey(); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // BAD: Reuse of `iv` in funcA1 + byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); + } + + private static void funcA2() throws Exception { + byte[] iv = getRandomWrapper2b(); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key = generateAESKey(); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // GOOD + byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); + } + + private static void funcB2() throws Exception { + byte[] iv = getRandomWrapper2b(); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key = generateAESKey(); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // GOOD + byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); + } + + private static void funcA3() throws Exception { + byte[] iv = getRandomWrapper2b(); + IvParameterSpec ivSpec1 = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key1 = generateAESKey(); + cipher.init(Cipher.ENCRYPT_MODE, key1, ivSpec1); // BAD: reuse of `iv` below + byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); + + IvParameterSpec ivSpec2 = new IvParameterSpec(iv); + Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey key2 = generateAESKey(); + cipher2.init(Cipher.ENCRYPT_MODE, key2, ivSpec2); // BAD: Reuse of `iv` above + byte[] ciphertext2 = cipher2.doFinal("Simple Test Data".getBytes()); + } + + public static void main(String[] args) { + try { + funcA2(); + funcB1(); + funcB2(); + } catch (Exception e) { + e.printStackTrace(); + } + } +}