diff --git a/cpp/ql/lib/experimental/quantum/Language.qll b/cpp/ql/lib/experimental/quantum/Language.qll index ebc246291a38..168c25cdfaa0 100644 --- a/cpp/ql/lib/experimental/quantum/Language.qll +++ b/cpp/ql/lib/experimental/quantum/Language.qll @@ -13,7 +13,9 @@ module CryptoInput implements InputSig { LocatableElement dfn_to_element(DataFlow::Node node) { result = node.asExpr() or result = node.asParameter() or - result = node.asVariable() + result = node.asVariable() or + result = node.asDefiningArgument() + // TODO: do we need asIndirectExpr()? } string locationToFileBaseNameAndLineNumberString(Location location) { @@ -90,7 +92,7 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig { module GenericDataSourceFlow = TaintTracking::Global; private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal { - ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral } + ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral } override DataFlow::Node getOutputNode() { result.asExpr() = this } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll index c2df3989f811..d46c2f691916 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll @@ -12,13 +12,15 @@ private import PaddingAlgorithmInstance * overlap with the known algorithm constants. * Padding consumers (specific padding consumers) are excluded from the set of sinks. */ -module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig { +module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof KnownOpenSSLAlgorithmConstant + source.asExpr() instanceof KnownOpenSslAlgorithmExpr and + // No need to flow direct operations to AVCs + not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall } predicate isSink(DataFlow::Node sink) { - exists(OpenSSLAlgorithmValueConsumer c | + exists(OpenSslAlgorithmValueConsumer c | c.getInputNode() = sink and // exclude padding algorithm consumers, since // these consumers take in different constant values @@ -43,11 +45,11 @@ module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow:: } } -module KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow = - DataFlow::Global; +module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow = + DataFlow::Global; module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSSLPaddingLiteral } + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral } predicate isSink(DataFlow::Node sink) { exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink) @@ -61,8 +63,8 @@ module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow = DataFlow::Global; -class OpenSSLAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep { - OpenSSLAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) } +class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep { + OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) } override DataFlow::Node getOutput() { exists(AlgorithmPassthroughCall c | c.getInNode() = this and c.getOutNode() = result) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll index 995b72a437ed..ba5f65a2203f 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll @@ -7,14 +7,14 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor private import AlgToAVCFlow /** - * Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type. + * Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type. * Does not bind if there is no mapping (no mapping to 'unknown' or 'other'). */ -predicate knownOpenSSLConstantToBlockModeFamilyType( - KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type +predicate knownOpenSslConstantToBlockModeFamilyType( + KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type ) { exists(string name | - name = e.getNormalizedName() and + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and ( name.matches("CBC") and type instanceof Crypto::CBC or @@ -39,34 +39,35 @@ predicate knownOpenSSLConstantToBlockModeFamilyType( ) } -class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, - Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmConstant +class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSslBlockModeAlgorithmExpr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; - KnownOpenSSLBlockModeConstantAlgorithmInstance() { + KnownOpenSslBlockModeConstantAlgorithmInstance() { // Two possibilities: // 1) The source is a literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // Possibility 1: - this instanceof Literal and + this instanceof OpenSslAlgorithmLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall - sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and + sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and getterCall = this + this instanceof OpenSslAlgorithmCall and + getterCall = this } override Crypto::TBlockCipherModeOfOperationType getModeType() { - knownOpenSSLConstantToBlockModeFamilyType(this, result) + knownOpenSslConstantToBlockModeFamilyType(this, result) or - not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode() + not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode() } // NOTE: I'm not going to attempt to parse out the mode specific part, so returning @@ -77,5 +78,5 @@ class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmIns result = this.(Call).getTarget().getName() } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll index 77251761040d..0fb8ecf95398 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll @@ -10,14 +10,14 @@ private import AlgToAVCFlow private import BlockAlgorithmInstance /** - * Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type. + * Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type. * Does not bind if there is no mapping (no mapping to 'unknown' or 'other'). */ -predicate knownOpenSSLConstantToCipherFamilyType( - KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type +predicate knownOpenSslConstantToCipherFamilyType( + KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type ) { exists(string name | - name = e.getNormalizedName() and + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and ( name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES()) or @@ -64,28 +64,29 @@ predicate knownOpenSSLConstantToCipherFamilyType( ) } -class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, - Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmConstant +class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslCipherAlgorithmExpr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; - KnownOpenSSLCipherConstantAlgorithmInstance() { + KnownOpenSslCipherConstantAlgorithmInstance() { // Two possibilities: // 1) The source is a literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // Possibility 1: - this instanceof Literal and + this instanceof OpenSslAlgorithmLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall - sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and + sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and getterCall = this + this instanceof OpenSslAlgorithmCall and + getterCall = this } override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { @@ -109,17 +110,17 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstan } override int getKeySizeFixed() { - this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = result + this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result } override Crypto::KeyOpAlg::Algorithm getAlgorithmType() { - knownOpenSSLConstantToCipherFamilyType(this, result) + knownOpenSslConstantToCipherFamilyType(this, result) or - not knownOpenSSLConstantToCipherFamilyType(this, _) and + not knownOpenSslConstantToCipherFamilyType(this, _) and result = Crypto::KeyOpAlg::TUnknownKeyOperationAlgorithmType() } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { // TODO: trace to any key size initializer, symmetric and asymmetric diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll index bebca15d4773..78cba4962864 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll @@ -6,31 +6,32 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer private import AlgToAVCFlow -class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, - Crypto::EllipticCurveInstance instanceof KnownOpenSSLEllipticCurveAlgorithmConstant +class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::EllipticCurveInstance instanceof KnownOpenSslEllipticCurveAlgorithmExpr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; - KnownOpenSSLEllipticCurveConstantAlgorithmInstance() { + KnownOpenSslEllipticCurveConstantAlgorithmInstance() { // Two possibilities: // 1) The source is a literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // Possibility 1: - this instanceof Literal and + this instanceof OpenSslAlgorithmLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and getterCall = this + this instanceof OpenSslAlgorithmCall and + getterCall = this } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } override string getRawEllipticCurveName() { result = this.(Literal).getValue().toString() @@ -43,11 +44,11 @@ class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorith } override string getParsedEllipticCurveName() { - result = this.(KnownOpenSSLEllipticCurveAlgorithmConstant).getNormalizedName() + result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() } override int getKeySize() { - Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant) + Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr) .getNormalizedName(), result, _) } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll index ca1882f3b6e3..0cc8e24f0a6c 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll @@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase private import AlgToAVCFlow -predicate knownOpenSSLConstantToHashFamilyType( - KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type +predicate knownOpenSslConstantToHashFamilyType( + KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type ) { exists(string name | - name = e.getNormalizedName() and + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and ( name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B or @@ -29,7 +29,7 @@ predicate knownOpenSSLConstantToHashFamilyType( or name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1 or - name.matches("SHA+%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2 + name.matches("SHA_%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2 or name.matches("SHA3-%") and type instanceof Crypto::SHA3 or @@ -44,36 +44,37 @@ predicate knownOpenSSLConstantToHashFamilyType( ) } -class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, - Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmConstant +class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::HashAlgorithmInstance instanceof KnownOpenSslHashAlgorithmExpr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; - KnownOpenSSLHashConstantAlgorithmInstance() { + KnownOpenSslHashConstantAlgorithmInstance() { // Two possibilities: // 1) The source is a literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // Possibility 1: - this instanceof Literal and + this instanceof OpenSslAlgorithmLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall - sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and + sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and getterCall = this + this instanceof OpenSslAlgorithmCall and + getterCall = this } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } override Crypto::THashType getHashFamily() { - knownOpenSSLConstantToHashFamilyType(this, result) + knownOpenSslConstantToHashFamilyType(this, result) or - not knownOpenSSLConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType() + not knownOpenSslConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType() } override string getRawHashAlgorithmName() { @@ -83,6 +84,6 @@ class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance } override int getFixedDigestLength() { - this.(KnownOpenSSLHashAlgorithmConstant).getExplicitDigestLength() = result + this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll index c72b9a8e9254..1addda3a9eff 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll @@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase private import AlgToAVCFlow -predicate knownOpenSSLConstantToKeyAgreementFamilyType( - KnownOpenSSLKeyAgreementAlgorithmConstant e, Crypto::TKeyAgreementType type +predicate knownOpenSslConstantToKeyAgreementFamilyType( + KnownOpenSslKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type ) { exists(string name | - name = e.getNormalizedName() and + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and ( name = "ECDH" and type = Crypto::ECDH() or @@ -22,36 +22,37 @@ predicate knownOpenSSLConstantToKeyAgreementFamilyType( ) } -class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, - Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSSLKeyAgreementAlgorithmConstant +class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSslKeyAgreementAlgorithmExpr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; - KnownOpenSSLHashConstantAlgorithmInstance() { + KnownOpenSslKeyAgreementConstantAlgorithmInstance() { // Two possibilities: // 1) The source is a literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // Possibility 1: - this instanceof Literal and + this instanceof OpenSslAlgorithmLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and getterCall = this + this instanceof OpenSslAlgorithmCall and + getterCall = this } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } override Crypto::TKeyAgreementType getKeyAgreementType() { - knownOpenSSLConstantToKeyAgreementFamilyType(this, result) + knownOpenSslConstantToKeyAgreementFamilyType(this, result) or - not knownOpenSSLConstantToKeyAgreementFamilyType(this, _) and + not knownOpenSslConstantToKeyAgreementFamilyType(this, _) and result = Crypto::OtherKeyAgreementType() } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll index 7b2b9549d001..9d60547a45ad 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll @@ -1,39 +1,116 @@ import cpp import experimental.quantum.OpenSSL.GenericSourceCandidateLiteral -predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) { - resolveAlgorithmFromCall(e, normalizedName, algType) - or - resolveAlgorithmFromLiteral(e, normalizedName, algType) +predicate resolveAlgorithmFromExpr( + KnownOpenSslAlgorithmExpr e, string normalizedName, string algType +) { + normalizedName = e.getNormalizedName() and + algType = e.getAlgType() } -class KnownOpenSSLAlgorithmConstant extends Expr { - KnownOpenSSLAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, _) } +/** + * An expression that resolves to a known OpenSsl algorithm constant. + * This can be a literal, a call to a known OpenSsl algorithm constant getter, + * or a call to an operation that directly operates on a known algorithm. + */ +abstract class KnownOpenSslAlgorithmExpr extends Expr { + abstract string getNormalizedName(); + + abstract string getAlgType(); +} + +class OpenSslAlgorithmLiteral extends KnownOpenSslAlgorithmExpr instanceof Literal { + string normalizedName; + string algType; + + OpenSslAlgorithmLiteral() { resolveAlgorithmFromLiteral(this, normalizedName, algType) } - string getNormalizedName() { resolveAlgorithmFromExpr(this, result, _) } + override string getNormalizedName() { result = normalizedName } - string getAlgType() { resolveAlgorithmFromExpr(this, _, result) } + override string getAlgType() { result = algType } } -class KnownOpenSSLCipherAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { +/** + * A call to either an OpenSsl algorithm constant 'getter', e.g., EVP_MD5() + * or call to an operation that directly operates on a known algorithm, e.g., AES_encrypt + */ +abstract class OpenSslAlgorithmCall extends KnownOpenSslAlgorithmExpr instanceof Call { } + +/** + * A call to a 'direct algorithm getter', e.g., EVP_MD5() + * This approach to fetching algorithms was used in OpenSsl 1.0.2. + * The strategy for resolving these calls is to parse the target name + * and resolve the name as though it were a known literal. + * There are a few exceptions where the name doesn't directly match the + * known literal set. If that occurs, users must add the name to the + * set of aliases. E.g., EVP_dss() and EVP_dss1() needed such mappings + * alias = "dss" and target = "dsa" + * or + * alias = "dss1" and target = "dsaWithSHA1" + */ +class OpenSslDirectAlgorithmFetchCall extends OpenSslAlgorithmCall { + string normalizedName; string algType; - KnownOpenSSLCipherAlgorithmConstant() { - resolveAlgorithmFromExpr(this, _, algType) and + OpenSslDirectAlgorithmFetchCall() { + //ASSUMPTION: these cases will have operands for the call + not exists(this.(Call).getAnArgument()) and + exists(string name, string parsedTargetName | + parsedTargetName = + this.(Call).getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and + name = resolveAlgorithmAlias(parsedTargetName) and + knownOpenSslAlgorithmLiteral(name, _, normalizedName, algType) + ) + } + + override string getNormalizedName() { result = normalizedName } + + override string getAlgType() { result = algType } +} + +/** + * A call to an OpenSsl operation that directly operates on a known algorithm. + * An algorithm construct is not generated for these calls, rather, the operation + * is directly performed, and the algorithm is inferred by the operation itself. + */ +class OpenSslDirectAlgorithmOperationCall extends OpenSslAlgorithmCall { + string normalizedName; + string algType; + + OpenSslDirectAlgorithmOperationCall() { + //TODO: this set will have to be exhaustive, and for each operation + //further modeling will be necessary for each case to map the APIs operands + //ASSUMPTION: these cases must have operands for the call + exists(this.(Call).getAnArgument()) and + //TODO: Each case would be enumerated here. Will likely need an exhaustive mapping much like + // for known constants. + knownOpenSslAlgorithmOperationCall(this, normalizedName, algType) + } + + override string getNormalizedName() { result = normalizedName } + + override string getAlgType() { result = algType } +} + +class KnownOpenSslCipherAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + string algType; + + KnownOpenSslCipherAlgorithmExpr() { + algType = this.(KnownOpenSslAlgorithmExpr).getAlgType() and algType.matches("%ENCRYPTION") } int getExplicitKeySize() { exists(string name | - name = this.getNormalizedName() and + name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and resolveAlgorithmFromExpr(this, name, algType) and result = name.regexpCapture(".*-(\\d*)", 1).toInt() ) } } -class KnownOpenSSLPaddingAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLPaddingAlgorithmConstant() { +class KnownOpenSslPaddingAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslPaddingAlgorithmExpr() { exists(string algType | resolveAlgorithmFromExpr(this, _, algType) and algType.matches("%PADDING") @@ -41,55 +118,62 @@ class KnownOpenSSLPaddingAlgorithmConstant extends KnownOpenSSLAlgorithmConstant } } -class KnownOpenSSLBlockModeAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLBlockModeAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") } +class KnownOpenSslBlockModeAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslBlockModeAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") } } -class KnownOpenSSLHashAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLHashAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "HASH") } +class KnownOpenSslHashAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslHashAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "HASH") } int getExplicitDigestLength() { exists(string name | - name = this.getNormalizedName() and + name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and resolveAlgorithmFromExpr(this, name, "HASH") and result = name.regexpCapture(".*-(\\d*)$", 1).toInt() ) } } -class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLEllipticCurveAlgorithmConstant() { - resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE") - } +class KnownOpenSslMacAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "MAC") } } -class KnownOpenSSLSignatureAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLSignatureAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") } +class KnownOpenSslHMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr { + KnownOpenSslHMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "HMAC", "MAC") } + + /** + * Gets an explicit cipher algorithm for this MAC algorithm. + * This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256" + */ + KnownOpenSslHashAlgorithmExpr getExplicitHashAlgorithm() { result = this } } -class KnownOpenSSLKeyAgreementAlgorithmConstant extends KnownOpenSSLAlgorithmConstant { - KnownOpenSSLKeyAgreementAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") } +class KnownOpenSslCMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr { + KnownOpenSslCMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "CMAC", "MAC") } + + /** + * Gets an explicit cipher algorithm for this MAC algorithm. + * This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256" + */ + KnownOpenSslCipherAlgorithmExpr getExplicitCipherAlgorithm() { result = this } } -/** - * Resolves a call to a 'direct algorithm getter', e.g., EVP_MD5() - * This approach to fetching algorithms was used in OpenSSL 1.0.2. - * The strategy for resolving these calls is to parse the target name - * and resolve the name as though it were a known literal. - * There are a few exceptions where the name doesn't directly match the - * known literal set. If that occurs, users must add the name to the - * set of aliases. E.g., EVP_dss() and EVP_dss1() needed such mappings - * alias = "dss" and target = "dsa" - * or - * alias = "dss1" and target = "dsaWithSHA1" - */ -predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) { - exists(string name, string parsedTargetName | - parsedTargetName = - c.getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and - name = resolveAlgorithmAlias(parsedTargetName) and - knownOpenSSLAlgorithmLiteral(name, _, normalized, algType) - ) +class KnownOpenSslEllipticCurveAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslEllipticCurveAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE") } +} + +class KnownOpenSslSignatureAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslSignatureAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") } +} + +class KnownOpenSslKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr { + KnownOpenSslKeyAgreementAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") } +} + +predicate knownOpenSslAlgorithmOperationCall(Call c, string normalized, string algType) { + c.getTarget().getName() in ["EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new"] and + normalized = "RSA" and + algType = "ASYMMETRIC_ENCRYPTION" } /** @@ -98,13 +182,13 @@ predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) { * If this predicate does not hold, then `e` can be interpreted as being of `UNKNOWN` type. */ predicate resolveAlgorithmFromLiteral( - OpenSSLGenericSourceCandidateLiteral e, string normalized, string algType + OpenSslGenericSourceCandidateLiteral e, string normalized, string algType ) { - knownOpenSSLAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType) + knownOpenSslAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType) or exists(string name | name = resolveAlgorithmAlias(e.getValue()) and - knownOpenSSLAlgorithmLiteral(name, _, normalized, algType) + knownOpenSslAlgorithmLiteral(name, _, normalized, algType) ) } @@ -115,7 +199,7 @@ string resolveAlgorithmAlias(string name) { result = getAlgorithmAlias(lower) or // or the name is itself a known algorithm - knownOpenSSLAlgorithmLiteral(lower, _, _, _) and result = lower + knownOpenSslAlgorithmLiteral(lower, _, _, _) and result = lower ) } @@ -138,9 +222,9 @@ predicate customAliases(string target, string alias) { } /** - * A hard-coded mapping of known algorithm aliases in OpenSSL. + * A hard-coded mapping of known algorithm aliases in OpenSsl. * This was derived by applying the same kind of logic foun din `customAliases` to the - * OpenSSL code base directly. + * OpenSsl code base directly. * * The `target` and `alias` are converted to lowercase to be of a standard form. */ @@ -247,7 +331,7 @@ predicate defaultAliases(string target, string alias) { * `normalized` is the normalized name of the algorithm (e.g., "AES128" for "aes-128-cbc") * `algType` is the type of algorithm (e.g., "SYMMETRIC_ENCRYPTION") */ -predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, string algType) { +predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized, string algType) { name = "dhKeyAgreement" and nid = 28 and normalized = "DH" and algType = "KEY_AGREEMENT" or name = "x9.42 dh" and nid = 29 and normalized = "DH" and algType = "KEY_AGREEMENT" @@ -886,6 +970,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "id-alg-dh-sig-hmac-sha1" and nid = 325 and normalized = "DH" and algType = "KEY_AGREEMENT" or + name = "id-alg-dh-sig-hmac-sha1" and nid = 325 and normalized = "HMAC" and algType = "MAC" + or name = "aes-128-ofb" and nid = 420 and normalized = "AES-128" and algType = "SYMMETRIC_ENCRYPTION" or name = "aes-128-ofb" and nid = 420 and normalized = "OFB" and algType = "BLOCK_MODE" @@ -1064,8 +1150,12 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "hmac-md5" and nid = 780 and normalized = "MD5" and algType = "HASH" or + name = "hmac-md5" and nid = 780 and normalized = "HMAC" and algType = "HASH" + or name = "hmac-sha1" and nid = 781 and normalized = "SHA1" and algType = "HASH" or + name = "hmac-sha1" and nid = 781 and normalized = "HMAC" and algType = "MAC" + or name = "md_gost94" and nid = 809 and normalized = "GOST94" and algType = "HASH" or name = "gost94" and nid = 812 and normalized = "GOST94" and algType = "HASH" @@ -1140,10 +1230,14 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "rc4-hmac-md5" and nid = 915 and normalized = "MD5" and algType = "HASH" or + name = "rc4-hmac-md5" and nid = 915 and normalized = "HMAC" and algType = "MAC" + or name = "rc4-hmac-md5" and nid = 915 and normalized = "RC4" and algType = "SYMMETRIC_ENCRYPTION" or name = "aes-128-cbc-hmac-sha1" and nid = 916 and normalized = "SHA1" and algType = "HASH" or + name = "aes-128-cbc-hmac-sha1" and nid = 916 and normalized = "HMAC" and algType = "MAC" + or name = "aes-128-cbc-hmac-sha1" and nid = 916 and normalized = "AES-128" and @@ -1153,6 +1247,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "aes-192-cbc-hmac-sha1" and nid = 917 and normalized = "SHA1" and algType = "HASH" or + name = "aes-192-cbc-hmac-sha1" and nid = 917 and normalized = "HMAC" and algType = "MAC" + or name = "aes-192-cbc-hmac-sha1" and nid = 917 and normalized = "AES-192" and @@ -1167,6 +1263,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "aes-256-cbc-hmac-sha1" and nid = 918 and normalized = "CBC" and algType = "BLOCK_MODE" or + name = "aes-256-cbc-hmac-sha1" and nid = 918 and normalized = "HMAC" and algType = "MAC" + or name = "aes-128-cbc-hmac-sha256" and nid = 948 and normalized = "SHA-256" and algType = "HASH" or name = "aes-128-cbc-hmac-sha256" and @@ -1178,6 +1276,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "aes-192-cbc-hmac-sha256" and nid = 949 and normalized = "SHA-256" and algType = "HASH" or + name = "aes-192-cbc-hmac-sha256" and nid = 949 and normalized = "HMAC" and algType = "MAC" + or name = "aes-192-cbc-hmac-sha256" and nid = 949 and normalized = "AES-192" and @@ -1187,6 +1287,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "aes-256-cbc-hmac-sha256" and nid = 950 and normalized = "SHA-256" and algType = "HASH" or + name = "aes-256-cbc-hmac-sha256" and nid = 950 and normalized = "HMAC" and algType = "MAC" + or name = "aes-256-cbc-hmac-sha256" and nid = 950 and normalized = "AES-256" and @@ -1226,6 +1328,11 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, normalized = "CAMELLIA-128" and algType = "SYMMETRIC_ENCRYPTION" or + name = "camellia-128-cmac" and + nid = 964 and + normalized = "CMAC" and + algType = "MAC" + or name = "camellia-192-gcm" and nid = 965 and normalized = "CAMELLIA-192" and @@ -1278,6 +1385,11 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, normalized = "CAMELLIA-256" and algType = "SYMMETRIC_ENCRYPTION" or + name = "camellia-256-cmac" and + nid = 972 and + normalized = "CMAC" and + algType = "MAC" + or name = "id-scrypt" and nid = 973 and normalized = "SCRYPT" and algType = "KEY_DERIVATION" or name = "gost89-cnt-12" and @@ -1291,11 +1403,13 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "md_gost12_512" and nid = 983 and normalized = "GOST" and algType = "HASH" or + // TODO: re-evaluate: this is a signing algorithm using hashing and curves name = "id-tc26-signwithdigest-gost3410-2012-256" and nid = 985 and normalized = "GOST34102012" and algType = "SYMMETRIC_ENCRYPTION" or + // TODO: re-evaluate: this is a signing algorithm using hashing and curves name = "id-tc26-signwithdigest-gost3410-2012-512" and nid = 986 and normalized = "GOST34102012" and @@ -1304,22 +1418,42 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, name = "id-tc26-hmac-gost-3411-2012-256" and nid = 988 and normalized = "GOST34112012" and - algType = "SYMMETRIC_ENCRYPTION" + algType = "HASH" + or + name = "id-tc26-hmac-gost-3411-2012-256" and + nid = 988 and + normalized = "HMAC" and + algType = "MAC" or name = "id-tc26-hmac-gost-3411-2012-512" and nid = 989 and normalized = "GOST34112012" and - algType = "SYMMETRIC_ENCRYPTION" + algType = "HASH" + or + name = "id-tc26-hmac-gost-3411-2012-512" and + nid = 989 and + normalized = "HMAC" and + algType = "MAC" or name = "id-tc26-agreement-gost-3410-2012-256" and nid = 992 and normalized = "GOST34102012" and - algType = "SYMMETRIC_ENCRYPTION" + algType = "ELLIPTIC_CURVE" + or + name = "id-tc26-agreement-gost-3410-2012-256" and + nid = 992 and + normalized = "GOST34102012" and + algType = "KEY_AGREEMENT" or name = "id-tc26-agreement-gost-3410-2012-512" and nid = 993 and normalized = "GOST34102012" and - algType = "SYMMETRIC_ENCRYPTION" + algType = "ELLIPTIC_CURVE" + or + name = "id-tc26-agreement-gost-3410-2012-512" and + nid = 993 and + normalized = "GOST34102012" and + algType = "KEY_AGREEMENT" or name = "id-tc26-gost-3410-2012-512-constants" and nid = 996 and @@ -1407,12 +1541,20 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "hmac-sha3-224" and nid = 1102 and normalized = "SHA3-224" and algType = "HASH" or + name = "hmac-sha3-224" and nid = 1102 and normalized = "HMAC" and algType = "MAC" + or name = "hmac-sha3-256" and nid = 1103 and normalized = "SHA3-256" and algType = "HASH" or + name = "hmac-sha3-256" and nid = 1103 and normalized = "HMAC" and algType = "MAC" + or name = "hmac-sha3-384" and nid = 1104 and normalized = "SHA3-384" and algType = "HASH" or + name = "hmac-sha3-384" and nid = 1104 and normalized = "HMAC" and algType = "MAC" + or name = "hmac-sha3-512" and nid = 1105 and normalized = "SHA3-512" and algType = "HASH" or + name = "hmac-sha3-512" and nid = 1105 and normalized = "HMAC" and algType = "MAC" + or name = "id-dsa-with-sha384" and nid = 1106 and normalized = "DSA" and algType = "SIGNATURE" or name = "id-dsa-with-sha384" and nid = 1106 and normalized = "SHA-384" and algType = "HASH" @@ -2180,34 +2322,67 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, normalized = "GOST" and algType = "SYMMETRIC_ENCRYPTION" or + name = "hmac gost 34.11-2012 256 bit" and + nid = 988 and + normalized = "HMAC" and + algType = "MAC" + or name = "hmac gost 34.11-2012 512 bit" and nid = 989 and normalized = "GOST" and algType = "SYMMETRIC_ENCRYPTION" or + name = "hmac gost 34.11-2012 512 bit" and + nid = 989 and + normalized = "HMAC" and + algType = "MAC" + or name = "hmac gost 34.11-94" and nid = 810 and normalized = "GOST" and algType = "SYMMETRIC_ENCRYPTION" or + name = "hmac gost 34.11-94" and + nid = 810 and + normalized = "HMAC" and + algType = "MAC" + or name = "hmacwithmd5" and nid = 797 and normalized = "MD5" and algType = "HASH" or + name = "hmacwithmd5" and nid = 797 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha1" and nid = 163 and normalized = "SHA1" and algType = "HASH" or + name = "hmacwithsha1" and nid = 163 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha224" and nid = 798 and normalized = "SHA-224" and algType = "HASH" or + name = "hmacwithsha224" and nid = 798 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha256" and nid = 799 and normalized = "SHA-256" and algType = "HASH" or + name = "hmacwithsha256" and nid = 799 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha384" and nid = 800 and normalized = "SHA-384" and algType = "HASH" or + name = "hmacwithsha384" and nid = 800 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha512" and nid = 801 and normalized = "SHA-512" and algType = "HASH" or + name = "hmacwithsha512" and nid = 801 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha512-224" and nid = 1193 and normalized = "SHA-512-224" and algType = "HASH" or + name = "hmacwithsha512-224" and nid = 1193 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsha512-256" and nid = 1194 and normalized = "SHA-512-256" and algType = "HASH" or + name = "hmacwithsha512-256" and nid = 1194 and normalized = "HMAC" and algType = "MAC" + or name = "hmacwithsm3" and nid = 1281 and normalized = "SM3" and algType = "HASH" or + name = "hmacwithsm3" and nid = 1281 and normalized = "HMAC" and algType = "MAC" + or name = "id-aes128-ccm" and nid = 896 and normalized = "AES-128" and @@ -2457,12 +2632,20 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, or name = "id-hmacwithsha3-224" and nid = 1102 and normalized = "SHA3-224" and algType = "HASH" or + name = "id-hmacwithsha3-224" and nid = 1102 and normalized = "HMAC" and algType = "MAC" + or name = "id-hmacwithsha3-256" and nid = 1103 and normalized = "SHA3-256" and algType = "HASH" or + name = "id-hmacwithsha3-256" and nid = 1103 and normalized = "HMAC" and algType = "MAC" + or name = "id-hmacwithsha3-384" and nid = 1104 and normalized = "SHA3-384" and algType = "HASH" or + name = "id-hmacwithsha3-384" and nid = 1104 and normalized = "HMAC" and algType = "MAC" + or name = "id-hmacwithsha3-512" and nid = 1105 and normalized = "SHA3-512" and algType = "HASH" or + name = "id-hmacwithsha3-512" and nid = 1105 and normalized = "HMAC" and algType = "MAC" + or name = "id-regctrl" and nid = 313 and normalized = "CTR" and algType = "BLOCK_MODE" or name = "id-smime-alg-3deswrap" and @@ -2818,93 +3001,93 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, name = "ripemd160withrsa" and nid = 119 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "ripemd160withrsa" and nid = 119 and normalized = "RIPEMD160" and algType = "HASH" or - name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-md2" and nid = 7 and normalized = "MD2" and algType = "HASH" or - name = "rsa-md4" and nid = 396 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-md4" and nid = 396 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-md4" and nid = 396 and normalized = "MD4" and algType = "HASH" or - name = "rsa-md5" and nid = 8 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-md5" and nid = 8 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-md5" and nid = 8 and normalized = "MD5" and algType = "HASH" or - name = "rsa-mdc2" and nid = 96 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-mdc2" and nid = 96 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-mdc2" and nid = 96 and normalized = "MDC2" and algType = "HASH" or - name = "rsa-np-md5" and nid = 104 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-np-md5" and nid = 104 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-np-md5" and nid = 104 and normalized = "MD5" and algType = "HASH" or - name = "rsa-ripemd160" and nid = 119 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-ripemd160" and nid = 119 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-ripemd160" and nid = 119 and normalized = "RIPEMD160" and algType = "HASH" or - name = "rsa-sha" and nid = 42 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha" and nid = 42 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha" and nid = 42 and normalized = "SHA" and algType = "HASH" or - name = "rsa-sha1" and nid = 65 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha1" and nid = 65 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha1" and nid = 65 and normalized = "SHA1" and algType = "HASH" or - name = "rsa-sha1-2" and nid = 115 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha1-2" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha1-2" and nid = 115 and normalized = "SHA1" and algType = "HASH" or - name = "rsa-sha224" and nid = 671 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha224" and nid = 671 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha224" and nid = 671 and normalized = "SHA-224" and algType = "HASH" or - name = "rsa-sha256" and nid = 668 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha256" and nid = 668 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha256" and nid = 668 and normalized = "SHA-256" and algType = "HASH" or - name = "rsa-sha3-224" and nid = 1116 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha3-224" and nid = 1116 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha3-224" and nid = 1116 and normalized = "SHA3-224" and algType = "HASH" or - name = "rsa-sha3-256" and nid = 1117 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha3-256" and nid = 1117 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha3-256" and nid = 1117 and normalized = "SHA3-256" and algType = "HASH" or - name = "rsa-sha3-384" and nid = 1118 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha3-384" and nid = 1118 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha3-384" and nid = 1118 and normalized = "SHA3-384" and algType = "HASH" or - name = "rsa-sha3-512" and nid = 1119 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha3-512" and nid = 1119 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha3-512" and nid = 1119 and normalized = "SHA3-512" and algType = "HASH" or - name = "rsa-sha384" and nid = 669 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha384" and nid = 669 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha384" and nid = 669 and normalized = "SHA-384" and algType = "HASH" or - name = "rsa-sha512" and nid = 670 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sha512" and nid = 670 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sha512" and nid = 670 and normalized = "SHA-512" and algType = "HASH" or name = "rsa-sha512/224" and nid = 1145 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "rsa-sha512/224" and nid = 1145 and normalized = "SHA-512-224" and algType = "HASH" or name = "rsa-sha512/256" and nid = 1146 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "rsa-sha512/256" and nid = 1146 and normalized = "SHA-512-256" and algType = "HASH" or - name = "rsa-sm3" and nid = 1144 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsa-sm3" and nid = 1144 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsa-sm3" and nid = 1144 and normalized = "SM3" and algType = "HASH" or @@ -2928,52 +3111,52 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, normalized = "OAEP" and algType = "ASYMMETRIC_PADDING" or - name = "rsasignature" and nid = 377 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsasignature" and nid = 377 and normalized = "RSA" and algType = "SIGNATURE" or - name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE" or name = "rsassa-pss" and nid = 912 and normalized = "PSS" and algType = "ASYMMETRIC_PADDING" or - name = "rsassapss" and nid = 912 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "rsassapss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE" or - name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "ASYMMETRIC_PADDING" + name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "SIGNATURE" or - name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE" or name = "sha1withrsa" and nid = 115 and normalized = "SHA1" and algType = "HASH" or name = "sha1withrsaencryption" and nid = 65 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha1withrsaencryption" and nid = 65 and normalized = "SHA1" and algType = "HASH" or name = "sha224withrsaencryption" and nid = 671 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha224withrsaencryption" and nid = 671 and normalized = "SHA-224" and algType = "HASH" or name = "sha256withrsaencryption" and nid = 668 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha256withrsaencryption" and nid = 668 and normalized = "SHA-256" and algType = "HASH" or name = "sha384withrsaencryption" and nid = 669 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha384withrsaencryption" and nid = 669 and normalized = "SHA-384" and algType = "HASH" or name = "sha512-224withrsaencryption" and nid = 1145 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha512-224withrsaencryption" and nid = 1145 and @@ -2983,7 +3166,7 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, name = "sha512-256withrsaencryption" and nid = 1146 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha512-256withrsaencryption" and nid = 1146 and @@ -2993,14 +3176,14 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, name = "sha512withrsaencryption" and nid = 670 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sha512withrsaencryption" and nid = 670 and normalized = "SHA-512" and algType = "HASH" or name = "shawithrsaencryption" and nid = 42 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "shawithrsaencryption" and nid = 42 and normalized = "SHA" and algType = "HASH" or @@ -3017,7 +3200,11 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, name = "sm3withrsaencryption" and nid = 1144 and normalized = "RSA" and - algType = "ASYMMETRIC_ENCRYPTION" + algType = "SIGNATURE" or name = "sm3withrsaencryption" and nid = 1144 and normalized = "SM3" and algType = "HASH" + or + name = "hmac" and nid = 855 and normalized = "HMAC" and algType = "MAC" + or + name = "cmac" and nid = 894 and normalized = "CMAC" and algType = "MAC" } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll new file mode 100644 index 000000000000..2e476824316b --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll @@ -0,0 +1,66 @@ +import cpp +private import experimental.quantum.Language +private import KnownAlgorithmConstants +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers +private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase +private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations +private import AlgToAVCFlow + +class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::MACAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr +{ + OpenSslAlgorithmValueConsumer getterCall; + + KnownOpenSslMacConstantAlgorithmInstance() { + // Two possibilities: + // 1) The source is a literal and flows to a getter, then we know we have an instance + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that + // Possibility 1: + this instanceof OpenSslAlgorithmLiteral and + exists(DataFlow::Node src, DataFlow::Node sink | + // Sink is an argument to a CipherGetterCall + sink = getterCall.getInputNode() and + // Source is `this` + src.asExpr() = this and + // This traces to a getter + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + ) + or + // Possibility 2: + this instanceof OpenSslAlgorithmCall and + getterCall = this + } + + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } + + override string getRawMacAlgorithmName() { + result = this.(Literal).getValue().toString() + or + result = this.(Call).getTarget().getName() + } + + override Crypto::TMACType getMacType() { + this instanceof KnownOpenSslHMacAlgorithmExpr and result instanceof Crypto::THMAC + or + this instanceof KnownOpenSslCMacAlgorithmExpr and result instanceof Crypto::TCMAC + } +} + +class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HMACAlgorithmInstance, + KnownOpenSslMacConstantAlgorithmInstance +{ + override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { + if exists(this.(KnownOpenSslHMacAlgorithmExpr).getExplicitHashAlgorithm()) + then + // ASSUMPTION: if there is an explicit hash algorithm, it is already modeled + // and we can simply grab that model's AVC + exists(OpenSslAlgorithmInstance inst | inst.getAvc() = result and inst = this) + else + // ASSUMPTION: If no explicit algorithm is given, then it is assumed to be configured by + // a signature operation + exists(Crypto::SignatureOperationInstance s | + s.getHashAlgorithmValueConsumer() = result and + s.getAnAlgorithmValueConsumer() = this.getAvc() + ) + } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstanceBase.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstanceBase.qll index b05ee9180b9b..0352cfa50634 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstanceBase.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstanceBase.qll @@ -1,6 +1,6 @@ private import experimental.quantum.Language private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase -abstract class OpenSSLAlgorithmInstance extends Crypto::AlgorithmInstance { - abstract OpenSSLAlgorithmValueConsumer getAVC(); +abstract class OpenSslAlgorithmInstance extends Crypto::AlgorithmInstance { + abstract OpenSslAlgorithmValueConsumer getAvc(); } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstances.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstances.qll index 55beb58588b3..a779f531f945 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstances.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/OpenSSLAlgorithmInstances.qll @@ -4,3 +4,5 @@ import PaddingAlgorithmInstance import BlockAlgorithmInstance import HashAlgorithmInstance import EllipticCurveAlgorithmInstance +import SignatureAlgorithmInstance +import MACAlgorithmInstance diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll index b4c34607e450..7a34b69ddf54 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll @@ -17,21 +17,21 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor * # define RSA_PKCS1_WITH_TLS_PADDING 7 * # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8 */ -class OpenSSLPaddingLiteral extends Literal { +class OpenSslPaddingLiteral extends Literal { // TODO: we can be more specific about where the literal is in a larger expression // to avoid literals that are clealy not representing an algorithm, e.g., array indices. - OpenSSLPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] } + OpenSslPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] } } /** - * Given a `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type. + * Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type. * Does not bind if there is no mapping (no mapping to 'unknown' or 'other'). */ -predicate knownOpenSSLConstantToPaddingFamilyType( - KnownOpenSSLPaddingAlgorithmConstant e, Crypto::TPaddingType type +predicate knownOpenSslConstantToPaddingFamilyType( + KnownOpenSslPaddingAlgorithmExpr e, Crypto::TPaddingType type ) { exists(string name | - name = e.getNormalizedName() and + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and ( name.matches("OAEP") and type = Crypto::OAEP() or @@ -44,44 +44,44 @@ predicate knownOpenSSLConstantToPaddingFamilyType( ) } -//abstract class OpenSSLPaddingAlgorithmInstance extends OpenSSLAlgorithmInstance, Crypto::PaddingAlgorithmInstance{} +//abstract class OpenSslPaddingAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance{} // TODO: need to alter this to include known padding constants which don't have the // same mechanics as those with known nids -class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, +class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Expr { - OpenSSLAlgorithmValueConsumer getterCall; + OpenSslAlgorithmValueConsumer getterCall; boolean isPaddingSpecificConsumer; - KnownOpenSSLPaddingConstantAlgorithmInstance() { + KnownOpenSslPaddingConstantAlgorithmInstance() { // three possibilities: // 1) The source is a 'typical' literal and flows to a getter, then we know we have an instance - // 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that + // 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that // 3) the source is a padding-specific literal flowing to a padding-specific consumer // Possibility 1: - this instanceof Literal and - this instanceof KnownOpenSSLPaddingAlgorithmConstant and + this instanceof OpenSslAlgorithmLiteral and + this instanceof KnownOpenSslPaddingAlgorithmExpr and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall - sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and + sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a getter - KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and isPaddingSpecificConsumer = false ) or // Possibility 2: - this instanceof DirectAlgorithmValueConsumer and + this instanceof OpenSslAlgorithmCall and getterCall = this and - this instanceof KnownOpenSSLPaddingAlgorithmConstant and + this instanceof KnownOpenSslPaddingAlgorithmExpr and isPaddingSpecificConsumer = false or // Possibility 3: padding-specific literal - this instanceof OpenSSLPaddingLiteral and + this instanceof OpenSslPaddingLiteral and exists(DataFlow::Node src, DataFlow::Node sink | // Sink is an argument to a CipherGetterCall - sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and + sink = getterCall.getInputNode() and // Source is `this` src.asExpr() = this and // This traces to a padding-specific consumer @@ -96,7 +96,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta result = this.(Call).getTarget().getName() } - override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } Crypto::TPaddingType getKnownPaddingType() { this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5() @@ -119,7 +119,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta ) or isPaddingSpecificConsumer = false and - knownOpenSSLConstantToPaddingFamilyType(this, result) + knownOpenSslConstantToPaddingFamilyType(this, result) } } @@ -127,7 +127,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta // // not the same as 'typical' constants found in the set of known algorithm constants // // they do not have an NID // // TODO: what about setting the padding directly? -// class KnownRSAPaddingConstant extends OpenSSLPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal +// class KnownRSAPaddingConstant extends OpenSslPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal // { // KnownRSAPaddingConstant() { // // from rsa.h in openssl: @@ -162,7 +162,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta // } // } class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance, - KnownOpenSSLPaddingConstantAlgorithmInstance + KnownOpenSslPaddingConstantAlgorithmInstance { OAEPPaddingAlgorithmInstance() { this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP() diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll new file mode 100644 index 000000000000..afd67410c0ad --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll @@ -0,0 +1,102 @@ +import cpp +private import experimental.quantum.Language +private import KnownAlgorithmConstants +private import Crypto::KeyOpAlg as KeyOpAlg +private import OpenSSLAlgorithmInstanceBase +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer +private import AlgToAVCFlow + +/** + * Gets the signature algorithm type based on the normalized algorithm name. + */ +private predicate knownOpenSslConstantToSignatureFamilyType( + KnownOpenSslSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type +) { + exists(string name | + name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and + ( + name.matches("RSA%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA()) + or + name.matches("DSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::DSA()) + or + name.matches("ECDSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::ECDSA()) + or + name.matches("ED25519%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA()) + or + name.matches("ED448%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA()) + ) + ) +} + +/** + * A signature algorithm instance derived from an OpenSsl constant. + */ +class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmInstance, + Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslSignatureAlgorithmExpr +{ + OpenSslAlgorithmValueConsumer getterCall; + + KnownOpenSslSignatureConstantAlgorithmInstance() { + // Two possibilities: + // 1) The source is a literal and flows to a getter, then we know we have an instance + // 2) The source is a KnownOpenSslAlgorithm call, and we know we have an instance immediately from that + // Possibility 1: + this instanceof OpenSslAlgorithmLiteral and + exists(DataFlow::Node src, DataFlow::Node sink | + // Sink is an argument to a signature getter call + sink = getterCall.getInputNode() and + // Source is `this` + src.asExpr() = this and + // This traces to a getter + KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) + ) + or + // Possibility 2: + this instanceof OpenSslAlgorithmCall and + getterCall = this + } + + override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() } + + override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() } + + override string getRawAlgorithmName() { + result = this.(Literal).getValue().toString() + or + result = this.(Call).getTarget().getName() + } + + override int getKeySizeFixed() { + // TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSslEllipticCurveConstantAlgorithmInstance + // TODO: maybe add getExplicitKeySize to KnownOpenSslSignatureAlgorithmExpr and use it here + none() + } + + override KeyOpAlg::Algorithm getAlgorithmType() { + knownOpenSslConstantToSignatureFamilyType(this, result) + or + not knownOpenSslConstantToSignatureFamilyType(this, _) and + result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType()) + } + + override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } + + override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { + // TODO: trace to any key size initializer + // probably PKeyAlgorithmValueConsumer and SignatureAlgorithmValueConsumer + none() + } + + /** + * No mode for signatures. + */ + override predicate shouldHaveModeOfOperation() { none() } + + /** + * Padding only for RSA. + */ + override predicate shouldHavePaddingScheme() { + this.getAlgorithmType() instanceof KeyOpAlg::TAsymmetricCipher + } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll index 8aa5d946baee..b06e55c0817e 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll @@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase private import OpenSSLAlgorithmValueConsumerBase -abstract class CipherAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class CipherAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } // https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html -class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer { +class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPCipherAlgorithmValueConsumer() { + EvpCipherAlgorithmValueConsumer() { resultNode.asExpr() = this and ( this.(Call).getTarget().getName() in [ @@ -30,8 +30,8 @@ class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer { // override DataFlow::Node getInputNode() { result = valueArgNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) - //TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to - // OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set. + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) + //TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to + // OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set. } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll index affb7ae6095e..a4a65ead63d8 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll @@ -7,26 +7,27 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor * Cases like EVP_MD5(), * there is no input, rather it directly gets an algorithm * and returns it. + * Also includes operations directly using an algorithm + * like AES_encrypt(). */ -class DirectAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { - DataFlow::Node resultNode; - Expr resultExpr; - - DirectAlgorithmValueConsumer() { - this instanceof KnownOpenSSLAlgorithmConstant and - this instanceof Call and - resultExpr = this and - resultNode.asExpr() = resultExpr - } - +class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanceof OpenSslAlgorithmCall +{ /** * These cases take in no explicit value (the value is implicit) */ override Crypto::ConsumerInputDataFlowNode getInputNode() { none() } - override DataFlow::Node getResultNode() { result = resultNode } + /** + * Gets the DataFlow node represeting the output algorithm entity + * created as a result of this call. + */ + override DataFlow::Node getResultNode() { + this instanceof OpenSslDirectAlgorithmFetchCall and + result.asExpr() = this + // NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated + // the algorithm is directly used + } - // override DataFlow::Node getOutputNode() { result = resultNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { // Note: algorithm source definitions enforces that // this class will be a known algorithm source diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll index 4bff4cb05db2..daf6baf2f031 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll @@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -abstract class EllipticCurveValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class EllipticCurveValueConsumer extends OpenSslAlgorithmValueConsumer { } //https://docs.openssl.org/3.0/man3/EC_KEY_new/#name -class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer { +class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPEllipticCurveAlgorithmConsumer() { + EvpEllipticCurveAlgorithmConsumer() { resultNode.asExpr() = this.(Call) and // in all cases the result is the return ( this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and @@ -25,7 +25,7 @@ class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer { } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } override DataFlow::Node getResultNode() { result = resultNode } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll index 6c4a9c9bd6cd..a03114b276d2 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll @@ -4,20 +4,20 @@ private import semmle.code.cpp.dataflow.new.DataFlow private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -abstract class HashAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } /** * EVP_Q_Digest directly consumes algorithm constant values */ -class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer { - EVP_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" } +class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer { + Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" } override Crypto::ConsumerInputDataFlowNode getInputNode() { result.asExpr() = this.(Call).getArgument(1) } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } override DataFlow::Node getResultNode() { @@ -27,15 +27,43 @@ class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer { } } +/** + * An instance from https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/ + * where the digest is directly consumed by name. + * In these cases, the operation is not yet performed, but there is + * these functions are treated as 'initializers' and track the algorithm through + * `EvpInitializer` mechanics, i.e., the resultNode is considered 'none' + */ +class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer { + DataFlow::Node valueArgNode; + + EvpPkeySetCtxALgorithmConsumer() { + this.(Call).getTarget().getName() in [ + "EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_oaep_md_name", + "EVP_PKEY_CTX_set_dsa_paramgen_md_props" + ] and + valueArgNode.asExpr() = this.(Call).getArgument(1) + } + + override DataFlow::Node getResultNode() { none() } + + override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } + + override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) + } +} + /** * The EVP digest algorithm getters * https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis + * https://docs.openssl.org/3.0/man3/EVP_DigestSignInit/#name */ -class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { +class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPDigestAlgorithmValueConsumer() { + EvpDigestAlgorithmValueConsumer() { resultNode.asExpr() = this and ( this.(Call).getTarget().getName() in [ @@ -45,6 +73,9 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { or this.(Call).getTarget().getName() = "EVP_MD_fetch" and valueArgNode.asExpr() = this.(Call).getArgument(1) + or + this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and + valueArgNode.asExpr() = this.(Call).getArgument(2) ) } @@ -53,6 +84,6 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll index e66beccd301a..830adece0f31 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll @@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -abstract class KEMAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class KemAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } -class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer { +class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPKEMAlgorithmValueConsumer() { + EvpKemAlgorithmValueConsumer() { resultNode.asExpr() = this and ( this.(Call).getTarget().getName() = "EVP_KEM_fetch" and @@ -23,6 +23,6 @@ class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer { override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll index b5f24ec875ad..88c36a37eb51 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll @@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -abstract class KeyExchangeAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class KeyExchangeAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } -class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer { +class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPKeyExchangeAlgorithmValueConsumer() { + EvpKeyExchangeAlgorithmValueConsumer() { resultNode.asExpr() = this and ( this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and @@ -23,6 +23,6 @@ class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueCons override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumerBase.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumerBase.qll index b0cdee1f8f5d..292e554c0fb0 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumerBase.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumerBase.qll @@ -1,6 +1,6 @@ private import experimental.quantum.Language -abstract class OpenSSLAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call { +abstract class OpenSslAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call { /** * Returns the node representing the resulting algorithm */ diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumers.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumers.qll index c76d6d6f041c..8b862e2a7ccb 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumers.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumers.qll @@ -5,3 +5,4 @@ import PaddingAlgorithmValueConsumer import HashAlgorithmValueConsumer import EllipticCurveAlgorithmValueConsumer import PKeyAlgorithmValueConsumer +import SignatureAlgorithmValueConsumer diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll index 0d40ceeb68af..f7c8fef37941 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll @@ -4,13 +4,13 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -abstract class PKeyValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class PKeyValueConsumer extends OpenSslAlgorithmValueConsumer { } -class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer { +class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVPPKeyAlgorithmConsumer() { + EvpPKeyAlgorithmConsumer() { resultNode.asExpr() = this.(Call) and // in all cases the result is the return ( // NOTE: some of these consumers are themselves key gen operations, @@ -23,7 +23,8 @@ class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer { or this.(Call).getTarget().getName() in [ "EVP_PKEY_CTX_new_from_name", "EVP_PKEY_new_raw_private_key_ex", - "EVP_PKEY_new_raw_public_key_ex", "EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_set_group_name" + "EVP_PKEY_new_raw_public_key_ex", "EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_ctrl_uint64", + "EVP_PKEY_CTX_ctrl_str", "EVP_PKEY_CTX_set_group_name" ] and valueArgNode.asExpr() = this.(Call).getArgument(1) or @@ -46,7 +47,7 @@ class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer { } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } override DataFlow::Node getResultNode() { result = resultNode } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll index c60918519c80..f080fc0f12a2 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll @@ -4,16 +4,16 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase private import OpenSSLAlgorithmValueConsumerBase -abstract class PaddingAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } +abstract class PaddingAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } // https://docs.openssl.org/master/man7/EVP_ASYM_CIPHER-RSA/#rsa-asymmetric-cipher-parameters // TODO: need to handle setting padding through EVP_PKEY_CTX_set_params, where modes like "OSSL_PKEY_RSA_PAD_MODE_OAEP" // are set. -class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer { +class Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer { DataFlow::Node valueArgNode; DataFlow::Node resultNode; - EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer() { + Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer() { resultNode.asExpr() = this and this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_padding" and valueArgNode.asExpr() = this.(Call).getArgument(1) @@ -25,8 +25,8 @@ class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorit // override DataFlow::Node getInputNode() { result = valueArgNode } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { - exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) - //TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to - // OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set. + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) + //TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to + // OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set. } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll new file mode 100644 index 000000000000..c6f3fb8959c8 --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll @@ -0,0 +1,32 @@ +import cpp +private import experimental.quantum.Language +private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants +private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase +private import OpenSSLAlgorithmValueConsumerBase +private import experimental.quantum.OpenSSL.LibraryDetector + +abstract class SignatureAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { } + +class EvpSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer { + DataFlow::Node valueArgNode; + DataFlow::Node resultNode; + + EvpSignatureAlgorithmValueConsumer() { + resultNode.asExpr() = this and + ( + // EVP_SIGNATURE + this.(Call).getTarget().getName() = "EVP_SIGNATURE_fetch" and + valueArgNode.asExpr() = this.(Call).getArgument(1) + // EVP_PKEY_get1_DSA, EVP_PKEY_get1_RSA + // DSA_SIG_new, DSA_SIG_get0, RSA_sign ? + ) + } + + override DataFlow::Node getResultNode() { result = resultNode } + + override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } + + override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { + exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) + } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll new file mode 100644 index 000000000000..10aa145804b6 --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll @@ -0,0 +1,19 @@ +import semmle.code.cpp.dataflow.new.DataFlow +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers + +/** + * Flows from algorithm values to operations, specific to OpenSsl + */ +module AvcToCallArgConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + exists(OpenSslAlgorithmValueConsumer c | c.getResultNode() = source) + } + + /** + * Trace to any call accepting the algorithm. + * NOTE: users must restrict this set to the operations they are interested in. + */ + predicate isSink(DataFlow::Node sink) { exists(Call c | c.getAnArgument() = sink.asExpr()) } +} + +module AvcToCallArgFlow = DataFlow::Global; diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/CtxFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/CtxFlow.qll index 38b49b8d9010..63ec3e181325 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/CtxFlow.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/CtxFlow.qll @@ -28,7 +28,7 @@ import semmle.code.cpp.dataflow.new.DataFlow * - EVP_MD_CTX * - EVP_PKEY_CTX */ -private class CtxType extends Type { +class CtxType extends Type { CtxType() { // It is possible for users to use the underlying type of the CTX variables // these have a name matching 'evp_%ctx_%st @@ -47,7 +47,7 @@ private class CtxType extends Type { /** * A pointer to a CtxType */ -private class CtxPointerExpr extends Expr { +class CtxPointerExpr extends Expr { CtxPointerExpr() { this.getType() instanceof CtxType and this.getType() instanceof PointerType @@ -57,12 +57,19 @@ private class CtxPointerExpr extends Expr { /** * A call argument of type CtxPointerExpr. */ -private class CtxPointerArgument extends CtxPointerExpr { +class CtxPointerArgument extends CtxPointerExpr { CtxPointerArgument() { exists(Call c | c.getAnArgument() = this) } Call getCall() { result.getAnArgument() = this } } +/** + * A call returning a CtxPointerExpr. + */ +private class CtxPointerReturn extends CtxPointerExpr instanceof Call { + Call getCall() { result = this } +} + /** * A call whose target contains 'free' or 'reset' and has an argument of type * CtxPointerArgument. @@ -74,66 +81,141 @@ private class CtxClearCall extends Call { } } +abstract private class CtxPassThroughCall extends Call { + abstract DataFlow::Node getNode1(); + + abstract DataFlow::Node getNode2(); +} + /** * A call whose target contains 'copy' and has an argument of type * CtxPointerArgument. */ -private class CtxCopyOutArgCall extends Call { +private class CtxCopyOutArgCall extends CtxPassThroughCall { + DataFlow::Node n1; + DataFlow::Node n2; + CtxCopyOutArgCall() { this.getTarget().getName().toLowerCase().matches("%copy%") and - this.getAnArgument() instanceof CtxPointerArgument + n1.asExpr() = this.getAnArgument() and + n1.getType() instanceof CtxType and + n2.asDefiningArgument() = this.getAnArgument() and + n2.getType() instanceof CtxType and + n1.asDefiningArgument() != n2.asExpr() } + + override DataFlow::Node getNode1() { result = n1 } + + override DataFlow::Node getNode2() { result = n2 } } /** * A call whose target contains 'dup' and has an argument of type * CtxPointerArgument. */ -private class CtxCopyReturnCall extends Call, CtxPointerExpr { +private class CtxCopyReturnCall extends CtxPassThroughCall, CtxPointerExpr { + DataFlow::Node n1; + CtxCopyReturnCall() { this.getTarget().getName().toLowerCase().matches("%dup%") and - this.getAnArgument() instanceof CtxPointerArgument + n1.asExpr() = this.getAnArgument() and + n1.getType() instanceof CtxType } + + override DataFlow::Node getNode1() { result = n1 } + + override DataFlow::Node getNode2() { result.asExpr() = this } } /** - * Flow from any CtxPointerArgument to any other CtxPointerArgument + * A call to `EVP_PKEY_paramgen` acts as a kind of pass through. + * It's output pkey is eventually used in a new operation generating + * a fresh context pointer (e.g., `EVP_PKEY_CTX_new`). + * It is easier to model this as a pass through + * than to model the flow from the paramgen to the new key generation. */ -module OpenSSLCtxArgumentFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CtxPointerArgument } +private class CtxParamGenCall extends CtxPassThroughCall { + DataFlow::Node n1; + DataFlow::Node n2; - predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CtxPointerArgument } + CtxParamGenCall() { + this.getTarget().getName() = "EVP_PKEY_paramgen" and + n1.asExpr() = this.getArgument(0) and + ( + n2.asExpr() = this.getArgument(1) + or + n2.asDefiningArgument() = this.getArgument(1) + ) + } + + override DataFlow::Node getNode1() { result = n1 } + + override DataFlow::Node getNode2() { result = n2 } +} + +/** + * If the current node gets is an argument to a function + * that returns a pointer type, immediately flow through. + * NOTE: this passthrough is required if we allow + * intermediate steps to go into variables that are not a CTX type. + * See for example `CtxParamGenCall`. + */ +private class CallArgToCtxRet extends CtxPassThroughCall, CtxPointerExpr { + DataFlow::Node n1; + DataFlow::Node n2; + + CallArgToCtxRet() { + this.getAnArgument() = n1.asExpr() and + n2.asExpr() = this + } + + override DataFlow::Node getNode1() { result = n1 } + + override DataFlow::Node getNode2() { result = n2 } +} + +/** + * A source Ctx of interest is any argument or return of type CtxPointerExpr. + */ +class CtxPointerSource extends CtxPointerExpr { + CtxPointerSource() { + this instanceof CtxPointerReturn or + this instanceof CtxPointerArgument + } + + DataFlow::Node asNode() { + result.asExpr() = this + or + result.asDefiningArgument() = this + } +} + +/** + * Flow from any CtxPointerSource to other CtxPointerSource. + */ +module OpenSslCtxSourceToSourceFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { exists(CtxPointerSource s | s.asNode() = source) } + + predicate isSink(DataFlow::Node sink) { exists(CtxPointerSource s | s.asNode() = sink) } predicate isBarrier(DataFlow::Node node) { exists(CtxClearCall c | c.getAnArgument() = node.asExpr()) } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(CtxCopyOutArgCall c | - c.getAnArgument() = node1.asExpr() and - c.getAnArgument() = node2.asExpr() and - node1.asExpr() != node2.asExpr() and - node2.asExpr().getType() instanceof CtxType - ) - or - exists(CtxCopyReturnCall c | - c.getAnArgument() = node1.asExpr() and - c = node2.asExpr() and - node1.asExpr() != node2.asExpr() and - node2.asExpr().getType() instanceof CtxType - ) + exists(CtxPassThroughCall c | c.getNode1() = node1 and c.getNode2() = node2) } } -module OpenSSLCtxArgumentFlow = DataFlow::Global; +module OpenSslCtxSourceToArgumentFlow = DataFlow::Global; /** * Holds if there is a context flow from the source to the sink. */ -predicate ctxArgFlowsToCtxArg(CtxPointerArgument source, CtxPointerArgument sink) { +predicate ctxSrcToSrcFlow(CtxPointerSource source, CtxPointerSource sink) { exists(DataFlow::Node a, DataFlow::Node b | - OpenSSLCtxArgumentFlow::flow(a, b) and - a.asExpr() = source and - b.asExpr() = sink + OpenSslCtxSourceToArgumentFlow::flow(a, b) and + a = source.asNode() and + b = sink.asNode() ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/GenericSourceCandidateLiteral.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/GenericSourceCandidateLiteral.qll index 8841adc17b6e..a5d6d23f245d 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/GenericSourceCandidateLiteral.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/GenericSourceCandidateLiteral.qll @@ -14,9 +14,9 @@ private class IntLiteral extends Literal { /** * Holds if a StringLiteral could conceivably be used in some way for cryptography. * Note: this predicate should only consider restrictions with respect to strings only. - * General restrictions are in the OpenSSLGenericSourceCandidateLiteral class. + * General restrictions are in the OpenSslGenericSourceCandidateLiteral class. */ -private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s) { +private predicate isOpenSslStringLiteralGenericSourceCandidate(StringLiteral s) { // 'EC' is a constant that may be used where typical algorithms are specified, // but EC specifically means set up a default curve container, that will later be //specified explicitly (or if not a default) curve is used. @@ -49,9 +49,9 @@ private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s) /** * Holds if a StringLiteral could conceivably be used in some way for cryptography. * Note: this predicate should only consider restrictions with respect to integers only. - * General restrictions are in the OpenSSLGenericSourceCandidateLiteral class. + * General restrictions are in the OpenSslGenericSourceCandidateLiteral class. */ -private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) { +private predicate isOpenSslIntLiteralGenericSourceCandidate(IntLiteral l) { // Ignore integer values of 0, commonly referring to NULL only (no known algorithm 0) l.getValue().toInt() != 0 and // ASSUMPTION, no negative numbers are allowed @@ -102,11 +102,11 @@ private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) { * "AES" may be a legitimate algorithm literal, but the literal will not be used for an operation directly * since it is in a equality comparison, hence this case would also be filtered. */ -class OpenSSLGenericSourceCandidateLiteral extends Literal { - OpenSSLGenericSourceCandidateLiteral() { +class OpenSslGenericSourceCandidateLiteral extends Literal { + OpenSslGenericSourceCandidateLiteral() { ( - isOpenSSLIntLiteralGenericSourceCandidate(this) or - isOpenSSLStringLiteralGenericSourceCandidate(this) + isOpenSslIntLiteralGenericSourceCandidate(this) or + isOpenSslStringLiteralGenericSourceCandidate(this) ) and // ********* General filters beyond what is filtered for strings and ints ********* // An algorithm literal in a switch case will not be directly applied to an operation. diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/KeyFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/KeyFlow.qll new file mode 100644 index 000000000000..7e30866a67a6 --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/KeyFlow.qll @@ -0,0 +1,27 @@ +import semmle.code.cpp.dataflow.new.DataFlow +private import Operations.OpenSSLOperations +private import experimental.quantum.Language + +/** + * Flow from key creation to key used in a call + */ +module OpenSslKeyFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + // NOTE/ASSUMPTION: it is assumed the operation is also an OpenSslOperation. + // All operations modeled for openssl should be modeled as OpenSslOperation. + exists(Crypto::KeyCreationOperationInstance keygen | keygen.getOutputKeyArtifact() = source) + } + + predicate isSink(DataFlow::Node sink) { exists(Call call | call.getAnArgument() = sink.asExpr()) } + //TODO: consideration for additional flow steps? Can a key be copied for example? +} + +module OpenSslKeyFlow = TaintTracking::Global; + +Crypto::KeyCreationOperationInstance getSourceKeyCreationInstanceFromArg(Expr arg) { + exists(DataFlow::Node src, DataFlow::Node sink | + OpenSslKeyFlow::flow(src, sink) and + result.getOutputKeyArtifact() = src and + sink.asExpr() = arg + ) +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/LibraryDetector.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/LibraryDetector.qll index 5ff02cd95197..c7e56fab1be0 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/LibraryDetector.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/LibraryDetector.qll @@ -1,7 +1,7 @@ import cpp -predicate isPossibleOpenSSLFunction(Function f) { - isPossibleOpenSSLLocation(f.getADeclarationLocation()) +predicate isPossibleOpenSslFunction(Function f) { + isPossibleOpenSslLocation(f.getADeclarationLocation()) } -predicate isPossibleOpenSSLLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") } +predicate isPossibleOpenSslLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll index 10ceec43e5c1..706cac65f8c4 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll @@ -1,4 +1,4 @@ -module OpenSSLModel { +module OpenSslModel { import AlgorithmInstances.OpenSSLAlgorithmInstances import AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers import Operations.OpenSSLOperations diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/ECKeyGenOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/ECKeyGenOperation.qll index 40103569cac0..65eebae585b3 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/ECKeyGenOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/ECKeyGenOperation.qll @@ -1,10 +1,9 @@ private import experimental.quantum.Language -private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow private import OpenSSLOperationBase private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers private import semmle.code.cpp.dataflow.new.DataFlow -class ECKeyGenOperation extends OpenSSLOperation, Crypto::KeyGenerationOperationInstance { +class ECKeyGenOperation extends OpenSslOperation, Crypto::KeyGenerationOperationInstance { ECKeyGenOperation() { this.(Call).getTarget().getName() = "EC_KEY_generate_key" } override Expr getAlgorithmArg() { result = this.(Call).getArgument(0) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherInitializer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherInitializer.qll deleted file mode 100644 index e6e9954a3332..000000000000 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherInitializer.qll +++ /dev/null @@ -1,117 +0,0 @@ -/** - * see: https://docs.openssl.org/master/man3/EVP_EncryptInit/ - * Models cipher initialization for EVP cipher operations. - */ - -private import experimental.quantum.Language -private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow -private import OpenSSLOperationBase - -module EncValToInitEncArgConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr().getValue().toInt() in [0, 1] } - - predicate isSink(DataFlow::Node sink) { - exists(EVP_Cipher_Initializer initCall | sink.asExpr() = initCall.getOperationSubtypeArg()) - } -} - -module EncValToInitEncArgFlow = DataFlow::Global; - -int getEncConfigValue(Expr e) { - exists(EVP_Cipher_Initializer initCall | e = initCall.getOperationSubtypeArg()) and - exists(DataFlow::Node a, DataFlow::Node b | - EncValToInitEncArgFlow::flow(a, b) and b.asExpr() = e and result = a.asExpr().getValue().toInt() - ) -} - -bindingset[i] -Crypto::KeyOperationSubtype intToCipherOperationSubtype(int i) { - if i = 0 - then result instanceof Crypto::TEncryptMode - else - if i = 1 - then result instanceof Crypto::TDecryptMode - else result instanceof Crypto::TUnknownKeyOperationMode -} - -// TODO: need to add key consumer -abstract class EVP_Cipher_Initializer extends EVPInitialize { - override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } - - abstract Expr getOperationSubtypeArg(); - - override Crypto::KeyOperationSubtype getKeyOperationSubtype() { - if this.(Call).getTarget().getName().toLowerCase().matches("%encrypt%") - then result instanceof Crypto::TEncryptMode - else - if this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%") - then result instanceof Crypto::TDecryptMode - else - if exists(getEncConfigValue(this.getOperationSubtypeArg())) - then result = intToCipherOperationSubtype(getEncConfigValue(this.getOperationSubtypeArg())) - else result instanceof Crypto::TUnknownKeyOperationMode - } -} - -abstract class EVP_EX_Initializer extends EVP_Cipher_Initializer { - override Expr getKeyArg() { result = this.(Call).getArgument(3) } - - override Expr getIVArg() { result = this.(Call).getArgument(4) } -} - -abstract class EVP_EX2_Initializer extends EVP_Cipher_Initializer { - override Expr getKeyArg() { result = this.(Call).getArgument(2) } - - override Expr getIVArg() { result = this.(Call).getArgument(3) } -} - -class EVP_Cipher_EX_Init_Call extends EVP_EX_Initializer { - EVP_Cipher_EX_Init_Call() { - this.(Call).getTarget().getName() in [ - "EVP_EncryptInit_ex", "EVP_DecryptInit_ex", "EVP_CipherInit_ex" - ] - } - - override Expr getOperationSubtypeArg() { - this.(Call).getTarget().getName().toLowerCase().matches("%cipherinit%") and - result = this.(Call).getArgument(5) - } -} - -class EVP_Cipher_EX2_or_Simple_Init_Call extends EVP_EX2_Initializer { - EVP_Cipher_EX2_or_Simple_Init_Call() { - this.(Call).getTarget().getName() in [ - "EVP_EncryptInit_ex2", "EVP_DecryptInit_ex2", "EVP_CipherInit_ex2", "EVP_EncryptInit", - "EVP_DecryptInit", "EVP_CipherInit" - ] - } - - override Expr getOperationSubtypeArg() { - this.(Call).getTarget().getName().toLowerCase().matches("%cipherinit%") and - result = this.(Call).getArgument(4) - } -} - -class EVP_CipherInit_SKEY_Call extends EVP_EX2_Initializer { - EVP_CipherInit_SKEY_Call() { this.(Call).getTarget().getName() in ["EVP_CipherInit_SKEY"] } - - override Expr getOperationSubtypeArg() { result = this.(Call).getArgument(5) } -} - -class EVPCipherInitializerAlgorithmArgument extends Expr { - EVPCipherInitializerAlgorithmArgument() { - exists(EVP_Cipher_Initializer initCall | this = initCall.getAlgorithmArg()) - } -} - -class EVPCipherInitializerKeyArgument extends Expr { - EVPCipherInitializerKeyArgument() { - exists(EVP_Cipher_Initializer initCall | this = initCall.getKeyArg()) - } -} - -class EVPCipherInitializerIVArgument extends Expr { - EVPCipherInitializerIVArgument() { - exists(EVP_Cipher_Initializer initCall | this = initCall.getIVArg()) - } -} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll index 5f24d840ff88..1f5bf9e442ca 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll @@ -1,16 +1,90 @@ private import experimental.quantum.Language -private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow -private import EVPCipherInitializer +private import experimental.quantum.OpenSSL.CtxFlow private import OpenSSLOperationBase private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers -class EVP_Cipher_Update_Call extends EVPUpdate { - EVP_Cipher_Update_Call() { +// TODO: need to add key consumer +abstract class Evp_Cipher_Initializer extends EvpKeyOperationSubtypeInitializer, + EvpPrimaryAlgorithmInitializer, EvpKeyInitializer, EvpIVInitializer +{ + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + + override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } +} + +abstract class Evp_EX_Initializer extends Evp_Cipher_Initializer { + override Expr getKeyArg() { + // Null key indicates the key is not actually set + // This pattern can occur during a multi-step initialization + // TODO/Note: not flowing 0 to the sink, assuming a direct use of NULL for now + result = this.(Call).getArgument(3) and + (exists(result.getValue()) implies result.getValue().toInt() != 0) + } + + override Expr getIVArg() { + // Null IV indicates the IV is not actually set + // This occurs given that setting the IV sometimes requires first setting the IV size. + // TODO/Note: not flowing 0 to the sink, assuming a direct use of NULL for now + result = this.(Call).getArgument(4) and + (exists(result.getValue()) implies result.getValue().toInt() != 0) + } +} + +abstract class Evp_EX2_Initializer extends Evp_Cipher_Initializer { + override Expr getKeyArg() { result = this.(Call).getArgument(2) } + + override Expr getIVArg() { result = this.(Call).getArgument(3) } +} + +class EvpCipherEXInitCall extends Evp_EX_Initializer { + EvpCipherEXInitCall() { + this.(Call).getTarget().getName() in [ + "EVP_EncryptInit_ex", "EVP_DecryptInit_ex", "EVP_CipherInit_ex" + ] + } + + override Expr getKeyOperationSubtypeArg() { + // NOTE: for EncryptInit and DecryptInit there is no subtype arg + // the subtype is determined automatically by the initializer based on the operation name + this.(Call).getTarget().getName().toLowerCase().matches("%cipherinit%") and + result = this.(Call).getArgument(5) + } +} + +// if this.(Call).getTarget().getName().toLowerCase().matches("%encrypt%") +// then result instanceof Crypto::TEncryptMode +// else +// if this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%") +// then result instanceof Crypto::TDecryptMode +class Evp_Cipher_EX2_or_Simple_Init_Call extends Evp_EX2_Initializer { + Evp_Cipher_EX2_or_Simple_Init_Call() { + this.(Call).getTarget().getName() in [ + "EVP_EncryptInit_ex2", "EVP_DecryptInit_ex2", "EVP_CipherInit_ex2", "EVP_EncryptInit", + "EVP_DecryptInit", "EVP_CipherInit" + ] + } + + override Expr getKeyOperationSubtypeArg() { + this.(Call).getTarget().getName().toLowerCase().matches("%cipherinit%") and + result = this.(Call).getArgument(4) + } +} + +class Evp_CipherInit_SKey_Call extends Evp_EX2_Initializer { + Evp_CipherInit_SKey_Call() { this.(Call).getTarget().getName() = "EVP_CipherInit_SKEY" } + + override Expr getKeyOperationSubtypeArg() { result = this.(Call).getArgument(5) } +} + +class Evp_Cipher_Update_Call extends EvpUpdate { + Evp_Cipher_Update_Call() { this.(Call).getTarget().getName() in [ "EVP_EncryptUpdate", "EVP_DecryptUpdate", "EVP_CipherUpdate" ] } + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + override Expr getInputArg() { result = this.(Call).getArgument(3) } override Expr getOutputArg() { result = this.(Call).getArgument(1) } @@ -20,7 +94,7 @@ class EVP_Cipher_Update_Call extends EVPUpdate { * see: https://docs.openssl.org/master/man3/EVP_EncryptInit/#synopsis * Base configuration for all EVP cipher operations. */ -abstract class EVP_Cipher_Operation extends EVPOperation, Crypto::KeyOperationInstance { +abstract class Evp_Cipher_Operation extends EvpOperation, Crypto::KeyOperationInstance { override Expr getOutputArg() { result = this.(Call).getArgument(1) } override Crypto::KeyOperationSubtype getKeyOperationSubtype() { @@ -30,36 +104,42 @@ abstract class EVP_Cipher_Operation extends EVPOperation, Crypto::KeyOperationIn result instanceof Crypto::TDecryptMode and this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%") or - result = this.getInitCall().getKeyOperationSubtype() and + result = this.getInitCall().(EvpKeyOperationSubtypeInitializer).getKeyOperationSubtype() and this.(Call).getTarget().getName().toLowerCase().matches("%cipher%") } override Crypto::ConsumerInputDataFlowNode getNonceConsumer() { - this.getInitCall().getIVArg() = result.asExpr() + this.getInitCall().(EvpIVInitializer).getIVArg() = result.asExpr() } override Crypto::ConsumerInputDataFlowNode getKeyConsumer() { - this.getInitCall().getKeyArg() = result.asExpr() + this.getInitCall().(EvpKeyInitializer).getKeyArg() = result.asExpr() // todo: or track to the EVP_PKEY_CTX_new } override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { - result = EVPOperation.super.getOutputArtifact() + result = EvpOperation.super.getOutputArtifact() } override Crypto::ConsumerInputDataFlowNode getInputConsumer() { - result = EVPOperation.super.getInputConsumer() + result = EvpOperation.super.getInputConsumer() } } -class EVP_Cipher_Call extends EVPOperation, EVP_Cipher_Operation { - EVP_Cipher_Call() { this.(Call).getTarget().getName() = "EVP_Cipher" } +class Evp_Cipher_Call extends EvpOperation, Evp_Cipher_Operation { + Evp_Cipher_Call() { this.(Call).getTarget().getName() = "EVP_Cipher" } override Expr getInputArg() { result = this.(Call).getArgument(2) } + + override Expr getAlgorithmArg() { + result = this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() + } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } } -class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation { - EVP_Cipher_Final_Call() { +class Evp_Cipher_Final_Call extends EvpFinal, Evp_Cipher_Operation { + Evp_Cipher_Final_Call() { this.(Call).getTarget().getName() in [ "EVP_EncryptFinal_ex", "EVP_DecryptFinal_ex", "EVP_CipherFinal_ex", "EVP_EncryptFinal", "EVP_DecryptFinal", "EVP_CipherFinal" @@ -70,8 +150,32 @@ class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation { * Output is both from update calls and from the final call. */ override Expr getOutputArg() { - result = EVPFinal.super.getOutputArg() + result = EvpFinal.super.getOutputArg() or - result = EVP_Cipher_Operation.super.getOutputArg() + result = Evp_Cipher_Operation.super.getOutputArg() + } + + override Expr getAlgorithmArg() { + result = this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() + } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +/** + * https://docs.openssl.org/3.2/man3/EVP_PKEY_decrypt/ + * https://docs.openssl.org/3.2/man3/EVP_PKEY_encrypt + */ +class Evp_PKey_Cipher_Operation extends Evp_Cipher_Operation { + Evp_PKey_Cipher_Operation() { + this.(Call).getTarget().getName() in ["EVP_PKEY_encrypt", "EVP_PKEY_decrypt"] + } + + override Expr getInputArg() { result = this.(Call).getArgument(3) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + + override Expr getAlgorithmArg() { + result = this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashInitializer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashInitializer.qll deleted file mode 100644 index 7309242f198b..000000000000 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashInitializer.qll +++ /dev/null @@ -1,14 +0,0 @@ -import cpp -private import OpenSSLOperationBase - -abstract class EVP_Hash_Initializer extends EVPInitialize { } - -class EVP_DigestInit_Variant_Calls extends EVP_Hash_Initializer { - EVP_DigestInit_Variant_Calls() { - this.(Call).getTarget().getName() in [ - "EVP_DigestInit", "EVP_DigestInit_ex", "EVP_DigestInit_ex2" - ] - } - - override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } -} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll index 796f71398385..b99c5432a1a0 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll @@ -3,24 +3,37 @@ */ private import experimental.quantum.Language -private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow +private import experimental.quantum.OpenSSL.CtxFlow private import OpenSSLOperationBase -private import EVPHashInitializer private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers -class EVP_Digest_Update_Call extends EVPUpdate { - EVP_Digest_Update_Call() { this.(Call).getTarget().getName() = "EVP_DigestUpdate" } +class Evp_DigestInit_Variant_Calls extends EvpPrimaryAlgorithmInitializer { + Evp_DigestInit_Variant_Calls() { + this.(Call).getTarget().getName() in [ + "EVP_DigestInit", "EVP_DigestInit_ex", "EVP_DigestInit_ex2" + ] + } + + override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class Evp_Digest_Update_Call extends EvpUpdate { + Evp_Digest_Update_Call() { this.(Call).getTarget().getName() = "EVP_DigestUpdate" } override Expr getInputArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } } //https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis -class EVP_Q_Digest_Operation extends EVPOperation, Crypto::HashOperationInstance { - EVP_Q_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Q_digest" } +class Evp_Q_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance { + Evp_Q_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Q_digest" } override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } - override EVP_Hash_Initializer getInitCall() { + override EvpInitializer getInitCall() { // This variant of digest does not use an init // and even if it were used, the init would be ignored/undefined none() @@ -31,23 +44,25 @@ class EVP_Q_Digest_Operation extends EVPOperation, Crypto::HashOperationInstance override Expr getOutputArg() { result = this.(Call).getArgument(5) } override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { - result = EVPOperation.super.getOutputArtifact() + result = EvpOperation.super.getOutputArtifact() } override Crypto::ConsumerInputDataFlowNode getInputConsumer() { - result = EVPOperation.super.getInputConsumer() + result = EvpOperation.super.getInputConsumer() } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } } -class EVP_Digest_Operation extends EVPOperation, Crypto::HashOperationInstance { - EVP_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Digest" } +class Evp_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance { + Evp_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Digest" } // There is no context argument for this function - override Expr getContextArg() { none() } + override CtxPointerSource getContext() { none() } override Expr getAlgorithmArg() { result = this.(Call).getArgument(4) } - override EVP_Hash_Initializer getInitCall() { + override EvpPrimaryAlgorithmInitializer getInitCall() { // This variant of digest does not use an init // and even if it were used, the init would be ignored/undefined none() @@ -58,28 +73,34 @@ class EVP_Digest_Operation extends EVPOperation, Crypto::HashOperationInstance { override Expr getOutputArg() { result = this.(Call).getArgument(2) } override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { - result = EVPOperation.super.getOutputArtifact() + result = EvpOperation.super.getOutputArtifact() } override Crypto::ConsumerInputDataFlowNode getInputConsumer() { - result = EVPOperation.super.getInputConsumer() + result = EvpOperation.super.getInputConsumer() } } -class EVP_Digest_Final_Call extends EVPFinal, Crypto::HashOperationInstance { - EVP_Digest_Final_Call() { +class Evp_Digest_Final_Call extends EvpFinal, Crypto::HashOperationInstance { + Evp_Digest_Final_Call() { this.(Call).getTarget().getName() in [ "EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF" ] } + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + override Expr getOutputArg() { result = this.(Call).getArgument(1) } override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { - result = EVPFinal.super.getOutputArtifact() + result = EvpFinal.super.getOutputArtifact() } override Crypto::ConsumerInputDataFlowNode getInputConsumer() { - result = EVPFinal.super.getInputConsumer() + result = EvpFinal.super.getInputConsumer() + } + + override Expr getAlgorithmArg() { + result = this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPKeyGenOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPKeyGenOperation.qll new file mode 100644 index 000000000000..47f341e17b1a --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPKeyGenOperation.qll @@ -0,0 +1,96 @@ +private import experimental.quantum.Language +private import experimental.quantum.OpenSSL.CtxFlow +private import OpenSSLOperationBase +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers + +class EvpKeyGenInitialize extends EvpPrimaryAlgorithmInitializer { + EvpKeyGenInitialize() { + this.(Call).getTarget().getName() in [ + "EVP_PKEY_keygen_init", + "EVP_PKEY_paramgen_init" + ] + } + + /** + * Gets the algorithm argument. + * In this case the algorithm is encoded through the context argument. + * The context may be directly created from an algorithm consumer, + * or from a new operation off of a prior key. Either way, + * we will treat this argument as the algorithm argument. + */ + override Expr getAlgorithmArg() { result = this.getContext() } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpKeyGenOperation extends EvpOperation, Crypto::KeyGenerationOperationInstance { + DataFlow::Node keyResultNode; + + EvpKeyGenOperation() { + this.(Call).getTarget().getName() in ["EVP_RSA_gen", "EVP_PKEY_Q_keygen"] and + keyResultNode.asExpr() = this + or + this.(Call).getTarget().getName() in ["EVP_PKEY_generate", "EVP_PKEY_keygen"] and + keyResultNode.asDefiningArgument() = this.(Call).getArgument(1) + } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + + override Expr getAlgorithmArg() { + this.(Call).getTarget().getName() = "EVP_PKEY_Q_keygen" and + result = this.(Call).getArgument(0) + or + result = this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() + } + + override Crypto::KeyArtifactType getOutputKeyType() { result = Crypto::TAsymmetricKeyType() } + + override Expr getInputArg() { none() } + + override Expr getOutputArg() { result = keyResultNode.asExpr() } + + override Crypto::ArtifactOutputDataFlowNode getOutputKeyArtifact() { result = keyResultNode } + + override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { + this.(Call).getTarget().getName() = "EVP_PKEY_Q_keygen" and + result = DataFlow::exprNode(this.(Call).getArgument(3)) and + // Arg 3 (0 based) is only a key size if the 'type' parameter is RSA, however, + // as a crude approximation, assume that if the type of the argument is not a derived type + // the argument must specify a key size (this is to avoid tracing if "rsa" is in the type parameter) + not this.(Call).getArgument(3).getType().getUnderlyingType() instanceof DerivedType + or + this.(Call).getTarget().getName() = "EVP_RSA_gen" and + result = DataFlow::exprNode(this.(Call).getArgument(0)) + or + result = DataFlow::exprNode(this.getInitCall().(EvpKeySizeInitializer).getKeySizeArg()) + } +} + +/** + * A call to `EVP_PKEY_new_mac_key` that creatse a new generic MAC key. + * Signature: EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen); + */ +class EvpNewMacKey extends EvpOperation, Crypto::KeyGenerationOperationInstance { + DataFlow::Node keyResultNode; + + EvpNewMacKey() { + this.(Call).getTarget().getName() = "EVP_PKEY_new_mac_key" and keyResultNode.asExpr() = this + } + + override CtxPointerSource getContext() { none() } + + override Crypto::KeyArtifactType getOutputKeyType() { result = Crypto::TSymmetricKeyType() } + + override Expr getOutputArg() { result = keyResultNode.asExpr() } + + override Crypto::ArtifactOutputDataFlowNode getOutputKeyArtifact() { result = keyResultNode } + + override Expr getInputArg() { none() } + + override Expr getAlgorithmArg() { result = this.(Call).getArgument(0) } + + override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { + result = DataFlow::exprNode(this.(Call).getArgument(3)) + } +} +/// TODO: https://docs.openssl.org/3.0/man3/EVP_PKEY_new/#synopsis diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll new file mode 100644 index 000000000000..d7060931317f --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll @@ -0,0 +1,119 @@ +/** + * Initializers for EVP PKey + * including: + * https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/ + * https://docs.openssl.org/3.0/man3/EVP_EncryptInit/#synopsis + */ + +import cpp +private import experimental.quantum.OpenSSL.CtxFlow +private import OpenSSLOperations + +/** + * A call to `EVP_PKEY_CTX_new` or `EVP_PKEY_CTX_new_from_pkey`. + * These calls initialize the context from a prior key. + * The key may be generated previously, or merely had it's + * parameters set (e.g., `EVP_PKEY_paramgen`). + * NOTE: for the case of `EVP_PKEY_paramgen`, these calls + * are encoded as context passthroughs, and any operation + * will get all associated initializers for the paramgen + * at the final keygen operation automatically. + */ +class EvpNewKeyCtx extends EvpKeyInitializer { + Expr keyArg; + + EvpNewKeyCtx() { + this.(Call).getTarget().getName() = "EVP_PKEY_CTX_new" and + keyArg = this.(Call).getArgument(0) + or + this.(Call).getTarget().getName() = "EVP_PKEY_CTX_new_from_pkey" and + keyArg = this.(Call).getArgument(1) + } + + /** + * Context is returned + */ + override CtxPointerSource getContext() { result = this } + + override Expr getKeyArg() { result = keyArg } +} + +/** + * A call to "EVP_PKEY_CTX_set_ec_paramgen_curve_nid". + * Note that this is a primary algorithm as the pattenr is to specify an "EC" context, + * then set the specific curve later. Although the curve is set later, it is the primary + * algorithm intended for an operation. + */ +class EvpCtxSetPrimaryAlgorithmInitializer extends EvpPrimaryAlgorithmInitializer { + EvpCtxSetPrimaryAlgorithmInitializer() { + this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_ec_paramgen_curve_nid" + } + + override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpCtxSetHashAlgorithmInitializer extends EvpHashAlgorithmInitializer { + EvpCtxSetHashAlgorithmInitializer() { + this.(Call).getTarget().getName() in [ + "EVP_PKEY_CTX_set_signature_md", "EVP_PKEY_CTX_set_rsa_mgf1_md_name", + "EVP_PKEY_CTX_set_rsa_mgf1_md", "EVP_PKEY_CTX_set_rsa_oaep_md_name", + "EVP_PKEY_CTX_set_rsa_oaep_md", "EVP_PKEY_CTX_set_dsa_paramgen_md", + "EVP_PKEY_CTX_set_dh_kdf_md", "EVP_PKEY_CTX_set_ecdh_kdf_md" + ] + } + + override Expr getHashAlgorithmArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpCtxSetKeySizeInitializer extends EvpKeySizeInitializer { + Expr arg; + + EvpCtxSetKeySizeInitializer() { + this.(Call).getTarget().getName() in [ + "EVP_PKEY_CTX_set_rsa_keygen_bits", "EVP_PKEY_CTX_set_dsa_paramgen_bits", + "EVP_CIPHER_CTX_set_key_length" + ] and + arg = this.(Call).getArgument(1) + or + this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" and + arg = this.(Call).getArgument(2) + } + + override Expr getKeySizeArg() { result = arg } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpCtxSetKeyInitializer extends EvpKeyInitializer { + EvpCtxSetKeyInitializer() { this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" } + + override Expr getKeyArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpCtxSetPaddingInitializer extends EvpPaddingInitializer { + EvpCtxSetPaddingInitializer() { + this.(Call).getTarget().getName() in [ + "EVP_PKEY_CTX_set_rsa_padding", "EVP_CIPHER_CTX_set_padding" + ] + } + + override Expr getPaddingArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpCtxSetSaltLengthInitializer extends EvpSaltLengthInitializer { + EvpCtxSetSaltLengthInitializer() { + this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_pss_saltlen" + } + + override Expr getSaltLengthArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPSignatureOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPSignatureOperation.qll new file mode 100644 index 000000000000..41a828652917 --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPSignatureOperation.qll @@ -0,0 +1,200 @@ +/** + * Provides classes for modeling OpenSSL's EVP signature operations + */ + +private import experimental.quantum.Language +private import experimental.quantum.OpenSSL.AvcFlow +private import experimental.quantum.OpenSSL.CtxFlow +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers +private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations + +// TODO: verification functions +class EvpSignatureDigestInitializer extends EvpHashAlgorithmInitializer { + Expr arg; + + EvpSignatureDigestInitializer() { + this.(Call).getTarget().getName() in ["EVP_DigestSignInit_ex", "EVP_DigestSignInit"] and + arg = this.(Call).getArgument(2) + or + this.(Call).getTarget().getName() in ["EVP_SignInit", "EVP_SignInit_ex"] and + arg = this.(Call).getArgument(1) + } + + override Expr getHashAlgorithmArg() { result = arg } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpSignatureKeyInitializer extends EvpKeyInitializer { + Expr arg; + + EvpSignatureKeyInitializer() { + this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and + arg = this.(Call).getArgument(5) + or + this.(Call).getTarget().getName() = "EVP_DigestSignInit" and + arg = this.(Call).getArgument(4) + } + + override Expr getKeyArg() { result = arg } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class EvpSignaturePrimaryAlgorithmInitializer extends EvpPrimaryAlgorithmInitializer { + Expr arg; + + EvpSignaturePrimaryAlgorithmInitializer() { + // signature algorithm + this.(Call).getTarget().getName() in ["EVP_PKEY_sign_init_ex2", "EVP_PKEY_sign_message_init"] and + arg = this.(Call).getArgument(1) + or + // configuration through the context argument + this.(Call).getTarget().getName() in ["EVP_PKEY_sign_init", "EVP_PKEY_sign_init_ex"] and + arg = this.getContext() + } + + override Expr getAlgorithmArg() { result = arg } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +class Evp_Signature_Update_Call extends EvpUpdate { + Evp_Signature_Update_Call() { + this.(Call).getTarget().getName() in [ + "EVP_DigestSignUpdate", "EVP_SignUpdate", "EVP_PKEY_sign_message_update" + ] + } + + /** + * Input is the message to sign. + */ + override Expr getInputArg() { result = this.(Call).getArgument(1) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } +} + +/** + * We model output explicit output arguments as predicate to use it in constructors. + * The predicate must cover all EVP_Signature_Operation subclasses. + */ +pragma[inline] +private Expr signatureOperationOutputArg(Call call) { + if call.getTarget().getName() = "EVP_SignFinal_ex" + then result = call.getArgument(2) + else result = call.getArgument(1) +} + +/** + * The base configuration for all EVP signature operations. + */ +abstract class EvpSignatureOperation extends EvpOperation, Crypto::SignatureOperationInstance { + EvpSignatureOperation() { + this.(Call).getTarget().getName().matches("EVP_%") and + // NULL output argument means the call is to get the size of the signature and such call is not an operation + ( + not exists(signatureOperationOutputArg(this).getValue()) + or + signatureOperationOutputArg(this).getValue() != "0" + ) + } + + Expr getHashAlgorithmArg() { + this.getInitCall().(EvpHashAlgorithmInitializer).getHashAlgorithmArg() = result + } + + override Expr getAlgorithmArg() { + this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() = result + } + + override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { + AvcToCallArgFlow::flow(result.(OpenSslAlgorithmValueConsumer).getResultNode(), + DataFlow::exprNode(this.getHashAlgorithmArg())) + } + + /** + * Signing, verification or unknown. + */ + override Crypto::KeyOperationSubtype getKeyOperationSubtype() { + // TODO: if this KeyOperationSubtype does not match initialization call's KeyOperationSubtype then we found a bug + if this.(Call).getTarget().getName().toLowerCase().matches("%sign%") + then result instanceof Crypto::TSignMode + else + if this.(Call).getTarget().getName().toLowerCase().matches("%verify%") + then result instanceof Crypto::TVerifyMode + else result instanceof Crypto::TUnknownKeyOperationMode + } + + override Crypto::ConsumerInputDataFlowNode getNonceConsumer() { + // TODO: some signing operations may have explicit nonce generators + none() + } + + /** + * Keys provided in the initialization call or in a context are found by this method. + * Keys in explicit arguments are found by overridden methods in extending classes. + */ + override Crypto::ConsumerInputDataFlowNode getKeyConsumer() { + result = DataFlow::exprNode(this.getInitCall().(EvpKeyInitializer).getKeyArg()) + } + + override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { + result = EvpOperation.super.getOutputArtifact() + } + + override Crypto::ConsumerInputDataFlowNode getInputConsumer() { + result = EvpOperation.super.getInputConsumer() + } + + /** + * TODO: only signing operations for now, change when verificaiton is added + */ + override Crypto::ConsumerInputDataFlowNode getSignatureConsumer() { none() } +} + +class Evp_Signature_Call extends EvpSignatureOperation { + Evp_Signature_Call() { this.(Call).getTarget().getName() in ["EVP_DigestSign", "EVP_PKEY_sign"] } + + /** + * Output is the signature. + */ + override Expr getOutputArg() { result = signatureOperationOutputArg(this) } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + + /** + * Input is the message to sign. + */ + override Expr getInputArg() { result = this.(Call).getArgument(3) } +} + +class Evp_Signature_Final_Call extends EvpFinal, EvpSignatureOperation { + Evp_Signature_Final_Call() { + this.(Call).getTarget().getName() in [ + "EVP_DigestSignFinal", + "EVP_SignFinal_ex", + "EVP_SignFinal", + "EVP_PKEY_sign_message_final" + ] + } + + override CtxPointerSource getContext() { result = this.(Call).getArgument(0) } + + override Expr getAlgorithmArg() { + this.getInitCall().(EvpPrimaryAlgorithmInitializer).getAlgorithmArg() = result + } + + override Crypto::ConsumerInputDataFlowNode getKeyConsumer() { + // key provided as an argument + this.(Call).getTarget().getName() in ["EVP_SignFinal", "EVP_SignFinal_ex"] and + result = DataFlow::exprNode(this.(Call).getArgument(3)) + or + // or find key in the initialization call + result = EvpSignatureOperation.super.getKeyConsumer() + } + + /** + * Output is the signature. + */ + override Expr getOutputArg() { result = signatureOperationOutputArg(this) } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll index 6ada6cb4665d..7f940e34502d 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll @@ -1,14 +1,51 @@ private import experimental.quantum.Language -private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow +private import experimental.quantum.OpenSSL.AvcFlow +private import experimental.quantum.OpenSSL.CtxFlow +private import experimental.quantum.OpenSSL.KeyFlow private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers +// Importing these intializers here to ensure the are part of any model that is +// using OpenSslOperationBase. This further ensures that initializers are tied to opeartions +// even if only importing the operation by itself. +import EVPPKeyCtxInitializer + +module EncValToInitEncArgConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().getValue().toInt() in [0, 1] } + + predicate isSink(DataFlow::Node sink) { + exists(EvpKeyOperationSubtypeInitializer initCall | + sink.asExpr() = initCall.getKeyOperationSubtypeArg() + ) + } +} + +module EncValToInitEncArgFlow = DataFlow::Global; + +private predicate argToAvc(Expr arg, Crypto::AlgorithmValueConsumer avc) { + // NOTE: because we trace through keys to their sources we must consider that the arg is an avc + // Consider this example: + // EVP_PKEY *pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, key_len); + // The key may trace into a signing operation. Tracing through the key we will get the arg taking `EVP_PKEY_HMAC` + // as the algorithm value consumer (the input node of the AVC). The output node of this AVC + // is the call return of `EVP_PKEY_new_mac_key`. If we trace from the AVC result to + // the input argument this will not be possible (from the return to the call argument is a backwards flow). + // Therefore, we must consider the input node of the AVC as the argument. + // This should only occur due to tracing through keys to find configuration data. + avc.getInputNode().asExpr() = arg + or + AvcToCallArgFlow::flow(avc.(OpenSslAlgorithmValueConsumer).getResultNode(), + DataFlow::exprNode(arg)) +} /** - * A class for all OpenSSL operations. + * A class for all OpenSsl operations. */ -abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Call { +abstract class OpenSslOperation extends Crypto::OperationInstance instanceof Call { /** - * Expression that specifies the algorithm for the operation. - * Will be an argument of the operation in the simplest case. + * Gets the argument that specifies the algorithm for the operation. + * This argument might not be immediately present at the specified operation. + * For example, it might be set in an initialization call. + * Modelers of the operation are resonsible for linking the operation to any + * initialization calls, and providing that argument as a returned value here. */ abstract Expr getAlgorithmArg(); @@ -16,54 +53,182 @@ abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Cal * Algorithm is specified in initialization call or is implicitly established by the key. */ override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { - AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(), - DataFlow::exprNode(this.getAlgorithmArg())) + argToAvc(this.getAlgorithmArg(), result) } } /** - * A Call to initialization functions from the EVP API. + * A Call to an initialization function for an operation. * These are not operations in the sense of Crypto::OperationInstance, * but they are used to initialize the context for the operation. + * There may be multiple initialization calls for the same operation. + * Intended for use with EvPOperation. */ -abstract class EVPInitialize extends Call { +abstract class EvpInitializer extends Call { /** - * Gets the context argument that ties together initialization, updates and/or final calls. + * Gets the context argument or return that ties together initialization, updates and/or final calls. + * The context is the context coming into the initializer and is the output as well. + * This is assumed to be the same argument. */ - Expr getContextArg() { result = this.(Call).getArgument(0) } + abstract CtxPointerSource getContext(); +} - /** - * Gets the type of key operation, none if not applicable. - */ - Crypto::KeyOperationSubtype getKeyOperationSubtype() { none() } +/** + * A call to initialize a key size. + */ +abstract class EvpKeySizeInitializer extends EvpInitializer { + abstract Expr getKeySizeArg(); +} - /** - * Explicitly specified algorithm or none if implicit (e.g., established by the key). - * None if not applicable. - */ - Expr getAlgorithmArg() { none() } +/** + * A call to initialize a key operation subtype. + */ +abstract class EvpKeyOperationSubtypeInitializer extends EvpInitializer { + abstract Expr getKeyOperationSubtypeArg(); + + private Crypto::KeyOperationSubtype intToCipherOperationSubtype(int i) { + i = 0 and + result instanceof Crypto::TEncryptMode + or + i = 1 and result instanceof Crypto::TDecryptMode + } + + Crypto::KeyOperationSubtype getKeyOperationSubtype() { + exists(DataFlow::Node a, DataFlow::Node b | + EncValToInitEncArgFlow::flow(a, b) and + b.asExpr() = this.getKeyOperationSubtypeArg() and + result = this.intToCipherOperationSubtype(a.asExpr().getValue().toInt()) + ) + or + // Infer the subtype from the initialization call, and ignore the argument + this.(Call).getTarget().getName().toLowerCase().matches("%encrypt%") and + result instanceof Crypto::TEncryptMode + or + this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%") and + result instanceof Crypto::TDecryptMode + } +} + +/** + * An primary algorithm initializer initializes the primary algorithm for a given operation. + * For example, for a signing operation, the algorithm initializer may initialize algorithms + * like RSA. Other algorithsm may be initialized on an operation, as part of a larger + * operation/protocol. For example, hashing operations on signing operations; however, + * these are not the primary algorithm. Any other algorithms initialized on an operation + * require a specialized initializer, such as EvpHashAlgorithmInitializer. + */ +abstract class EvpPrimaryAlgorithmInitializer extends EvpInitializer { + abstract Expr getAlgorithmArg(); + + Crypto::AlgorithmValueConsumer getAlgorithmValueConsumer() { + argToAvc(this.getAlgorithmArg(), result) + } +} + +/** + * A call to initialize a key. + */ +abstract class EvpKeyInitializer extends EvpInitializer { + abstract Expr getKeyArg(); +} + +/** + * Any key initializer may initialize the algorithm and the key size through + * the key. Extend any instance of key initializer provide initialization + * of the algorithm and key size from the key. + */ +class EvpInitializerThroughKey extends EvpPrimaryAlgorithmInitializer, EvpKeySizeInitializer instanceof EvpKeyInitializer +{ + //TODO: charpred that traces from creation to key arg, grab creator + override CtxPointerSource getContext() { result = EvpKeyInitializer.super.getContext() } + + override Expr getAlgorithmArg() { + result = + getSourceKeyCreationInstanceFromArg(this.getKeyArg()).(OpenSslOperation).getAlgorithmArg() + } + override Expr getKeySizeArg() { + result = getSourceKeyCreationInstanceFromArg(this.getKeyArg()).getKeySizeConsumer().asExpr() + } + + Expr getKeyArg() { result = EvpKeyInitializer.super.getKeyArg() } +} + +/** + * A default initializer for any key operation that accepts a key as input. + * A key initializer allows for a mechanic to go backwards to the key creation operation + * and find the algorithm and key size. + * If a user were to stipualte a key consumer for an operation but fail to indicate it as an + * initializer, automatic tracing to the creation operation would not occur. + * USERS SHOULD NOT NEED TO USE OR EXTEND THIS CLASS DIRECTLY. + * + * TODO: re-evaluate this approach + */ +class DefaultKeyInitializer extends EvpKeyInitializer instanceof Crypto::KeyOperationInstance { + Expr arg; + + DefaultKeyInitializer() { + exists(Call c | + c.getAChild*() = arg and + arg = this.(Crypto::KeyOperationInstance).getKeyConsumer().asExpr() and + c = this + ) + } + + override Expr getKeyArg() { result = arg } + + override CtxPointerSource getContext() { result = this.(EvpOperation).getContext() } +} + +abstract class EvpIVInitializer extends EvpInitializer { + abstract Expr getIVArg(); +} + +/** + * A call to initialize padding. + */ +abstract class EvpPaddingInitializer extends EvpInitializer { /** - * Gets the key for the operation, none if not applicable. + * Gets the padding mode argument. + * e.g., `EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING)` argument 1 (0-based) */ - Expr getKeyArg() { none() } + abstract Expr getPaddingArg(); +} +/** + * A call to initialize a salt length. + */ +abstract class EvpSaltLengthInitializer extends EvpInitializer { /** - * Gets the IV/nonce, none if not applicable. + * Gets the salt length argument. + * e.g., `EVP_PKEY_CTX_set_scrypt_salt_len(ctx, 16)` argument 1 (0-based) */ - Expr getIVArg() { none() } + abstract Expr getSaltLengthArg(); } /** - * A Call to update functions from the EVP API. + * A call to initialize a hash algorithm. + */ +abstract class EvpHashAlgorithmInitializer extends EvpInitializer { + abstract Expr getHashAlgorithmArg(); + + Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { + argToAvc(this.getHashAlgorithmArg(), result) + } +} + +/** + * A Call to an "update" function. * These are not operations in the sense of Crypto::OperationInstance, - * but they are used to update the context for the operation. + * but produce intermediate results for the operation that are later finalized + * (see EvpFinal). + * Intended for use with EvPOperation. */ -abstract class EVPUpdate extends Call { +abstract class EvpUpdate extends Call { /** * Gets the context argument that ties together initialization, updates and/or final calls. */ - Expr getContextArg() { result = this.(Call).getArgument(0) } + abstract CtxPointerSource getContext(); /** * Update calls always have some input data like plaintext or message digest. @@ -76,31 +241,16 @@ abstract class EVPUpdate extends Call { Expr getOutputArg() { none() } } -/** - * Flows from algorithm values to operations, specific to OpenSSL - */ -private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source) - } - - predicate isSink(DataFlow::Node sink) { - exists(EVPOperation c | c.getAlgorithmArg() = sink.asExpr()) - } -} - -private module AlgGetterToAlgConsumerFlow = DataFlow::Global; - /** * The base class for all operations of the EVP API. * This captures one-shot APIs (with and without an initilizer call) and final calls. - * Provides some default methods for Crypto::KeyOperationInstance class + * Provides some default methods for Crypto::KeyOperationInstance class. */ -abstract class EVPOperation extends OpenSSLOperation { +abstract class EvpOperation extends OpenSslOperation { /** * Gets the context argument that ties together initialization, updates and/or final calls. */ - Expr getContextArg() { result = this.(Call).getArgument(0) } + abstract CtxPointerSource getContext(); /** * Some input data like plaintext or message digest. @@ -113,17 +263,10 @@ abstract class EVPOperation extends OpenSSLOperation { */ abstract Expr getOutputArg(); - /** - * Overwrite with an explicitly specified algorithm or leave base implementation to find it in the initialization call. - */ - override Expr getAlgorithmArg() { result = this.getInitCall().getAlgorithmArg() } - /** * Finds the initialization call, may be none. */ - EVPInitialize getInitCall() { - CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg()) - } + EvpInitializer getInitCall() { ctxSrcToSrcFlow(result.getContext(), this.getContext()) } Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = DataFlow::exprNode(this.getOutputArg()) @@ -138,15 +281,17 @@ abstract class EVPOperation extends OpenSSLOperation { } /** - * The final calls of the EVP API. + * An EVP final call, + * which is typicall used in an update/final pattern. + * Final operations are typically identified by "final" in the name, + * e.g., "EVP_DigestFinal", "EVP_EncryptFinal", etc. + * however, this is not a strict rule. */ -abstract class EVPFinal extends EVPOperation { +abstract class EvpFinal extends EvpOperation { /** * All update calls that were executed before this final call. */ - EVPUpdate getUpdateCalls() { - CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg()) - } + EvpUpdate getUpdateCalls() { ctxSrcToSrcFlow(result.getContext(), this.getContext()) } /** * Gets the input data provided to all update calls. @@ -160,3 +305,11 @@ abstract class EVPFinal extends EVPOperation { */ override Expr getOutputArg() { result = this.getUpdateCalls().getOutputArg() } } +// Expr getAlgorithmArgFromContext(Expr contextArg) { +// exists(EVPPKeyAlgorithmConsumer source | +// result = source.getValueArgExpr() and +// ctxFlowsToCtxArg(source.getResultNode().asExpr(), ctx) +// ) +// or +// result = getAlgorithmFromKey(getKeyFromCtx(ctx)) +// } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperations.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperations.qll index f6ff0dd1f077..78b8f8ce080d 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperations.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperations.qll @@ -2,3 +2,5 @@ import OpenSSLOperationBase import EVPCipherOperation import EVPHashOperation import ECKeyGenOperation +import EVPSignatureOperation +import EVPKeyGenOperation diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Random.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Random.qll index e599ed82169b..d39087bcbce0 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Random.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Random.qll @@ -3,11 +3,10 @@ private import experimental.quantum.Language private import LibraryDetector private import semmle.code.cpp.dataflow.new.DataFlow -class OpenSSLRandomNumberGeneratorInstance extends Crypto::RandomNumberGenerationInstance instanceof Call +class OpenSslRandomNumberGeneratorInstance extends Crypto::RandomNumberGenerationInstance instanceof Call { - OpenSSLRandomNumberGeneratorInstance() { - this.(Call).getTarget().getName() in ["RAND_bytes", "RAND_pseudo_bytes"] and - isPossibleOpenSSLFunction(this.(Call).getTarget()) + OpenSslRandomNumberGeneratorInstance() { + this.(Call).getTarget().getName() in ["RAND_bytes", "RAND_pseudo_bytes"] } override Crypto::DataFlowNode getOutputNode() { diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected b/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected new file mode 100644 index 000000000000..e9e3bf868ae0 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected @@ -0,0 +1,126 @@ +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Mode | openssl_basic.c:23:37:23:51 | ModeOfOperation | +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Padding | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | +| openssl_basic.c:31:49:31:51 | Key | Source | openssl_basic.c:179:43:179:76 | Constant | +| openssl_basic.c:31:54:31:55 | Nonce | Source | openssl_basic.c:180:42:180:59 | Constant | +| openssl_basic.c:35:54:35:62 | Message | Source | openssl_basic.c:181:49:181:87 | Constant | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Algorithm | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Input | openssl_basic.c:35:54:35:62 | Message | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Key | openssl_basic.c:31:49:31:51 | Key | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Nonce | openssl_basic.c:31:54:31:55 | Nonce | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Output | openssl_basic.c:35:36:35:45 | KeyOperationOutput | +| openssl_basic.c:40:13:40:31 | EncryptOperation | Output | openssl_basic.c:40:38:40:53 | KeyOperationOutput | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Mode | openssl_basic.c:69:33:69:47 | ModeOfOperation | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Padding | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | +| openssl_basic.c:77:45:77:47 | Key | Source | openssl_basic.c:179:43:179:76 | Constant | +| openssl_basic.c:77:50:77:51 | Nonce | Source | openssl_basic.c:180:42:180:59 | Constant | +| openssl_basic.c:81:49:81:58 | Message | Source | openssl_basic.c:81:49:81:58 | Message | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Algorithm | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Input | openssl_basic.c:81:49:81:58 | Message | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Key | openssl_basic.c:77:45:77:47 | Key | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Nonce | openssl_basic.c:77:50:77:51 | Nonce | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Output | openssl_basic.c:81:32:81:40 | KeyOperationOutput | +| openssl_basic.c:90:11:90:29 | DecryptOperation | Output | openssl_basic.c:90:36:90:50 | KeyOperationOutput | +| openssl_basic.c:120:37:120:43 | Message | Source | openssl_basic.c:181:49:181:87 | Constant | +| openssl_basic.c:124:13:124:30 | HashOperation | Algorithm | openssl_basic.c:116:38:116:47 | HashAlgorithm | +| openssl_basic.c:124:13:124:30 | HashOperation | Digest | openssl_basic.c:124:39:124:44 | Digest | +| openssl_basic.c:124:13:124:30 | HashOperation | Message | openssl_basic.c:120:37:120:43 | Message | +| openssl_basic.c:124:39:124:44 | Digest | Source | openssl_basic.c:124:39:124:44 | Digest | +| openssl_basic.c:144:13:144:22 | HashOperation | Algorithm | openssl_basic.c:144:67:144:73 | HashAlgorithm | +| openssl_basic.c:144:13:144:22 | HashOperation | Digest | openssl_basic.c:144:46:144:51 | Digest | +| openssl_basic.c:144:13:144:22 | HashOperation | Message | openssl_basic.c:144:24:144:30 | Message | +| openssl_basic.c:144:24:144:30 | Message | Source | openssl_basic.c:181:49:181:87 | Constant | +| openssl_basic.c:144:46:144:51 | Digest | Source | openssl_basic.c:144:46:144:51 | Digest | +| openssl_basic.c:155:22:155:41 | KeyGeneration | Algorithm | openssl_basic.c:155:22:155:41 | KeyGeneration | +| openssl_basic.c:155:22:155:41 | KeyGeneration | Output | openssl_basic.c:155:22:155:41 | Key | +| openssl_basic.c:155:43:155:55 | MACAlgorithm | H | openssl_basic.c:160:39:160:48 | HashAlgorithm | +| openssl_basic.c:160:59:160:62 | Key | Source | openssl_basic.c:155:22:155:41 | Key | +| openssl_basic.c:163:35:163:41 | Message | Source | openssl_basic.c:181:49:181:87 | Constant | +| openssl_basic.c:167:9:167:27 | SignOperation | Algorithm | openssl_basic.c:167:9:167:27 | SignOperation | +| openssl_basic.c:167:9:167:27 | SignOperation | HashAlgorithm | openssl_basic.c:160:39:160:48 | HashAlgorithm | +| openssl_basic.c:167:9:167:27 | SignOperation | Input | openssl_basic.c:163:35:163:41 | Message | +| openssl_basic.c:167:9:167:27 | SignOperation | Key | openssl_basic.c:160:59:160:62 | Key | +| openssl_basic.c:167:9:167:27 | SignOperation | Output | openssl_basic.c:167:34:167:36 | SignatureOutput | +| openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | Mode | openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | +| openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | Padding | openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | +| openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | Mode | openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | Padding | openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:55:9:55:23 | KeyGeneration | Algorithm | openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:55:9:55:23 | KeyGeneration | Output | openssl_pkey.c:55:30:55:34 | Key | +| openssl_pkey.c:55:30:55:34 | Key | Algorithm | openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:60:28:60:31 | Key | Source | openssl_pkey.c:55:30:55:34 | Key | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | Algorithm | openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | Input | openssl_pkey.c:64:58:64:66 | Message | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | Key | openssl_pkey.c:60:28:60:31 | Key | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | Nonce | openssl_pkey.c:64:9:64:24 | EncryptOperation | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | Output | openssl_pkey.c:64:31:64:39 | KeyOperationOutput | +| openssl_pkey.c:64:58:64:66 | Message | Source | openssl_pkey.c:45:49:45:65 | Constant | +| openssl_signature.c:22:34:22:40 | Message | Source | openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:22:34:22:40 | Message | Source | openssl_signature.c:685:37:685:77 | Constant | +| openssl_signature.c:22:34:22:40 | Message | Source | openssl_signature.c:741:37:741:77 | Constant | +| openssl_signature.c:23:9:23:26 | HashOperation | Algorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:23:9:23:26 | HashOperation | Algorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:23:9:23:26 | HashOperation | Digest | openssl_signature.c:23:36:23:41 | Digest | +| openssl_signature.c:23:9:23:26 | HashOperation | Message | openssl_signature.c:22:34:22:40 | Message | +| openssl_signature.c:23:36:23:41 | Digest | Source | openssl_signature.c:23:36:23:41 | Digest | +| openssl_signature.c:70:32:70:38 | Message | Source | openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:75:28:75:36 | Message | Source | openssl_signature.c:75:28:75:36 | Message | +| openssl_signature.c:80:9:80:21 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:80:9:80:21 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:80:9:80:21 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:80:9:80:21 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:80:9:80:21 | SignOperation | Input | openssl_signature.c:70:32:70:38 | Message | +| openssl_signature.c:80:9:80:21 | SignOperation | Input | openssl_signature.c:75:28:75:36 | Message | +| openssl_signature.c:80:9:80:21 | SignOperation | Key | openssl_signature.c:80:53:80:56 | Key | +| openssl_signature.c:80:9:80:21 | SignOperation | Output | openssl_signature.c:80:31:80:40 | SignatureOutput | +| openssl_signature.c:80:53:80:56 | Key | Source | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:80:53:80:56 | Key | Source | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:133:52:133:55 | Key | Source | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:133:52:133:55 | Key | Source | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:134:38:134:44 | Message | Source | openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:142:9:142:27 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:142:9:142:27 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:142:9:142:27 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:142:9:142:27 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:142:9:142:27 | SignOperation | Input | openssl_signature.c:134:38:134:44 | Message | +| openssl_signature.c:142:9:142:27 | SignOperation | Key | openssl_signature.c:133:52:133:55 | Key | +| openssl_signature.c:142:9:142:27 | SignOperation | Output | openssl_signature.c:142:37:142:46 | SignatureOutput | +| openssl_signature.c:190:57:190:60 | Key | Source | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:190:57:190:60 | Key | Source | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:196:38:196:44 | Message | Source | openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:204:9:204:27 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:204:9:204:27 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:204:9:204:27 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:204:9:204:27 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:204:9:204:27 | SignOperation | Input | openssl_signature.c:196:38:196:44 | Message | +| openssl_signature.c:204:9:204:27 | SignOperation | Key | openssl_signature.c:190:57:190:60 | Key | +| openssl_signature.c:204:9:204:27 | SignOperation | Output | openssl_signature.c:204:37:204:46 | SignatureOutput | +| openssl_signature.c:260:39:260:42 | Key | Source | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:260:39:260:42 | Key | Source | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:270:9:270:21 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:270:9:270:21 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:270:9:270:21 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:270:9:270:21 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:270:9:270:21 | SignOperation | Input | openssl_signature.c:270:60:270:65 | Message | +| openssl_signature.c:270:9:270:21 | SignOperation | Key | openssl_signature.c:260:39:260:42 | Key | +| openssl_signature.c:270:9:270:21 | SignOperation | Output | openssl_signature.c:270:33:270:42 | SignatureOutput | +| openssl_signature.c:270:60:270:65 | Message | Source | openssl_signature.c:270:60:270:65 | Message | +| openssl_signature.c:321:39:321:42 | Key | Source | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:321:39:321:42 | Key | Source | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:326:48:326:54 | Message | Source | openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:334:9:334:35 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:334:9:334:35 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:334:9:334:35 | SignOperation | Algorithm | openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | +| openssl_signature.c:334:9:334:35 | SignOperation | Algorithm | openssl_signature.c:758:60:758:64 | KeyOperationAlgorithm | +| openssl_signature.c:334:9:334:35 | SignOperation | HashAlgorithm | openssl_signature.c:334:9:334:35 | SignOperation | +| openssl_signature.c:334:9:334:35 | SignOperation | Input | openssl_signature.c:326:48:326:54 | Message | +| openssl_signature.c:334:9:334:35 | SignOperation | Key | openssl_signature.c:321:39:321:42 | Key | +| openssl_signature.c:334:9:334:35 | SignOperation | Output | openssl_signature.c:334:47:334:56 | SignatureOutput | +| openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:548:9:548:23 | KeyGeneration | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:548:9:548:23 | KeyGeneration | Output | openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:548:34:548:37 | Key | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:578:9:578:23 | KeyGeneration | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:578:9:578:23 | KeyGeneration | Output | openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:578:34:578:37 | Key | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | Padding | openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_edges.ql b/cpp/ql/test/experimental/library-tests/quantum/node_edges.ql new file mode 100644 index 000000000000..6d6507a91bfc --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/node_edges.ql @@ -0,0 +1,5 @@ +import cpp +import experimental.quantum.Language + +from Crypto::NodeBase n, string key +select n, key, n.getChild(key) diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected b/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected new file mode 100644 index 000000000000..1ac047ad334e --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected @@ -0,0 +1,79 @@ +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | KeySize | 256 | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Name | AES | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | RawName | EVP_aes_256_gcm | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Structure | Block | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:23:37:23:51 | ModeOfOperation | Name | GCM | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:23:37:23:51 | ModeOfOperation | RawName | EVP_aes_256_gcm | openssl_basic.c:23:37:23:51 | openssl_basic.c:23:37:23:51 | +| openssl_basic.c:31:49:31:51 | Key | KeyType | Unknown | openssl_basic.c:31:49:31:51 | openssl_basic.c:31:49:31:51 | +| openssl_basic.c:40:13:40:31 | EncryptOperation | KeyOperationSubtype | Encrypt | openssl_basic.c:40:13:40:31 | openssl_basic.c:40:13:40:31 | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | KeySize | 256 | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Name | AES | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | RawName | EVP_aes_256_gcm | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Structure | Block | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:69:33:69:47 | ModeOfOperation | Name | GCM | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:69:33:69:47 | ModeOfOperation | RawName | EVP_aes_256_gcm | openssl_basic.c:69:33:69:47 | openssl_basic.c:69:33:69:47 | +| openssl_basic.c:77:45:77:47 | Key | KeyType | Unknown | openssl_basic.c:77:45:77:47 | openssl_basic.c:77:45:77:47 | +| openssl_basic.c:90:11:90:29 | DecryptOperation | KeyOperationSubtype | Decrypt | openssl_basic.c:90:11:90:29 | openssl_basic.c:90:11:90:29 | +| openssl_basic.c:116:38:116:47 | HashAlgorithm | DigestSize | 256 | openssl_basic.c:116:38:116:47 | openssl_basic.c:116:38:116:47 | +| openssl_basic.c:116:38:116:47 | HashAlgorithm | Name | SHA2 | openssl_basic.c:116:38:116:47 | openssl_basic.c:116:38:116:47 | +| openssl_basic.c:116:38:116:47 | HashAlgorithm | RawName | EVP_sha256 | openssl_basic.c:116:38:116:47 | openssl_basic.c:116:38:116:47 | +| openssl_basic.c:144:67:144:73 | HashAlgorithm | DigestSize | 128 | openssl_basic.c:144:67:144:73 | openssl_basic.c:144:67:144:73 | +| openssl_basic.c:144:67:144:73 | HashAlgorithm | Name | MD5 | openssl_basic.c:144:67:144:73 | openssl_basic.c:144:67:144:73 | +| openssl_basic.c:144:67:144:73 | HashAlgorithm | RawName | EVP_md5 | openssl_basic.c:144:67:144:73 | openssl_basic.c:144:67:144:73 | +| openssl_basic.c:155:22:155:41 | Key | KeyType | Symmetric | openssl_basic.c:155:22:155:41 | openssl_basic.c:155:22:155:41 | +| openssl_basic.c:155:43:155:55 | MACAlgorithm | Name | HMAC | openssl_basic.c:155:43:155:55 | openssl_basic.c:155:43:155:55 | +| openssl_basic.c:155:43:155:55 | MACAlgorithm | RawName | 855 | openssl_basic.c:155:43:155:55 | openssl_basic.c:155:43:155:55 | +| openssl_basic.c:160:39:160:48 | HashAlgorithm | DigestSize | 256 | openssl_basic.c:160:39:160:48 | openssl_basic.c:160:39:160:48 | +| openssl_basic.c:160:39:160:48 | HashAlgorithm | Name | SHA2 | openssl_basic.c:160:39:160:48 | openssl_basic.c:160:39:160:48 | +| openssl_basic.c:160:39:160:48 | HashAlgorithm | RawName | EVP_sha256 | openssl_basic.c:160:39:160:48 | openssl_basic.c:160:39:160:48 | +| openssl_basic.c:160:59:160:62 | Key | KeyType | Unknown | openssl_basic.c:160:59:160:62 | openssl_basic.c:160:59:160:62 | +| openssl_basic.c:167:9:167:27 | SignOperation | KeyOperationSubtype | Sign | openssl_basic.c:167:9:167:27 | openssl_basic.c:167:9:167:27 | +| openssl_basic.c:179:43:179:76 | Constant | Description | 01234567890123456789012345678901 | openssl_basic.c:179:43:179:76 | openssl_basic.c:179:43:179:76 | +| openssl_basic.c:180:42:180:59 | Constant | Description | 0123456789012345 | openssl_basic.c:180:42:180:59 | openssl_basic.c:180:42:180:59 | +| openssl_basic.c:181:49:181:87 | Constant | Description | This is a test message for encryption | openssl_basic.c:181:49:181:87 | openssl_basic.c:181:49:181:87 | +| openssl_basic.c:218:32:218:33 | Constant | Description | 32 | openssl_basic.c:218:32:218:33 | openssl_basic.c:218:32:218:33 | +| openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | Name | RSA | openssl_pkey.c:21:10:21:28 | openssl_pkey.c:21:10:21:28 | +| openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | RawName | RSA_generate_key_ex | openssl_pkey.c:21:10:21:28 | openssl_pkey.c:21:10:21:28 | +| openssl_pkey.c:45:49:45:65 | Constant | Description | Hello, OpenSSL! | openssl_pkey.c:45:49:45:65 | openssl_pkey.c:45:49:45:65 | +| openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | Name | RSA | openssl_pkey.c:50:31:50:42 | openssl_pkey.c:50:31:50:42 | +| openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | RawName | 6 | openssl_pkey.c:50:31:50:42 | openssl_pkey.c:50:31:50:42 | +| openssl_pkey.c:54:47:54:50 | Constant | Description | 2048 | openssl_pkey.c:54:47:54:50 | openssl_pkey.c:54:47:54:50 | +| openssl_pkey.c:55:30:55:34 | Key | KeyType | Asymmetric | openssl_pkey.c:55:30:55:34 | openssl_pkey.c:55:30:55:34 | +| openssl_pkey.c:60:28:60:31 | Key | KeyType | Unknown | openssl_pkey.c:60:28:60:31 | openssl_pkey.c:60:28:60:31 | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | KeyOperationSubtype | Encrypt | openssl_pkey.c:64:9:64:24 | openssl_pkey.c:64:9:64:24 | +| openssl_signature.c:80:9:80:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:80:9:80:21 | openssl_signature.c:80:9:80:21 | +| openssl_signature.c:80:53:80:56 | Key | KeyType | Unknown | openssl_signature.c:80:53:80:56 | openssl_signature.c:80:53:80:56 | +| openssl_signature.c:133:52:133:55 | Key | KeyType | Unknown | openssl_signature.c:133:52:133:55 | openssl_signature.c:133:52:133:55 | +| openssl_signature.c:142:9:142:27 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:142:9:142:27 | openssl_signature.c:142:9:142:27 | +| openssl_signature.c:190:57:190:60 | Key | KeyType | Unknown | openssl_signature.c:190:57:190:60 | openssl_signature.c:190:57:190:60 | +| openssl_signature.c:204:9:204:27 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:204:9:204:27 | openssl_signature.c:204:9:204:27 | +| openssl_signature.c:260:39:260:42 | Key | KeyType | Unknown | openssl_signature.c:260:39:260:42 | openssl_signature.c:260:39:260:42 | +| openssl_signature.c:270:9:270:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:270:9:270:21 | openssl_signature.c:270:9:270:21 | +| openssl_signature.c:321:39:321:42 | Key | KeyType | Unknown | openssl_signature.c:321:39:321:42 | openssl_signature.c:321:39:321:42 | +| openssl_signature.c:334:9:334:35 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:334:9:334:35 | openssl_signature.c:334:9:334:35 | +| openssl_signature.c:521:46:521:66 | PaddingAlgorithm | Name | PSS | openssl_signature.c:521:46:521:66 | openssl_signature.c:521:46:521:66 | +| openssl_signature.c:521:46:521:66 | PaddingAlgorithm | RawName | 6 | openssl_signature.c:521:46:521:66 | openssl_signature.c:521:46:521:66 | +| openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:543:35:543:46 | openssl_signature.c:543:35:543:46 | +| openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:543:35:543:46 | openssl_signature.c:543:35:543:46 | +| openssl_signature.c:547:51:547:54 | Constant | Description | 2048 | openssl_signature.c:547:51:547:54 | openssl_signature.c:547:51:547:54 | +| openssl_signature.c:548:34:548:37 | Key | KeyType | Asymmetric | openssl_signature.c:548:34:548:37 | openssl_signature.c:548:34:548:37 | +| openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | Name | DSA | openssl_signature.c:565:50:565:54 | openssl_signature.c:565:50:565:54 | +| openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | RawName | dsa | openssl_signature.c:565:50:565:54 | openssl_signature.c:565:50:565:54 | +| openssl_signature.c:569:55:569:58 | Constant | Description | 2048 | openssl_signature.c:569:55:569:58 | openssl_signature.c:569:55:569:58 | +| openssl_signature.c:578:34:578:37 | Key | KeyType | Asymmetric | openssl_signature.c:578:34:578:37 | openssl_signature.c:578:34:578:37 | +| openssl_signature.c:602:37:602:77 | Constant | Description | Test message for OpenSSL signature APIs | openssl_signature.c:602:37:602:77 | openssl_signature.c:602:37:602:77 | +| openssl_signature.c:684:24:684:33 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:684:24:684:33 | openssl_signature.c:684:24:684:33 | +| openssl_signature.c:684:24:684:33 | HashAlgorithm | Name | SHA2 | openssl_signature.c:684:24:684:33 | openssl_signature.c:684:24:684:33 | +| openssl_signature.c:684:24:684:33 | HashAlgorithm | RawName | EVP_sha256 | openssl_signature.c:684:24:684:33 | openssl_signature.c:684:24:684:33 | +| openssl_signature.c:685:37:685:77 | Constant | Description | Test message for OpenSSL signature APIs | openssl_signature.c:685:37:685:77 | openssl_signature.c:685:37:685:77 | +| openssl_signature.c:702:60:702:71 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:702:60:702:71 | openssl_signature.c:702:60:702:71 | +| openssl_signature.c:702:60:702:71 | HashAlgorithm | Name | SHA2 | openssl_signature.c:702:60:702:71 | openssl_signature.c:702:60:702:71 | +| openssl_signature.c:702:60:702:71 | HashAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:702:60:702:71 | openssl_signature.c:702:60:702:71 | +| openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:702:60:702:71 | openssl_signature.c:702:60:702:71 | +| openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:702:60:702:71 | openssl_signature.c:702:60:702:71 | +| openssl_signature.c:740:24:740:33 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:740:24:740:33 | openssl_signature.c:740:24:740:33 | +| openssl_signature.c:740:24:740:33 | HashAlgorithm | Name | SHA2 | openssl_signature.c:740:24:740:33 | openssl_signature.c:740:24:740:33 | +| openssl_signature.c:740:24:740:33 | HashAlgorithm | RawName | EVP_sha256 | openssl_signature.c:740:24:740:33 | openssl_signature.c:740:24:740:33 | +| openssl_signature.c:741:37:741:77 | Constant | Description | Test message for OpenSSL signature APIs | openssl_signature.c:741:37:741:77 | openssl_signature.c:741:37:741:77 | +| openssl_signature.c:758:60:758:64 | KeyOperationAlgorithm | Name | DSA | openssl_signature.c:758:60:758:64 | openssl_signature.c:758:60:758:64 | +| openssl_signature.c:758:60:758:64 | KeyOperationAlgorithm | RawName | dsa | openssl_signature.c:758:60:758:64 | openssl_signature.c:758:60:758:64 | diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_properties.ql b/cpp/ql/test/experimental/library-tests/quantum/node_properties.ql new file mode 100644 index 000000000000..38d3a59b31f1 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/node_properties.ql @@ -0,0 +1,6 @@ +import cpp +import experimental.quantum.Language + +from Crypto::NodeBase n, string key, string value, Location location +where n.properties(key, value, location) +select n, key, value, location diff --git a/cpp/ql/test/experimental/library-tests/quantum/nodes.expected b/cpp/ql/test/experimental/library-tests/quantum/nodes.expected new file mode 100644 index 000000000000..5c3b212b0804 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/nodes.expected @@ -0,0 +1,87 @@ +| openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | +| openssl_basic.c:23:37:23:51 | ModeOfOperation | +| openssl_basic.c:31:49:31:51 | Key | +| openssl_basic.c:31:54:31:55 | Nonce | +| openssl_basic.c:35:36:35:45 | KeyOperationOutput | +| openssl_basic.c:35:54:35:62 | Message | +| openssl_basic.c:40:13:40:31 | EncryptOperation | +| openssl_basic.c:40:38:40:53 | KeyOperationOutput | +| openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | +| openssl_basic.c:69:33:69:47 | ModeOfOperation | +| openssl_basic.c:77:45:77:47 | Key | +| openssl_basic.c:77:50:77:51 | Nonce | +| openssl_basic.c:81:32:81:40 | KeyOperationOutput | +| openssl_basic.c:81:49:81:58 | Message | +| openssl_basic.c:90:11:90:29 | DecryptOperation | +| openssl_basic.c:90:36:90:50 | KeyOperationOutput | +| openssl_basic.c:116:38:116:47 | HashAlgorithm | +| openssl_basic.c:120:37:120:43 | Message | +| openssl_basic.c:124:13:124:30 | HashOperation | +| openssl_basic.c:124:39:124:44 | Digest | +| openssl_basic.c:144:13:144:22 | HashOperation | +| openssl_basic.c:144:24:144:30 | Message | +| openssl_basic.c:144:46:144:51 | Digest | +| openssl_basic.c:144:67:144:73 | HashAlgorithm | +| openssl_basic.c:155:22:155:41 | Key | +| openssl_basic.c:155:22:155:41 | KeyGeneration | +| openssl_basic.c:155:43:155:55 | MACAlgorithm | +| openssl_basic.c:160:39:160:48 | HashAlgorithm | +| openssl_basic.c:160:59:160:62 | Key | +| openssl_basic.c:163:35:163:41 | Message | +| openssl_basic.c:167:9:167:27 | SignOperation | +| openssl_basic.c:167:34:167:36 | SignatureOutput | +| openssl_basic.c:179:43:179:76 | Constant | +| openssl_basic.c:180:42:180:59 | Constant | +| openssl_basic.c:181:49:181:87 | Constant | +| openssl_basic.c:218:32:218:33 | Constant | +| openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | +| openssl_pkey.c:45:49:45:65 | Constant | +| openssl_pkey.c:50:31:50:42 | KeyOperationAlgorithm | +| openssl_pkey.c:54:47:54:50 | Constant | +| openssl_pkey.c:55:9:55:23 | KeyGeneration | +| openssl_pkey.c:55:30:55:34 | Key | +| openssl_pkey.c:60:28:60:31 | Key | +| openssl_pkey.c:64:9:64:24 | EncryptOperation | +| openssl_pkey.c:64:31:64:39 | KeyOperationOutput | +| openssl_pkey.c:64:58:64:66 | Message | +| openssl_signature.c:22:34:22:40 | Message | +| openssl_signature.c:23:9:23:26 | HashOperation | +| openssl_signature.c:23:36:23:41 | Digest | +| openssl_signature.c:70:32:70:38 | Message | +| openssl_signature.c:75:28:75:36 | Message | +| openssl_signature.c:80:9:80:21 | SignOperation | +| openssl_signature.c:80:31:80:40 | SignatureOutput | +| openssl_signature.c:80:53:80:56 | Key | +| openssl_signature.c:133:52:133:55 | Key | +| openssl_signature.c:134:38:134:44 | Message | +| openssl_signature.c:142:9:142:27 | SignOperation | +| openssl_signature.c:142:37:142:46 | SignatureOutput | +| openssl_signature.c:190:57:190:60 | Key | +| openssl_signature.c:196:38:196:44 | Message | +| openssl_signature.c:204:9:204:27 | SignOperation | +| openssl_signature.c:204:37:204:46 | SignatureOutput | +| openssl_signature.c:260:39:260:42 | Key | +| openssl_signature.c:270:9:270:21 | SignOperation | +| openssl_signature.c:270:33:270:42 | SignatureOutput | +| openssl_signature.c:270:60:270:65 | Message | +| openssl_signature.c:321:39:321:42 | Key | +| openssl_signature.c:326:48:326:54 | Message | +| openssl_signature.c:334:9:334:35 | SignOperation | +| openssl_signature.c:334:47:334:56 | SignatureOutput | +| openssl_signature.c:521:46:521:66 | PaddingAlgorithm | +| openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | +| openssl_signature.c:547:51:547:54 | Constant | +| openssl_signature.c:548:9:548:23 | KeyGeneration | +| openssl_signature.c:548:34:548:37 | Key | +| openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | +| openssl_signature.c:569:55:569:58 | Constant | +| openssl_signature.c:578:9:578:23 | KeyGeneration | +| openssl_signature.c:578:34:578:37 | Key | +| openssl_signature.c:602:37:602:77 | Constant | +| openssl_signature.c:684:24:684:33 | HashAlgorithm | +| openssl_signature.c:685:37:685:77 | Constant | +| openssl_signature.c:702:60:702:71 | HashAlgorithm | +| openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | +| openssl_signature.c:740:24:740:33 | HashAlgorithm | +| openssl_signature.c:741:37:741:77 | Constant | +| openssl_signature.c:758:60:758:64 | KeyOperationAlgorithm | diff --git a/cpp/ql/test/experimental/library-tests/quantum/nodes.ql b/cpp/ql/test/experimental/library-tests/quantum/nodes.ql new file mode 100644 index 000000000000..83858a7d60d8 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/nodes.ql @@ -0,0 +1,5 @@ +import cpp +import experimental.quantum.Language + +from Crypto::NodeBase n +select n diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.expected deleted file mode 100644 index 749e7ee0fc61..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.expected +++ /dev/null @@ -1,2 +0,0 @@ -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:179:43:179:76 | Constant | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:179:43:179:76 | Constant | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.ql deleted file mode 100644 index 039477ebc6ac..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_key_sources.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::CipherOperationNode op, Crypto::KeyArtifactNode k -where op.getAKey() = k -select op, k, k.getSourceNode() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.expected deleted file mode 100644 index 76cce2449439..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.expected +++ /dev/null @@ -1,2 +0,0 @@ -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:180:42:180:59 | Constant | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:180:42:180:59 | Constant | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.ql deleted file mode 100644 index d37ccf3762d5..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_nonce_sources.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::CipherOperationNode op, Crypto::NonceArtifactNode n -where op.getANonce() = n -select op, n, n.getSourceNode() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.expected deleted file mode 100644 index 73b0af3ad5f4..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.expected +++ /dev/null @@ -1,16 +0,0 @@ -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:35:36:35:45 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:35:36:35:45 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:35:36:35:45 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:35:36:35:45 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:81:32:81:40 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:81:32:81:40 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:81:32:81:40 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:81:32:81:40 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | -| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.ql deleted file mode 100644 index 9ce06567195d..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_operations.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::CipherOperationNode n -select n, n.getAnInputArtifact(), n.getAnOutputArtifact(), n.getAKey(), n.getANonce(), - n.getAnAlgorithmOrGenericSource(), n.getKeyOperationSubtype() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.expected deleted file mode 100644 index 1bea7895a349..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.expected +++ /dev/null @@ -1 +0,0 @@ -| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:181:49:181:87 | Constant | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.ql deleted file mode 100644 index 762dfb0c02bd..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/cipher_plaintext_sources.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::CipherOperationNode n, Crypto::MessageArtifactNode m -where n.getAnInputArtifact() = m -select n, m, m.getSourceNode() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.expected deleted file mode 100644 index 79ba1387a1ec..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.expected +++ /dev/null @@ -1,2 +0,0 @@ -| openssl_basic.c:124:13:124:30 | HashOperation | openssl_basic.c:120:37:120:43 | Message | openssl_basic.c:181:49:181:87 | Constant | -| openssl_basic.c:144:13:144:22 | HashOperation | openssl_basic.c:144:24:144:30 | Message | openssl_basic.c:181:49:181:87 | Constant | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.ql deleted file mode 100644 index fff38028b642..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_input_sources.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::HashOperationNode n, Crypto::MessageArtifactNode m -where n.getInputArtifact() = m -select n, m, m.getSourceNode() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.expected b/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.expected deleted file mode 100644 index 247c4389bc1a..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.expected +++ /dev/null @@ -1,2 +0,0 @@ -| openssl_basic.c:124:13:124:30 | HashOperation | openssl_basic.c:124:39:124:44 | Digest | openssl_basic.c:116:38:116:47 | HashAlgorithm | openssl_basic.c:120:37:120:43 | Message | -| openssl_basic.c:144:13:144:22 | HashOperation | openssl_basic.c:144:46:144:51 | Digest | openssl_basic.c:144:67:144:73 | HashAlgorithm | openssl_basic.c:144:24:144:30 | Message | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.ql b/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.ql deleted file mode 100644 index 50d831230e8f..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/hash_operations.ql +++ /dev/null @@ -1,5 +0,0 @@ -import cpp -import experimental.quantum.Language - -from Crypto::HashOperationNode n -select n, n.getDigest(), n.getAnAlgorithmOrGenericSource(), n.getInputArtifact() diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/options b/cpp/ql/test/experimental/library-tests/quantum/openssl/options deleted file mode 100644 index eb3abc42d12c..000000000000 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: -I ../../../stubs \ No newline at end of file diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl/openssl_basic.c b/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c similarity index 98% rename from cpp/ql/test/experimental/library-tests/quantum/openssl/openssl_basic.c rename to cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c index ba6aa805c0b3..f1ffbfa24d36 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl/openssl_basic.c +++ b/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c @@ -1,6 +1,6 @@ -#include "openssl/evp_stubs.h" -#include "openssl/alg_macro_stubs.h" -#include "openssl/rand_stubs.h" +#include "openssl/evp.h" +#include "openssl/obj_mac.h" +#include "openssl/rand.h" size_t strlen(const char* str); diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl_pkey.c b/cpp/ql/test/experimental/library-tests/quantum/openssl_pkey.c new file mode 100644 index 000000000000..ba5e43bf33c7 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/openssl_pkey.c @@ -0,0 +1,70 @@ + +#include +#include +#include +#include + +// #include +// #include +// #include +// #include +// #include +// #include + + +int generate_rsa_pkey() { + int key_length = 2048; + RSA *rsa = RSA_new(); + BIGNUM *bne = BN_new(); + BN_set_word(bne, RSA_F4); + + if (!RSA_generate_key_ex(rsa, key_length, bne, NULL)) { + return -1; + } + + // Save private key + FILE *priv_file = fopen("private_key.pem", "wb"); + PEM_write_RSAPrivateKey(priv_file, rsa, NULL, NULL, 0, NULL, NULL); + fclose(priv_file); + + // Save public key + FILE *pub_file = fopen("public_key.pem", "wb"); + PEM_write_RSA_PUBKEY(pub_file, rsa); + fclose(pub_file); + + RSA_free(rsa); + BN_free(bne); + + return 0; +} + + +int generate_evp_pkey() { + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + unsigned char *plaintext = (unsigned char *)"Hello, OpenSSL!"; + unsigned char encrypted[256]; + size_t encrypted_len; + + // Generate RSA key + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!ctx) return -1; + + if (EVP_PKEY_keygen_init(ctx) <= 0) return -1; + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) return -1; + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) return -1; + + EVP_PKEY_CTX_free(ctx); + + // Encrypt using the generated key + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) handleErrors(); + + if (EVP_PKEY_encrypt_init(ctx) <= 0) return -1; + if (EVP_PKEY_encrypt(ctx, encrypted, &encrypted_len, plaintext, strlen((char *)plaintext)) <= 0) return -1; + + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + + return 0; +} diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c b/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c new file mode 100644 index 000000000000..f8be74416423 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c @@ -0,0 +1,819 @@ +// #ifdef USE_REAL_HEADERS +#include +#include +#include +#include + +/* ============================================================================= + * UTILITY FUNCTIONS - Common operations shared across signature APIs + * ============================================================================= + */ + +/** + * Create message digest from raw message data + */ +static int create_digest(const unsigned char *message, size_t message_len, + const EVP_MD *md, unsigned char *digest, unsigned int *digest_len) { + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + int ret = 0; + + if (!md_ctx || + EVP_DigestInit_ex(md_ctx, md, NULL) != 1 || + EVP_DigestUpdate(md_ctx, message, message_len) != 1 || + EVP_DigestFinal_ex(md_ctx, digest, digest_len) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/** + * Allocate signature buffer with appropriate size + */ +static unsigned char* allocate_signature_buffer(size_t *sig_len, const EVP_PKEY *pkey) { + *sig_len = EVP_PKEY_size(pkey); + return OPENSSL_malloc(*sig_len); +} + +/** + * Helper to extract key from EVP_PKEY + */ +static RSA* get_rsa_from_pkey(EVP_PKEY *pkey) { + return EVP_PKEY_get1_RSA(pkey); +} + +static DSA* get_dsa_from_pkey(EVP_PKEY *pkey) { + return EVP_PKEY_get1_DSA(pkey); +} + +/* ============================================================================= + * EVP_SIGN/VERIFY API - Legacy high-level API (older, simpler) + * ============================================================================= + */ + +/** + * Sign message using EVP_Sign API (legacy) + * Simple API with built-in hashing and signing + */ +int sign_using_evp_sign(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_MD_CTX *md_ctx = NULL; + unsigned int sig_len = 0; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_SignInit(md_ctx, md) != 1 || + EVP_SignUpdate(md_ctx, message, message_len) != 1) { + goto cleanup; + } + + // more updates + EVP_SignUpdate(md_ctx, message+1, message_len-1); + + *signature = allocate_signature_buffer(signature_len, pkey); + if (!*signature) goto cleanup; + + if (EVP_SignFinal(md_ctx, *signature, &sig_len, pkey) == 1) { + *signature_len = sig_len; + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/** + * Verify signature using EVP_Verify API (legacy) + * Simple API with built-in hashing and verification + */ +int verify_using_evp_verify(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_MD_CTX *md_ctx = NULL; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_VerifyInit(md_ctx, md) != 1 || + EVP_VerifyUpdate(md_ctx, message, message_len) != 1 || + EVP_VerifyUpdate(md_ctx, message+1, message_len-1) != 1 || + EVP_VerifyFinal(md_ctx, signature, (unsigned int)signature_len, pkey) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/* ============================================================================= + * EVP_DIGESTSIGN/DIGESTVERIFY API - Modern recommended API + * ============================================================================= + */ + +/** + * Sign message using EVP_DigestSign API (recommended) + * Modern flexible API with better algorithm support + */ +int sign_using_evp_digestsign(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_MD_CTX *md_ctx = NULL; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_DigestSignInit(md_ctx, NULL, md, NULL, pkey) != 1 || + EVP_DigestSignUpdate(md_ctx, message, message_len) != 1 || + EVP_DigestSignFinal(md_ctx, NULL, signature_len) != 1) { + goto cleanup; + } + + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) goto cleanup; + + if (EVP_DigestSignFinal(md_ctx, *signature, signature_len) == 1) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/** + * Verify signature using EVP_DigestVerify API (recommended) + * Modern flexible API with better algorithm support + */ +int verify_using_evp_digestverify(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_MD_CTX *md_ctx = NULL; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_DigestVerifyInit(md_ctx, NULL, md, NULL, pkey) != 1 || + EVP_DigestVerifyUpdate(md_ctx, message, message_len) != 1 || + EVP_DigestVerifyFinal(md_ctx, signature, signature_len) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/** + * Sign with explicit PKEY_CTX for fine-grained parameter control + * Allows custom parameter settings (e.g., padding, salt length) + */ +int sign_using_digestsign_with_ctx(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + EVP_PKEY *pkey, const EVP_MD *md, + int (*param_setter)(EVP_PKEY_CTX *ctx)) { + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) { + goto cleanup; + } + + if (param_setter && param_setter(pkey_ctx) != 1) goto cleanup; + + if (EVP_DigestSignUpdate(md_ctx, message, message_len) != 1 || + EVP_DigestSignFinal(md_ctx, NULL, signature_len) != 1) { + goto cleanup; + } + + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) goto cleanup; + + if (EVP_DigestSignFinal(md_ctx, *signature, signature_len) == 1) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/** + * Verify with explicit PKEY_CTX for fine-grained parameter control + */ +int verify_using_digestverify_with_ctx(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + EVP_PKEY *pkey, const EVP_MD *md, + int (*param_setter)(EVP_PKEY_CTX *ctx)) { + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + int ret = 0; + + if (!(md_ctx = EVP_MD_CTX_new()) || + EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) { + goto cleanup; + } + + if (param_setter && param_setter(pkey_ctx) != 1) goto cleanup; + + if (EVP_DigestVerifyUpdate(md_ctx, message, message_len) != 1 || + EVP_DigestVerifyFinal(md_ctx, signature, signature_len) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/* ============================================================================= + * EVP_PKEY_SIGN/VERIFY API - Lower level API with pre-hashed input + * ============================================================================= + */ + +/** + * Sign pre-hashed digest using EVP_PKEY_sign API + * Lower-level API requiring pre-computed digest + */ +int sign_using_evp_pkey_sign(const unsigned char *digest, size_t digest_len, + unsigned char **signature, size_t *signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_PKEY_CTX *pkey_ctx = NULL; + int ret = 0; + + if (!(pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) || + EVP_PKEY_sign_init(pkey_ctx) != 1 || + EVP_PKEY_CTX_set_signature_md(pkey_ctx, md) != 1 || + EVP_PKEY_sign(pkey_ctx, NULL, signature_len, digest, digest_len) != 1) { + goto cleanup; + } + + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) goto cleanup; + + if (EVP_PKEY_sign(pkey_ctx, *signature, signature_len, digest, digest_len) == 1) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +} + +/** + * Verify pre-hashed digest using EVP_PKEY_verify API + * Lower-level API requiring pre-computed digest + */ +int verify_using_evp_pkey_verify(const unsigned char *digest, size_t digest_len, + const unsigned char *signature, size_t signature_len, + EVP_PKEY *pkey, const EVP_MD *md) { + EVP_PKEY_CTX *pkey_ctx = NULL; + int ret = 0; + + if (!(pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL)) || + EVP_PKEY_verify_init(pkey_ctx) != 1 || + EVP_PKEY_CTX_set_signature_md(pkey_ctx, md) != 1 || + EVP_PKEY_verify(pkey_ctx, signature, signature_len, digest, digest_len) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +} + +/* ============================================================================= + * EVP_PKEY_SIGN_MESSAGE API - Streamlined message signing + * ============================================================================= + */ + +/** + * Sign message using EVP_PKEY_sign_message API + * Streamlined interface for direct message signing + */ +int sign_using_evp_pkey_sign_message(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + EVP_PKEY *pkey, const EVP_MD *md, const char *alg_name) { + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_SIGNATURE *alg = NULL; + int ret = 0; + + if (!(pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL))) goto cleanup; + + alg = EVP_SIGNATURE_fetch(NULL, alg_name, NULL); + + if (EVP_PKEY_sign_message_init(pkey_ctx, alg, NULL) != 1 || + EVP_PKEY_sign_message_update(pkey_ctx, message, message_len) != 1 || + EVP_PKEY_sign_message_final(pkey_ctx, NULL, signature_len) != 1) { + goto cleanup; + } + + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) goto cleanup; + + if (EVP_PKEY_sign_message_final(pkey_ctx, *signature, signature_len) == 1) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +} + +/** + * Verify message using EVP_PKEY_verify_message API + * Streamlined interface for direct message verification + */ +int verify_using_evp_pkey_verify_message(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + EVP_PKEY *pkey, const EVP_MD *md, const char *alg_name) { + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_SIGNATURE *alg = NULL; + int ret = 0; + + if (!(pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL))) goto cleanup; + + alg = EVP_SIGNATURE_fetch(NULL, alg_name, NULL); + + if (EVP_PKEY_verify_message_init(pkey_ctx, alg, NULL) != 1) goto cleanup; + + EVP_PKEY_CTX_set_signature(pkey_ctx, signature, signature_len); + + if (EVP_PKEY_verify_message_update(pkey_ctx, message, message_len) != 1 || + EVP_PKEY_verify_message_final(pkey_ctx) != 1) { + goto cleanup; + } + ret = 1; + +cleanup: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +} + +/* ============================================================================= + * LOW-LEVEL RSA API - Algorithm-specific functions (deprecated) + * ============================================================================= + */ + +/** + * Sign using low-level RSA_sign API (deprecated, RSA-only) + * Direct RSA signing with manual digest computation + */ +int sign_using_rsa_sign(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + RSA *rsa_key, int hash_nid, const EVP_MD *md) { + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + int ret = 0; + + if (!create_digest(message, message_len, md, digest, &digest_len)) return 0; + + *signature_len = RSA_size(rsa_key); + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) return 0; + + if (RSA_sign(hash_nid, digest, digest_len, *signature, + (unsigned int*)signature_len, rsa_key) == 1) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + + return ret; +} + +/** + * Verify using low-level RSA_verify API (deprecated, RSA-only) + * Direct RSA verification with manual digest computation + */ +int verify_using_rsa_verify(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + RSA *rsa_key, int hash_nid, const EVP_MD *md) { + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + + if (!create_digest(message, message_len, md, digest, &digest_len)) return 0; + + return RSA_verify(hash_nid, digest, digest_len, signature, + (unsigned int)signature_len, rsa_key); +} + +/* ============================================================================= + * LOW-LEVEL DSA API - Algorithm-specific functions (deprecated) + * ============================================================================= + */ + +/** + * Sign using low-level DSA_do_sign API (deprecated, DSA-only) + * Direct DSA signing with manual digest and signature encoding + */ +int sign_using_dsa_sign(const unsigned char *message, size_t message_len, + unsigned char **signature, size_t *signature_len, + DSA *dsa_key, const EVP_MD *md) { + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + DSA_SIG *sig = NULL; + const BIGNUM *r = NULL, *s = NULL; + unsigned int bn_len; + int ret = 0; + + if (!create_digest(message, message_len, md, digest, &digest_len)) return 0; + + sig = DSA_do_sign(digest, digest_len, dsa_key); + if (!sig) return 0; + + DSA_SIG_get0(sig, &r, &s); + if (!r || !s) goto cleanup; + + bn_len = DSA_size(dsa_key) / 2; + *signature_len = DSA_size(dsa_key); + *signature = OPENSSL_malloc(*signature_len); + if (!*signature) goto cleanup; + + memset(*signature, 0, *signature_len); + + if (BN_bn2bin(r, *signature + (bn_len - BN_num_bytes(r))) > 0 && + BN_bn2bin(s, *signature + bn_len + (bn_len - BN_num_bytes(s))) > 0) { + ret = 1; + } else { + OPENSSL_free(*signature); + *signature = NULL; + } + +cleanup: + DSA_SIG_free(sig); + return ret; +} + +/** + * Verify using low-level DSA_do_verify API (deprecated, DSA-only) + * Direct DSA verification with manual digest and signature decoding + */ +int verify_using_dsa_verify(const unsigned char *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + DSA *dsa_key, const EVP_MD *md) { + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + DSA_SIG *sig = NULL; + BIGNUM *r = NULL, *s = NULL; + unsigned int bn_len; + int ret = 0; + + if (!create_digest(message, message_len, md, digest, &digest_len)) return 0; + + sig = DSA_SIG_new(); + if (!sig) return 0; + + r = BN_new(); + s = BN_new(); + if (!r || !s) goto cleanup; + + bn_len = DSA_size(dsa_key) / 2; + + if (BN_bin2bn(signature, bn_len, r) && + BN_bin2bn(signature + bn_len, bn_len, s) && + DSA_SIG_set0(sig, r, s) == 1) { + /* r and s are now owned by sig */ + r = s = NULL; + ret = DSA_do_verify(digest, digest_len, sig, dsa_key); + } + +cleanup: + DSA_SIG_free(sig); + BN_free(r); + BN_free(s); + return (ret == 1); +} + +/* ============================================================================= + * PARAMETER SETTERS - Helper functions for algorithm configuration + * ============================================================================= + */ + +/** + * Set RSA PSS padding mode + */ +int set_rsa_pss_padding(EVP_PKEY_CTX *ctx) { + return EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING); +} + +/** + * No-op parameter setter for default behavior + */ +int no_parameter_setter(EVP_PKEY_CTX *ctx) { + return 1; +} + +/* ============================================================================= + * KEY GENERATION HELPERS + * ============================================================================= + */ + +/** + * Generate RSA key pair for testing + */ +static EVP_PKEY* generate_rsa_key(void) { + EVP_PKEY_CTX *key_ctx = NULL; + EVP_PKEY *key = NULL; + + key_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!key_ctx) return NULL; + + if (EVP_PKEY_keygen_init(key_ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_keygen_bits(key_ctx, 2048) <= 0 || + EVP_PKEY_keygen(key_ctx, &key) <= 0) { + EVP_PKEY_free(key); + key = NULL; + } + + EVP_PKEY_CTX_free(key_ctx); + return key; +} + +/** + * Generate DSA key pair for testing + */ +static EVP_PKEY* generate_dsa_key(void) { + EVP_PKEY_CTX *param_ctx = NULL, *key_ctx = NULL; + EVP_PKEY *params = NULL, *key = NULL; + + /* Generate parameters first */ + param_ctx = EVP_PKEY_CTX_new_from_name(NULL, "dsa", NULL); + if (!param_ctx) return NULL; + + if (EVP_PKEY_paramgen_init(param_ctx) <= 0 || + EVP_PKEY_CTX_set_dsa_paramgen_bits(param_ctx, 2048) <= 0 || + EVP_PKEY_paramgen(param_ctx, ¶ms) <= 0) { + goto cleanup; + } + + /* Generate key using parameters */ + key_ctx = EVP_PKEY_CTX_new(params, NULL); + if (!key_ctx || + EVP_PKEY_keygen_init(key_ctx) <= 0 || + EVP_PKEY_keygen(key_ctx, &key) <= 0) { + EVP_PKEY_free(key); + key = NULL; + } + +cleanup: + EVP_PKEY_CTX_free(param_ctx); + EVP_PKEY_CTX_free(key_ctx); + EVP_PKEY_free(params); + return key; +} + +/* ============================================================================= + * TEST FUNCTIONS - Comprehensive API testing + * ============================================================================= + */ + +/** + * Test all signature APIs with a given key and algorithm + * Demonstrates the 6 different signature API approaches + */ +int test_signature_apis(EVP_PKEY *key, const EVP_MD *md, + int (*param_setter)(EVP_PKEY_CTX *ctx), + const char *algo_name) { + const unsigned char message[] = "Test message for OpenSSL signature APIs"; + const size_t message_len = strlen((char *)message); + + unsigned char *sig1 = NULL, *sig2 = NULL, *sig3 = NULL, + *sig4 = NULL, *sig6 = NULL; + size_t sig_len1 = 0, sig_len2 = 0, sig_len3 = 0, sig_len4 = 0, sig_len6 = 0; + + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + int success = 1; + + printf("\nTesting signature APIs with %s:\n", algo_name); + + /* Test 1: EVP_Sign API */ + printf("1. EVP_Sign API: "); + if (sign_using_evp_sign(message, message_len, &sig1, &sig_len1, key, md) && + verify_using_evp_verify(message, message_len, sig1, sig_len1, key, md)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + /* Test 2: EVP_DigestSign API */ + printf("2. EVP_DigestSign API: "); + if (sign_using_evp_digestsign(message, message_len, &sig2, &sig_len2, key, md) && + verify_using_evp_digestverify(message, message_len, sig2, sig_len2, key, md)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + /* Test 3: EVP_PKEY_sign API (requires pre-hashed input) */ + printf("3. EVP_PKEY_sign API: "); + if (create_digest(message, message_len, md, digest, &digest_len) && + sign_using_evp_pkey_sign(digest, digest_len, &sig3, &sig_len3, key, md) && + verify_using_evp_pkey_verify(digest, digest_len, sig3, sig_len3, key, md)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + /* Test 4: EVP_DigestSign with explicit PKEY_CTX */ + printf("4. EVP_DigestSign with explicit PKEY_CTX: "); + if (sign_using_digestsign_with_ctx(message, message_len, &sig4, &sig_len4, + key, md, param_setter) && + verify_using_digestverify_with_ctx(message, message_len, sig4, sig_len4, + key, md, param_setter)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + /* Test 6: EVP_PKEY_sign_message API */ + printf("6. EVP_PKEY_sign_message API: "); + if (sign_using_evp_pkey_sign_message(message, message_len, &sig6, &sig_len6, key, md, algo_name) && + verify_using_evp_pkey_verify_message(message, message_len, sig6, sig_len6, key, md, algo_name)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + /* Cleanup */ + OPENSSL_free(sig1); + OPENSSL_free(sig2); + OPENSSL_free(sig3); + OPENSSL_free(sig4); + OPENSSL_free(sig6); + + return success; +} + +/** + * Test RSA-specific signature APIs including low-level RSA functions + */ +int test_signature_apis_rsa(void) { + EVP_PKEY *key = NULL; + RSA *rsa_key = NULL; + const EVP_MD *md = EVP_sha256(); + const unsigned char message[] = "Test message for OpenSSL signature APIs"; + const size_t message_len = strlen((char *)message); + unsigned char *sig5 = NULL; + size_t sig_len5 = 0; + int success = 1; + + printf("\nGenerating RSA key pair...\n"); + key = generate_rsa_key(); + if (!key) return 0; + + rsa_key = get_rsa_from_pkey(key); + if (!rsa_key) { + EVP_PKEY_free(key); + return 0; + } + + /* Test generic APIs */ + if (!test_signature_apis(key, md, set_rsa_pss_padding, "RSA-SHA256")) { + success = 0; + } + + /* Test 5: Low-level RSA API */ + printf("5. Low-level RSA API: "); + if (sign_using_rsa_sign(message, message_len, &sig5, &sig_len5, + rsa_key, NID_sha256, md) && + verify_using_rsa_verify(message, message_len, sig5, sig_len5, + rsa_key, NID_sha256, md)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + printf("\nRSA API Summary:\n"); + printf("1. EVP_Sign API: Legacy, simple\n"); + printf("2. EVP_DigestSign API: Modern, recommended\n"); + printf("3. EVP_PKEY_sign API: Lower-level, pre-hashed input\n"); + printf("4. EVP_DigestSign with PKEY_CTX: Fine-grained control\n"); + printf("5. Low-level RSA API: Deprecated, algorithm-specific\n"); + printf("6. EVP_PKEY_sign_message API: Streamlined message signing\n"); + + /* Cleanup */ + OPENSSL_free(sig5); + RSA_free(rsa_key); + EVP_PKEY_free(key); + + return success; +} + +/** + * Test DSA-specific signature APIs including low-level DSA functions + */ +int test_signature_apis_dsa(void) { + EVP_PKEY *key = NULL; + DSA *dsa_key = NULL; + const EVP_MD *md = EVP_sha256(); + const unsigned char message[] = "Test message for OpenSSL signature APIs"; + const size_t message_len = strlen((char *)message); + unsigned char *sig5 = NULL; + size_t sig_len5 = 0; + int success = 1; + + printf("\nGenerating DSA key pair...\n"); + key = generate_dsa_key(); + if (!key) return 0; + + dsa_key = get_dsa_from_pkey(key); + if (!dsa_key) { + EVP_PKEY_free(key); + return 0; + } + + /* Test generic APIs */ + if (!test_signature_apis(key, md, no_parameter_setter, "dsa")) { + success = 0; + } + + /* Test 5: Low-level DSA API */ + printf("5. Low-level DSA API: "); + if (sign_using_dsa_sign(message, message_len, &sig5, &sig_len5, dsa_key, md) && + verify_using_dsa_verify(message, message_len, sig5, sig_len5, dsa_key, md)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + success = 0; + } + + printf("\nDSA API Summary:\n"); + printf("1. EVP_Sign API: Legacy, simple\n"); + printf("2. EVP_DigestSign API: Modern, recommended\n"); + printf("3. EVP_PKEY_sign API: Lower-level, pre-hashed input\n"); + printf("4. EVP_DigestSign with PKEY_CTX: Fine-grained control\n"); + printf("5. Low-level DSA API: Deprecated, algorithm-specific\n"); + printf("6. EVP_PKEY_sign_message API: Streamlined message signing\n"); + + /* Cleanup */ + OPENSSL_free(sig5); + EVP_PKEY_free(key); + + return success; +} + +/* ============================================================================= + * MAIN FUNCTION - Entry point for testing all signature APIs + * ============================================================================= + */ + +// /** +// * Main function demonstrating all OpenSSL signature APIs +// * Tests both RSA and DSA algorithms with all 6 API approaches +// */ +// int main(void) { +// /* Initialize OpenSSL */ +// OpenSSL_add_all_algorithms(); +// ERR_load_crypto_strings(); + +// printf("=================================================================\n"); +// printf("OpenSSL Signature API Demonstration\n"); +// printf("=================================================================\n"); + +// printf("\n-------- TESTING RSA SIGNATURES --------\n"); +// int rsa_result = test_signature_apis_rsa(); + +// printf("\n-------- TESTING DSA SIGNATURES --------\n"); +// int dsa_result = test_signature_apis_dsa(); + +// printf("\n=================================================================\n"); +// if (rsa_result && dsa_result) { +// printf("All tests completed successfully.\n"); +// return 0; +// } else { +// printf("Some tests failed.\n"); +// return 1; +// } +// } \ No newline at end of file diff --git a/cpp/ql/test/experimental/library-tests/quantum/options b/cpp/ql/test/experimental/library-tests/quantum/options new file mode 100644 index 000000000000..41ee5b35e27e --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/quantum/options @@ -0,0 +1 @@ +semmle-extractor-options: -I ../../stubs \ No newline at end of file diff --git a/cpp/ql/test/experimental/stubs/openssl/dsa.h b/cpp/ql/test/experimental/stubs/openssl/dsa.h new file mode 100644 index 000000000000..ceda764a3687 --- /dev/null +++ b/cpp/ql/test/experimental/stubs/openssl/dsa.h @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +# pragma once +# include "type_stubs.h" + +/* + * DSA Paramgen types + * Note, adding to this list requires adjustments to various checks + * in dsa_gen range validation checks + */ +#define DSA_PARAMGEN_TYPE_FIPS_186_4 0 /* Use FIPS186-4 standard */ +#define DSA_PARAMGEN_TYPE_FIPS_186_2 1 /* Use legacy FIPS186-2 standard */ +#define DSA_PARAMGEN_TYPE_FIPS_DEFAULT 2 + +DSA *ossl_dsa_new(OSSL_LIB_CTX *libctx); +void ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx); + +int ossl_dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, + BN_GENCB *cb); + +int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); + +FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa); +int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]); +int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[], + int include_private); +DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); + +int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, + const BIGNUM *priv_key, BIGNUM *pub_key); +int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret); +int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret); +int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, + int *ret); +int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret); +int ossl_dsa_check_pairwise(const DSA *dsa); +int ossl_dsa_is_foreign(const DSA *dsa); +DSA *ossl_dsa_dup(const DSA *dsa, int selection); + + +int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); +int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits); +int EVP_PKEY_CTX_set_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx, + const char *md_name, + const char *md_properties); +int EVP_PKEY_CTX_set_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex); +int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name); +int EVP_PKEY_CTX_set_dsa_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen); +int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + + +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 + +# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + +typedef int DSA_SIG; +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); diff --git a/cpp/ql/test/experimental/stubs/openssl/evp_stubs.h b/cpp/ql/test/experimental/stubs/openssl/evp.h similarity index 88% rename from cpp/ql/test/experimental/stubs/openssl/evp_stubs.h rename to cpp/ql/test/experimental/stubs/openssl/evp.h index 4bc1af0b15d6..cd5194343747 100644 --- a/cpp/ql/test/experimental/stubs/openssl/evp_stubs.h +++ b/cpp/ql/test/experimental/stubs/openssl/evp.h @@ -1,9 +1,22 @@ +#include "type_stubs.h" #ifndef OSSL_EVP_H #define OSSL_EVP_H -// Common defines and integer types. -#define NULL 0 +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 +# define EVP_MAX_AEAD_TAG_LENGTH 16 + +/* Maximum pipes in cipher pipelining */ +# define EVP_MAX_PIPES 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +// Common defines and integer types. # define EVP_CTRL_INIT 0x0 # define EVP_CTRL_SET_KEY_LENGTH 0x1 # define EVP_CTRL_GET_RC2_KEY_BITS 0x2 @@ -29,645 +42,6 @@ # define EVP_CTRL_CCM_SET_L 0x14 # define EVP_CTRL_CCM_SET_MSGLEN 0x15 -typedef unsigned long size_t; - -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -// Type aliases. -typedef int OSSL_PROVIDER; - -typedef int OSSL_FUNC_keymgmt_import_fn; - -typedef int OSSL_FUNC_digest_get_ctx_params_fn; - -typedef int OSSL_FUNC_cipher_settable_ctx_params_fn; - -typedef int ASN1_STRING; - -typedef int OSSL_FUNC_mac_set_ctx_params_fn; - -typedef int OSSL_FUNC_signature_digest_verify_update_fn; - -typedef int OSSL_FUNC_provider_get_reason_strings_fn; - -typedef int OSSL_FUNC_core_get_params_fn; - -typedef int OSSL_FUNC_rand_get_seed_fn; - -typedef int OSSL_FUNC_rand_instantiate_fn; - -typedef int OSSL_FUNC_keymgmt_gen_get_params_fn; - -typedef int EVP_PKEY_gen_cb; - -typedef int OSSL_FUNC_provider_unquery_operation_fn; - -typedef int OSSL_FUNC_cleanup_user_entropy_fn; - -typedef int OSSL_FUNC_asym_cipher_decrypt_fn; - -typedef int OSSL_FUNC_cipher_pipeline_decrypt_init_fn; - -typedef int X509_PUBKEY; - -typedef int OSSL_FUNC_BIO_puts_fn; - -typedef int OSSL_FUNC_signature_verify_fn; - -typedef int OSSL_FUNC_encoder_gettable_params_fn; - -typedef int OSSL_FUNC_keymgmt_validate_fn; - -typedef int EVP_PBE_KEYGEN_EX; - -typedef int OSSL_FUNC_keyexch_dupctx_fn; - -typedef int OSSL_FUNC_kdf_newctx_fn; - -typedef int OSSL_FUNC_signature_digest_verify_final_fn; - -typedef int OSSL_FUNC_signature_set_ctx_params_fn; - -typedef int OSSL_FUNC_rand_reseed_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_release_rcd_fn; - -typedef int OSSL_FUNC_store_open_fn; - -typedef int OSSL_FUNC_encoder_newctx_fn; - -typedef int EVP_KEYMGMT; - -typedef int OSSL_FUNC_core_vset_error_fn; - -typedef int EVP_KEYEXCH; - -typedef int OSSL_FUNC_signature_gettable_ctx_md_params_fn; - -typedef int OSSL_FUNC_CRYPTO_secure_free_fn; - -typedef int OSSL_FUNC_keymgmt_import_types_fn; - -typedef int OSSL_FUNC_signature_sign_message_update_fn; - -typedef int OSSL_FUNC_keymgmt_gen_gettable_params_fn; - -typedef int OSSL_FUNC_cipher_update_fn; - -typedef int OSSL_FUNC_mac_newctx_fn; - -typedef int OSSL_FUNC_keymgmt_set_params_fn; - -typedef int X509_ALGOR; - -typedef int OSSL_FUNC_signature_get_ctx_params_fn; - -typedef int ASN1_ITEM; - -typedef int EVP_SIGNATURE; - -typedef int OSSL_FUNC_CRYPTO_realloc_fn; - -typedef int OSSL_FUNC_BIO_new_file_fn; - -typedef int OSSL_FUNC_signature_sign_message_final_fn; - -typedef int OSSL_FUNC_cipher_newctx_fn; - -typedef int OSSL_FUNC_rand_nonce_fn; - -typedef int EVP_MD; - -typedef int OSSL_FUNC_kdf_reset_fn; - -typedef int OSSL_FUNC_keyexch_settable_ctx_params_fn; - -typedef int OSSL_FUNC_store_export_object_fn; - -typedef int OSSL_FUNC_CRYPTO_secure_allocated_fn; - -typedef int OSSL_FUNC_cipher_pipeline_update_fn; - -typedef int OSSL_FUNC_keyexch_freectx_fn; - -typedef int OSSL_FUNC_kdf_gettable_params_fn; - -typedef int OSSL_FUNC_rand_set_ctx_params_fn; - -typedef int OSSL_FUNC_signature_verify_message_init_fn; - -typedef int OSSL_FUNC_keymgmt_free_fn; - -typedef int OSSL_FUNC_rand_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_signature_digest_sign_update_fn; - -typedef int OSSL_FUNC_keymgmt_has_fn; - -typedef int OSSL_FUNC_kdf_get_ctx_params_fn; - -typedef int OSSL_FUNC_provider_get0_dispatch_fn; - -typedef int OSSL_FUNC_signature_verify_message_update_fn; - -typedef int OSSL_FUNC_rand_lock_fn; - -typedef int EVP_KEM; - -typedef int OSSL_FUNC_BIO_read_ex_fn; - -typedef int X509_SIG_INFO; - -typedef int OSSL_FUNC_keymgmt_import_types_ex_fn; - -typedef int OSSL_FUNC_encoder_free_object_fn; - -typedef int OSSL_FUNC_asym_cipher_decrypt_init_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_alert_fn; - -typedef int OSSL_FUNC_cipher_get_params_fn; - -typedef int OSSL_FUNC_get_nonce_fn; - -typedef int ASN1_OBJECT; - -typedef int OSSL_LIB_CTX; - -typedef int OSSL_FUNC_keymgmt_gen_set_params_fn; - -typedef int OSSL_FUNC_provider_deregister_child_cb_fn; - -typedef int OSSL_PARAM; - -typedef int OSSL_FUNC_decoder_gettable_params_fn; - -typedef int OSSL_FUNC_cipher_pipeline_final_fn; - -typedef int OSSL_FUNC_signature_freectx_fn; - -typedef int EVP_PKEY_METHOD; - -typedef int OSSL_FUNC_CRYPTO_zalloc_fn; - -typedef int OSSL_FUNC_keymgmt_query_operation_name_fn; - -typedef int OSSL_FUNC_core_set_error_mark_fn; - -typedef int OSSL_FUNC_asym_cipher_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_CRYPTO_free_fn; - -typedef int OSSL_FUNC_indicator_cb_fn; - -typedef int OSSL_FUNC_kdf_freectx_fn; - -typedef int ENGINE; - -typedef int EVP_PKEY; - -typedef int PKCS8_PRIV_KEY_INFO; - -typedef int OSSL_FUNC_signature_digest_verify_fn; - -typedef int OSSL_FUNC_mac_final_fn; - -typedef int OSSL_FUNC_core_pop_error_to_mark_fn; - -typedef int OSSL_FUNC_signature_verify_recover_fn; - -typedef int OSSL_FUNC_keymgmt_gen_settable_params_fn; - -typedef int OSSL_FUNC_provider_self_test_fn; - -typedef int OSSL_FUNC_digest_gettable_params_fn; - -typedef int OSSL_FUNC_CRYPTO_secure_malloc_fn; - -typedef int OSSL_FUNC_keymgmt_get_params_fn; - -typedef int OSSL_FUNC_mac_freectx_fn; - -typedef int OSSL_FUNC_cleanup_user_nonce_fn; - -typedef int EVP_SKEYMGMT; - -typedef int OSSL_FUNC_core_set_error_debug_fn; - -typedef int OSSL_FUNC_cipher_decrypt_skey_init_fn; - -typedef int OSSL_FUNC_BIO_new_membuf_fn; - -typedef int OSSL_FUNC_provider_query_operation_fn; - -typedef int OSSL_FUNC_signature_set_ctx_md_params_fn; - -typedef int OSSL_FUNC_encoder_does_selection_fn; - -typedef int OSSL_FUNC_kem_get_ctx_params_fn; - -typedef int OSSL_FUNC_cipher_gettable_params_fn; - -typedef int OSSL_FUNC_digest_final_fn; - -typedef int OSSL_FUNC_rand_generate_fn; - -typedef int EVP_PKEY_CTX; - -typedef int OSSL_FUNC_kem_decapsulate_fn; - -typedef int OSSL_FUNC_skeymgmt_generate_fn; - -typedef int OSSL_FUNC_asym_cipher_encrypt_init_fn; - -typedef int OSSL_FUNC_kdf_get_params_fn; - -typedef int OSSL_FUNC_cipher_encrypt_skey_init_fn; - -typedef int OSSL_FUNC_encoder_get_params_fn; - -typedef int OSSL_FUNC_asym_cipher_freectx_fn; - -typedef int OSSL_FUNC_CRYPTO_secure_clear_free_fn; - -typedef int OSSL_FUNC_store_load_fn; - -typedef int OSSL_FUNC_digest_update_fn; - -typedef int OSSL_FUNC_provider_up_ref_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_recv_rcd_fn; - -typedef int OSSL_FUNC_signature_digest_sign_init_fn; - -typedef int OSSL_FUNC_keymgmt_load_fn; - -typedef int OSSL_FUNC_keyexch_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_rand_get_params_fn; - -typedef int OSSL_FUNC_rand_verify_zeroization_fn; - -typedef int OSSL_FUNC_skeymgmt_export_fn; - -typedef int OSSL_FUNC_BIO_free_fn; - -typedef int OSSL_FUNC_rand_settable_ctx_params_fn; - -typedef int OSSL_FUNC_cleanup_entropy_fn; - -typedef int OSSL_FUNC_encoder_settable_ctx_params_fn; - -typedef int OSSL_DISPATCH; - -typedef int OSSL_FUNC_OPENSSL_cleanse_fn; - -typedef int OSSL_FUNC_digest_dupctx_fn; - -typedef int OSSL_FUNC_kem_decapsulate_init_fn; - -typedef int EVP_MAC_CTX; - -typedef int OSSL_FUNC_digest_squeeze_fn; - -typedef int OSSL_FUNC_keyexch_set_ctx_params_fn; - -typedef int EVP_ENCODE_CTX; - -typedef int OSSL_FUNC_BIO_vsnprintf_fn; - -typedef int OSSL_FUNC_mac_dupctx_fn; - -typedef int OSSL_FUNC_kdf_derive_fn; - -typedef int OSSL_FUNC_encoder_set_ctx_params_fn; - -typedef int OSSL_FUNC_rand_freectx_fn; - -typedef int OSSL_FUNC_BIO_ctrl_fn; - -typedef int EVP_CIPHER; - -typedef int OSSL_FUNC_cipher_set_ctx_params_fn; - -typedef int OSSL_FUNC_rand_enable_locking_fn; - -typedef int OSSL_FUNC_keyexch_newctx_fn; - -typedef int OSSL_FUNC_signature_settable_ctx_params_fn; - -typedef int OSSL_FUNC_provider_gettable_params_fn; - -typedef int OSSL_FUNC_keymgmt_gen_set_template_fn; - -typedef int OSSL_FUNC_keymgmt_settable_params_fn; - -typedef int OSSL_FUNC_keymgmt_gen_cleanup_fn; - -typedef int OSSL_FUNC_kdf_set_ctx_params_fn; - -typedef int OSSL_FUNC_rand_unlock_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn; - -typedef int OSSL_FUNC_signature_digest_sign_fn; - -typedef int OSSL_FUNC_keymgmt_gettable_params_fn; - -typedef int OSSL_FUNC_kem_auth_encapsulate_init_fn; - -typedef int OSSL_FUNC_kem_encapsulate_fn; - -typedef int OSSL_FUNC_CRYPTO_secure_zalloc_fn; - -typedef int OSSL_FUNC_rand_get_ctx_params_fn; - -typedef int OSSL_FUNC_store_delete_fn; - -typedef int OSSL_FUNC_cipher_pipeline_encrypt_init_fn; - -typedef int OSSL_FUNC_cipher_dupctx_fn; - -typedef int OSSL_FUNC_store_settable_ctx_params_fn; - -typedef int FILE; - -typedef int OSSL_FUNC_provider_teardown_fn; - -typedef int OSSL_FUNC_kdf_dupctx_fn; - -typedef int OSSL_FUNC_decoder_newctx_fn; - -typedef int ASN1_BIT_STRING; - -typedef int OSSL_FUNC_core_clear_last_error_mark_fn; - -typedef int OSSL_FUNC_core_obj_create_fn; - -typedef int OSSL_FUNC_keyexch_init_fn; - -typedef int OSSL_FUNC_kem_gettable_ctx_params_fn; - -typedef int EVP_MD_CTX; - -typedef int OSSL_FUNC_decoder_decode_fn; - -typedef int OSSL_FUNC_mac_gettable_params_fn; - -typedef int OSSL_FUNC_kem_set_ctx_params_fn; - -typedef int OSSL_FUNC_encoder_encode_fn; - -typedef int OSSL_FUNC_core_gettable_params_fn; - -typedef int OSSL_FUNC_mac_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_get_user_entropy_fn; - -typedef int OSSL_FUNC_kdf_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_keymgmt_gen_fn; - -typedef int OSSL_FUNC_keyexch_set_peer_fn; - -typedef int OSSL_FUNC_core_obj_add_sigid_fn; - -typedef int OSSL_FUNC_keymgmt_export_types_ex_fn; - -typedef int OSSL_FUNC_kem_newctx_fn; - -typedef int OSSL_FUNC_signature_sign_init_fn; - -typedef int OSSL_FUNC_asym_cipher_get_ctx_params_fn; - -typedef int OSSL_FUNC_CRYPTO_clear_free_fn; - -typedef int OSSL_FUNC_encoder_freectx_fn; - -typedef int OSSL_FUNC_kem_freectx_fn; - -typedef int OSSL_FUNC_provider_get0_provider_ctx_fn; - -typedef int OSSL_FUNC_digest_copyctx_fn; - -typedef int OSSL_FUNC_provider_name_fn; - -typedef int OSSL_FUNC_cipher_decrypt_init_fn; - -typedef int EVP_PKEY_ASN1_METHOD; - -typedef int OSSL_FUNC_keyexch_get_ctx_params_fn; - -typedef int OSSL_FUNC_store_set_ctx_params_fn; - -typedef int ASN1_TYPE; - -typedef int OSSL_FUNC_skeymgmt_imp_settable_params_fn; - -typedef int OSSL_FUNC_cipher_get_ctx_params_fn; - -typedef int EVP_MAC; - -typedef int OSSL_FUNC_store_attach_fn; - -typedef int OSSL_FUNC_signature_get_ctx_md_params_fn; - -typedef int OSSL_FUNC_encoder_import_object_fn; - -typedef int OSSL_FUNC_cleanup_nonce_fn; - -typedef int OSSL_FUNC_kem_auth_decapsulate_init_fn; - -typedef int OSSL_CALLBACK; - -typedef int OSSL_FUNC_skeymgmt_import_fn; - -typedef int OSSL_FUNC_cipher_freectx_fn; - -typedef int OSSL_FUNC_asym_cipher_dupctx_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_send_fn; - -typedef int OSSL_FUNC_CRYPTO_clear_realloc_fn; - -typedef int OSSL_FUNC_signature_verify_recover_init_fn; - -typedef int OSSL_FUNC_provider_free_fn; - -typedef int EVP_RAND; - -typedef int OSSL_FUNC_digest_newctx_fn; - -typedef int OSSL_FUNC_cipher_final_fn; - -typedef int OSSL_FUNC_keymgmt_new_fn; - -typedef int EVP_CIPHER_CTX; - -typedef int OSSL_FUNC_decoder_does_selection_fn; - -typedef int OSSL_FUNC_signature_digest_verify_init_fn; - -typedef int OSSL_FUNC_digest_set_ctx_params_fn; - -typedef int OSSL_FUNC_rand_newctx_fn; - -typedef int OSSL_FUNC_BIO_vprintf_fn; - -typedef int OSSL_FUNC_keymgmt_gen_init_fn; - -typedef int EVP_RAND_CTX; - -typedef int OSSL_FUNC_store_close_fn; - -typedef int OSSL_FUNC_asym_cipher_encrypt_fn; - -typedef int OSSL_FUNC_mac_get_params_fn; - -typedef int OSSL_FUNC_get_entropy_fn; - -typedef int OSSL_FUNC_digest_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn; - -typedef int OSSL_FUNC_skeymgmt_free_fn; - -typedef int OSSL_FUNC_mac_settable_ctx_params_fn; - -typedef int OSSL_FUNC_decoder_export_object_fn; - -typedef int OSSL_FUNC_rand_clear_seed_fn; - -typedef int OSSL_FUNC_mac_get_ctx_params_fn; - -typedef int OSSL_FUNC_digest_digest_fn; - -typedef int EVP_SKEY; - -typedef int OSSL_FUNC_cipher_gettable_ctx_params_fn; - -typedef int OSSL_FUNC_CRYPTO_malloc_fn; - -typedef int OSSL_FUNC_asym_cipher_settable_ctx_params_fn; - -typedef int OSSL_FUNC_signature_dupctx_fn; - -typedef int OSSL_FUNC_BIO_write_ex_fn; - -typedef int OSSL_FUNC_rand_set_callbacks_fn; - -typedef int OSSL_FUNC_keymgmt_match_fn; - -typedef int OSSL_FUNC_signature_digest_sign_final_fn; - -typedef int OSSL_FUNC_provider_get_params_fn; - -typedef int OSSL_FUNC_BIO_gets_fn; - -typedef int OSSL_FUNC_cipher_encrypt_init_fn; - -typedef int OSSL_FUNC_signature_verify_message_final_fn; - -typedef int BIGNUM; - -typedef int OSSL_FUNC_digest_freectx_fn; - -typedef int OSSL_FUNC_asym_cipher_set_ctx_params_fn; - -typedef int OSSL_FUNC_signature_gettable_ctx_params_fn; - -typedef int BIO; - -typedef int OSSL_FUNC_digest_get_params_fn; - -typedef int OSSL_FUNC_skeymgmt_get_key_id_fn; - -typedef int OSSL_FUNC_rand_uninstantiate_fn; - -typedef int OSSL_FUNC_decoder_get_params_fn; - -typedef int OSSL_FUNC_signature_newctx_fn; - -typedef int OSSL_FUNC_signature_sign_fn; - -typedef int OSSL_FUNC_decoder_set_ctx_params_fn; - -typedef int OSSL_FUNC_kem_dupctx_fn; - -typedef int OSSL_FUNC_get_user_nonce_fn; - -typedef int OSSL_FUNC_mac_init_skey_fn; - -typedef int ASN1_PCTX; - -typedef int OSSL_FUNC_provider_get_capabilities_fn; - -typedef int OSSL_FUNC_provider_register_child_cb_fn; - -typedef int OSSL_FUNC_kem_settable_ctx_params_fn; - -typedef int OSSL_FUNC_signature_query_key_types_fn; - -typedef int OSSL_FUNC_signature_settable_ctx_md_params_fn; - -typedef int OSSL_FUNC_asym_cipher_newctx_fn; - -typedef int OSSL_FUNC_store_open_ex_fn; - -typedef int OSSL_FUNC_keyexch_derive_fn; - -typedef int OSSL_FUNC_kdf_settable_ctx_params_fn; - -typedef int OSSL_FUNC_skeymgmt_gen_settable_params_fn; - -typedef int OSSL_FUNC_digest_settable_ctx_params_fn; - -typedef int OSSL_FUNC_kem_encapsulate_init_fn; - -typedef int OSSL_FUNC_core_new_error_fn; - -typedef int OSSL_FUNC_BIO_up_ref_fn; - -typedef int OSSL_FUNC_self_test_cb_fn; - -typedef int OSSL_FUNC_keymgmt_export_types_fn; - -typedef int OSSL_FUNC_core_get_libctx_fn; - -typedef int OSSL_FUNC_digest_init_fn; - -typedef int EVP_ASYM_CIPHER; - -typedef int OSSL_FUNC_decoder_settable_ctx_params_fn; - -typedef int OSSL_FUNC_signature_sign_message_init_fn; - -typedef int OSSL_FUNC_rand_gettable_params_fn; - -typedef int OSSL_FUNC_mac_update_fn; - -typedef int OSSL_FUNC_keymgmt_export_fn; - -typedef int OSSL_FUNC_provider_random_bytes_fn; - -typedef int OSSL_FUNC_decoder_freectx_fn; - -typedef int OSSL_FUNC_mac_init_fn; - -typedef int OSSL_FUNC_store_eof_fn; - -typedef int OSSL_FUNC_signature_verify_init_fn; - -typedef int EVP_PBE_KEYGEN; - -typedef int OSSL_FUNC_core_thread_start_fn; - -typedef int OSSL_FUNC_cipher_cipher_fn; - -typedef int OSSL_FUNC_keymgmt_dup_fn; - // Function stubs. OSSL_FUNC_core_gettable_params_fn * OSSL_FUNC_core_gettable_params(const OSSL_DISPATCH * opf) { return NULL; diff --git a/cpp/ql/test/experimental/stubs/openssl/alg_macro_stubs.h b/cpp/ql/test/experimental/stubs/openssl/obj_mac.h similarity index 99% rename from cpp/ql/test/experimental/stubs/openssl/alg_macro_stubs.h rename to cpp/ql/test/experimental/stubs/openssl/obj_mac.h index 3058681d71d7..8737d21e63e4 100644 --- a/cpp/ql/test/experimental/stubs/openssl/alg_macro_stubs.h +++ b/cpp/ql/test/experimental/stubs/openssl/obj_mac.h @@ -1,3 +1,13 @@ +/* + * Generated by crypto/objects/objects.pl + * + * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + # define EVP_PKEY_NONE NID_undef # define EVP_PKEY_RSA NID_rsaEncryption # define EVP_PKEY_RSA2 NID_rsa diff --git a/cpp/ql/test/experimental/stubs/openssl/pem.h b/cpp/ql/test/experimental/stubs/openssl/pem.h new file mode 100644 index 000000000000..48b785e8f9a1 --- /dev/null +++ b/cpp/ql/test/experimental/stubs/openssl/pem.h @@ -0,0 +1,527 @@ +/* + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include "type_stubs.h" + +#ifndef OPENSSL_PEM_H +# define OPENSSL_PEM_H +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" +# define PEM_STRING_SM2PARAMETERS "SM2 PARAMETERS" +# define PEM_STRING_ACERT "ATTRIBUTE CERTIFICATE" + +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# define PEM_read_cb_fnsig(name, type, INTYPE, readname) \ + type *PEM_##readname##_##name(INTYPE *out, type **x, \ + pem_password_cb *cb, void *u) +# define PEM_read_cb_ex_fnsig(name, type, INTYPE, readname) \ + type *PEM_##readname##_##name##_ex(INTYPE *out, type **x, \ + pem_password_cb *cb, void *u, \ + OSSL_LIB_CTX *libctx, \ + const char *propq) + +# define PEM_write_fnsig(name, type, OUTTYPE, writename) \ + int PEM_##writename##_##name(OUTTYPE *out, const type *x) +# define PEM_write_cb_fnsig(name, type, OUTTYPE, writename) \ + int PEM_##writename##_##name(OUTTYPE *out, const type *x, \ + const EVP_CIPHER *enc, \ + const unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u) +# define PEM_write_ex_fnsig(name, type, OUTTYPE, writename) \ + int PEM_##writename##_##name##_ex(OUTTYPE *out, const type *x, \ + OSSL_LIB_CTX *libctx, \ + const char *propq) +# define PEM_write_cb_ex_fnsig(name, type, OUTTYPE, writename) \ + int PEM_##writename##_##name##_ex(OUTTYPE *out, const type *x, \ + const EVP_CIPHER *enc, \ + const unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u, \ + OSSL_LIB_CTX *libctx, \ + const char *propq) + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# endif +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# endif +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str, fp, \ + (void **)x, cb, u); \ + } + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ + PEM_write_fnsig(name, type, FILE, write) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, out, \ + x, NULL, NULL, 0, NULL, NULL); \ + } + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ + PEM_write_cb_fnsig(name, type, FILE, write) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, out, \ + x, enc, kstr, klen, cb, u); \ + } + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) +# endif +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + type *PEM_read_bio_##name(BIO *bp, type **x, \ + pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str, bp, \ + (void **)x, cb, u); \ + } + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + PEM_write_fnsig(name, type, BIO, write_bio) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, out, \ + x, NULL,NULL,0,NULL,NULL); \ + } + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + PEM_write_cb_fnsig(name, type, BIO, write_bio) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, out, \ + x, enc, kstr, klen, cb, u); \ + } + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) +# endif + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +/* + * The mysterious 'extern' that's passed to some macros is innocuous, + * and is there to quiet pre-C99 compilers that may complain about empty + * arguments in macro calls. + */ +# if defined(OPENSSL_NO_STDIO) + +# define DECLARE_PEM_read_fp_attr(attr, name, type) /**/ +# define DECLARE_PEM_read_fp_ex_attr(attr, name, type) /**/ +# define DECLARE_PEM_write_fp_attr(attr, name, type) /**/ +# define DECLARE_PEM_write_fp_ex_attr(attr, name, type) /**/ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_fp_const_attr(attr, name, type) /**/ +# endif +# define DECLARE_PEM_write_cb_fp_attr(attr, name, type) /**/ +# define DECLARE_PEM_write_cb_fp_ex_attr(attr, name, type) /**/ + +# else + +# define DECLARE_PEM_read_fp_attr(attr, name, type) \ + attr PEM_read_cb_fnsig(name, type, FILE, read); +# define DECLARE_PEM_read_fp_ex_attr(attr, name, type) \ + attr PEM_read_cb_fnsig(name, type, FILE, read); \ + attr PEM_read_cb_ex_fnsig(name, type, FILE, read); + +# define DECLARE_PEM_write_fp_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, FILE, write); +# define DECLARE_PEM_write_fp_ex_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, FILE, write); \ + attr PEM_write_ex_fnsig(name, type, FILE, write); +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_fp_const_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, FILE, write); +# endif +# define DECLARE_PEM_write_cb_fp_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, FILE, write); +# define DECLARE_PEM_write_cb_fp_ex_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, FILE, write); \ + attr PEM_write_cb_ex_fnsig(name, type, FILE, write); + +# endif + +# define DECLARE_PEM_read_fp(name, type) \ + DECLARE_PEM_read_fp_attr(extern, name, type) +# define DECLARE_PEM_write_fp(name, type) \ + DECLARE_PEM_write_fp_attr(extern, name, type) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_fp_const(name, type) \ + DECLARE_PEM_write_fp_const_attr(extern, name, type) +# endif +# define DECLARE_PEM_write_cb_fp(name, type) \ + DECLARE_PEM_write_cb_fp_attr(extern, name, type) + +# define DECLARE_PEM_read_bio_attr(attr, name, type) \ + attr PEM_read_cb_fnsig(name, type, BIO, read_bio); +# define DECLARE_PEM_read_bio_ex_attr(attr, name, type) \ + attr PEM_read_cb_fnsig(name, type, BIO, read_bio); \ + attr PEM_read_cb_ex_fnsig(name, type, BIO, read_bio); +# define DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_bio_attr(extern, name, type) +# define DECLARE_PEM_read_bio_ex(name, type) \ + DECLARE_PEM_read_bio_ex_attr(extern, name, type) + +# define DECLARE_PEM_write_bio_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio_ex_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, BIO, write_bio); \ + attr PEM_write_ex_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_bio_attr(extern, name, type) +# define DECLARE_PEM_write_bio_ex(name, type) \ + DECLARE_PEM_write_bio_ex_attr(extern, name, type) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_bio_const_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_bio_const_attr(extern, name, type) +# endif + +# define DECLARE_PEM_write_cb_bio_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_cb_bio_ex_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, BIO, write_bio); \ + attr PEM_write_cb_ex_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_bio_attr(extern, name, type) +# define DECLARE_PEM_write_cb_ex_bio(name, type) \ + DECLARE_PEM_write_cb_bio_ex_attr(extern, name, type) + +# define DECLARE_PEM_write_attr(attr, name, type) \ + DECLARE_PEM_write_bio_attr(attr, name, type) \ + DECLARE_PEM_write_fp_attr(attr, name, type) +# define DECLARE_PEM_write_ex_attr(attr, name, type) \ + DECLARE_PEM_write_bio_ex_attr(attr, name, type) \ + DECLARE_PEM_write_fp_ex_attr(attr, name, type) +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_attr(extern, name, type) +# define DECLARE_PEM_write_ex(name, type) \ + DECLARE_PEM_write_ex_attr(extern, name, type) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_const_attr(attr, name, type) \ + DECLARE_PEM_write_bio_const_attr(attr, name, type) \ + DECLARE_PEM_write_fp_const_attr(attr, name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_const_attr(extern, name, type) +# endif +# define DECLARE_PEM_write_cb_attr(attr, name, type) \ + DECLARE_PEM_write_cb_bio_attr(attr, name, type) \ + DECLARE_PEM_write_cb_fp_attr(attr, name, type) +# define DECLARE_PEM_write_cb_ex_attr(attr, name, type) \ + DECLARE_PEM_write_cb_bio_ex_attr(attr, name, type) \ + DECLARE_PEM_write_cb_fp_ex_attr(attr, name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_attr(extern, name, type) +# define DECLARE_PEM_write_cb_ex(name, type) \ + DECLARE_PEM_write_cb_ex_attr(extern, name, type) +# define DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_read_bio_attr(attr, name, type) \ + DECLARE_PEM_read_fp_attr(attr, name, type) +# define DECLARE_PEM_read_ex_attr(attr, name, type) \ + DECLARE_PEM_read_bio_ex_attr(attr, name, type) \ + DECLARE_PEM_read_fp_ex_attr(attr, name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_attr(extern, name, type) +# define DECLARE_PEM_read_ex(name, type) \ + DECLARE_PEM_read_ex_attr(extern, name, type) +# define DECLARE_PEM_rw_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_attr(attr, name, type) +# define DECLARE_PEM_rw_ex_attr(attr, name, type) \ + DECLARE_PEM_read_ex_attr(attr, name, type) \ + DECLARE_PEM_write_ex_attr(attr, name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_rw_attr(extern, name, type) +# define DECLARE_PEM_rw_ex(name, type) \ + DECLARE_PEM_rw_ex_attr(extern, name, type) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_rw_const_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_const_attr(attr, name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_rw_const_attr(extern, name, type) +# endif +# define DECLARE_PEM_rw_cb_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_cb_attr(attr, name, type) +# define DECLARE_PEM_rw_cb_ex_attr(attr, name, type) \ + DECLARE_PEM_read_ex_attr(attr, name, type) \ + DECLARE_PEM_write_cb_ex_attr(attr, name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_rw_cb_attr(extern, name, type) +# define DECLARE_PEM_rw_cb_ex(name, type) \ + DECLARE_PEM_rw_cb_ex_attr(extern, name, type) + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +# define PEM_FLAG_SECURE 0x1 +# define PEM_FLAG_EAY_COMPATIBLE 0x2 +# define PEM_FLAG_ONLY_B64 0x4 +int PEM_read_bio_ex(BIO *bp, char **name, char **header, + unsigned char **data, long *len, unsigned int flags); +int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio_ctx(OSSL_i2d_of_void_ctx *i2d, void *vctx, + const char *name, BIO *bp, const void *x, + const EVP_CIPHER *enc, const unsigned char *kstr, + int klen, pem_password_cb *cb, void *u); + +X509_INFO *PEM_X509_INFO_read_bio(BIO *bp, X509_INFO *sk, + pem_password_cb *cb, void *u); +X509_INFO +*PEM_X509_INFO_read_bio_ex(BIO *bp, X509_INFO *sk, + pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, + const char *propq); + +int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u); +X509_INFO *PEM_X509_INFO_read(FILE *fp, X509_INFO *sk, + pem_password_cb *cb, void *u); +X509_INFO +*PEM_X509_INFO_read_ex(FILE *fp, X509_INFO *sk, pem_password_cb *cb, + void *u, OSSL_LIB_CTX *libctx, const char *propq); + +int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +int PEM_SignUpdate(EVP_MD_CTX *ctx, const unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +/* The default pem_password_cb that's used internally */ +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, const char *str); + + + +// DECLARE_PEM_rw(X509, X509) +// DECLARE_PEM_rw(X509_AUX, X509) +// DECLARE_PEM_rw(X509_REQ, X509_REQ) +// DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +// DECLARE_PEM_rw(X509_CRL, X509_CRL) +// DECLARE_PEM_rw(X509_PUBKEY, X509_PUBKEY) +// DECLARE_PEM_rw(PKCS7, PKCS7) +// DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +// DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +// # ifndef OPENSSL_NO_DEPRECATED_3_0 +// DECLARE_PEM_rw_cb_attr(OSSL_DEPRECATEDIN_3_0, RSAPrivateKey, RSA) +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, RSAPublicKey, RSA) +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, RSA_PUBKEY, RSA) +// # endif +// # ifndef OPENSSL_NO_DEPRECATED_3_0 +// # ifndef OPENSSL_NO_DSA +// DECLARE_PEM_rw_cb_attr(OSSL_DEPRECATEDIN_3_0, DSAPrivateKey, DSA) +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, DSA_PUBKEY, DSA) +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, DSAparams, DSA) +// # endif +// # endif + +// # ifndef OPENSSL_NO_DEPRECATED_3_0 +// # ifndef OPENSSL_NO_EC +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, ECPKParameters, EC_GROUP) +// DECLARE_PEM_rw_cb_attr(OSSL_DEPRECATEDIN_3_0, ECPrivateKey, EC_KEY) +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, EC_PUBKEY, EC_KEY) +// # endif +// # endif + +// # ifndef OPENSSL_NO_DH +// # ifndef OPENSSL_NO_DEPRECATED_3_0 +// DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, DHparams, DH) +// DECLARE_PEM_write_attr(OSSL_DEPRECATEDIN_3_0, DHxparams, DH) +// # endif +// # endif +DECLARE_PEM_rw_cb_ex(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw_ex(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, + const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +/* Why do these take a signed char *kstr? */ +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, const EVP_PKEY *, const EVP_CIPHER *, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, + pem_password_cb *cd, void *u); +EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, + OSSL_LIB_CTX *libctx, const char *propq); +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, const EVP_PKEY *x); + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk); +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +EVP_PKEY *b2i_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); +int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +int i2b_PVK_bio_ex(BIO *out, const EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); + +# ifdef __cplusplus +} +# endif +#endif \ No newline at end of file diff --git a/cpp/ql/test/experimental/stubs/openssl/rand.h b/cpp/ql/test/experimental/stubs/openssl/rand.h new file mode 100644 index 000000000000..9b632725b9d7 --- /dev/null +++ b/cpp/ql/test/experimental/stubs/openssl/rand.h @@ -0,0 +1,20 @@ +/* + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ + +int RAND_bytes(unsigned char *buf, int num); + +int RAND_pseudo_bytes(unsigned char *buf, int num); \ No newline at end of file diff --git a/cpp/ql/test/experimental/stubs/openssl/rand_stubs.h b/cpp/ql/test/experimental/stubs/openssl/rand_stubs.h deleted file mode 100644 index 8d9b5c53c9ff..000000000000 --- a/cpp/ql/test/experimental/stubs/openssl/rand_stubs.h +++ /dev/null @@ -1,3 +0,0 @@ -int RAND_bytes(unsigned char *buf, int num); - -int RAND_pseudo_bytes(unsigned char *buf, int num); \ No newline at end of file diff --git a/cpp/ql/test/experimental/stubs/openssl/rsa.h b/cpp/ql/test/experimental/stubs/openssl/rsa.h new file mode 100644 index 000000000000..4bacb17f9c6f --- /dev/null +++ b/cpp/ql/test/experimental/stubs/openssl/rsa.h @@ -0,0 +1,585 @@ +/* + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +# include "type_stubs.h" + +#ifndef OPENSSL_RSA_H +# define OPENSSL_RSA_H +# pragma once + + +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +/* The types RSA and RSA_METHOD are defined in ossl_typ.h */ + +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 2048 + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif + +/* exponent limit enforced for "large" modulus only */ +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif +/* based on RFC 8017 appendix A.1.2 */ +# define RSA_ASN1_VERSION_DEFAULT 0 +# define RSA_ASN1_VERSION_MULTI 1 + +# define RSA_DEFAULT_PRIME_NUM 2 + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001 +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define RSA_FLAG_NO_CONSTTIME 0x0000 +# endif +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# ifndef OPENSSL_NO_DEPRECATED_0_9_8 +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +/*- + * New with 3.0: use part of the flags to denote exact type of RSA key, + * some of which are limited to specific signature and encryption schemes. + * These different types share the same RSA structure, but indicate the + * use of certain fields in that structure. + * Currently known are: + * RSA - this is the "normal" unlimited RSA structure (typenum 0) + * RSASSA-PSS - indicates that the PSS parameters are used. + * RSAES-OAEP - no specific field used for the moment, but OAEP padding + * is expected. (currently unused) + * + * 4 bits allow for 16 types + */ +# define RSA_FLAG_TYPE_MASK 0xF000 +# define RSA_FLAG_TYPE_RSA 0x0000 +# define RSA_FLAG_TYPE_RSASSAPSS 0x1000 +# define RSA_FLAG_TYPE_RSAESOAEP 0x2000 + +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode); +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode); + +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); + +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits); +int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); +int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes); +int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen); +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); + +/* Salt length matches digest */ +# define RSA_PSS_SALTLEN_DIGEST -1 +/* Verify only: auto detect salt length */ +# define RSA_PSS_SALTLEN_AUTO -2 +/* Set salt length to maximum possible */ +# define RSA_PSS_SALTLEN_MAX -3 +/* Auto-detect on verify, set salt length to min(maximum possible, digest + * length) on sign */ +# define RSA_PSS_SALTLEN_AUTO_DIGEST_MAX -4 +/* Old compatible max salt length for sign only */ +# define RSA_PSS_SALTLEN_MAX_SIGN -2 + +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops); +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); +int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namelen); +int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name(EVP_PKEY_CTX *ctx, + const char *mdname); + +int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx, + const char *mdname, + const char *mdprops); + +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops); +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); +int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namelen); +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen); +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label); + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES (EVP_PKEY_ALG_CTRL + 13) + +# define EVP_PKEY_CTRL_RSA_IMPLICIT_REJECTION (EVP_PKEY_ALG_CTRL + 14) + + +# define RSA_PKCS1_PADDING 1 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 + +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 +# define RSA_PKCS1_WITH_TLS_PADDING 7 + +/* internal RSA_ only */ +# define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_bits(const RSA *rsa); +int RSA_size(const RSA *rsa); +int RSA_security_bits(const RSA *rsa); + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r, + BIGNUM *dmp1, BIGNUM *dmq1, + BIGNUM *iqmp); +int RSA_set0_multi_prime_params(RSA *r, + BIGNUM *primes[], + BIGNUM *exps[], + BIGNUM *coeffs[], + int pnum); +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, + const BIGNUM **d); +void RSA_get0_factors(const RSA *r, + const BIGNUM **p, const BIGNUM **q); +int RSA_get_multi_prime_extra_count(const RSA *r); +int RSA_get0_multi_prime_factors(const RSA *r, + const BIGNUM *primes[]); +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, + const BIGNUM **dmq1, + const BIGNUM **iqmp); + +int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], + const BIGNUM *coeffs[]); +const BIGNUM *RSA_get0_n(const RSA *d); +const BIGNUM *RSA_get0_e(const RSA *d); +const BIGNUM *RSA_get0_d(const RSA *d); +const BIGNUM *RSA_get0_p(const RSA *d); +const BIGNUM *RSA_get0_q(const RSA *d); +const BIGNUM *RSA_get0_dmp1(const RSA *r); +const BIGNUM *RSA_get0_dmq1(const RSA *r); +const BIGNUM *RSA_get0_iqmp(const RSA *r); +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r); +void RSA_clear_flags(RSA *r, int flags); +int RSA_test_flags(const RSA *r, int flags); +void RSA_set_flags(RSA *r, int flags); +int RSA_get_version(RSA *r); +ENGINE *RSA_get0_engine(const RSA *r); + +# define EVP_RSA_gen(bits) \ + EVP_PKEY_Q_keygen(NULL, NULL, "RSA", (size_t)(0 + (bits))) + +/* Deprecated version */ +RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), + void *cb_arg); + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); +/* Multi-prime version */ +int RSA_generate_multi_prime_key(RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb); + + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, + BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, + const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, + const BIGNUM *e, + BN_GENCB *cb); + +int RSA_check_key(const RSA *); +int RSA_check_key_ex(const RSA *, BN_GENCB *cb); + /* next 4 return -1 on error */ + +int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding); + +int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding); + +int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding); + +int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_null_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* these are the actual RSA functions */ +const RSA_METHOD *RSA_PKCS1_OpenSSL(void); + + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + /* Decoded hash algorithm from maskGenAlgorithm */ + X509_ALGOR *maskHash; +}; + +// DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) +// DECLARE_ASN1_DUP_FUNCTION(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; + /* Decoded hash algorithm from maskGenFunc */ + X509_ALGOR *maskHash; +} RSA_OAEP_PARAMS; + +// DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef OPENSSL_NO_STDIO +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +int RSA_print(BIO *bp, const RSA *r, int offset); + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ + +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); + +int RSA_verify_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigbuf, unsigned int siglen, + RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); + +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); + +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); + +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, + const EVP_MD *dgst); + +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); + +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); + +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); + +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_X931_hash_id(int nid); + + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); + +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +# define RSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef) +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +// DECLARE_ASN1_DUP_FUNCTION_name_attr(, RSA, RSAPublicKey) +// DECLARE_ASN1_DUP_FUNCTION_name_attr(, RSA, RSAPrivateKey) + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +RSA_METHOD *RSA_meth_new(const char *name, int flags); +void RSA_meth_free(RSA_METHOD *meth); +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +const char *RSA_meth_get0_name(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, + const char *name); +int RSA_meth_get_flags(const RSA_METHOD *meth); +int RSA_meth_set_flags(RSA_METHOD *meth, int flags); +void *RSA_meth_get0_app_data(const RSA_METHOD *meth); +int RSA_meth_set0_app_data(RSA_METHOD *meth, + void *app_data); + +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) (int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, int padding); + +int RSA_meth_set_pub_enc(RSA_METHOD *rsa, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); + +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) (int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, int padding); + +int RSA_meth_set_pub_dec(RSA_METHOD *rsa, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); + +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) (int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, int padding); + +int RSA_meth_set_priv_enc(RSA_METHOD *rsa, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); + +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) (int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, int padding); + +int RSA_meth_set_priv_dec(RSA_METHOD *rsa, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); + +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) (BIGNUM *r0, + const BIGNUM *i, + RSA *rsa, BN_CTX *ctx); + +int RSA_meth_set_mod_exp(RSA_METHOD *rsa, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx)); + +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + +int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx)); + +int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa); + +int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa)); + +int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa); + +int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa)); + +int (*RSA_meth_get_sign(const RSA_METHOD *meth)) (int type, + const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, + unsigned int *siglen, + const RSA *rsa); + +int RSA_meth_set_sign(RSA_METHOD *rsa, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)); + +int (*RSA_meth_get_verify(const RSA_METHOD *meth)) (int dtype, + const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, + const RSA *rsa); + +int RSA_meth_set_verify(RSA_METHOD *rsa, + int (*verify) (int dtype, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)); + +int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) (RSA *rsa, int bits, + BIGNUM *e, BN_GENCB *cb); + +int RSA_meth_set_keygen(RSA_METHOD *rsa, + int (*keygen) (RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb)); + +int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) (RSA *rsa, + int bits, + int primes, + BIGNUM *e, + BN_GENCB *cb); + +int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb)); +#endif /* !OPENSSL_NO_DEPRECATED_3_0 */ + +# ifdef __cplusplus +} +# endif +#endif \ No newline at end of file diff --git a/cpp/ql/test/experimental/stubs/openssl/type_stubs.h b/cpp/ql/test/experimental/stubs/openssl/type_stubs.h new file mode 100644 index 000000000000..f14e39234478 --- /dev/null +++ b/cpp/ql/test/experimental/stubs/openssl/type_stubs.h @@ -0,0 +1,702 @@ +#pragma once + +#define NULL 0 + +typedef unsigned long size_t; + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +typedef int OSSL_PROVIDER; + +typedef int OSSL_FUNC_keymgmt_import_fn; + +typedef int OSSL_FUNC_digest_get_ctx_params_fn; + +typedef int OSSL_FUNC_cipher_settable_ctx_params_fn; + +typedef int OSSL_FUNC_mac_set_ctx_params_fn; + +typedef int OSSL_FUNC_signature_digest_verify_update_fn; + +typedef int OSSL_FUNC_provider_get_reason_strings_fn; + +typedef int OSSL_FUNC_core_get_params_fn; + +typedef int OSSL_FUNC_rand_get_seed_fn; + +typedef int OSSL_FUNC_rand_instantiate_fn; + +typedef int OSSL_FUNC_keymgmt_gen_get_params_fn; + +typedef int EVP_PKEY_gen_cb; + +typedef int OSSL_FUNC_provider_unquery_operation_fn; + +typedef int OSSL_FUNC_cleanup_user_entropy_fn; + +typedef int OSSL_FUNC_asym_cipher_decrypt_fn; + +typedef int OSSL_FUNC_cipher_pipeline_decrypt_init_fn; + +typedef int X509_PUBKEY; + +typedef int OSSL_FUNC_BIO_puts_fn; + +typedef int OSSL_FUNC_signature_verify_fn; + +typedef int OSSL_FUNC_encoder_gettable_params_fn; + +typedef int OSSL_FUNC_keymgmt_validate_fn; + +typedef int EVP_PBE_KEYGEN_EX; + +typedef int OSSL_FUNC_keyexch_dupctx_fn; + +typedef int OSSL_FUNC_kdf_newctx_fn; + +typedef int OSSL_FUNC_signature_digest_verify_final_fn; + +typedef int OSSL_FUNC_signature_set_ctx_params_fn; + +typedef int OSSL_FUNC_rand_reseed_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_release_rcd_fn; + +typedef int OSSL_FUNC_store_open_fn; + +typedef int OSSL_FUNC_encoder_newctx_fn; + +typedef int EVP_KEYMGMT; + +typedef int OSSL_FUNC_core_vset_error_fn; + +typedef int EVP_KEYEXCH; + +typedef int OSSL_FUNC_signature_gettable_ctx_md_params_fn; + +typedef int OSSL_FUNC_CRYPTO_secure_free_fn; + +typedef int OSSL_FUNC_keymgmt_import_types_fn; + +typedef int OSSL_FUNC_signature_sign_message_update_fn; + +typedef int OSSL_FUNC_keymgmt_gen_gettable_params_fn; + +typedef int OSSL_FUNC_cipher_update_fn; + +typedef int OSSL_FUNC_mac_newctx_fn; + +typedef int OSSL_FUNC_keymgmt_set_params_fn; + +typedef int X509_ALGOR; + +typedef int OSSL_FUNC_signature_get_ctx_params_fn; + +typedef int ASN1_ITEM; + +typedef int EVP_SIGNATURE; + +typedef int OSSL_FUNC_CRYPTO_realloc_fn; + +typedef int OSSL_FUNC_BIO_new_file_fn; + +typedef int OSSL_FUNC_signature_sign_message_final_fn; + +typedef int OSSL_FUNC_cipher_newctx_fn; + +typedef int OSSL_FUNC_rand_nonce_fn; + +typedef int EVP_MD; + +typedef int OSSL_FUNC_kdf_reset_fn; + +typedef int OSSL_FUNC_keyexch_settable_ctx_params_fn; + +typedef int OSSL_FUNC_store_export_object_fn; + +typedef int OSSL_FUNC_CRYPTO_secure_allocated_fn; + +typedef int OSSL_FUNC_cipher_pipeline_update_fn; + +typedef int OSSL_FUNC_keyexch_freectx_fn; + +typedef int OSSL_FUNC_kdf_gettable_params_fn; + +typedef int OSSL_FUNC_rand_set_ctx_params_fn; + +typedef int OSSL_FUNC_signature_verify_message_init_fn; + +typedef int OSSL_FUNC_keymgmt_free_fn; + +typedef int OSSL_FUNC_rand_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_signature_digest_sign_update_fn; + +typedef int OSSL_FUNC_keymgmt_has_fn; + +typedef int OSSL_FUNC_kdf_get_ctx_params_fn; + +typedef int OSSL_FUNC_provider_get0_dispatch_fn; + +typedef int OSSL_FUNC_signature_verify_message_update_fn; + +typedef int OSSL_FUNC_rand_lock_fn; + +typedef int EVP_KEM; + +typedef int OSSL_FUNC_BIO_read_ex_fn; + +typedef int X509_SIG_INFO; + +typedef int OSSL_FUNC_keymgmt_import_types_ex_fn; + +typedef int OSSL_FUNC_encoder_free_object_fn; + +typedef int OSSL_FUNC_asym_cipher_decrypt_init_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_alert_fn; + +typedef int OSSL_FUNC_cipher_get_params_fn; + +typedef int OSSL_FUNC_get_nonce_fn; + +typedef int ASN1_OBJECT; + +typedef int OSSL_LIB_CTX; + +typedef int OSSL_FUNC_keymgmt_gen_set_params_fn; + +typedef int OSSL_FUNC_provider_deregister_child_cb_fn; + +typedef int OSSL_PARAM; + +typedef int OSSL_FUNC_decoder_gettable_params_fn; + +typedef int OSSL_FUNC_cipher_pipeline_final_fn; + +typedef int OSSL_FUNC_signature_freectx_fn; + +typedef int EVP_PKEY_METHOD; + +typedef int OSSL_FUNC_CRYPTO_zalloc_fn; + +typedef int OSSL_FUNC_keymgmt_query_operation_name_fn; + +typedef int OSSL_FUNC_core_set_error_mark_fn; + +typedef int OSSL_FUNC_asym_cipher_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_CRYPTO_free_fn; + +typedef int OSSL_FUNC_indicator_cb_fn; + +typedef int OSSL_FUNC_kdf_freectx_fn; + +typedef int ENGINE; + +typedef int EVP_PKEY; + +typedef int PKCS8_PRIV_KEY_INFO; + +typedef int OSSL_FUNC_signature_digest_verify_fn; + +typedef int OSSL_FUNC_mac_final_fn; + +typedef int OSSL_FUNC_core_pop_error_to_mark_fn; + +typedef int OSSL_FUNC_signature_verify_recover_fn; + +typedef int OSSL_FUNC_keymgmt_gen_settable_params_fn; + +typedef int OSSL_FUNC_provider_self_test_fn; + +typedef int OSSL_FUNC_digest_gettable_params_fn; + +typedef int OSSL_FUNC_CRYPTO_secure_malloc_fn; + +typedef int OSSL_FUNC_keymgmt_get_params_fn; + +typedef int OSSL_FUNC_mac_freectx_fn; + +typedef int OSSL_FUNC_cleanup_user_nonce_fn; + +typedef int EVP_SKEYMGMT; + +typedef int OSSL_FUNC_core_set_error_debug_fn; + +typedef int OSSL_FUNC_cipher_decrypt_skey_init_fn; + +typedef int OSSL_FUNC_BIO_new_membuf_fn; + +typedef int OSSL_FUNC_provider_query_operation_fn; + +typedef int OSSL_FUNC_signature_set_ctx_md_params_fn; + +typedef int OSSL_FUNC_encoder_does_selection_fn; + +typedef int OSSL_FUNC_kem_get_ctx_params_fn; + +typedef int OSSL_FUNC_cipher_gettable_params_fn; + +typedef int OSSL_FUNC_digest_final_fn; + +typedef int OSSL_FUNC_rand_generate_fn; + +typedef int EVP_PKEY_CTX; + +typedef int OSSL_FUNC_kem_decapsulate_fn; + +typedef int OSSL_FUNC_skeymgmt_generate_fn; + +typedef int OSSL_FUNC_asym_cipher_encrypt_init_fn; + +typedef int OSSL_FUNC_kdf_get_params_fn; + +typedef int OSSL_FUNC_cipher_encrypt_skey_init_fn; + +typedef int OSSL_FUNC_encoder_get_params_fn; + +typedef int OSSL_FUNC_asym_cipher_freectx_fn; + +typedef int OSSL_FUNC_CRYPTO_secure_clear_free_fn; + +typedef int OSSL_FUNC_store_load_fn; + +typedef int OSSL_FUNC_digest_update_fn; + +typedef int OSSL_FUNC_provider_up_ref_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_recv_rcd_fn; + +typedef int OSSL_FUNC_signature_digest_sign_init_fn; + +typedef int OSSL_FUNC_keymgmt_load_fn; + +typedef int OSSL_FUNC_keyexch_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_rand_get_params_fn; + +typedef int OSSL_FUNC_rand_verify_zeroization_fn; + +typedef int OSSL_FUNC_skeymgmt_export_fn; + +typedef int OSSL_FUNC_BIO_free_fn; + +typedef int OSSL_FUNC_rand_settable_ctx_params_fn; + +typedef int OSSL_FUNC_cleanup_entropy_fn; + +typedef int OSSL_FUNC_encoder_settable_ctx_params_fn; + +typedef int OSSL_DISPATCH; + +typedef int OSSL_FUNC_OPENSSL_cleanse_fn; + +typedef int OSSL_FUNC_digest_dupctx_fn; + +typedef int OSSL_FUNC_kem_decapsulate_init_fn; + +typedef int EVP_MAC_CTX; + +typedef int OSSL_FUNC_digest_squeeze_fn; + +typedef int OSSL_FUNC_keyexch_set_ctx_params_fn; + +typedef int EVP_ENCODE_CTX; + +typedef int OSSL_FUNC_BIO_vsnprintf_fn; + +typedef int OSSL_FUNC_mac_dupctx_fn; + +typedef int OSSL_FUNC_kdf_derive_fn; + +typedef int OSSL_FUNC_encoder_set_ctx_params_fn; + +typedef int OSSL_FUNC_rand_freectx_fn; + +typedef int OSSL_FUNC_BIO_ctrl_fn; + +typedef int EVP_CIPHER; + +typedef int OSSL_FUNC_cipher_set_ctx_params_fn; + +typedef int OSSL_FUNC_rand_enable_locking_fn; + +typedef int OSSL_FUNC_keyexch_newctx_fn; + +typedef int OSSL_FUNC_signature_settable_ctx_params_fn; + +typedef int OSSL_FUNC_provider_gettable_params_fn; + +typedef int OSSL_FUNC_keymgmt_gen_set_template_fn; + +typedef int OSSL_FUNC_keymgmt_settable_params_fn; + +typedef int OSSL_FUNC_keymgmt_gen_cleanup_fn; + +typedef int OSSL_FUNC_kdf_set_ctx_params_fn; + +typedef int OSSL_FUNC_rand_unlock_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn; + +typedef int OSSL_FUNC_signature_digest_sign_fn; + +typedef int OSSL_FUNC_keymgmt_gettable_params_fn; + +typedef int OSSL_FUNC_kem_auth_encapsulate_init_fn; + +typedef int OSSL_FUNC_kem_encapsulate_fn; + +typedef int OSSL_FUNC_CRYPTO_secure_zalloc_fn; + +typedef int OSSL_FUNC_rand_get_ctx_params_fn; + +typedef int OSSL_FUNC_store_delete_fn; + +typedef int OSSL_FUNC_cipher_pipeline_encrypt_init_fn; + +typedef int OSSL_FUNC_cipher_dupctx_fn; + +typedef int OSSL_FUNC_store_settable_ctx_params_fn; + +typedef int FILE; + +typedef int OSSL_FUNC_provider_teardown_fn; + +typedef int OSSL_FUNC_kdf_dupctx_fn; + +typedef int OSSL_FUNC_decoder_newctx_fn; + +typedef int OSSL_FUNC_core_clear_last_error_mark_fn; + +typedef int OSSL_FUNC_core_obj_create_fn; + +typedef int OSSL_FUNC_keyexch_init_fn; + +typedef int OSSL_FUNC_kem_gettable_ctx_params_fn; + +typedef int EVP_MD_CTX; + +typedef int OSSL_FUNC_decoder_decode_fn; + +typedef int OSSL_FUNC_mac_gettable_params_fn; + +typedef int OSSL_FUNC_kem_set_ctx_params_fn; + +typedef int OSSL_FUNC_encoder_encode_fn; + +typedef int OSSL_FUNC_core_gettable_params_fn; + +typedef int OSSL_FUNC_mac_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_get_user_entropy_fn; + +typedef int OSSL_FUNC_kdf_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_keymgmt_gen_fn; + +typedef int OSSL_FUNC_keyexch_set_peer_fn; + +typedef int OSSL_FUNC_core_obj_add_sigid_fn; + +typedef int OSSL_FUNC_keymgmt_export_types_ex_fn; + +typedef int OSSL_FUNC_kem_newctx_fn; + +typedef int OSSL_FUNC_signature_sign_init_fn; + +typedef int OSSL_FUNC_asym_cipher_get_ctx_params_fn; + +typedef int OSSL_FUNC_CRYPTO_clear_free_fn; + +typedef int OSSL_FUNC_encoder_freectx_fn; + +typedef int OSSL_FUNC_kem_freectx_fn; + +typedef int OSSL_FUNC_provider_get0_provider_ctx_fn; + +typedef int OSSL_FUNC_digest_copyctx_fn; + +typedef int OSSL_FUNC_provider_name_fn; + +typedef int OSSL_FUNC_cipher_decrypt_init_fn; + +typedef int EVP_PKEY_ASN1_METHOD; + +typedef int OSSL_FUNC_keyexch_get_ctx_params_fn; + +typedef int OSSL_FUNC_store_set_ctx_params_fn; + +typedef int ASN1_TYPE; + +typedef int OSSL_FUNC_skeymgmt_imp_settable_params_fn; + +typedef int OSSL_FUNC_cipher_get_ctx_params_fn; + +typedef int EVP_MAC; + +typedef int OSSL_FUNC_store_attach_fn; + +typedef int OSSL_FUNC_signature_get_ctx_md_params_fn; + +typedef int OSSL_FUNC_encoder_import_object_fn; + +typedef int OSSL_FUNC_cleanup_nonce_fn; + +typedef int OSSL_FUNC_kem_auth_decapsulate_init_fn; + +typedef int OSSL_CALLBACK; + +typedef int OSSL_FUNC_skeymgmt_import_fn; + +typedef int OSSL_FUNC_cipher_freectx_fn; + +typedef int OSSL_FUNC_asym_cipher_dupctx_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_crypto_send_fn; + +typedef int OSSL_FUNC_CRYPTO_clear_realloc_fn; + +typedef int OSSL_FUNC_signature_verify_recover_init_fn; + +typedef int OSSL_FUNC_provider_free_fn; + +typedef int EVP_RAND; + +typedef int OSSL_FUNC_digest_newctx_fn; + +typedef int OSSL_FUNC_cipher_final_fn; + +typedef int OSSL_FUNC_keymgmt_new_fn; + +typedef int EVP_CIPHER_CTX; + +typedef int OSSL_FUNC_decoder_does_selection_fn; + +typedef int OSSL_FUNC_signature_digest_verify_init_fn; + +typedef int OSSL_FUNC_digest_set_ctx_params_fn; + +typedef int OSSL_FUNC_rand_newctx_fn; + +typedef int OSSL_FUNC_BIO_vprintf_fn; + +typedef int OSSL_FUNC_keymgmt_gen_init_fn; + +typedef int EVP_RAND_CTX; + +typedef int OSSL_FUNC_store_close_fn; + +typedef int OSSL_FUNC_asym_cipher_encrypt_fn; + +typedef int OSSL_FUNC_mac_get_params_fn; + +typedef int OSSL_FUNC_get_entropy_fn; + +typedef int OSSL_FUNC_digest_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn; + +typedef int OSSL_FUNC_skeymgmt_free_fn; + +typedef int OSSL_FUNC_mac_settable_ctx_params_fn; + +typedef int OSSL_FUNC_decoder_export_object_fn; + +typedef int OSSL_FUNC_rand_clear_seed_fn; + +typedef int OSSL_FUNC_mac_get_ctx_params_fn; + +typedef int OSSL_FUNC_digest_digest_fn; + +typedef int EVP_SKEY; + +typedef int OSSL_FUNC_cipher_gettable_ctx_params_fn; + +typedef int OSSL_FUNC_CRYPTO_malloc_fn; + +typedef int OSSL_FUNC_asym_cipher_settable_ctx_params_fn; + +typedef int OSSL_FUNC_signature_dupctx_fn; + +typedef int OSSL_FUNC_BIO_write_ex_fn; + +typedef int OSSL_FUNC_rand_set_callbacks_fn; + +typedef int OSSL_FUNC_keymgmt_match_fn; + +typedef int OSSL_FUNC_signature_digest_sign_final_fn; + +typedef int OSSL_FUNC_provider_get_params_fn; + +typedef int OSSL_FUNC_BIO_gets_fn; + +typedef int OSSL_FUNC_cipher_encrypt_init_fn; + +typedef int OSSL_FUNC_signature_verify_message_final_fn; + +typedef int BIGNUM; + +typedef int OSSL_FUNC_digest_freectx_fn; + +typedef int OSSL_FUNC_asym_cipher_set_ctx_params_fn; + +typedef int OSSL_FUNC_signature_gettable_ctx_params_fn; + +typedef int BIO; + +typedef int OSSL_FUNC_digest_get_params_fn; + +typedef int OSSL_FUNC_skeymgmt_get_key_id_fn; + +typedef int OSSL_FUNC_rand_uninstantiate_fn; + +typedef int OSSL_FUNC_decoder_get_params_fn; + +typedef int OSSL_FUNC_signature_newctx_fn; + +typedef int OSSL_FUNC_signature_sign_fn; + +typedef int OSSL_FUNC_decoder_set_ctx_params_fn; + +typedef int OSSL_FUNC_kem_dupctx_fn; + +typedef int OSSL_FUNC_get_user_nonce_fn; + +typedef int OSSL_FUNC_mac_init_skey_fn; + +typedef int ASN1_PCTX; + +typedef int OSSL_FUNC_provider_get_capabilities_fn; + +typedef int OSSL_FUNC_provider_register_child_cb_fn; + +typedef int OSSL_FUNC_kem_settable_ctx_params_fn; + +typedef int OSSL_FUNC_signature_query_key_types_fn; + +typedef int OSSL_FUNC_signature_settable_ctx_md_params_fn; + +typedef int OSSL_FUNC_asym_cipher_newctx_fn; + +typedef int OSSL_FUNC_store_open_ex_fn; + +typedef int OSSL_FUNC_keyexch_derive_fn; + +typedef int OSSL_FUNC_kdf_settable_ctx_params_fn; + +typedef int OSSL_FUNC_skeymgmt_gen_settable_params_fn; + +typedef int OSSL_FUNC_digest_settable_ctx_params_fn; + +typedef int OSSL_FUNC_kem_encapsulate_init_fn; + +typedef int OSSL_FUNC_core_new_error_fn; + +typedef int OSSL_FUNC_BIO_up_ref_fn; + +typedef int OSSL_FUNC_self_test_cb_fn; + +typedef int OSSL_FUNC_keymgmt_export_types_fn; + +typedef int OSSL_FUNC_core_get_libctx_fn; + +typedef int OSSL_FUNC_digest_init_fn; + +typedef int EVP_ASYM_CIPHER; + +typedef int OSSL_FUNC_decoder_settable_ctx_params_fn; + +typedef int OSSL_FUNC_signature_sign_message_init_fn; + +typedef int OSSL_FUNC_rand_gettable_params_fn; + +typedef int OSSL_FUNC_mac_update_fn; + +typedef int OSSL_FUNC_keymgmt_export_fn; + +typedef int OSSL_FUNC_provider_random_bytes_fn; + +typedef int OSSL_FUNC_decoder_freectx_fn; + +typedef int OSSL_FUNC_mac_init_fn; + +typedef int OSSL_FUNC_store_eof_fn; + +typedef int OSSL_FUNC_signature_verify_init_fn; + +typedef int EVP_PBE_KEYGEN; + +typedef int OSSL_FUNC_core_thread_start_fn; + +typedef int OSSL_FUNC_cipher_cipher_fn; + +typedef int OSSL_FUNC_keymgmt_dup_fn; + +typedef int RSA; + +typedef int BIGNUM; + +typedef int ENGINE; + +typedef int RSA_METHOD; + +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; + +typedef int EVP_CIPHER_INFO; + +typedef int pem_password_cb; + +typedef int X509_INFO; + +typedef int RSA_PSS_PARAMS; + +typedef int BN_GENCB; + +typedef int BN_CTX; + +typedef int BN_BLINDING; + +typedef int BN_MONT_CTX; + +typedef int d2i_of_void; + +typedef int i2d_of_void; + +typedef int OSSL_i2d_of_void_ctx; + +typedef int DSA; + +typedef int FFC_PARAMS; \ No newline at end of file diff --git a/java/ql/lib/experimental/quantum/JCA.qll b/java/ql/lib/experimental/quantum/JCA.qll index f785c3c96285..16afa26347fe 100644 --- a/java/ql/lib/experimental/quantum/JCA.qll +++ b/java/ql/lib/experimental/quantum/JCA.qll @@ -1243,7 +1243,7 @@ module JCAModel { exists(hash_name_to_type_known(this.getRawHashAlgorithmName(), result)) } - override string getRawMACAlgorithmName() { + override string getRawMacAlgorithmName() { result = super.getRawKDFAlgorithmName().splitAt("PBKDF2With", 1) } @@ -1251,7 +1251,7 @@ module JCAModel { result = super.getRawKDFAlgorithmName().splitAt("WithHmac", 1) } - override Crypto::TMACType getMACType() { result instanceof Crypto::THMAC } + override Crypto::TMACType getMacType() { result instanceof Crypto::THMAC } override Crypto::AlgorithmValueConsumer getHMACAlgorithmValueConsumer() { result = this } @@ -1487,9 +1487,9 @@ module JCAModel { MACGetInstanceAlgorithmValueConsumer getConsumer() { result = consumer } - override string getRawMACAlgorithmName() { result = super.getValue() } + override string getRawMacAlgorithmName() { result = super.getValue() } - override Crypto::TMACType getMACType() { + override Crypto::TMACType getMacType() { if mac_name_to_mac_type_known(_, super.getValue()) then mac_name_to_mac_type_known(result, super.getValue()) else result instanceof Crypto::TOtherMACType diff --git a/shared/quantum/codeql/quantum/experimental/Model.qll b/shared/quantum/codeql/quantum/experimental/Model.qll index e7bbe65d3115..d4a900f9bcac 100644 --- a/shared/quantum/codeql/quantum/experimental/Model.qll +++ b/shared/quantum/codeql/quantum/experimental/Model.qll @@ -597,8 +597,7 @@ module CryptographyBase Input> { newtype TSignatureAlgorithmType = DSA() or ECDSA() or - Ed25519() or - Ed448() or + EDDSA() or // e.g., ED25519 or ED448 OtherSignatureAlgorithmType() newtype TKEMAlgorithmType = @@ -703,9 +702,7 @@ module CryptographyBase Input> { or type = TSignature(ECDSA()) and name = "ECDSA" or - type = TSignature(Ed25519()) and name = "Ed25519" - or - type = TSignature(Ed448()) and name = "Ed448" + type = TSignature(EDDSA()) and name = "EDSA" or type = TSignature(OtherSignatureAlgorithmType()) and name = "UnknownSignature" or @@ -804,6 +801,14 @@ module CryptographyBase Input> { * verification operation. */ abstract ConsumerInputDataFlowNode getSignatureConsumer(); + + /** + * Gets the consumer of a hash algorithm. + * This is intended for signature operations they are explicitly configured + * with a hash algorithm. If a signature is not configured with an explicit + * hash algorithm, users do not need to provide a consumer (set none()). + */ + abstract AlgorithmValueConsumer getHashAlgorithmValueConsumer(); } /** @@ -955,14 +960,14 @@ module CryptographyBase Input> { /** * Gets the type of this MAC algorithm, e.g., "HMAC" or "CMAC". */ - abstract TMACType getMACType(); + abstract TMACType getMacType(); /** * Gets the isolated name as it appears in source, e.g., "HMAC-SHA256" in "HMAC-SHA256/UnrelatedInformation". * * This name should not be parsed or formatted beyond isolating the raw MAC name if necessary. */ - abstract string getRawMACAlgorithmName(); + abstract string getRawMacAlgorithmName(); } abstract class MACOperationInstance extends OperationInstance { @@ -978,7 +983,7 @@ module CryptographyBase Input> { } abstract class HMACAlgorithmInstance extends MACAlgorithmInstance { - HMACAlgorithmInstance() { this.getMACType() instanceof THMAC } + HMACAlgorithmInstance() { this.getMacType() instanceof THMAC } /** * Gets the hash algorithm used by this HMAC algorithm. @@ -1054,7 +1059,11 @@ module CryptographyBase Input> { digestLength = 512 // TODO: verify } - abstract private class KeyCreationOperationInstance extends OperationInstance { + /** + * Users should not extend this class directly, but instead use + * `KeyCreationOperationInstance` or `KeyDerivationOperationInstance`. + */ + abstract class KeyCreationOperationInstance extends OperationInstance { abstract string getKeyCreationTypeDescription(); /** @@ -1657,14 +1666,19 @@ module CryptographyBase Input> { result = this.getAKnownAlgorithm() or result = instance - .(KeyCreationOperationInstance) + .(KeyArtifactOutputInstance) + .getCreator() .getAnAlgorithmValueConsumer() .getAGenericSourceNode() } KeyCreationCandidateAlgorithmNode getAKnownAlgorithm() { result = - instance.(KeyCreationOperationInstance).getAnAlgorithmValueConsumer().getAKnownSourceNode() + instance + .(KeyArtifactOutputInstance) + .getCreator() + .getAnAlgorithmValueConsumer() + .getAKnownSourceNode() } override NodeBase getChild(string edgeName) { @@ -1730,6 +1744,12 @@ module CryptographyBase Input> { override string getInternalType() { result = instance.getKeyCreationTypeDescription() } + NodeBase getAKeySizeSource() { + result = instance.getKeySizeConsumer().getConsumer().getAGenericSourceNode() + or + result = instance.getKeySizeConsumer().getConsumer().getAKnownSourceNode() + } + /** * Gets the key artifact produced by this operation. */ @@ -1794,17 +1814,17 @@ module CryptographyBase Input> { override LocatableElement asElement() { result = instance } final override string getRawAlgorithmName() { - result = instance.asAlg().getRawMACAlgorithmName() + result = instance.asAlg().getRawMacAlgorithmName() } - TMACType getMACType() { result = instance.asAlg().getMACType() } + TMACType getMacType() { result = instance.asAlg().getMacType() } final private predicate macToNameMapping(TMACType type, string name) { type instanceof THMAC and name = "HMAC" } - override string getAlgorithmName() { this.macToNameMapping(this.getMACType(), result) } + override string getAlgorithmName() { this.macToNameMapping(this.getMacType(), result) } } final class HMACAlgorithmNode extends MACAlgorithmNode { @@ -2130,6 +2150,14 @@ module CryptographyBase Input> { key = "Key" and if exists(this.getAKey()) then result = this.getAKey() else result = this } + + override predicate properties(string key, string value, Location location) { + super.properties(key, value, location) + or + key = "KeyOperationSubtype" and + value = this.getKeyOperationSubtype().toString() and + location = this.getLocation() + } } class CipherOperationNode extends KeyOperationNode { @@ -2172,15 +2200,25 @@ module CryptographyBase Input> { result.asElement() = instance.getSignatureConsumer().getConsumer() } + HashAlgorithmNode getHashAlgorithm() { + result = instance.getHashAlgorithmValueConsumer().getAKnownSourceNode() + } + override NodeBase getChild(string key) { result = super.getChild(key) or // [KNOWN_OR_UNKNOWN] - only if we know the type is verify this.getKeyOperationSubtype() = TVerifyMode() and key = "Signature" and - if exists(this.getASignatureArtifact()) - then result = this.getASignatureArtifact() - else result = this + ( + if exists(this.getASignatureArtifact()) + then result = this.getASignatureArtifact() + else result = this + ) + or + // [KNOWN_OR_UNKNOWN] + key = "HashAlgorithm" and + (if exists(this.getHashAlgorithm()) then result = this.getHashAlgorithm() else result = this) } }