Skip to content

Commit ddeb42c

Browse files
committed
Crypto: Adding false positive to BadMacUse.java, we have no way to avoid this FP currently but should note it exists in the test case.
1 parent c50175b commit ddeb42c

File tree

2 files changed

+84
-16
lines changed

2 files changed

+84
-16
lines changed
Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,36 @@
11
#select
2-
| BadMacUse.java:60:42:60:50 | plaintext | BadMacUse.java:54:28:54:53 | doFinal(...) : byte[] | BadMacUse.java:60:42:60:50 | plaintext | MAC order potentially wrong: observed a potential decrypt operation output to MAC implying the MAC is on plaintext, and not a cipher. |
2+
| BadMacUse.java:56:42:56:50 | plaintext | BadMacUse.java:50:28:50:53 | doFinal(...) : byte[] | BadMacUse.java:56:42:56:50 | plaintext | MAC order potentially wrong: observed a potential decrypt operation output to MAC implying the MAC is on plaintext, and not a cipher. |
3+
| BadMacUse.java:124:42:124:51 | ciphertext | BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | BadMacUse.java:124:42:124:51 | ciphertext | MAC order potentially wrong: observed a potential decrypt operation output to MAC implying the MAC is on plaintext, and not a cipher. |
34
edges
4-
| BadMacUse.java:30:29:30:53 | doFinal(...) : byte[] | BadMacUse.java:35:42:35:51 | ciphertext | provenance | |
5-
| BadMacUse.java:54:28:54:53 | doFinal(...) : byte[] | BadMacUse.java:60:42:60:50 | plaintext | provenance | |
5+
| BadMacUse.java:27:29:27:53 | doFinal(...) : byte[] | BadMacUse.java:32:42:32:51 | ciphertext | provenance | |
6+
| BadMacUse.java:50:28:50:53 | doFinal(...) : byte[] | BadMacUse.java:56:42:56:50 | plaintext | provenance | |
7+
| BadMacUse.java:84:83:84:91 | iv : byte[] | BadMacUse.java:90:63:90:64 | iv : byte[] | provenance | |
8+
| BadMacUse.java:90:43:90:65 | new IvParameterSpec(...) : IvParameterSpec | BadMacUse.java:91:42:91:56 | ivParameterSpec | provenance | Sink:MaD:1 |
9+
| BadMacUse.java:90:63:90:64 | iv : byte[] | BadMacUse.java:90:43:90:65 | new IvParameterSpec(...) : IvParameterSpec | provenance | Config |
10+
| BadMacUse.java:90:63:90:64 | iv : byte[] | BadMacUse.java:90:43:90:65 | new IvParameterSpec(...) : IvParameterSpec | provenance | MaD:2 |
11+
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | BadMacUse.java:118:29:118:106 | cipherOperationWrapper(...) : byte[] | provenance | |
12+
| BadMacUse.java:117:38:117:39 | iv : byte[] | BadMacUse.java:118:83:118:84 | iv : byte[] | provenance | |
13+
| BadMacUse.java:118:29:118:106 | cipherOperationWrapper(...) : byte[] | BadMacUse.java:124:42:124:51 | ciphertext | provenance | |
14+
| BadMacUse.java:118:83:118:84 | iv : byte[] | BadMacUse.java:84:83:84:91 | iv : byte[] | provenance | |
15+
models
16+
| 1 | Sink: javax.crypto; Cipher; true; init; (int,Key,AlgorithmParameterSpec); ; Argument[2]; encryption-iv; manual |
17+
| 2 | Summary: javax.crypto.spec; IvParameterSpec; true; IvParameterSpec; ; ; Argument[0]; Argument[this]; taint; manual |
618
nodes
7-
| BadMacUse.java:30:29:30:53 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
8-
| BadMacUse.java:35:42:35:51 | ciphertext | semmle.label | ciphertext |
9-
| BadMacUse.java:54:28:54:53 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
10-
| BadMacUse.java:60:42:60:50 | plaintext | semmle.label | plaintext |
19+
| BadMacUse.java:27:29:27:53 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
20+
| BadMacUse.java:32:42:32:51 | ciphertext | semmle.label | ciphertext |
21+
| BadMacUse.java:50:28:50:53 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
22+
| BadMacUse.java:56:42:56:50 | plaintext | semmle.label | plaintext |
23+
| BadMacUse.java:84:83:84:91 | iv : byte[] | semmle.label | iv : byte[] |
24+
| BadMacUse.java:90:43:90:65 | new IvParameterSpec(...) : IvParameterSpec | semmle.label | new IvParameterSpec(...) : IvParameterSpec |
25+
| BadMacUse.java:90:63:90:64 | iv : byte[] | semmle.label | iv : byte[] |
26+
| BadMacUse.java:91:42:91:56 | ivParameterSpec | semmle.label | ivParameterSpec |
27+
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
28+
| BadMacUse.java:117:38:117:39 | iv : byte[] | semmle.label | iv : byte[] |
29+
| BadMacUse.java:118:29:118:106 | cipherOperationWrapper(...) : byte[] | semmle.label | cipherOperationWrapper(...) : byte[] |
30+
| BadMacUse.java:118:83:118:84 | iv : byte[] | semmle.label | iv : byte[] |
31+
| BadMacUse.java:124:42:124:51 | ciphertext | semmle.label | ciphertext |
1132
subpaths
1233
testFailures
13-
| BadMacUse.java:67:118:67:128 | // $Source | Missing result: Source |
34+
| BadMacUse.java:63:118:63:128 | // $Source | Missing result: Source |
35+
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | Unexpected result: Source |
36+
| BadMacUse.java:124:42:124:51 | ciphertext | Unexpected result: Alert |

java/ql/test/experimental/query-tests/quantum/examples/BadMacUse/BadMacUse.java

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1+
12
import java.security.*;
23
import java.util.Arrays;
3-
import java.util.Base64;
44
import javax.crypto.Cipher;
5-
import javax.crypto.KeyGenerator;
65
import javax.crypto.Mac;
76
import javax.crypto.SecretKey;
8-
import javax.crypto.SecretKeyFactory;
9-
import javax.crypto.spec.PBEKeySpec;
7+
import javax.crypto.spec.IvParameterSpec;
108
import javax.crypto.spec.SecretKeySpec;
119

12-
1310
class BadMacUse {
1411

1512
private byte[] generateSalt(int length) {
1613
byte[] salt = new byte[length];
1714
new SecureRandom().nextBytes(salt);
1815
return salt;
1916
}
20-
17+
2118
public void CipherThenMac(byte[] encryptionKeyBytes, byte[] macKeyBytes) throws Exception {
2219
// Create keys directly from provided byte arrays
2320
SecretKey encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
@@ -40,7 +37,6 @@ public void CipherThenMac(byte[] encryptionKeyBytes, byte[] macKeyBytes) throws
4037
System.arraycopy(computedMac, 0, output, ciphertext.length, computedMac.length);
4138
}
4239

43-
4440
public void BadDecryptThenMacOnPlaintextVerify(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] input) throws Exception {
4541
// Split input into ciphertext and MAC
4642
int macLength = 32; // HMAC-SHA256 output length
@@ -84,4 +80,53 @@ public void BadMacOnPlaintext(byte[] encryptionKeyBytes, byte[] macKeyBytes, byt
8480
System.arraycopy(ciphertext, 0, output, 0, ciphertext.length);
8581
System.arraycopy(computedMac, 0, output, ciphertext.length, computedMac.length);
8682
}
87-
}
83+
84+
public byte[] cipherOperationWrapper(byte[] bytes, byte[] encryptionKeyBytes, byte[] iv, int mode)
85+
throws Exception {
86+
87+
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
88+
SecretKeySpec secretKeySpec = new SecretKeySpec(encryptionKeyBytes, "AES");
89+
90+
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
91+
cipher.init(mode, secretKeySpec, ivParameterSpec);
92+
return cipher.doFinal(bytes);
93+
}
94+
95+
/**
96+
* A use of the cipher operation wrapper for decryption to throw off the
97+
* analysis
98+
*/
99+
public byte[] decryptUsingWrapper(byte[] ciphertext, byte[] encryptionKeyBytes, byte[] iv) throws Exception {
100+
return cipherOperationWrapper(ciphertext, encryptionKeyBytes, iv, Cipher.DECRYPT_MODE);
101+
}
102+
103+
/**
104+
* A use of the cipher operation wrapper for encryption to throw off the
105+
* analysis
106+
*/
107+
public byte[] encryptUsingWrapper(byte[] plaintext, byte[] encryptionKeyBytes, byte[] iv) throws Exception {
108+
return cipherOperationWrapper(plaintext, encryptionKeyBytes, iv, Cipher.ENCRYPT_MODE);
109+
}
110+
111+
/**
112+
* Encrypt then mac using the wrapper function
113+
*/
114+
public byte[] falsePositiveDecryptToMac(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] plaintext) throws Exception {
115+
// Encrypt the plaintext
116+
byte[] iv = new byte[16];
117+
new SecureRandom().nextBytes(iv);
118+
byte[] ciphertext = cipherOperationWrapper(plaintext, encryptionKeyBytes, iv, Cipher.ENCRYPT_MODE);
119+
120+
// Compute HMAC over the ciphertext using the MAC key
121+
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
122+
Mac mac = Mac.getInstance("HmacSHA256");
123+
mac.init(macKey);
124+
byte[] computedMac = mac.doFinal(ciphertext); // False Positive
125+
126+
// Concatenate ciphertext and MAC
127+
byte[] output = new byte[ciphertext.length + computedMac.length];
128+
System.arraycopy(ciphertext, 0, output, 0, ciphertext.length);
129+
System.arraycopy(computedMac, 0, output, ciphertext.length, computedMac.length);
130+
return output;
131+
}
132+
}

0 commit comments

Comments
 (0)