Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
experimental/quantum/Analysis/ReusedNonce.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea what this means.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advantage of inline expectations is that the results stay synchronized with the comments. In short, use

query: experimental/quantum/Analysis/ReusedNonce.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql

in the qlref, and add $ Alert to all the comments that start with // BAD:.

Original file line number Diff line number Diff line change
@@ -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();
}
}
}