Skip to content

Commit f480d90

Browse files
committed
Crypto: Add missing block mode JCA Models, add block mode unit tests
1 parent e127341 commit f480d90

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed

java/ql/lib/experimental/quantum/JCA.qll

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ module JCAModel {
3030
].toUpperCase())
3131
}
3232

33-
// TODO: Verify that the CFB% case works correctly
34-
bindingset[mode]
35-
predicate cipher_modes(string mode) {
36-
mode.toUpperCase()
37-
.matches([
38-
"NONE", "CBC", "CCM", "CFB", "CFB%", "CTR", "CTS", "ECB", "GCM", "KW", "KWP", "OFB",
39-
"OFB%", "PCBC"
40-
].toUpperCase())
41-
}
42-
4333
// TODO: Verify that the OAEPWith% case works correctly
4434
bindingset[padding]
4535
predicate cipher_padding(string padding) {
@@ -184,6 +174,14 @@ module JCAModel {
184174
type = KeyOpAlg::SIV() and name = "SIV"
185175
or
186176
type = KeyOpAlg::OCB() and name = "OCB"
177+
or
178+
type = KeyOpAlg::CFB() and name = "CFB"
179+
or
180+
type = KeyOpAlg::OFB() and name = "OFB"
181+
or
182+
type = KeyOpAlg::PCBC() and name = "PCBC"
183+
or
184+
type = KeyOpAlg::KWP() and name = "KWP"
187185
}
188186

189187
bindingset[name]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import javax.crypto.Cipher;
2+
import javax.crypto.KeyGenerator;
3+
import javax.crypto.SecretKey;
4+
import javax.crypto.spec.IvParameterSpec;
5+
6+
public class Test {
7+
public static void main(String[] args) throws Exception {
8+
SecretKey key = KeyGenerator.getInstance("AES").generateKey();
9+
IvParameterSpec iv = new IvParameterSpec(new byte[16]);
10+
byte[] data = "SensitiveData".getBytes();
11+
12+
// Insecure block mode: ECB
13+
Cipher cipherECB = Cipher.getInstance("AES/ECB/PKCS5Padding"); // $Alert
14+
cipherECB.init(Cipher.ENCRYPT_MODE, key);
15+
byte[] ecbEncrypted = cipherECB.doFinal(data);
16+
System.out.println("ECB encrypted: " + bytesToHex(ecbEncrypted));
17+
18+
// Insecure block mode: CFB
19+
Cipher cipherCFB = Cipher.getInstance("AES/CFB/PKCS5Padding"); // $Alert
20+
cipherCFB.init(Cipher.ENCRYPT_MODE, key, iv);
21+
byte[] cfbEncrypted = cipherCFB.doFinal(data);
22+
System.out.println("CFB encrypted: " + bytesToHex(cfbEncrypted));
23+
24+
// Insecure block mode: OFB
25+
Cipher cipherOFB = Cipher.getInstance("AES/OFB/PKCS5Padding"); // $Alert
26+
cipherOFB.init(Cipher.ENCRYPT_MODE, key, iv);
27+
byte[] ofbEncrypted = cipherOFB.doFinal(data);
28+
System.out.println("OFB encrypted: " + bytesToHex(ofbEncrypted));
29+
30+
// Insecure block mode: CTR
31+
Cipher cipherCTR = Cipher.getInstance("AES/CTR/NoPadding"); // $Alert
32+
cipherCTR.init(Cipher.ENCRYPT_MODE, key, iv);
33+
byte[] ctrEncrypted = cipherCTR.doFinal(data);
34+
System.out.println("CTR encrypted: " + bytesToHex(ctrEncrypted));
35+
36+
// Secure block mode: CBC with random IV
37+
IvParameterSpec randomIv = new IvParameterSpec(KeyGenerator.getInstance("AES").generateKey().getEncoded());
38+
Cipher cipherCBCRandomIV = Cipher.getInstance("AES/CBC/PKCS5Padding");
39+
cipherCBCRandomIV.init(Cipher.ENCRYPT_MODE, key, randomIv);
40+
byte[] cbcRandomIVEncrypted = cipherCBCRandomIV.doFinal(data);
41+
System.out.println("CBC (random IV) encrypted: " + bytesToHex(cbcRandomIVEncrypted));
42+
43+
// Secure block mode: GCM (authenticated encryption)
44+
IvParameterSpec gcmIv = new IvParameterSpec(new byte[12]);
45+
Cipher cipherGCM = Cipher.getInstance("AES/GCM/NoPadding");
46+
cipherGCM.init(Cipher.ENCRYPT_MODE, key, gcmIv);
47+
byte[] gcmEncrypted = cipherGCM.doFinal(data);
48+
System.out.println("GCM encrypted: " + bytesToHex(gcmEncrypted));
49+
}
50+
51+
private static String bytesToHex(byte[] bytes) {
52+
StringBuilder sb = new StringBuilder();
53+
for (byte b : bytes)
54+
sb.append(String.format("%02x", b));
55+
return sb.toString();
56+
}
57+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| Test.java:13:47:13:68 | KeyOperationAlgorithm | Weak AES block mode instance $@. | Test.java:13:47:13:68 | ModeOfOperation | ModeOfOperation |
2+
| Test.java:19:47:19:68 | KeyOperationAlgorithm | Weak AES block mode instance $@. | Test.java:19:47:19:68 | ModeOfOperation | ModeOfOperation |
3+
| Test.java:25:47:25:68 | KeyOperationAlgorithm | Weak AES block mode instance $@. | Test.java:25:47:25:68 | ModeOfOperation | ModeOfOperation |
4+
| Test.java:31:47:31:65 | KeyOperationAlgorithm | Weak AES block mode instance $@. | Test.java:31:47:31:65 | ModeOfOperation | ModeOfOperation |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
query: experimental/quantum/Examples/WeakBlockModes.ql
2+
postprocess:
3+
- utils/test/PrettyPrintModels.ql
4+
- utils/test/InlineExpectationsTestQuery.ql

shared/quantum/codeql/quantum/experimental/Standardization.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ module Types {
214214
CCM() or // Used in lightweight cryptography (IoT, WPA2)
215215
SIV() or // Misuse-resistant encryption, used in secure storage
216216
OCB() or // Efficient AEAD mode
217+
KWP() or
217218
OFB() or
219+
PCBC() or
218220
OtherMode()
219221

220222
class ModeOfOperationType extends TModeOfOperationType {

0 commit comments

Comments
 (0)