mirror of
https://github.com/github/codeql.git
synced 2026-04-27 01:35:13 +02:00
Merge pull request #20696 from bdrodes/bad_mac_decrypt_then_mac
Crypto: Adding bad decrypt then mac order query.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#select
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:152:42:152:51 | ciphertext | Incorrect decryption and MAC order: Decryption of cipher text occurs before validation of MAC on cipher text. |
|
||||
edges
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] | BadMacUse.java:92:31:92:35 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:100:39:100:48 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:100:39:100:48 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:108:39:108:47 | plaintext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:108:39:108:47 | plaintext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:118:52:118:60 | plaintext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:118:52:118:60 | plaintext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:146:48:146:57 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:146:48:146:57 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:99:39:99:55 | ciphertext : byte[] | BadMacUse.java:100:39:100:48 | ciphertext : byte[] | provenance | |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:108:39:108:47 | plaintext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:118:52:118:60 | plaintext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | BadMacUse.java:99:39:99:55 | ciphertext : byte[] | provenance | |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | BadMacUse.java:152:42:152:51 | ciphertext | provenance | |
|
||||
nodes
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| BadMacUse.java:99:39:99:55 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
|
||||
| BadMacUse.java:108:39:108:47 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:118:52:118:60 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
|
||||
subpaths
|
||||
testFailures
|
||||
| BadMacUse.java:50:56:50:65 | // $Source | Missing result: Source |
|
||||
| BadMacUse.java:63:118:63:127 | // $Source | Missing result: Source |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:146:95:146:104 | // $Source | Missing result: Source |
|
||||
@@ -0,0 +1,4 @@
|
||||
query: experimental/quantum/Examples/BadMacOrderDecryptThenMac.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -34,3 +34,4 @@ testFailures
|
||||
| BadMacUse.java:63:118:63:127 | // $Source | Missing result: Source |
|
||||
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:124:42:124:51 | ciphertext | Unexpected result: Alert |
|
||||
| BadMacUse.java:146:95:146:104 | // $Source | Missing result: Source |
|
||||
|
||||
@@ -1,14 +1,51 @@
|
||||
#select
|
||||
| BadMacUse.java:76:44:76:52 | plaintext | BadMacUse.java:63:82:63:97 | plaintext : byte[] | BadMacUse.java:76:44:76:52 | plaintext | Incorrect MAC usage: Encryption plaintext also used for MAC. Flow shows plaintext to final use through intermediate mac or encryption operation here $@ | BadMacUse.java:71:42:71:50 | plaintext | plaintext |
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | BadMacUse.java:139:79:139:90 | input : byte[] | BadMacUse.java:152:42:152:51 | ciphertext | Incorrect MAC usage: Encryption plaintext also used for MAC. Flow shows plaintext to final use through intermediate mac or encryption operation here $@ | BadMacUse.java:92:31:92:35 | bytes | bytes |
|
||||
edges
|
||||
| BadMacUse.java:63:82:63:97 | plaintext : byte[] | BadMacUse.java:71:42:71:50 | plaintext : byte[] | provenance | |
|
||||
| BadMacUse.java:71:42:71:50 | plaintext : byte[] | BadMacUse.java:71:42:71:50 | plaintext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:71:42:71:50 | plaintext : byte[] | BadMacUse.java:76:44:76:52 | plaintext | provenance | |
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] | BadMacUse.java:92:31:92:35 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] [[]] : Object | BadMacUse.java:92:31:92:35 | bytes : byte[] [[]] : Object | provenance | |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | BadMacUse.java:146:48:146:57 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] [[]] : Object | BadMacUse.java:146:48:146:57 | ciphertext : byte[] | provenance | Config |
|
||||
| BadMacUse.java:99:39:99:55 | ciphertext : byte[] [[]] : Object | BadMacUse.java:100:39:100:48 | ciphertext : byte[] [[]] : Object | provenance | |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] [[]] : Object | BadMacUse.java:84:42:84:53 | bytes : byte[] [[]] : Object | provenance | |
|
||||
| BadMacUse.java:107:39:107:54 | plaintext : byte[] | BadMacUse.java:108:39:108:47 | plaintext : byte[] | provenance | |
|
||||
| BadMacUse.java:108:39:108:47 | plaintext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:114:92:114:107 | plaintext : byte[] | BadMacUse.java:118:52:118:60 | plaintext : byte[] | provenance | |
|
||||
| BadMacUse.java:118:52:118:60 | plaintext : byte[] | BadMacUse.java:84:42:84:53 | bytes : byte[] | provenance | |
|
||||
| BadMacUse.java:139:79:139:90 | input : byte[] | BadMacUse.java:142:48:142:52 | input : byte[] | provenance | |
|
||||
| BadMacUse.java:142:29:142:82 | copyOfRange(...) : byte[] [[]] : Object | BadMacUse.java:146:48:146:57 | ciphertext : byte[] [[]] : Object | provenance | |
|
||||
| BadMacUse.java:142:48:142:52 | input : byte[] | BadMacUse.java:142:29:142:82 | copyOfRange(...) : byte[] [[]] : Object | provenance | MaD:1 |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | BadMacUse.java:152:42:152:51 | ciphertext | provenance | |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] [[]] : Object | BadMacUse.java:99:39:99:55 | ciphertext : byte[] [[]] : Object | provenance | |
|
||||
models
|
||||
| 1 | Summary: java.util; Arrays; false; copyOfRange; ; ; Argument[0].ArrayElement; ReturnValue.ArrayElement; value; manual |
|
||||
nodes
|
||||
| BadMacUse.java:63:82:63:97 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:71:42:71:50 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:71:42:71:50 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:76:44:76:52 | plaintext | semmle.label | plaintext |
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| BadMacUse.java:84:42:84:53 | bytes : byte[] [[]] : Object | semmle.label | bytes : byte[] [[]] : Object |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] | semmle.label | bytes : byte[] |
|
||||
| BadMacUse.java:92:31:92:35 | bytes : byte[] [[]] : Object | semmle.label | bytes : byte[] [[]] : Object |
|
||||
| BadMacUse.java:99:39:99:55 | ciphertext : byte[] [[]] : Object | semmle.label | ciphertext : byte[] [[]] : Object |
|
||||
| BadMacUse.java:100:39:100:48 | ciphertext : byte[] [[]] : Object | semmle.label | ciphertext : byte[] [[]] : Object |
|
||||
| BadMacUse.java:107:39:107:54 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:108:39:108:47 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:114:92:114:107 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:118:52:118:60 | plaintext : byte[] | semmle.label | plaintext : byte[] |
|
||||
| BadMacUse.java:139:79:139:90 | input : byte[] | semmle.label | input : byte[] |
|
||||
| BadMacUse.java:142:29:142:82 | copyOfRange(...) : byte[] [[]] : Object | semmle.label | copyOfRange(...) : byte[] [[]] : Object |
|
||||
| BadMacUse.java:142:48:142:52 | input : byte[] | semmle.label | input : byte[] |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
|
||||
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] [[]] : Object | semmle.label | ciphertext : byte[] [[]] : Object |
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
|
||||
subpaths
|
||||
testFailures
|
||||
| BadMacUse.java:50:56:50:65 | // $Source | Missing result: Source |
|
||||
| BadMacUse.java:139:79:139:90 | input : byte[] | Unexpected result: Source |
|
||||
| BadMacUse.java:146:95:146:104 | // $Source | Missing result: Source |
|
||||
| BadMacUse.java:152:42:152:51 | ciphertext | Unexpected result: Alert |
|
||||
|
||||
@@ -53,7 +53,7 @@ class BadMacUse {
|
||||
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(macKey);
|
||||
byte[] computedMac = mac.doFinal(plaintext); // $Alert[java/quantum/examples/bad-mac-order-decrypt-to-mac]
|
||||
byte[] computedMac = mac.doFinal(plaintext); // $Alert[java/quantum/examples/bad-mac-order-decrypt-to-mac]
|
||||
|
||||
if (!MessageDigest.isEqual(receivedMac, computedMac)) {
|
||||
throw new SecurityException("MAC verification failed");
|
||||
@@ -129,4 +129,30 @@ class BadMacUse {
|
||||
System.arraycopy(computedMac, 0, output, ciphertext.length, computedMac.length);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Correct inputs to a decrypt and MAC operation, but the ordering is unsafe.
|
||||
* The function decrypts THEN computes the MAC on the plaintext.
|
||||
* It should have the MAC computed on the ciphertext first.
|
||||
*/
|
||||
public void decryptThenMac(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] input) throws Exception {
|
||||
// Split input into ciphertext and MAC
|
||||
int macLength = 32; // HMAC-SHA256 output length
|
||||
byte[] ciphertext = Arrays.copyOfRange(input, 0, input.length - macLength);
|
||||
byte[] receivedMac = Arrays.copyOfRange(input, input.length - macLength, input.length);
|
||||
|
||||
// Decrypt first (unsafe)
|
||||
byte[] plaintext = decryptUsingWrapper(ciphertext, encryptionKeyBytes, new byte[16]); // $Source
|
||||
|
||||
// Now verify MAC (too late)
|
||||
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(macKey);
|
||||
byte[] computedMac = mac.doFinal(ciphertext); // $Alert[java/quantum/examples/bad-mac-order-decrypt-then-mac], False positive for Plaintext reuse
|
||||
|
||||
if (!MessageDigest.isEqual(receivedMac, computedMac)) {
|
||||
throw new SecurityException("MAC verification failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user