@@ -6,20 +6,84 @@ import go
66
77/**
88 * Names of cryptographic algorithms, separated into strong and weak variants.
9+ *
910 * The names are normalized: upper-case, no spaces, dashes or underscores.
11+ *
1012 * 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
1220 */
1321private 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+
1439 predicate isWeakHashingAlgorithm ( string name ) {
40+ name = "HAVEL128" or
41+ name = "MD2" or
42+ name = "MD4" or
1543 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
1650 name = "SHA1"
1751 }
1852
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+
1964 predicate isWeakEncryptionAlgorithm ( string name ) {
2065 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"
2277 }
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 ( ) }
2387}
2488
2589private import AlgorithmNames
@@ -28,9 +92,20 @@ private import AlgorithmNames
2892 * A cryptographic algorithm.
2993 */
3094private 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
32100 MkEncryptionAlgorithm ( string name , boolean isWeak ) {
101+ isStrongEncryptionAlgorithm ( name ) and isWeak = false
102+ or
33103 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
34109 }
35110
36111/**
@@ -46,11 +121,13 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
46121 abstract string getName ( ) ;
47122
48123 /**
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.
50126 */
51127 bindingset [ name]
52128 predicate matchesName ( string name ) {
53129 exists ( name .regexpReplaceAll ( "[-_]" , "" ) .regexpFind ( "(?i)\\Q" + getName ( ) + "\\E" , _, _) )
130+ // name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
54131 }
55132
56133 /**
@@ -60,7 +137,7 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
60137}
61138
62139/**
63- * A hashing algorithm
140+ * A hashing algorithm such as `MD5` or `SHA512`.
64141 */
65142class HashingAlgorithm extends MkHashingAlgorithm , CryptographicAlgorithm {
66143 string name ;
@@ -74,7 +151,7 @@ class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
74151}
75152
76153/**
77- * An encryption algorithm
154+ * An encryption algorithm such as `DES` or `AES512`.
78155 */
79156class EncryptionAlgorithm extends MkEncryptionAlgorithm , CryptographicAlgorithm {
80157 string name ;
@@ -87,97 +164,100 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
87164 override predicate isWeak ( ) { isWeak = true }
88165}
89166
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+
90181/**
91182 * An application of a cryptographic algorithm.
92183 */
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+
94190 /**
95191 * Gets the applied algorithm.
96192 */
97193 abstract CryptographicAlgorithm getAlgorithm ( ) ;
98194}
99195
100196/**
197+ * Below are the cryptographic functions that have been implemented so far for this library.
101198 * Class that checks for use of Md5 package.
102199 */
103- class Md5 extends CryptographicOperation {
200+ class Md5 extends CryptographicOperation , DataFlow:: CallNode {
201+ Expr input ;
104202 CryptographicAlgorithm algorithm ;
105- SelectorExpr sel ;
106- CallExpr call ;
107203
108204 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
117207 }
118208
209+ override Expr getInput ( ) { result = input }
210+
119211 override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
120212}
121213
122214/**
123- * Class that checks for use of SHA1 package.
215+ * Class that checks for use of Sha1 package.
124216 */
125- class Sha1 extends CryptographicOperation {
217+ class Sha1 extends CryptographicOperation , DataFlow:: CallNode {
218+ Expr input ;
126219 CryptographicAlgorithm algorithm ;
127- SelectorExpr sel ;
128- CallExpr call ;
129220
130221 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
139224 }
140225
226+ override Expr getInput ( ) { result = input }
227+
141228 override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
142229}
143230
144231/**
145232 * Class that checks for use of Des package.
146233 */
147- class Des extends CryptographicOperation {
234+ class Des extends CryptographicOperation , DataFlow:: CallNode {
235+ Expr input ;
148236 CryptographicAlgorithm algorithm ;
149- SelectorExpr sel ;
150- CallExpr call ;
151237
152238 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
161241 }
162242
243+ override Expr getInput ( ) { result = input }
244+
163245 override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
164246}
165247
166248/**
167- * Class that checks for use of RC4 package.
249+ * Class that checks for use of Rc4 package.
168250 */
169- class Rc4 extends CryptographicOperation {
251+ class Rc4 extends CryptographicOperation , DataFlow:: CallNode {
252+ Expr input ;
170253 CryptographicAlgorithm algorithm ;
171- SelectorExpr sel ;
172- CallExpr call ;
173254
174255 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
180258 }
181259
260+ override Expr getInput ( ) { result = input }
261+
182262 override CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
183263}
0 commit comments