@@ -6,20 +6,84 @@ import go
6
6
7
7
/**
8
8
* Names of cryptographic algorithms, separated into strong and weak variants.
9
+ *
9
10
* The names are normalized: upper-case, no spaces, dashes or underscores.
11
+ *
10
12
* The names are inspired by the names used in real world crypto libraries.
11
- * The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
13
+ *
14
+ * The classification into strong and weak are based on OWASP and Wikipedia (2020).
15
+ *
16
+ * Sources (more links in qhelp file):
17
+ * https://en.wikipedia.org/wiki/Strong_cryptography#Cryptographically_strong_algorithms
18
+ * https://en.wikipedia.org/wiki/Strong_cryptography#Examples
19
+ * https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
12
20
*/
13
21
private module AlgorithmNames {
22
+ predicate isStrongHashingAlgorithm ( string name ) {
23
+ name = "DSA" or
24
+ name = "ED25519" or
25
+ name = "ES256" or
26
+ name = "ECDSA256" or
27
+ name = "ES384" or
28
+ name = "ECDSA384" or
29
+ name = "ES512" or
30
+ name = "ECDSA512" or
31
+ name = "SHA2" or
32
+ name = "SHA224" or
33
+ name = "SHA256" or
34
+ name = "SHA384" or
35
+ name = "SHA512" or
36
+ name = "SHA3"
37
+ }
38
+
14
39
predicate isWeakHashingAlgorithm ( string name ) {
40
+ name = "HAVEL128" or
41
+ name = "MD2" or
42
+ name = "MD4" or
15
43
name = "MD5" or
44
+ name = "PANAMA" or
45
+ name = "RIPEMD" or
46
+ name = "RIPEMD128" or
47
+ name = "RIPEMD256" or
48
+ name = "RIPEMD320" or
49
+ name = "SHA0" or
16
50
name = "SHA1"
17
51
}
18
52
53
+ predicate isStrongEncryptionAlgorithm ( string name ) {
54
+ name = "AES" or
55
+ name = "AES128" or
56
+ name = "AES192" or
57
+ name = "AES256" or
58
+ name = "AES512" or
59
+ name = "RSA" or
60
+ name = "RABBIT" or
61
+ name = "BLOWFISH"
62
+ }
63
+
19
64
predicate isWeakEncryptionAlgorithm ( string name ) {
20
65
name = "DES" or
21
- name = "RC4"
66
+ name = "3DES" or
67
+ name = "TRIPLEDES" or
68
+ name = "TDEA" or
69
+ name = "TRIPLEDEA" or
70
+ name = "ARC2" or
71
+ name = "RC2" or
72
+ name = "ARC4" or
73
+ name = "RC4" or
74
+ name = "ARCFOUR" or
75
+ name = "ARC5" or
76
+ name = "RC5"
22
77
}
78
+
79
+ predicate isStrongPasswordHashingAlgorithm ( string name ) {
80
+ name = "ARGON2" or
81
+ name = "PBKDF2" or
82
+ name = "BCRYPT" or
83
+ name = "SCRYPT"
84
+ }
85
+
86
+ predicate isWeakPasswordHashingAlgorithm ( string name ) { none ( ) }
23
87
}
24
88
25
89
private import AlgorithmNames
@@ -28,9 +92,20 @@ private import AlgorithmNames
28
92
* A cryptographic algorithm.
29
93
*/
30
94
private newtype TCryptographicAlgorithm =
31
- MkHashingAlgorithm ( string name , boolean isWeak ) { isWeakHashingAlgorithm ( name ) and isWeak = true } or
95
+ MkHashingAlgorithm ( string name , boolean isWeak ) {
96
+ isStrongHashingAlgorithm ( name ) and isWeak = false
97
+ or
98
+ isWeakHashingAlgorithm ( name ) and isWeak = true
99
+ } or
32
100
MkEncryptionAlgorithm ( string name , boolean isWeak ) {
101
+ isStrongEncryptionAlgorithm ( name ) and isWeak = false
102
+ or
33
103
isWeakEncryptionAlgorithm ( name ) and isWeak = true
104
+ } or
105
+ MkPasswordHashingAlgorithm ( string name , boolean isWeak ) {
106
+ isStrongPasswordHashingAlgorithm ( name ) and isWeak = false
107
+ or
108
+ isWeakPasswordHashingAlgorithm ( name ) and isWeak = true
34
109
}
35
110
36
111
/**
@@ -46,11 +121,13 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
46
121
abstract string getName ( ) ;
47
122
48
123
/**
49
- * Holds if the name of this algorithm matches `name` modulo case, white space, dashes and underscores.
124
+ * Holds if the name of this algorithm matches `name` modulo case,
125
+ * white space, dashes and underscores.
50
126
*/
51
127
bindingset [ name]
52
128
predicate matchesName ( string name ) {
53
129
exists ( name .regexpReplaceAll ( "[-_]" , "" ) .regexpFind ( "(?i)\\Q" + getName ( ) + "\\E" , _, _) )
130
+ // name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
54
131
}
55
132
56
133
/**
@@ -60,7 +137,7 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
60
137
}
61
138
62
139
/**
63
- * A hashing algorithm
140
+ * A hashing algorithm such as `MD5` or `SHA512`.
64
141
*/
65
142
class HashingAlgorithm extends MkHashingAlgorithm , CryptographicAlgorithm {
66
143
string name ;
@@ -74,7 +151,7 @@ class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
74
151
}
75
152
76
153
/**
77
- * An encryption algorithm
154
+ * An encryption algorithm such as `DES` or `AES512`.
78
155
*/
79
156
class EncryptionAlgorithm extends MkEncryptionAlgorithm , CryptographicAlgorithm {
80
157
string name ;
@@ -87,97 +164,100 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
87
164
override predicate isWeak ( ) { isWeak = true }
88
165
}
89
166
167
+ /**
168
+ * A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
169
+ */
170
+ class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm , CryptographicAlgorithm {
171
+ string name ;
172
+ boolean isWeak ;
173
+
174
+ PasswordHashingAlgorithm ( ) { this = MkPasswordHashingAlgorithm ( name , isWeak ) }
175
+
176
+ override string getName ( ) { result = name }
177
+
178
+ override predicate isWeak ( ) { isWeak = true }
179
+ }
180
+
90
181
/**
91
182
* An application of a cryptographic algorithm.
92
183
*/
93
- abstract class CryptographicOperation extends Expr {
184
+ abstract class CryptographicOperation extends DataFlow:: Node {
185
+ /**
186
+ * Gets the input the algorithm is used on, e.g. the plain text input to be encrypted.
187
+ */
188
+ abstract Expr getInput ( ) ;
189
+
94
190
/**
95
191
* Gets the applied algorithm.
96
192
*/
97
193
abstract CryptographicAlgorithm getAlgorithm ( ) ;
98
194
}
99
195
100
196
/**
197
+ * Below are the cryptographic functions that have been implemented so far for this library.
101
198
* Class that checks for use of Md5 package.
102
199
*/
103
- class Md5 extends CryptographicOperation {
200
+ class Md5 extends CryptographicOperation , DataFlow:: CallNode {
201
+ Expr input ;
104
202
CryptographicAlgorithm algorithm ;
105
- SelectorExpr sel ;
106
- CallExpr call ;
107
203
108
204
Md5 ( ) {
109
- this = call and
110
- algorithm .matchesName ( sel .getBase ( ) .toString ( ) ) and
111
- algorithm .matchesName ( "MD5" ) and
112
- sel .getSelector ( ) .toString ( ) = call .getCalleeName ( ) .toString ( ) and
113
- (
114
- call .getCalleeName ( ) .toString ( ) = "New" or
115
- call .getCalleeName ( ) .toString ( ) = "Sum"
116
- )
205
+ getTarget ( ) .hasQualifiedName ( "crypto/md5" , [ "New" , "Sum" ] ) and
206
+ this .getArgument ( 0 ) .asExpr ( ) = input
117
207
}
118
208
209
+ override Expr getInput ( ) { result = input }
210
+
119
211
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
120
212
}
121
213
122
214
/**
123
- * Class that checks for use of SHA1 package.
215
+ * Class that checks for use of Sha1 package.
124
216
*/
125
- class Sha1 extends CryptographicOperation {
217
+ class Sha1 extends CryptographicOperation , DataFlow:: CallNode {
218
+ Expr input ;
126
219
CryptographicAlgorithm algorithm ;
127
- SelectorExpr sel ;
128
- CallExpr call ;
129
220
130
221
Sha1 ( ) {
131
- this = call and
132
- algorithm .matchesName ( sel .getBase ( ) .toString ( ) ) and
133
- algorithm .matchesName ( "SHA1" ) and
134
- sel .getSelector ( ) .toString ( ) = call .getCalleeName ( ) .toString ( ) and
135
- (
136
- call .getCalleeName ( ) .toString ( ) = "New" or
137
- call .getCalleeName ( ) .toString ( ) = "Sum"
138
- )
222
+ getTarget ( ) .hasQualifiedName ( "crypto/sha1" , [ "New" , "Sum" ] ) and
223
+ this .getArgument ( 0 ) .asExpr ( ) = input
139
224
}
140
225
226
+ override Expr getInput ( ) { result = input }
227
+
141
228
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
142
229
}
143
230
144
231
/**
145
232
* Class that checks for use of Des package.
146
233
*/
147
- class Des extends CryptographicOperation {
234
+ class Des extends CryptographicOperation , DataFlow:: CallNode {
235
+ Expr input ;
148
236
CryptographicAlgorithm algorithm ;
149
- SelectorExpr sel ;
150
- CallExpr call ;
151
237
152
238
Des ( ) {
153
- this = call and
154
- algorithm .matchesName ( sel .getBase ( ) .toString ( ) ) and
155
- algorithm .matchesName ( "DES" ) and
156
- sel .getSelector ( ) .toString ( ) = call .getCalleeName ( ) .toString ( ) and
157
- (
158
- call .getCalleeName ( ) .toString ( ) = "NewCipher" or
159
- call .getCalleeName ( ) .toString ( ) = "NewTripleDESCipher"
160
- )
239
+ getTarget ( ) .hasQualifiedName ( "crypto/des" , [ "NewCipher" , "NewTripleDESCipher" ] ) and
240
+ this .getArgument ( 0 ) .asExpr ( ) = input
161
241
}
162
242
243
+ override Expr getInput ( ) { result = input }
244
+
163
245
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
164
246
}
165
247
166
248
/**
167
- * Class that checks for use of RC4 package.
249
+ * Class that checks for use of Rc4 package.
168
250
*/
169
- class Rc4 extends CryptographicOperation {
251
+ class Rc4 extends CryptographicOperation , DataFlow:: CallNode {
252
+ Expr input ;
170
253
CryptographicAlgorithm algorithm ;
171
- SelectorExpr sel ;
172
- CallExpr call ;
173
254
174
255
Rc4 ( ) {
175
- this = call and
176
- algorithm .matchesName ( sel .getBase ( ) .toString ( ) ) and
177
- algorithm .matchesName ( "RC4" ) and
178
- sel .getSelector ( ) .toString ( ) = call .getCalleeName ( ) .toString ( ) and
179
- call .getCalleeName ( ) .toString ( ) = "NewCipher"
256
+ getTarget ( ) .hasQualifiedName ( "crypto/rc4" , [ "NewCipher" ] ) and
257
+ this .getArgument ( 0 ) .asExpr ( ) = input
180
258
}
181
259
260
+ override Expr getInput ( ) { result = input }
261
+
182
262
override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
183
263
}
0 commit comments