Skip to content

Commit 5d3f35b

Browse files
committed
HardcodedIVCNG qhelp and ql
1 parent 4eb92af commit 5d3f35b

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>An initialization vector (IV) is an input to a cryptographic primitive being used to provide the initial state. The IV is typically required to be random or pseudorandom (randomized scheme), but sometimes an IV only needs to be unpredictable or unique (stateful scheme).</p>
7+
<p>Randomization is crucial for some encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between (potentially similar) segments of the encrypted message.</p>
8+
</overview>
9+
10+
<recommendation>
11+
<p>All symmetric block ciphers must also be used with an appropriate initialization vector (IV) according to the mode of operation being used.</p>
12+
<p>If using a randomized scheme such as CBC, it is recommended to use cryptographically secure pseudorandom number generator such as <code>BCryptGenRandom</code>.</p>
13+
</recommendation>
14+
15+
<references>
16+
<li>
17+
<a href="https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptencrypt">BCryptEncrypt function (bcrypt.h)</a>
18+
<a href="https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom">BCryptGenRandom function (bcrypt.h)</a>
19+
<a href="https://en.wikipedia.org/wiki/Initialization_vector">Initialization vector (Wikipedia)</a>
20+
</li>
21+
</references>
22+
23+
</qhelp>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @name Weak cryptography
3+
* @description Finds usage of a static (hardcoded) IV. (CNG)
4+
* @kind problem
5+
* @id cpp/weak-crypto/cng/hardcoded-iv
6+
* @problem.severity error
7+
* @precision high
8+
* @tags security
9+
* external/cwe/cwe-327
10+
*/
11+
12+
import cpp
13+
import semmle.code.cpp.dataflow.new.DataFlow
14+
15+
/**
16+
* Gets const element of `ArrayAggregateLiteral`.
17+
*/
18+
Expr getConstElement(ArrayAggregateLiteral lit) {
19+
exists(int n |
20+
result = lit.getElementExpr(n, _) and
21+
result.isConstant()
22+
)
23+
}
24+
25+
/**
26+
* Gets the last element in an `ArrayAggregateLiteral`.
27+
*/
28+
Expr getLastElement(ArrayAggregateLiteral lit) {
29+
exists(int n |
30+
result = lit.getElementExpr(n, _) and
31+
not exists(lit.getElementExpr(n + 1, _))
32+
)
33+
}
34+
35+
module CngBCryptEncryptHardcodedIVConfiguration implements DataFlow::ConfigSig {
36+
predicate isSource(DataFlow::Node source) {
37+
exists(AggregateLiteral lit |
38+
getLastElement(lit) = source.asDefinition() and
39+
exists(getConstElement(lit))
40+
)
41+
}
42+
43+
predicate isSink(DataFlow::Node sink) {
44+
exists(FunctionCall call |
45+
// BCryptEncrypt 5h argument specifies the IV
46+
sink.asIndirectExpr() = call.getArgument(4) and
47+
call.getTarget().hasGlobalName("BCryptEncrypt")
48+
)
49+
}
50+
}
51+
52+
module Flow = DataFlow::Global<CngBCryptEncryptHardcodedIVConfiguration>;
53+
54+
from DataFlow::Node sl, DataFlow::Node fc, AggregateLiteral lit
55+
where
56+
Flow::flow(sl, fc) and
57+
getLastElement(lit) = sl.asDefinition()
58+
select lit, "Calling BCryptEncrypt with a hard-coded IV on function "

0 commit comments

Comments
 (0)