@@ -58,6 +58,10 @@ module JCAModel {
5858 Expr getProviderArg ( ) { result = this .getArgument ( 1 ) }
5959 }
6060
61+ class CipherDoFinalCall extends Call {
62+ CipherDoFinalCall ( ) { this .getCallee ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "doFinal" ) }
63+ }
64+
6165 /**
6266 * Data-flow configuration modelling flow from a cipher string literal to a `CipherGetInstanceCall` argument.
6367 */
@@ -92,6 +96,57 @@ module JCAModel {
9296 }
9397 }
9498
99+ // TODO: what if encrypt/decrypt mode isn't known
100+ private module CipherGetInstanceToFinalizeConfig implements DataFlow:: StateConfigSig {
101+ class FlowState = string ;
102+
103+ predicate isSource ( DataFlow:: Node src , FlowState state ) {
104+ state = "UNKNOWN" and
105+ src .asExpr ( ) instanceof CipherGetInstanceCall
106+ }
107+
108+ predicate isSink ( DataFlow:: Node sink , FlowState state ) {
109+ state in [ "ENCRYPT" , "DECRYPT" , "UNKNOWN" ] and
110+ exists ( CipherDoFinalCall c | c .getQualifier ( ) = sink .asExpr ( ) )
111+ }
112+
113+ predicate isAdditionalFlowStep (
114+ DataFlow:: Node node1 , FlowState state1 , DataFlow:: Node node2 , FlowState state2
115+ ) {
116+ state1 in [ "UNKNOWN" , "ENCRYPT" , "DECRYPT" ] and
117+ exists ( CipherInitCall c |
118+ c .getQualifier ( ) = node1 .asExpr ( ) and
119+ // TODO: not taking into consideration if the mode traces to this arg
120+ exists ( FieldAccess fa |
121+ c .getModeArg ( ) = fa and
122+ (
123+ fa .getField ( ) .getName ( ) = "ENCRYPT_MODE" and
124+ state2 = "ENCRYPT"
125+ or
126+ fa .getField ( ) .getName ( ) = "DECRYPT_MODE" and
127+ state2 = "DECRYPT"
128+ )
129+ )
130+ ) and
131+ node2 = node1
132+ }
133+ }
134+
135+ module CipherGetInstanceToFinalizeFlow =
136+ DataFlow:: GlobalWithState< CipherGetInstanceToFinalizeConfig > ;
137+
138+ // TODO: what if the mode is UNKNOWN?
139+ class CipherEncryptionOperation extends Crypto:: EncryptionOperationInstance instanceof Call {
140+ CipherEncryptionOperation ( ) {
141+ exists ( CipherGetInstanceToFinalizeFlow:: PathNode sink , CipherDoFinalCall c |
142+ CipherGetInstanceToFinalizeFlow:: flowPath ( _, sink ) and
143+ sink .getNode ( ) .asExpr ( ) = c .getQualifier ( ) and
144+ sink .getState ( ) = "ENCRYPT" and
145+ this = c
146+ )
147+ }
148+ }
149+
95150 /**
96151 * A block cipher mode of operation, where the mode is specified in the ALG or ALG/MODE/PADDING format.
97152 *
@@ -272,6 +327,8 @@ module JCAModel {
272327 class CipherInitCall extends MethodCall {
273328 CipherInitCall ( ) { this .getCallee ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "init" ) }
274329
330+ // TODO: this doesn't account for tracing the mode to this arg if expending this arg to have
331+ // the actual mode directly
275332 Expr getModeArg ( ) { result = this .getArgument ( 0 ) }
276333
277334 Expr getKey ( ) {
0 commit comments