Crypto: Adding tests for insecure iv or nonce. Updating generic literal sources to include array literals.

This commit is contained in:
REDMOND\brodes
2025-10-08 12:47:58 -04:00
parent bd34b6ce02
commit 83ff70bcd8
5 changed files with 241 additions and 5 deletions

View File

@@ -0,0 +1,7 @@
| InsecureIVorNonceSource.java:20:51:20:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:14:21:14:81 | Constant | Constant |
| InsecureIVorNonceSource.java:49:51:49:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:42:21:42:21 | Constant | Constant |
| InsecureIVorNonceSource.java:65:51:65:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:57:13:57:62 | Constant | Constant |
| InsecureIVorNonceSource.java:65:51:65:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:58:13:58:63 | Constant | Constant |
| InsecureIVorNonceSource.java:81:51:81:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:73:13:73:73 | Constant | Constant |
| InsecureIVorNonceSource.java:81:51:81:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:74:13:74:74 | Constant | Constant |
| InsecureIVorNonceSource.java:206:51:206:56 | Nonce | Nonce or IV uses insecure or constant source $@ | InsecureIVorNonceSource.java:194:26:194:30 | RandomNumberGeneration | RandomNumberGeneration |

View File

@@ -0,0 +1,210 @@
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Random;
import java.security.SecureRandom;
import java.util.Arrays;
public class InsecureIVorNonceSource {
// BAD: AES-GCM with static IV from a byte array
public byte[] encryptWithStaticIvByteArrayWithInitializer(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; // $Source
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/insecure-iv-or-nonce]
cipher.update(plaintext);
return cipher.doFinal();
}
// BAD: AES-GCM with static IV from zero-initialized byte array
public byte[] encryptWithZeroStaticIvByteArray(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = new byte[16]; // $Source
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/unknown-iv-or-nonce-initialization]
cipher.update(plaintext);
return cipher.doFinal();
}
// BAD: AES-CBC with static IV from 1-initialized byte array
public byte[] encryptWithStaticIvByteArray(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = new byte[16]; // $Source
for (byte i = 0; i < iv.length; i++) {
iv[i] = 1;
}
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/insecure-iv-or-nonce]
cipher.update(plaintext);
return cipher.doFinal();
}
// BAD: AES-GCM with static IV from a multidimensional byte array
public byte[] encryptWithOneOfStaticIvs01(byte[] key, byte[] plaintext) throws Exception {
byte[][] staticIvs = new byte[][] {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 42 }
}; // $Source
GCMParameterSpec ivSpec = new GCMParameterSpec(128, staticIvs[1]);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/insecure-iv-or-nonce]
cipher.update(plaintext);
return cipher.doFinal();
}
// BAD: AES-GCM with static IV from a multidimensional byte array
public byte[] encryptWithOneOfStaticIvs02(byte[] key, byte[] plaintext) throws Exception {
byte[][] staticIvs = new byte[][] {
new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 },
new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 42 }
}; // $Source
GCMParameterSpec ivSpec = new GCMParameterSpec(128, staticIvs[1]);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/insecure-iv-or-nonce]
cipher.update(plaintext);
return cipher.doFinal();
}
// BAD: AES-GCM with static IV from a zero-initialized multidimensional byte array
public byte[] encryptWithOneOfStaticZeroIvs(byte[] key, byte[] plaintext) throws Exception {
byte[][] ivs = new byte[][] {
new byte[8], // $Source
new byte[16] // $Source
};
GCMParameterSpec ivSpec = new GCMParameterSpec(128, ivs[1]);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/unknown-iv-or-nonce-initialization]
cipher.update(plaintext);
return cipher.doFinal();
}
// GOOD: AES-GCM with a random IV
public byte[] encryptWithRandomIv(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = new byte[16];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(iv);
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
cipher.update(plaintext);
return cipher.doFinal();
}
// GOOD: AES-GCM with a random IV
public byte[] encryptWithRandomIvByteByByte(byte[] key, byte[] plaintext) throws Exception {
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] iv = new byte[16];
for (int i = 0; i < iv.length; i++) {
iv[i] = (byte) random.nextInt();
}
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
cipher.update(plaintext);
return cipher.doFinal();
}
// GOOD: AES-GCM with a random IV
public byte[] encryptWithRandomIvWithSystemArrayCopy(byte[] key, byte[] plaintext) throws Exception {
byte[] randomBytes = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
byte[] iv = new byte[16];
System.arraycopy(randomBytes, 0, iv, 0, 16);
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
cipher.update(plaintext);
return cipher.doFinal();
}
// GOOD: AES-GCM with a random IV
public byte[] encryptWithRandomIvWithArraysCopy(byte[] key, byte[] plaintext) throws Exception {
byte[] randomBytes = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
byte[] iv = new byte[16];
iv = Arrays.copyOf(randomBytes, 16);
GCMParameterSpec ivSpec = new GCMParameterSpec(128, iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
cipher.update(plaintext);
return cipher.doFinal();
}
public byte[] generate(int size) throws Exception {
if (size == 0) {
return new byte[0];
}
byte[] randomBytes = new byte[size];
SecureRandom.getInstanceStrong().nextBytes(randomBytes);
return randomBytes;
}
// GOOD: AES-CBC with a random IV
public byte[] encryptWithGeneratedIvByteArray(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = generate(16);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
cipher.update(plaintext);
return cipher.doFinal();
}
public byte[] generateInsecureRandomBytes(int numBytes) {
Random random = new Random();
byte[] bytes = new byte[numBytes];
random.nextBytes(bytes); // $Source
return bytes;
}
// BAD: AES-CBC with an insecure random IV
public byte[] encryptWithGeneratedIvByteArrayInsecure(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = generateInsecureRandomBytes(16);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // $Alert[java/quantum/insecure-iv-or-nonce]]
cipher.update(plaintext);
return cipher.doFinal();
}
}

View File

@@ -0,0 +1,4 @@
query: experimental/quantum/Analysis/InsecureIVorNonceSource.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql