Skip to content

Commit 32d29ff

Browse files
committed
Changed casing on TCipherType, Added some initial fixes for hash support, started developing openssl hashing modeling.
1 parent b9bd199 commit 32d29ff

6 files changed

Lines changed: 185 additions & 42 deletions

File tree

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import experimental.Quantum.Language
33
import EVPCipherConsumers
44
import OpenSSLAlgorithmGetter
55

6-
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
6+
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
77
exists(string name, string algType | algType.toLowerCase().matches("%encryption") |
88
resolveAlgorithmFromLiteral(e, name, algType) and
99
(
@@ -21,9 +21,9 @@ predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
2121
or
2222
name.matches("CAST5") and type instanceof Crypto::CAST5
2323
or
24-
name.matches("2DES") and type instanceof Crypto::DOUBLEDES
24+
name.matches("2DES") and type instanceof Crypto::DoubleDES
2525
or
26-
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TRIPLEDES
26+
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TripleDES
2727
or
2828
name.matches("DES") and type instanceof Crypto::DES
2929
or
@@ -52,7 +52,6 @@ predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
5252
)
5353
}
5454

55-
5655
class CipherKnownAlgorithmLiteralAlgorithmInstance extends Crypto::CipherAlgorithmInstance instanceof Literal
5756
{
5857
OpenSSLAlgorithmGetterCall cipherGetterCall;
@@ -81,7 +80,9 @@ class CipherKnownAlgorithmLiteralAlgorithmInstance extends Crypto::CipherAlgorit
8180

8281
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
8382

84-
override Crypto::TCipherType getCipherFamily() { literalToCipherFamilyType(this, result) }
83+
override Crypto::TCipherType getCipherFamily() {
84+
literalToCipherFamilyType(this, result)
85+
}
8586
}
8687
// override Crypto::TCipherType getCipherFamily() {
8788
// if this.cipherNameMappingKnown(_, super.getAlgorithmName())
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import cpp
2+
import experimental.Quantum.Language
3+
import EVPCipherConsumers
4+
import OpenSSLAlgorithmGetter
5+
6+
predicate literalToHashFamilyType(Literal e, Crypto::THashType type) {
7+
exists(string name, string algType | algType.toLowerCase().matches("%hash") |
8+
resolveAlgorithmFromLiteral(e, name, algType) and
9+
(
10+
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
11+
or
12+
name.matches("BLAKE2S") and type instanceof Crypto::BLAKE2S
13+
or
14+
name.matches("RIPEMD160") and type instanceof Crypto::RIPEMD160
15+
or
16+
name.matches("MD2") and type instanceof Crypto::MD2
17+
or
18+
name.matches("MD4") and type instanceof Crypto::MD4
19+
or
20+
name.matches("MD5") and type instanceof Crypto::MD5
21+
or
22+
name.matches("POLY1305") and type instanceof Crypto::POLY1305
23+
or
24+
name.matches(["SHA1", "SHA"]) and type instanceof Crypto::SHA1
25+
or
26+
name.matches("SHA2") and type instanceof Crypto::SHA2
27+
or
28+
name.matches("SHA3") and type instanceof Crypto::SHA3
29+
or
30+
name.matches("SHAKE") and type instanceof Crypto::SHAKE
31+
or
32+
name.matches("SM3") and type instanceof Crypto::SM3
33+
or
34+
name.matches("WHIRLPOOL") and type instanceof Crypto::WHIRLPOOL
35+
// TODO: what about MD_GOST?
36+
)
37+
)
38+
}
39+
40+
class HashKnownAlgorithmLiteralAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof Literal
41+
{
42+
OpenSSLAlgorithmGetterCall cipherGetterCall;
43+
44+
HashKnownAlgorithmLiteralAlgorithmInstance() {
45+
exists(DataFlow::Node src, DataFlow::Node sink |
46+
sink = cipherGetterCall.getValueArgNode() and
47+
src.asExpr() = this and
48+
KnownAlgorithmLiteralToAlgorithmGetterFlow::flow(src, sink) and
49+
// Not just any known value, but specifically a known cipher operation
50+
exists(string algType |
51+
resolveAlgorithmFromLiteral(src.asExpr(), _, algType) and
52+
algType.toLowerCase().matches("hash")
53+
)
54+
)
55+
}
56+
57+
// TODO: should this not be part of the abstract algorithm definition?
58+
Crypto::AlgorithmConsumer getConsumer() {
59+
AlgGetterToAlgConsumerFlow::flow(cipherGetterCall.getResultNode(), DataFlow::exprNode(result))
60+
}
61+
62+
override Crypto::THashType getHashFamily() { literalToHashFamilyType(this, result) }
63+
64+
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
65+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import experimental.Quantum.Language
2+
import CtxFlow as CTXFlow
3+
4+
5+
//https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@ class EVPCipherGetterCall extends OpenSSLAlgorithmGetterCall {
162162
Expr resultExpr;
163163

164164
EVPCipherGetterCall() {
165-
// Flow out through the return pointer itself (trace the pointer, not what it is pointing to)
166165
resultExpr = this and
167166
resultNode.asExpr() = this and
167+
isPossibleOpenSSLFunction(this.getTarget()) and
168168
(
169169
this.getTarget().getName() in ["EVP_get_cipherbyname", "EVP_get_cipherbyobj"] and
170170
valueArgExpr = this.getArgument(0) and
@@ -188,6 +188,38 @@ class EVPCipherGetterCall extends OpenSSLAlgorithmGetterCall {
188188

189189
override Expr getResultExpr() { result = resultExpr }
190190
}
191+
192+
class EVPDigestGetterCall extends OpenSSLAlgorithmGetterCall {
193+
DataFlow::Node valueArgNode;
194+
DataFlow::Node resultNode;
195+
Expr valueArgExpr;
196+
Expr resultExpr;
197+
198+
EVPDigestGetterCall() {
199+
resultExpr = this and
200+
resultNode.asExpr() = this and
201+
isPossibleOpenSSLFunction(this.getTarget()) and
202+
(
203+
this.getTarget().getName() in [
204+
"EVP_get_digestbyname", "EVP_get_digestbyobj", "EVP_get_digestbynid"
205+
] and
206+
valueArgExpr = this.getArgument(0) and
207+
valueArgNode.asExpr() = valueArgExpr
208+
or
209+
this.getTarget().getName() = "EVP_MD_fetch" and
210+
valueArgExpr = this.getArgument(1) and
211+
valueArgNode.asExpr() = valueArgExpr
212+
)
213+
}
214+
215+
override DataFlow::Node getValueArgNode() { result = valueArgNode }
216+
217+
override DataFlow::Node getResultNode() { result = resultNode }
218+
219+
override Expr getValueArgExpr() { result = valueArgExpr }
220+
221+
override Expr getResultExpr() { result = resultExpr }
222+
}
191223
// /**
192224
// * Predicates/classes for identifying algorithm sinks.
193225
// * An Algorithm Sink is a function that takes an algorithm as an argument.

java/ql/lib/experimental/Quantum/JCA.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ module JCAModel {
123123
override Crypto::TCipherType getCipherFamily() {
124124
if this.cipherNameMappingKnown(_, super.getAlgorithmName())
125125
then this.cipherNameMappingKnown(result, super.getAlgorithmName())
126-
else result instanceof Crypto::OTHERCIPHERTYPE
126+
else result instanceof Crypto::OtherCipherType
127127
}
128128

129129
bindingset[name]
@@ -135,7 +135,7 @@ module JCAModel {
135135
type instanceof Crypto::DES
136136
or
137137
name = "TripleDES" and
138-
type instanceof Crypto::TRIPLEDES
138+
type instanceof Crypto::TripleDES
139139
or
140140
name = "IDEA" and
141141
type instanceof Crypto::IDEA

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,13 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
140140
/**
141141
* An element that represents a _known_ cryptographic algorithm.
142142
*/
143-
abstract class AlgorithmElement extends KnownElement { }
143+
abstract class AlgorithmElement extends KnownElement {
144+
/**
145+
* Gets the raw name as it appears in source, e.g., "AES/CBC/PKCS7Padding".
146+
* This name is not parsed or formatted.
147+
*/
148+
abstract string getRawAlgorithmName();
149+
}
144150

145151
/**
146152
* An element that represents a _known_ cryptographic artifact.
@@ -286,12 +292,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
286292
}
287293

288294
abstract class CipherAlgorithmInstance extends AlgorithmElement {
289-
/**
290-
* Gets the raw name as it appears in source, e.g., "AES/CBC/PKCS7Padding".
291-
* This name is not parsed or formatted.
292-
*/
293-
abstract string getRawAlgorithmName();
294-
295295
/**
296296
* Gets the type of this cipher, e.g., "AES" or "ChaCha20".
297297
*/
@@ -358,7 +358,12 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
358358

359359
abstract class HashOperationInstance extends KnownElement { }
360360

361-
abstract class HashAlgorithmInstance extends KnownElement { }
361+
abstract class HashAlgorithmInstance extends AlgorithmElement {
362+
/**
363+
* Gets the type of this digest algorithm, e.g., "SHA1", "SHA2", "MD5" etc.
364+
*/
365+
abstract THashType getHashFamily();
366+
}
362367

363368
abstract class KeyDerivationOperationInstance extends KnownElement { }
364369

@@ -875,15 +880,15 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
875880
IDEA() or
876881
KUZNYECHIK() or
877882
MAGMA() or
878-
TRIPLEDES() or
879-
DOUBLEDES() or
883+
TripleDES() or
884+
DoubleDES() or
880885
RC2() or
881886
RC4() or
882887
RC5() or
883888
RSA() or
884889
SEED() or
885890
SM4() or
886-
OTHERCIPHERTYPE()
891+
OtherCipherType()
887892

888893
final class CipherAlgorithmNode extends AlgorithmNode, TCipherAlgorithm {
889894
CipherAlgorithmInstance instance;
@@ -932,27 +937,47 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
932937
final private predicate cipherFamilyToNameAndStructure(
933938
TCipherType type, string name, TCipherStructureType s
934939
) {
935-
type instanceof AES and name = "AES" and s = Block() or
936-
type instanceof ARIA and name = "ARIA" and s = Block() or
937-
type instanceof BLOWFISH and name = "Blowfish" and s = Block() or
938-
type instanceof CAMELLIA and name = "Camellia" and s = Block() or
939-
type instanceof CAST5 and name = "CAST5" and s = Block() or
940-
type instanceof CHACHA20 and name = "ChaCha20" and s = Stream() or
941-
type instanceof DES and name = "DES" and s = Block() or
942-
type instanceof DESX and name = "DESX" and s = Block() or
943-
type instanceof GOST and name = "GOST" and s = Block() or
944-
type instanceof IDEA and name = "IDEA" and s = Block() or
945-
type instanceof KUZNYECHIK and name = "Kuznyechik" and s = Block() or
946-
type instanceof MAGMA and name = "Magma" and s = Block() or
947-
type instanceof TRIPLEDES and name = "TripleDES" and s = Block() or
948-
type instanceof DOUBLEDES and name = "DoubleDES" and s = Block() or
949-
type instanceof RC2 and name = "RC2" and s = Block() or
950-
type instanceof RC4 and name = "RC4" and s = Stream() or
951-
type instanceof RC5 and name = "RC5" and s = Block() or
952-
type instanceof RSA and name = "RSA" and s = Asymmetric() or
953-
type instanceof SEED and name = "SEED" and s = Block() or
954-
type instanceof SM4 and name = "SM4" and s = Block() or
955-
type instanceof OTHERCIPHERTYPE and
940+
type instanceof AES and name = "AES" and s = Block()
941+
or
942+
type instanceof ARIA and name = "ARIA" and s = Block()
943+
or
944+
type instanceof BLOWFISH and name = "Blowfish" and s = Block()
945+
or
946+
type instanceof CAMELLIA and name = "Camellia" and s = Block()
947+
or
948+
type instanceof CAST5 and name = "CAST5" and s = Block()
949+
or
950+
type instanceof CHACHA20 and name = "ChaCha20" and s = Stream()
951+
or
952+
type instanceof DES and name = "DES" and s = Block()
953+
or
954+
type instanceof DESX and name = "DESX" and s = Block()
955+
or
956+
type instanceof GOST and name = "GOST" and s = Block()
957+
or
958+
type instanceof IDEA and name = "IDEA" and s = Block()
959+
or
960+
type instanceof KUZNYECHIK and name = "Kuznyechik" and s = Block()
961+
or
962+
type instanceof MAGMA and name = "Magma" and s = Block()
963+
or
964+
type instanceof TripleDES and name = "TripleDES" and s = Block()
965+
or
966+
type instanceof DoubleDES and name = "DoubleDES" and s = Block()
967+
or
968+
type instanceof RC2 and name = "RC2" and s = Block()
969+
or
970+
type instanceof RC4 and name = "RC4" and s = Stream()
971+
or
972+
type instanceof RC5 and name = "RC5" and s = Block()
973+
or
974+
type instanceof RSA and name = "RSA" and s = Asymmetric()
975+
or
976+
type instanceof SEED and name = "SEED" and s = Block()
977+
or
978+
type instanceof SM4 and name = "SM4" and s = Block()
979+
or
980+
type instanceof OtherCipherType and
956981
name = this.getRawAlgorithmName() and
957982
s = UnknownCipherStructureType()
958983
}
@@ -1004,13 +1029,18 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
10041029
}
10051030

10061031
newtype THashType =
1032+
BLAKE2B() or
1033+
BLAKE2S() or
1034+
RIPEMD160() or
10071035
MD2() or
10081036
MD4() or
10091037
MD5() or
1038+
POLY1305() or
10101039
SHA1() or
10111040
SHA2() or
10121041
SHA3() or
1013-
RIPEMD160() or
1042+
SHAKE() or
1043+
SM3() or
10141044
WHIRLPOOL() or
10151045
OtherHashType()
10161046

@@ -1021,19 +1051,29 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
10211051
override string getInternalType() { result = "HashAlgorithm" }
10221052

10231053
final predicate hashTypeToNameMapping(THashType type, string name) {
1054+
type instanceof BLAKE2B and name = "BLAKE2B"
1055+
or
1056+
type instanceof BLAKE2S and name = "BLAKE2S"
1057+
or
1058+
type instanceof RIPEMD160 and name = "RIPEMD160"
1059+
or
10241060
type instanceof MD2 and name = "MD2"
10251061
or
10261062
type instanceof MD4 and name = "MD4"
10271063
or
10281064
type instanceof MD5 and name = "MD5"
10291065
or
1066+
type instanceof POLY1305 and name = "POLY1305"
1067+
or
10301068
type instanceof SHA1 and name = "SHA1"
10311069
or
10321070
type instanceof SHA2 and name = "SHA2"
10331071
or
10341072
type instanceof SHA3 and name = "SHA3"
10351073
or
1036-
type instanceof RIPEMD160 and name = "RIPEMD160"
1074+
type instanceof SHAKE and name = "SHAKE"
1075+
or
1076+
type instanceof SM3 and name = "SM3"
10371077
or
10381078
type instanceof WHIRLPOOL and name = "WHIRLPOOL"
10391079
or

0 commit comments

Comments
 (0)