Skip to content

Commit ad29826

Browse files
authored
Merge pull request #18 from raulgarciamsft/nccoe-pqc-migration
Initial PR - Proof of Concept using CNG
2 parents d392cda + d4ba46c commit ad29826

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import cpp
2+
import DataFlow::PathGraph
3+
import semmle.code.cpp.dataflow.TaintTracking
4+
5+
abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node {}
6+
abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node {}
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @id cpp/nist-pqc/pqc-vulnerable-algorithms-cng
3+
* @name Usage of PQC vulnerable algorithms
4+
* @description Usage of PQC vulnerable algorithms.
5+
* @microsoft.severity important
6+
* @kind path-problem
7+
* @problem.severity warning
8+
* @precision high
9+
* @tags security
10+
* pqc
11+
* nist
12+
*/
13+
14+
import cpp
15+
import DataFlow::PathGraph
16+
import WindowsCng
17+
import WindowsCngPQCVAsymmetricKeyUsage
18+
19+
// CNG-specific DataFlow configuration
20+
class BCryptConfiguration extends DataFlow::Configuration {
21+
BCryptConfiguration() {
22+
this = "BCryptConfiguration"
23+
}
24+
override predicate isSource(DataFlow::Node source) {
25+
source instanceof BCryptOpenAlgorithmProviderSource
26+
}
27+
28+
override predicate isSink(DataFlow::Node sink) {
29+
sink instanceof BCryptOpenAlgorithmProviderSink
30+
}
31+
32+
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
33+
isWindowsCngAsymmetricKeyAdditionalTaintStep( node1, node2)
34+
}
35+
}
36+
37+
from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
38+
where config.hasFlowPath(source, sink)
39+
select sink.getNode(), source, sink, "PQC vulnerable algorithm $@ in use has been detected.",
40+
source.getNode().asExpr(), source.getNode().asExpr().toString()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import cpp
2+
import WindowsCng
3+
4+
//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.)
5+
6+
predicate isExprAlgIdForBCryptOpenAlgorithmProvider(Expr e){
7+
exists( FunctionCall call |
8+
// BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used
9+
e = call.getArgument(1)
10+
and
11+
call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider")
12+
)
13+
}
14+
15+
predicate isExprAlgHandleForBCryptGenerateOrImportKeyPair(Expr e){
16+
exists( FunctionCall call |
17+
e = call.getArgument(0)
18+
and
19+
( call.getTarget().hasGlobalName("BCryptImportKeyPair") or
20+
call.getTarget().hasGlobalName("BCryptGenerateKeyPair"))
21+
)
22+
}
23+
24+
predicate isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(Expr e){
25+
exists( FunctionCall call |
26+
( e = call.getArgument(3) and call.getTarget().hasGlobalName("BCryptImportKeyPair") )or
27+
( e = call.getArgument(1) and call.getTarget().hasGlobalName("BCryptGenerateKeyPair") )
28+
)
29+
}
30+
31+
predicate isExprKeyHandleForBCryptSignHash(Expr e){
32+
exists( FunctionCall call |
33+
e = call.getArgument(0)
34+
and
35+
call.getTarget().hasGlobalName("BCryptSignHash")
36+
)
37+
}
38+
39+
class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink {
40+
BCryptSignHashArgumentSink() {
41+
isExprKeyHandleForBCryptSignHash(this.asExpr())
42+
}
43+
}
44+
45+
class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource {
46+
BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() {
47+
this.asExpr() instanceof StringLiteral and
48+
(
49+
this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"]
50+
or this.asExpr().getValue().matches("ECDH%")
51+
or this.asExpr().getValue().matches("RSA%")
52+
)
53+
}
54+
55+
}
56+
57+
predicate isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2)
58+
{
59+
isExprAlgIdForBCryptOpenAlgorithmProvider(node1.asExpr()) and
60+
isExprAlgHandleForBCryptGenerateOrImportKeyPair(node2.asExpr())
61+
}
62+
63+
64+
predicate isAdditionalTaintStepWithinGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2)
65+
{
66+
isExprAlgHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and
67+
isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node2.asExpr())
68+
}
69+
70+
predicate isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(DataFlow::Node node1, DataFlow::Node node2)
71+
{
72+
isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and
73+
isExprKeyHandleForBCryptSignHash(node2.asExpr())
74+
}
75+
76+
predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
77+
isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(node1, node2)
78+
or isAdditionalTaintStepWithinGenerateOrImportKeyPair(node1, node2)
79+
or isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(node1, node2)
80+
}
81+

0 commit comments

Comments
 (0)