Skip to content

Commit de3ff45

Browse files
committed
Misc updates for OpenSSL modeling to trace algorithm literals to known alg getters, and converting the literal to a TCipherType.
1 parent cce5f24 commit de3ff45

8 files changed

Lines changed: 651 additions & 149 deletions

File tree

cpp/ql/lib/experimental/Quantum/Language.qll

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,19 @@ module GenericDataSourceUniversalFlowConfig implements DataFlow::ConfigSig {
4949

5050

5151

52-
// TODO: I think this will be inefficient, no?
53-
class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource instanceof Literal {
54-
override DataFlow::Node getOutputNode() {
55-
result.asExpr() = this
56-
}
52+
// // TODO: I think this will be inefficient, no?
53+
// class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource instanceof Literal {
54+
// override DataFlow::Node getOutputNode() {
55+
// result.asExpr() = this
56+
// }
5757

58-
override predicate flowsTo(Crypto::FlowAwareElement other) {
59-
// TODO: separate config to avoid blowing up data-flow analysis
60-
GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
61-
}
58+
// override predicate flowsTo(Crypto::FlowAwareElement other) {
59+
// // TODO: separate config to avoid blowing up data-flow analysis
60+
// GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
61+
// }
6262

63-
override string getAdditionalDescription() { result = this.toString() }
64-
}
63+
// override string getAdditionalDescription() { result = this.toString() }
64+
// }
6565

6666
/**
6767
* Definitions of various generic data sources

cpp/ql/lib/experimental/Quantum/OpenSSL/CtxFlow.qll

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ class CTXType extends Type {
88
}
99

1010
class CTXPointerExpr extends Expr {
11-
CTXPointerExpr() {
12-
this.getType() instanceof CTXType and
13-
this.getType() instanceof PointerType
11+
CTXPointerExpr() {
12+
this.getType() instanceof CTXType and
13+
this.getType() instanceof PointerType
1414
}
1515
}
1616

1717
class CTXPointerArgument extends CTXPointerExpr {
18-
CTXPointerArgument() {
19-
20-
exists(Call c | c.getAnArgument() = this)
21-
}
18+
CTXPointerArgument() { exists(Call c | c.getAnArgument() = this) }
2219

2320
Call getCall() { result.getAnArgument() = this }
2421
}
@@ -31,14 +28,14 @@ class CTXClearCall extends Call {
3128
}
3229

3330
class CTXCopyOutArgCall extends Call {
34-
CTXCopyOutArgCall() {
31+
CTXCopyOutArgCall() {
3532
this.getTarget().getName().toLowerCase().matches(["%copy%"]) and
3633
this.getAnArgument() instanceof CTXPointerArgument
3734
}
3835
}
3936

4037
class CTXCopyReturnCall extends Call {
41-
CTXCopyReturnCall() {
38+
CTXCopyReturnCall() {
4239
this.getTarget().getName().toLowerCase().matches(["%dup%"]) and
4340
this.getAnArgument() instanceof CTXPointerArgument and
4441
this instanceof CTXPointerExpr
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import cpp
2+
import experimental.Quantum.Language
3+
import EVPCipherConsumers
4+
import OpenSSLAlgorithmGetter
5+
6+
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
7+
exists(string name, string algType | algType.toLowerCase().matches("%encryption") |
8+
resolveAlgorithmFromLiteral(e, name, algType) and
9+
(
10+
name.matches("AES%") and type instanceof Crypto::AES
11+
or
12+
name.matches("ARIA") and type instanceof Crypto::ARIA
13+
or
14+
name.matches("BLOWFISH") and type instanceof Crypto::BLOWFISH
15+
or
16+
name.matches("BF") and type instanceof Crypto::BLOWFISH
17+
or
18+
name.matches("CAMELLIA%") and type instanceof Crypto::CAMELLIA
19+
or
20+
name.matches("CHACHA20") and type instanceof Crypto::CHACHA20
21+
or
22+
name.matches("CAST5") and type instanceof Crypto::CAST5
23+
or
24+
name.matches("2DES") and type instanceof Crypto::DOUBLEDES
25+
or
26+
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TRIPLEDES
27+
or
28+
name.matches("DES") and type instanceof Crypto::DES
29+
or
30+
name.matches("DESX") and type instanceof Crypto::DESX
31+
or
32+
name.matches("GOST%") and type instanceof Crypto::GOST
33+
or
34+
name.matches("IDEA") and type instanceof Crypto::IDEA
35+
or
36+
name.matches("KUZNYECHIK") and type instanceof Crypto::KUZNYECHIK
37+
or
38+
name.matches("MAGMA") and type instanceof Crypto::MAGMA
39+
or
40+
name.matches("RC2") and type instanceof Crypto::RC2
41+
or
42+
name.matches("RC4") and type instanceof Crypto::RC4
43+
or
44+
name.matches("RC5") and type instanceof Crypto::RC5
45+
or
46+
name.matches("RSA") and type instanceof Crypto::RSA
47+
or
48+
name.matches("SEED") and type instanceof Crypto::SEED
49+
or
50+
name.matches("SM4") and type instanceof Crypto::SM4
51+
)
52+
)
53+
}
54+
55+
class CipherKnownAlgorithmLiteralAlgorithmInstance extends Crypto::CipherAlgorithmInstance instanceof Literal
56+
{
57+
CipherKnownAlgorithmLiteralAlgorithmInstance() {
58+
exists(EVPCipherGetterCall c, DataFlow::Node src, DataFlow::Node sink |
59+
sink = c.getValueArgNode() and
60+
src.asExpr() = this and
61+
KnownAlgorithmLiteralToAlgorithmGetterFlow::flow(src, sink) and
62+
// Not just any known value, but specifically a known cipher operation
63+
exists(string algType |
64+
resolveAlgorithmFromLiteral(src.asExpr(), _, algType) and
65+
algType.toLowerCase().matches("%encryption")
66+
)
67+
)
68+
}
69+
70+
Crypto::AlgorithmConsumer getConsumer() { none() } //result = consumer }
71+
72+
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
73+
none() // TODO: provider defaults
74+
}
75+
76+
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
77+
78+
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
79+
80+
override Crypto::TCipherType getCipherFamily() { literalToCipherFamilyType(this, result) }
81+
}
82+
// override Crypto::TCipherType getCipherFamily() {
83+
// if this.cipherNameMappingKnown(_, super.getAlgorithmName())
84+
// then this.cipherNameMappingKnown(result, super.getAlgorithmName())
85+
// else result instanceof Crypto::OtherCipherType
86+
// }
87+
// bindingset[name]
88+
// private predicate cipherNameMappingKnown(Crypto::TCipherType type, string name) {
89+
// name = "AES" and
90+
// type instanceof Crypto::AES
91+
// or
92+
// name = "DES" and
93+
// type instanceof Crypto::DES
94+
// or
95+
// name = "TripleDES" and
96+
// type instanceof Crypto::TripleDES
97+
// or
98+
// name = "IDEA" and
99+
// type instanceof Crypto::IDEA
100+
// or
101+
// name = "CAST5" and
102+
// type instanceof Crypto::CAST5
103+
// or
104+
// name = "ChaCha20" and
105+
// type instanceof Crypto::ChaCha20
106+
// or
107+
// name = "RC4" and
108+
// type instanceof Crypto::RC4
109+
// or
110+
// name = "RC5" and
111+
// type instanceof Crypto::RC5
112+
// or
113+
// name = "RSA" and
114+
// type instanceof Crypto::RSA
115+
// }
116+
// private predicate modeToNameMappingKnown(Crypto::TBlockCipherModeOperationType type, string name) {
117+
// type instanceof Crypto::ECB and name = "ECB"
118+
// or
119+
// type instanceof Crypto::CBC and name = "CBC"
120+
// or
121+
// type instanceof Crypto::GCM and name = "GCM"
122+
// or
123+
// type instanceof Crypto::CTR and name = "CTR"
124+
// or
125+
// type instanceof Crypto::XTS and name = "XTS"
126+
// or
127+
// type instanceof Crypto::CCM and name = "CCM"
128+
// or
129+
// type instanceof Crypto::SIV and name = "SIV"
130+
// or
131+
// type instanceof Crypto::OCB and name = "OCB"
132+
// }
133+
// override Crypto::TBlockCipherModeOperationType getModeType() {
134+
// if this.modeToNameMappingKnown(_, super.getMode())
135+
// then this.modeToNameMappingKnown(result, super.getMode())
136+
// else result instanceof Crypto::OtherMode
137+
// }
138+
// override string getRawModeAlgorithmName() { result = super.getMode() }
139+
// override string getRawPaddingAlgorithmName() { result = super.getPadding() }
140+
// bindingset[name]
141+
// private predicate paddingToNameMappingKnown(Crypto::TPaddingType type, string name) {
142+
// type instanceof Crypto::NoPadding and name = "NOPADDING"
143+
// or
144+
// type instanceof Crypto::PKCS7 and name = ["PKCS5Padding", "PKCS7Padding"] // TODO: misnomer in the JCA?
145+
// or
146+
// type instanceof Crypto::OAEP and name.matches("OAEP%") // TODO: handle OAEPWith%
147+
// }
148+
// }

cpp/ql/lib/experimental/Quantum/OpenSSL/EVPCipherConsumers.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import EVPCipherInitializer
22
import EVPCipherOperation
3-
import AlgorithmSource
3+
import EVPCipherAlgorithmSource
44

55

66
class EVP_Cipher_Initializer_Algorithm_Consumer extends Crypto::AlgorithmConsumer instanceof EVPCipherInitializerAlgorithmArgument
77
{
88
override DataFlow::Node getInputNode() { result.asExpr() = this }
99

1010
override Crypto::AlgorithmElement getAKnownAlgorithmSource() {
11-
result.(CipherLiteralAlgorithmInstance).getConsumer() = this
11+
result.(CipherKnownAlgorithmLiteralAlgorithmInstance).getConsumer() = this
1212
}
1313
}
1414
// //TODO: need a key consumer
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import cpp
2+
3+
predicate isPossibleOpenSSLFunction(Function f) {
4+
isPossibleOpenSSLLocation(f.getADeclarationLocation())
5+
}
6+
7+
predicate isPossibleOpenSSLLocation(Location l){
8+
l.toString().toLowerCase().matches("%openssl%")
9+
}
10+

0 commit comments

Comments
 (0)