@@ -4,12 +4,12 @@ import EVPCipherConsumers
4
4
import OpenSSLAlgorithmGetter
5
5
6
6
/**
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').
11
9
*/
12
- predicate knownOpenSSLConstantToCipherFamilyType ( KnownOpenSSLAlgorithmConstant e , Crypto:: TCipherType type ) {
10
+ predicate knownOpenSSLConstantToCipherFamilyType (
11
+ KnownOpenSSLAlgorithmConstant e , Crypto:: TCipherType type
12
+ ) {
13
13
exists ( string name | e .getAlgType ( ) .toLowerCase ( ) .matches ( "%encryption" ) |
14
14
name = e .getNormalizedName ( ) and
15
15
(
@@ -90,16 +90,92 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends Crypto::CipherAlgorith
90
90
}
91
91
92
92
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
94
97
}
95
98
96
99
override Crypto:: PaddingAlgorithmInstance getPaddingAlgorithm ( ) { none ( ) }
97
100
98
101
override string getRawAlgorithmName ( ) { result = this .( Literal ) .getValue ( ) .toString ( ) }
99
102
100
- override Crypto:: TCipherType getCipherFamily ( ) {
101
- knownOpenSSLConstantToCipherFamilyType ( this , result )
103
+ override Crypto:: TCipherType getCipherFamily ( ) {
104
+ knownOpenSSLConstantToCipherFamilyType ( this , result )
102
105
or
103
106
not knownOpenSSLConstantToCipherFamilyType ( this , _) and result = Crypto:: OtherCipherType ( )
104
107
}
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