@@ -4,12 +4,12 @@ import EVPCipherConsumers
44import OpenSSLAlgorithmGetter
55
66/**
7- * Given a literal `e`, converts this to a cipher family type.
8- * The literal must be a known literal representing a cipher algorithm.
9- * If the literal does not represent any known cipher algorithm,
10- * this predicate will not hold (i.e., it will not bind an unknown to an unknown cipher type)
7+ * Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
8+ * Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
119 */
12- predicate knownOpenSSLConstantToCipherFamilyType ( KnownOpenSSLAlgorithmConstant e , Crypto:: TCipherType type ) {
10+ predicate knownOpenSSLConstantToCipherFamilyType (
11+ KnownOpenSSLAlgorithmConstant e , Crypto:: TCipherType type
12+ ) {
1313 exists ( string name | e .getAlgType ( ) .toLowerCase ( ) .matches ( "%encryption" ) |
1414 name = e .getNormalizedName ( ) and
1515 (
@@ -90,16 +90,92 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends Crypto::CipherAlgorith
9090 }
9191
9292 override Crypto:: ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm ( ) {
93- none ( ) // TODO: provider defaults
93+ // if there is a block mode associated with the same element, then that's the block mode
94+ // note, if none are associated, we may need to parse if the cipher is a block cipher
95+ // to determine if this is an unknown vs not relevant.
96+ result = this
9497 }
9598
9699 override Crypto:: PaddingAlgorithmInstance getPaddingAlgorithm ( ) { none ( ) }
97100
98101 override string getRawAlgorithmName ( ) { result = this .( Literal ) .getValue ( ) .toString ( ) }
99102
100- override Crypto:: TCipherType getCipherFamily ( ) {
101- knownOpenSSLConstantToCipherFamilyType ( this , result )
103+ override Crypto:: TCipherType getCipherFamily ( ) {
104+ knownOpenSSLConstantToCipherFamilyType ( this , result )
102105 or
103106 not knownOpenSSLConstantToCipherFamilyType ( this , _) and result = Crypto:: OtherCipherType ( )
104107 }
105- }
108+ }
109+
110+ /**
111+ * Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
112+ * Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
113+ */
114+ predicate knownOpenSSLConstantToBlockModeFamilyType (
115+ KnownOpenSSLAlgorithmConstant e , Crypto:: TBlockCipherModeOperationType type
116+ ) {
117+ exists ( string name | e .getAlgType ( ) .toLowerCase ( ) .matches ( "block_mode" ) |
118+ name = e .getNormalizedName ( ) and
119+ (
120+ name .matches ( "CBC" ) and type instanceof Crypto:: CBC
121+ or
122+ name .matches ( "CFB%" ) and type instanceof Crypto:: CFB
123+ or
124+ name .matches ( "CTR" ) and type instanceof Crypto:: CTR
125+ or
126+ name .matches ( "GCM" ) and type instanceof Crypto:: GCM
127+ or
128+ name .matches ( "OFB" ) and type instanceof Crypto:: OFB
129+ or
130+ name .matches ( "XTS" ) and type instanceof Crypto:: XTS
131+ or
132+ name .matches ( "CCM" ) and type instanceof Crypto:: CCM
133+ or
134+ name .matches ( "GCM" ) and type instanceof Crypto:: GCM
135+ or
136+ name .matches ( "CCM" ) and type instanceof Crypto:: CCM
137+ or
138+ name .matches ( "ECB" ) and type instanceof Crypto:: ECB
139+ )
140+ )
141+ }
142+
143+ class KnownOpenSSLBlockModeConstantAlgorithmInstance extends Crypto:: ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLAlgorithmConstant
144+ {
145+ OpenSSLAlgorithmGetterCall getterCall ;
146+
147+ KnownOpenSSLBlockModeConstantAlgorithmInstance ( ) {
148+ // Not just any known value, but specifically a known cipher operation
149+ this .( KnownOpenSSLAlgorithmConstant ) .getAlgType ( ) .toLowerCase ( ) .matches ( "block_mode" ) and
150+ (
151+ // Two possibilities:
152+ // 1) The source is a literal and flows to a getter, then we know we have an instance
153+ // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
154+ // Possibility 1:
155+ this instanceof Literal and
156+ exists ( DataFlow:: Node src , DataFlow:: Node sink |
157+ // Sink is an argument to a CipherGetterCall
158+ sink = getterCall .( OpenSSLAlgorithmGetterCall ) .getValueArgNode ( ) and
159+ // Source is `this`
160+ src .asExpr ( ) = this and
161+ // This traces to a getter
162+ KnownOpenSSLAlgorithmToAlgorithmGetterFlow:: flow ( src , sink )
163+ )
164+ or
165+ // Possibility 2:
166+ this instanceof DirectGetterCall and getterCall = this
167+ )
168+ }
169+
170+ override Crypto:: TBlockCipherModeOperationType getModeType ( ) {
171+ knownOpenSSLConstantToBlockModeFamilyType ( this , result )
172+ or
173+ not knownOpenSSLConstantToBlockModeFamilyType ( this , _) and result = Crypto:: OtherMode ( )
174+ }
175+
176+ // NOTE: I'm not going to attempt to parse out the mode specific part, so returning
177+ // the same as the raw name for now.
178+ override string getRawModeAlgorithmName ( ) { result = this .( Literal ) .getValue ( ) .toString ( ) }
179+
180+ override string getRawAlgorithmName ( ) { result = this .getRawModeAlgorithmName ( ) }
181+ }
0 commit comments