@@ -17,7 +17,6 @@ private import semmle.python.ApiGraphs
1717 * See https://pycryptodome.readthedocs.io/en/latest/
1818 */
1919private module CryptodomeModel {
20- // ---------------------------------------------------------------------------
2120 /**
2221 * A call to `Cryptodome.PublicKey.RSA.generate`/`Crypto.PublicKey.RSA.generate`
2322 *
@@ -101,4 +100,115 @@ private module CryptodomeModel {
101100 // Note: There is not really a key-size argument, since it's always specified by the curve.
102101 override DataFlow:: Node getKeySizeArg ( ) { none ( ) }
103102 }
103+
104+ /**
105+ * A cryptographic operation on an instance from the `Cipher` subpackage of `Cryptodome`/`Crypto`.
106+ */
107+ class CryptodomeGenericCipherOperation extends Cryptography:: CryptographicOperation:: Range ,
108+ DataFlow:: CallCfgNode {
109+ string methodName ;
110+ string cipherName ;
111+
112+ CryptodomeGenericCipherOperation ( ) {
113+ methodName in [
114+ "encrypt" , "decrypt" , "verify" , "update" , "hexverify" , "encrypt_and_digest" ,
115+ "decrypt_and_verify"
116+ ] and
117+ this =
118+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] )
119+ .getMember ( [ "Cipher" ] )
120+ .getMember ( cipherName )
121+ .getMember ( "new" )
122+ .getReturn ( )
123+ .getMember ( methodName )
124+ .getACall ( )
125+ }
126+
127+ override Cryptography:: CryptographicAlgorithm getAlgorithm ( ) { result .matchesName ( cipherName ) }
128+
129+ override DataFlow:: Node getAnInput ( ) {
130+ methodName = "encrypt" and
131+ result in [ this .getArg ( 0 ) , this .getArgByName ( [ "message" , "plaintext" ] ) ]
132+ or
133+ methodName = "decrypt" and
134+ result in [ this .getArg ( 0 ) , this .getArgByName ( "ciphertext" ) ]
135+ or
136+ // for the following methods, method signatures can be found in
137+ // https://pycryptodome.readthedocs.io/en/latest/src/cipher/modern.html
138+ methodName in [ "update" ] and
139+ result in [ this .getArg ( 0 ) , this .getArgByName ( "data" ) ]
140+ or
141+ methodName in [ "verify" ] and
142+ result in [ this .getArg ( 0 ) , this .getArgByName ( [ "mac_tag" , "received_mac_tag" ] ) ]
143+ or
144+ methodName in [ "hexverify" ] and
145+ result in [ this .getArg ( 0 ) , this .getArgByName ( "mac_tag_hex" ) ]
146+ or
147+ methodName in [ "encrypt_and_digest" ] and
148+ result in [ this .getArg ( 0 ) , this .getArgByName ( "plaintext" ) ]
149+ or
150+ methodName in [ "decrypt_and_verify" ] and
151+ result in [ this .getArg ( 0 ) , this .getArgByName ( "ciphertext" ) ]
152+ }
153+ }
154+
155+ /**
156+ * A cryptographic operation on an instance from the `Signature` subpackage of `Cryptodome`/`Crypto`.
157+ */
158+ class CryptodomeGenericSignatureOperation extends Cryptography:: CryptographicOperation:: Range ,
159+ DataFlow:: CallCfgNode {
160+ string methodName ;
161+ string signatureName ;
162+
163+ CryptodomeGenericSignatureOperation ( ) {
164+ methodName in [ "sign" , "verify" ] and
165+ this =
166+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] )
167+ .getMember ( [ "Signature" ] )
168+ .getMember ( signatureName )
169+ .getMember ( "new" )
170+ .getReturn ( )
171+ .getMember ( methodName )
172+ .getACall ( )
173+ }
174+
175+ override Cryptography:: CryptographicAlgorithm getAlgorithm ( ) {
176+ result .matchesName ( signatureName )
177+ }
178+
179+ override DataFlow:: Node getAnInput ( ) {
180+ methodName = "sign" and
181+ result in [ this .getArg ( 0 ) , this .getArgByName ( "msg_hash" ) ] // Cryptodome.Hash instance
182+ or
183+ methodName in [ "verify" ] and
184+ (
185+ result in [ this .getArg ( 0 ) , this .getArgByName ( [ "msg_hash" ] ) ] // Cryptodome.Hash instance
186+ or
187+ result in [ this .getArg ( 1 ) , this .getArgByName ( [ "signature" ] ) ]
188+ )
189+ }
190+ }
191+
192+ /**
193+ * A cryptographic operation on an instance from the `Hash` subpackage of `Cryptodome`/`Crypto`.
194+ */
195+ class CryptodomeGenericHashOperation extends Cryptography:: CryptographicOperation:: Range ,
196+ DataFlow:: CallCfgNode {
197+ string hashName ;
198+
199+ CryptodomeGenericHashOperation ( ) {
200+ exists ( API:: Node hashModule |
201+ hashModule =
202+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] ) .getMember ( [ "Hash" ] ) .getMember ( hashName )
203+ |
204+ this = hashModule .getMember ( "new" ) .getACall ( )
205+ or
206+ this = hashModule .getMember ( "new" ) .getReturn ( ) .getMember ( "update" ) .getACall ( )
207+ )
208+ }
209+
210+ override Cryptography:: CryptographicAlgorithm getAlgorithm ( ) { result .matchesName ( hashName ) }
211+
212+ override DataFlow:: Node getAnInput ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "data" ) ] }
213+ }
104214}
0 commit comments