Skip to content

Commit a01d5e6

Browse files
authored
Merge pull request #19528 from bdrodes/openssl_elliptic_curve_algorithm_instances_and_consumers
Crypto: Add OpenSSL elliptic curve algorithm instances and consumers
2 parents 8780399 + 55119cf commit a01d5e6

22 files changed

+164
-74
lines changed

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import cpp
2-
import semmle.code.cpp.dataflow.new.DataFlow
3-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
4-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
2+
private import experimental.quantum.Language
3+
private import semmle.code.cpp.dataflow.new.DataFlow
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
56

67
/**
78
* Traces 'known algorithms' to AVCs, specifically

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import OpenSSLAlgorithmInstanceBase
4-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
6-
import AlgToAVCFlow
2+
private import experimental.quantum.Language
3+
private import OpenSSLAlgorithmInstanceBase
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
6+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
7+
private import AlgToAVCFlow
78

89
/**
910
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type.

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import KnownAlgorithmConstants
4-
import Crypto::KeyOpAlg as KeyOpAlg
5-
import OpenSSLAlgorithmInstanceBase
6-
import PaddingAlgorithmInstance
7-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
8-
import AlgToAVCFlow
9-
import BlockAlgorithmInstance
2+
private import experimental.quantum.Language
3+
private import KnownAlgorithmConstants
4+
private import Crypto::KeyOpAlg as KeyOpAlg
5+
private import OpenSSLAlgorithmInstanceBase
6+
private import PaddingAlgorithmInstance
7+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
8+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
9+
private import AlgToAVCFlow
10+
private import BlockAlgorithmInstance
1011

1112
/**
1213
* Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import cpp
2+
private import experimental.quantum.Language
3+
private import KnownAlgorithmConstants
4+
private import OpenSSLAlgorithmInstanceBase
5+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
6+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
7+
private import AlgToAVCFlow
8+
9+
class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
10+
Crypto::EllipticCurveInstance instanceof KnownOpenSSLEllipticCurveAlgorithmConstant
11+
{
12+
OpenSSLAlgorithmValueConsumer getterCall;
13+
14+
KnownOpenSSLEllipticCurveConstantAlgorithmInstance() {
15+
// Two possibilities:
16+
// 1) The source is a literal and flows to a getter, then we know we have an instance
17+
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
18+
// Possibility 1:
19+
this instanceof Literal and
20+
exists(DataFlow::Node src, DataFlow::Node sink |
21+
// Sink is an argument to a CipherGetterCall
22+
sink = getterCall.getInputNode() and
23+
// Source is `this`
24+
src.asExpr() = this and
25+
// This traces to a getter
26+
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
27+
)
28+
or
29+
// Possibility 2:
30+
this instanceof DirectAlgorithmValueConsumer and getterCall = this
31+
}
32+
33+
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
34+
35+
override string getRawEllipticCurveName() { result = this.(Literal).getValue().toString() }
36+
37+
override Crypto::TEllipticCurveType getEllipticCurveType() {
38+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
39+
.getNormalizedName(), _, result)
40+
}
41+
42+
override int getKeySize() {
43+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
44+
.getNormalizedName(), result, _)
45+
}
46+
}

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import KnownAlgorithmConstants
4-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
5-
import AlgToAVCFlow
2+
private import experimental.quantum.Language
3+
private import KnownAlgorithmConstants
4+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
5+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
6+
private import AlgToAVCFlow
67

78
predicate knownOpenSSLConstantToHashFamilyType(
89
KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import cpp
2-
import experimental.quantum.OpenSSL.LibraryDetector
2+
private import experimental.quantum.OpenSSL.LibraryDetector
33

44
predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) {
55
resolveAlgorithmFromCall(e, normalizedName, algType)
@@ -67,6 +67,15 @@ class KnownOpenSSLHashAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
6767
}
6868
}
6969

70+
class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
71+
KnownOpenSSLEllipticCurveAlgorithmConstant() {
72+
exists(string algType |
73+
resolveAlgorithmFromExpr(this, _, algType) and
74+
algType.toLowerCase().matches("elliptic_curve")
75+
)
76+
}
77+
}
78+
7079
/**
7180
* Resolves a call to a 'direct algorithm getter', e.g., EVP_MD5()
7281
* This approach to fetching algorithms was used in OpenSSL 1.0.2.

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstanceBase.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import experimental.quantum.Language
2-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
1+
private import experimental.quantum.Language
2+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
33

44
abstract class OpenSSLAlgorithmInstance extends Crypto::AlgorithmInstance {
55
abstract OpenSSLAlgorithmValueConsumer getAVC();

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstances.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ import CipherAlgorithmInstance
33
import PaddingAlgorithmInstance
44
import BlockAlgorithmInstance
55
import HashAlgorithmInstance
6+
import EllipticCurveAlgorithmInstance

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import OpenSSLAlgorithmInstanceBase
4-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5-
import AlgToAVCFlow
6-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
2+
private import experimental.quantum.Language
3+
private import OpenSSLAlgorithmInstanceBase
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import AlgToAVCFlow
6+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
7+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
78

89
/**
910
* Given a `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import experimental.quantum.OpenSSL.LibraryDetector
4-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5-
import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
6-
import OpenSSLAlgorithmValueConsumerBase
2+
private import experimental.quantum.Language
3+
private import experimental.quantum.OpenSSL.LibraryDetector
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
6+
private import OpenSSLAlgorithmValueConsumerBase
77

88
abstract class CipherAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
99

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
4-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
2+
private import experimental.quantum.Language
3+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
4+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
55

66
// TODO: can self referential to itself, which is also an algorithm (Known algorithm)
77
/**
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import cpp
2+
private import experimental.quantum.Language
3+
private import experimental.quantum.OpenSSL.LibraryDetector
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
6+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
7+
8+
abstract class EllipticCurveValueConsumer extends OpenSSLAlgorithmValueConsumer { }
9+
10+
//https://docs.openssl.org/3.0/man3/EC_KEY_new/#name
11+
class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
12+
DataFlow::Node valueArgNode;
13+
DataFlow::Node resultNode;
14+
15+
EVPEllipticCurveAlgorithmConsumer() {
16+
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
17+
isPossibleOpenSSLFunction(this.(Call).getTarget()) and
18+
(
19+
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
20+
valueArgNode.asExpr() = this.(Call).getArgument(0)
21+
or
22+
this.(Call).getTarget().getName() in [
23+
"EC_KEY_new_by_curve_name_ex", "EVP_PKEY_CTX_set_ec_paramgen_curve_nid"
24+
] and
25+
valueArgNode.asExpr() = this.(Call).getArgument(2)
26+
)
27+
}
28+
29+
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
30+
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
31+
}
32+
33+
override DataFlow::Node getResultNode() { result = resultNode }
34+
35+
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
36+
}

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
// import EVPHashInitializer
2-
// import EVPHashOperation
3-
// import EVPHashAlgorithmSource
41
import cpp
5-
import experimental.quantum.Language
6-
import semmle.code.cpp.dataflow.new.DataFlow
7-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
8-
import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
9-
import experimental.quantum.OpenSSL.LibraryDetector
2+
private import experimental.quantum.Language
3+
private import semmle.code.cpp.dataflow.new.DataFlow
4+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
5+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
6+
private import experimental.quantum.OpenSSL.LibraryDetector
107

118
abstract class HashAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
129

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import experimental.quantum.Language
2-
import semmle.code.cpp.dataflow.new.DataFlow
1+
private import experimental.quantum.Language
2+
private import semmle.code.cpp.dataflow.new.DataFlow
33

44
abstract class OpenSSLAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
55
/**

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ import CipherAlgorithmValueConsumer
33
import DirectAlgorithmValueConsumer
44
import PaddingAlgorithmValueConsumer
55
import HashAlgorithmValueConsumer
6+
import EllipticCurveAlgorithmValueConsumer

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import cpp
2-
import experimental.quantum.Language
3-
import experimental.quantum.OpenSSL.LibraryDetector
4-
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5-
import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
6-
import OpenSSLAlgorithmValueConsumerBase
2+
private import experimental.quantum.Language
3+
private import experimental.quantum.OpenSSL.LibraryDetector
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
5+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
6+
private import OpenSSLAlgorithmValueConsumerBase
77

88
abstract class PaddingAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
99

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* Models cipher initialization for EVP cipher operations.
44
*/
55

6-
import experimental.quantum.Language
7-
import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
6+
private import experimental.quantum.Language
7+
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
88

99
module EncValToInitEncArgConfig implements DataFlow::ConfigSig {
1010
predicate isSource(DataFlow::Node source) { source.asExpr().getValue().toInt() in [0, 1] }

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import experimental.quantum.Language
2-
import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
3-
import EVPCipherInitializer
4-
import OpenSSLOperationBase
5-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
1+
private import experimental.quantum.Language
2+
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
3+
private import EVPCipherInitializer
4+
private import OpenSSLOperationBase
5+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
66

77
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
88
predicate isSource(DataFlow::Node source) {

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
* https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
33
*/
44

5-
import experimental.quantum.Language
6-
import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
7-
import experimental.quantum.OpenSSL.LibraryDetector
8-
import OpenSSLOperationBase
9-
import EVPHashInitializer
10-
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
5+
private import experimental.quantum.Language
6+
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
7+
private import experimental.quantum.OpenSSL.LibraryDetector
8+
private import OpenSSLOperationBase
9+
private import EVPHashInitializer
10+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
1111

1212
// import EVPHashConsumers
1313
abstract class EVP_Hash_Operation extends OpenSSLOperation, Crypto::HashOperationInstance {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import experimental.quantum.Language
1+
private import experimental.quantum.Language
22

33
abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Call {
44
abstract Expr getInputArg();

java/ql/lib/experimental/quantum/JCA.qll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,13 +1606,8 @@ module JCAModel {
16061606
else result = Crypto::OtherEllipticCurveType()
16071607
}
16081608

1609-
override string getKeySize() {
1610-
exists(int keySize |
1611-
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), keySize,
1612-
_)
1613-
|
1614-
result = keySize.toString()
1615-
)
1609+
override int getKeySize() {
1610+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), result, _)
16161611
}
16171612

16181613
EllipticCurveAlgorithmValueConsumer getConsumer() { result = consumer }

shared/quantum/codeql/quantum/experimental/Model.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
972972

973973
abstract TEllipticCurveType getEllipticCurveType();
974974

975-
abstract string getKeySize();
975+
abstract int getKeySize();
976976

977977
/**
978978
* The 'parsed' curve name, e.g., "P-256" or "secp256r1"
@@ -2613,7 +2613,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
26132613
or
26142614
// [ONLY_KNOWN]
26152615
key = "KeySize" and
2616-
value = instance.asAlg().getKeySize() and
2616+
value = instance.asAlg().getKeySize().toString() and
26172617
location = this.getLocation()
26182618
or
26192619
// [KNOWN_OR_UNKNOWN]

0 commit comments

Comments
 (0)