Skip to content

Commit 729467c

Browse files
committed
Crypto: Separate out CTX parameter initialization, and add additional initializer subclasses.
1 parent 4f2045b commit 729467c

File tree

5 files changed

+128
-27
lines changed

5 files changed

+128
-27
lines changed

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,37 @@ class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
2727
}
2828
}
2929

30+
/**
31+
* Instances from https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/
32+
* where the digest is directly consumed by name.
33+
* In these cases, the operation is not yet performed, but there is
34+
* these functions are treated as 'initializers' and track the algorithm through
35+
* `EvpInitializer` mechanics, i.e., the resultNode is considered 'none'
36+
*/
37+
class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
38+
DataFlow::Node valueArgNode;
39+
40+
EvpPkeySetCtxALgorithmConsumer() {
41+
this.(Call).getTarget().getName() in [
42+
"EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_oaep_md_name",
43+
"EVP_PKEY_CTX_set_dsa_paramgen_md_props"
44+
] and
45+
valueArgNode.asExpr() = this.(Call).getArgument(1)
46+
}
47+
48+
override DataFlow::Node getResultNode() { none() }
49+
50+
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
51+
52+
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
53+
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
54+
}
55+
}
56+
3057
/**
3158
* The EVP digest algorithm getters
3259
* https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
60+
* https://docs.openssl.org/3.0/man3/EVP_DigestSignInit/#name
3361
*/
3462
class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
3563
DataFlow::Node valueArgNode;
@@ -43,8 +71,11 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
4371
] and
4472
valueArgNode.asExpr() = this.(Call).getArgument(0)
4573
or
46-
this.(Call).getTarget().getName() = "EVP_MD_fetch" and
74+
this.(Call).getTarget().getName() in ["EVP_MD_fetch"] and
4775
valueArgNode.asExpr() = this.(Call).getArgument(1)
76+
or
77+
this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and
78+
valueArgNode.asExpr() = this.(Call).getArgument(2)
4879
)
4980
}
5081

cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPKeyGenOperation.qll

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,32 +50,6 @@ class EVPNewKeyCtx extends EvpKeyInitializer {
5050
//TODO: do we specify the algorithm from the key as well?
5151
}
5252

53-
/**
54-
* A call to `EVP_PKEY_CTX_set_rsa_keygen_bits`.
55-
* This sets the key size for RSA key generation.
56-
*/
57-
class EVPSetRSAKeyKeyBits extends EvpKeySizeInitializer {
58-
EVPSetRSAKeyKeyBits() { this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_keygen_bits" }
59-
60-
override Expr getKeySizeArg() { result = this.(Call).getArgument(1) }
61-
62-
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
63-
}
64-
65-
/**
66-
* A call to `EVP_PKEY_CTX_set_dsa_paramgen_bits`.
67-
* This sets the key size for DSA key generation.
68-
*/
69-
class EVPSetDSAKeyParamGenBits extends EvpKeySizeInitializer {
70-
EVPSetDSAKeyParamGenBits() {
71-
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_dsa_paramgen_bits"
72-
}
73-
74-
override Expr getKeySizeArg() { result = this.(Call).getArgument(1) }
75-
76-
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
77-
}
78-
7953
class EVPKeyGenOperation extends EVPFinal, Crypto::KeyGenerationOperationInstance {
8054
DataFlow::Node keyResultNode;
8155

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Initializers from https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/
3+
*/
4+
5+
import cpp
6+
private import experimental.quantum.OpenSSL.CtxFlow
7+
private import OpenSSLOperationBase
8+
9+
class EvpCtxSetAlgorithmInitializer extends EvpAlgorithmInitializer {
10+
EvpCtxSetAlgorithmInitializer() {
11+
this.(Call).getTarget().getName() in [
12+
"EVP_PKEY_CTX_set_signature_md", "EVP_PKEY_CTX_set_rsa_mgf1_md_name",
13+
"EVP_PKEY_CTX_set_rsa_mgf1_md", "EVP_PKEY_CTX_set_rsa_oaep_md_name",
14+
"EVP_PKEY_CTX_set_rsa_oaep_md", "EVP_PKEY_CTX_set_dsa_paramgen_md",
15+
"EVP_PKEY_CTX_set_dsa_paramgen_md_props", "EVP_PKEY_CTX_set_dh_kdf_md",
16+
"EVP_PKEY_CTX_set_ec_paramgen_curve_nid", "EVP_PKEY_CTX_set_ecdh_kdf_md"
17+
]
18+
}
19+
20+
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
21+
22+
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
23+
}
24+
25+
class EvpCtxSetKeySizeInitializer extends EvpKeySizeInitializer {
26+
Expr arg;
27+
28+
EvpCtxSetKeySizeInitializer() {
29+
this.(Call).getTarget().getName() in [
30+
"EVP_PKEY_CTX_set_rsa_keygen_bits", "EVP_PKEY_CTX_set_dsa_paramgen_bits"
31+
] and
32+
arg = this.(Call).getArgument(1)
33+
or
34+
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" and
35+
arg = this.(Call).getArgument(2)
36+
}
37+
38+
override Expr getKeySizeArg() { result = arg }
39+
40+
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
41+
}
42+
43+
class EvpCtxSetKeyInitializer extends EvpKeyInitializer {
44+
EvpCtxSetKeyInitializer() { this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" }
45+
46+
override Expr getKeyArg() { result = this.(Call).getArgument(1) }
47+
48+
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
49+
}
50+
51+
class EvpCtxSetPaddingInitializer extends EvpPaddingInitializer {
52+
EvpCtxSetPaddingInitializer() {
53+
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_padding"
54+
}
55+
56+
override Expr getPaddingArg() { result = this.(Call).getArgument(1) }
57+
58+
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
59+
}
60+
61+
class EvpCtxSetSaltLengthInitializer extends EvpSaltLengthInitializer {
62+
EvpCtxSetSaltLengthInitializer() {
63+
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_pss_saltlen"
64+
}
65+
66+
override Expr getSaltLengthArg() { result = this.(Call).getArgument(1) }
67+
68+
override CtxPointerSource getContextArg() { result = this.(Call).getArgument(0) }
69+
}

cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
private import experimental.quantum.Language
22
private import experimental.quantum.OpenSSL.CtxFlow
33
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
4+
// Importing these intializers here to ensure the are part of any model that is
5+
// using OpenSSLOperationBase. This futher ensures that initializers are tied to opeartions
6+
// even if only importing the operation by itself.
7+
import EVPPKeyCtxInitializer
48

59
/**
610
* A class for all OpenSSL operations.
@@ -44,6 +48,12 @@ abstract class EvpKeySizeInitializer extends EvpInitializer {
4448
abstract Expr getKeySizeArg();
4549
}
4650

51+
/**
52+
* Unlike many initializers, this returns the key operation subtype immediately, not the arg.
53+
* This is a design choice in the overall model, in that the model will not do any tracking
54+
* for the subtype argument in any automated fashion. Users are currently expected to find the
55+
* subtype argument manually and associate a type directly.
56+
*/
4757
abstract class EvpKeyOperationSubtypeInitializer extends EvpInitializer {
4858
abstract Crypto::KeyOperationSubtype getKeyOperationSubtype();
4959
}
@@ -66,6 +76,22 @@ abstract class EvpIVInitializer extends EvpInitializer {
6676
abstract Expr getIVArg();
6777
}
6878

79+
abstract class EvpPaddingInitializer extends EvpInitializer {
80+
/**
81+
* Gets the padding mode argument.
82+
* e.g., `EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING)` argument 1 (0-based)
83+
*/
84+
abstract Expr getPaddingArg();
85+
}
86+
87+
abstract class EvpSaltLengthInitializer extends EvpInitializer {
88+
/**
89+
* Gets the salt length argument.
90+
* e.g., `EVP_PKEY_CTX_set_scrypt_salt_len(ctx, 16)` argument 1 (0-based)
91+
*/
92+
abstract Expr getSaltLengthArg();
93+
}
94+
6995
/**
7096
* A Call to an "update" function.
7197
* These are not operations in the sense of Crypto::OperationInstance,

cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperations.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ import EVPHashOperation
44
import ECKeyGenOperation
55
import EVPSignatureOperation
66
import EVPKeyGenOperation
7+
import EVPPKeyCtxInitializer

0 commit comments

Comments
 (0)