diff --git a/cpp/ql/lib/experimental/quantum/Language.qll b/cpp/ql/lib/experimental/quantum/Language.qll index 53cf7292b12f..e9c14245da87 100644 --- a/cpp/ql/lib/experimental/quantum/Language.qll +++ b/cpp/ql/lib/experimental/quantum/Language.qll @@ -14,8 +14,8 @@ module CryptoInput implements InputSig { result = node.asExpr() or result = node.asParameter() or result = node.asVariable() or - result = node.asDefiningArgument() - // TODO: do we need asIndirectExpr()? + result = node.asDefiningArgument() or + result = node.asIndirectExpr() } string locationToFileBaseNameAndLineNumberString(Location location) { @@ -53,7 +53,7 @@ module ArtifactFlowConfig implements DataFlow::ConfigSig { } } -module ArtifactFlow = DataFlow::Global; +module ArtifactFlow = TaintTracking::Global; /** * An artifact output to node input configuration @@ -93,7 +93,10 @@ module GenericDataSourceFlow = TaintTracking::Global; - import OpenSSL.OpenSSL diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll index f802e58d0a76..eafc839fbb8a 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll @@ -14,9 +14,13 @@ private import PaddingAlgorithmInstance */ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof KnownOpenSslAlgorithmExpr and + ( + source.asExpr() instanceof KnownOpenSslAlgorithmExpr or + source.asIndirectExpr() instanceof KnownOpenSslAlgorithmExpr + ) and // No need to flow direct operations to AVCs - not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall + not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall and + not source.asIndirectExpr() instanceof OpenSslDirectAlgorithmOperationCall } predicate isSink(DataFlow::Node sink) { @@ -46,10 +50,12 @@ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow:: } module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow = - DataFlow::Global; + TaintTracking::Global; module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral } + predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof OpenSslSpecialPaddingLiteral + } predicate isSink(DataFlow::Node sink) { exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink) @@ -61,7 +67,7 @@ module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF } module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow = - DataFlow::Global; + TaintTracking::Global; class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep { OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll index 4bd4b4497660..a0cbad2c57d5 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll @@ -53,7 +53,8 @@ class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmIns // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll index 47ffd67924a6..94251c39b566 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll @@ -2,12 +2,10 @@ import cpp private import experimental.quantum.Language private import KnownAlgorithmConstants private import Crypto::KeyOpAlg as KeyOpAlg -private import OpenSSLAlgorithmInstanceBase -private import PaddingAlgorithmInstance -private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase -private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer +private import experimental.quantum.OpenSSL.Operations.OpenSSLOperationBase +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers +private import OpenSSLAlgorithmInstances private import AlgToAVCFlow -private import BlockAlgorithmInstance /** * Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type. @@ -79,7 +77,8 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) @@ -97,10 +96,13 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan } override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { - //TODO: the padding is either self, or it flows through getter ctx to a set padding call - // like EVP_PKEY_CTX_set_rsa_padding result = this - // TODO or trace through getter ctx to set padding + or + exists(OperationStep s | + this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and + s.getAlgorithmValueConsumerForInput(PaddingAlgorithmIO()) = + result.(OpenSslAlgorithmInstance).getAvc() + ) } override string getRawAlgorithmName() { diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll index 82a2b1357f27..ef7186d07a0e 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll @@ -21,7 +21,8 @@ class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorith // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll index 2be84b68f616..55b2dcd7af4c 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/HashAlgorithmInstance.qll @@ -59,7 +59,8 @@ class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll index 1addda3a9eff..542c56666d98 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KeyAgreementAlgorithmInstance.qll @@ -37,7 +37,8 @@ class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithm // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll index 4328253f1a4f..dcc7ad08ae5a 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll @@ -171,9 +171,15 @@ class KnownOpenSslKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSsl } 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 + c.getTarget().getName() in [ + "EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new", "RSA_sign", "RSA_verify" + ] and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION" + or + c.getTarget().getName() in ["DSA_do_sign", "DSA_do_verify"] and + normalized = "DSA" and + algType = "SIGNATURE" } /** diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll index 97b183b7e7d3..5590f74082cb 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/MACAlgorithmInstance.qll @@ -2,12 +2,13 @@ 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.AlgorithmInstances.OpenSSLAlgorithmInstances private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations +private import Crypto::KeyOpAlg as KeyOpAlg private import AlgToAVCFlow class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance, - Crypto::MacAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr + Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr { OpenSslAlgorithmValueConsumer getterCall; @@ -21,7 +22,8 @@ class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance, // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) @@ -33,17 +35,34 @@ class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance, override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall } - override string getRawMacAlgorithmName() { + override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() or result = this.(Call).getTarget().getName() } - override Crypto::MacType getMacType() { - this instanceof KnownOpenSslHMacAlgorithmExpr and result = Crypto::HMAC() - or - this instanceof KnownOpenSslCMacAlgorithmExpr and result = Crypto::CMAC() + override Crypto::KeyOpAlg::AlgorithmType getAlgorithmType() { + if this instanceof KnownOpenSslHMacAlgorithmExpr + then result = KeyOpAlg::TMac(KeyOpAlg::HMAC()) + else + if this instanceof KnownOpenSslCMacAlgorithmExpr + then result = KeyOpAlg::TMac(KeyOpAlg::CMAC()) + else result = KeyOpAlg::TMac(KeyOpAlg::OtherMacAlgorithmType()) + } + + override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { + // TODO: trace to any key size initializer? + none() + } + + override int getKeySizeFixed() { + // TODO: are there known fixed key sizes to consider? + none() } + + override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() } + + override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() } } class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmInstance, @@ -60,9 +79,13 @@ class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmIns // where the current AVC traces to a HashAlgorithmIO consuming operation step. // TODO: need to consider getting reset values, tracing down to the first set for now exists(OperationStep s, AvcContextCreationStep avc | - avc = this.getAvc() and + avc = super.getAvc() and avc.flowsToOperationStep(s) and s.getAlgorithmValueConsumerForInput(HashAlgorithmIO()) = result ) } + + override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() } + + override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll index d487e05d0660..3a3b2d66c28c 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll @@ -1,10 +1,10 @@ import cpp private import experimental.quantum.Language private import OpenSSLAlgorithmInstanceBase +private import experimental.quantum.OpenSSL.Operations.OpenSSLOperationBase private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants private import AlgToAVCFlow -private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer -private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase +private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg /** @@ -18,13 +18,14 @@ private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as K * # define RSA_PKCS1_WITH_TLS_PADDING 7 * # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8 */ -class OpenSslPaddingLiteral extends Literal { +class OpenSslSpecialPaddingLiteral 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] } + OpenSslSpecialPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] } } /** + * Holds if `e` has the given `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'). */ @@ -45,9 +46,6 @@ predicate knownOpenSslConstantToPaddingFamilyType( ) } -//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, Crypto::PaddingAlgorithmInstance instanceof Expr { @@ -66,7 +64,8 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta // Sink is an argument to a CipherGetterCall sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and isPaddingSpecificConsumer = false @@ -79,12 +78,13 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta isPaddingSpecificConsumer = false or // Possibility 3: padding-specific literal - this instanceof OpenSslPaddingLiteral and + this instanceof OpenSslSpecialPaddingLiteral 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 + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a padding-specific consumer RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink) ) and @@ -124,44 +124,6 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta } } -// // Values used for EVP_PKEY_CTX_set_rsa_padding, these are -// // 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 -// { -// KnownRSAPaddingConstant() { -// // from rsa.h in openssl: -// // # 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 -// this instanceof Literal and -// this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] -// // TODO: trace to padding-specific consumers -// RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow -// } -// override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() } -// override Crypto::TPaddingType getPaddingType() { -// if this.(Literal).getValue().toInt() in [1, 6, 7, 8] -// then result = Crypto::PKCS1_v1_5() -// else -// if this.(Literal).getValue().toInt() = 3 -// then result = Crypto::NoPadding() -// else -// if this.(Literal).getValue().toInt() = 4 -// then result = Crypto::OAEP() -// else -// if this.(Literal).getValue().toInt() = 5 -// then result = Crypto::ANSI_X9_23() -// else result = Crypto::OtherPadding() -// } -// } class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance, KnownOpenSslPaddingConstantAlgorithmInstance { @@ -170,10 +132,18 @@ class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance, } override Crypto::HashAlgorithmInstance getOaepEncodingHashAlgorithm() { - none() //TODO + exists(OperationStep s | + this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and + s.getAlgorithmValueConsumerForInput(HashAlgorithmOaepIO()) = + result.(OpenSslAlgorithmInstance).getAvc() + ) } override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() { - none() //TODO + exists(OperationStep s | + this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and + s.getAlgorithmValueConsumerForInput(HashAlgorithmMgf1IO()) = + result.(OpenSslAlgorithmInstance).getAvc() + ) } } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll index cc2e5771ffc8..dda7aea22dcd 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/SignatureAlgorithmInstance.qll @@ -47,7 +47,8 @@ class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmIns // Sink is an argument to a signature getter call sink = getterCall.getInputNode() and // Source is `this` - src.asExpr() = this and + // NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr + this = [src.asExpr(), src.asIndirectExpr()] and // This traces to a getter KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) ) diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll index b06e55c0817e..a2de555d7f46 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll @@ -12,15 +12,17 @@ class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer { DataFlow::Node resultNode; EvpCipherAlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asIndirectExpr() = this and ( - this.(Call).getTarget().getName() in [ - "EVP_get_cipherbyname", "EVP_get_cipherbyobj", "EVP_get_cipherbynid" - ] and + this.(Call).getTarget().getName() in ["EVP_get_cipherbyname", "EVP_get_cipherbyobj"] and + valueArgNode.asIndirectExpr() = this.(Call).getArgument(0) + or + this.(Call).getTarget().getName() = "EVP_get_cipherbynid" and + // algorithm is an NID (int), use asExpr() valueArgNode.asExpr() = this.(Call).getArgument(0) or this.(Call).getTarget().getName() in ["EVP_CIPHER_fetch", "EVP_ASYM_CIPHER_fetch"] and - valueArgNode.asExpr() = this.(Call).getArgument(1) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll index d200cf2a0961..3269c41cad6b 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll @@ -23,7 +23,7 @@ class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanc */ override DataFlow::Node getResultNode() { this instanceof OpenSslDirectAlgorithmFetchCall and - result.asExpr() = this + result.asIndirectExpr() = this // NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated // the algorithm is directly used } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll index daf6baf2f031..94272f8abcc4 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll @@ -12,14 +12,19 @@ class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer { DataFlow::Node resultNode; EvpEllipticCurveAlgorithmConsumer() { - resultNode.asExpr() = this.(Call) and // in all cases the result is the return + resultNode.asIndirectExpr() = 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 + this.(Call).getTarget().getName() = "EVP_EC_gen" and + valueArgNode.asIndirectExpr() = this.(Call).getArgument(0) + or + this.(Call).getTarget().getName() = "EC_KEY_new_by_curve_name" and + // algorithm is an NID (int), use asExpr() valueArgNode.asExpr() = this.(Call).getArgument(0) or this.(Call).getTarget().getName() in [ "EC_KEY_new_by_curve_name_ex", "EVP_PKEY_CTX_set_ec_paramgen_curve_nid" ] and + // algorithm is an NID (int), use asExpr valueArgNode.asExpr() = this.(Call).getArgument(2) ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll index 114cf78a112e..c79547e587dd 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/HashAlgorithmValueConsumer.qll @@ -13,7 +13,7 @@ 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) + result.asIndirectExpr() = this.(Call).getArgument(1) } override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { @@ -42,7 +42,7 @@ class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer { "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) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) } override DataFlow::Node getResultNode() { none() } @@ -64,18 +64,18 @@ class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { DataFlow::Node resultNode; EvpDigestAlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asIndirectExpr() = this and ( this.(Call).getTarget().getName() in [ "EVP_get_digestbyname", "EVP_get_digestbynid", "EVP_get_digestbyobj" ] and - valueArgNode.asExpr() = this.(Call).getArgument(0) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(0) or this.(Call).getTarget().getName() = "EVP_MD_fetch" and - valueArgNode.asExpr() = this.(Call).getArgument(1) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) or this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and - valueArgNode.asExpr() = this.(Call).getArgument(2) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(2) ) } @@ -87,3 +87,21 @@ class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer { exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i) } } + +class RsaSignOrVerifyHashAlgorithmValueConsumer extends HashAlgorithmValueConsumer { + DataFlow::Node valueArgNode; + + RsaSignOrVerifyHashAlgorithmValueConsumer() { + this.(Call).getTarget().getName() in ["RSA_sign", "RSA_verify"] and + // arg 0 is an int, use asExpr + valueArgNode.asExpr() = this.(Call).getArgument(0) + } + + override DataFlow::Node getResultNode() { none() } + + 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/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll index 830adece0f31..918dc57ff97a 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KEMAlgorithmValueConsumer.qll @@ -11,10 +11,10 @@ class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer { DataFlow::Node resultNode; EvpKemAlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asIndirectExpr() = this and ( this.(Call).getTarget().getName() = "EVP_KEM_fetch" and - valueArgNode.asExpr() = this.(Call).getArgument(1) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll index 88c36a37eb51..b4634b625f90 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/KeyExchangeAlgorithmValueConsumer.qll @@ -11,10 +11,10 @@ class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueCons DataFlow::Node resultNode; EvpKeyExchangeAlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asIndirectExpr() = this and ( this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and - valueArgNode.asExpr() = this.(Call).getArgument(1) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll index f7c8fef37941..ba5cb8146ad5 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PKeyAlgorithmValueConsumer.qll @@ -11,7 +11,7 @@ class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer { DataFlow::Node resultNode; EvpPKeyAlgorithmConsumer() { - resultNode.asExpr() = this.(Call) and // in all cases the result is the return + resultNode.asIndirectExpr() = this.(Call) and // in all cases the result is the return ( // NOTE: some of these consumers are themselves key gen operations, // in these cases, the operation will be created separately for the same function. @@ -19,6 +19,7 @@ class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer { "EVP_PKEY_CTX_new_id", "EVP_PKEY_new_raw_private_key", "EVP_PKEY_new_raw_public_key", "EVP_PKEY_new_mac_key" ] and + // Algorithm is an int, use asExpr valueArgNode.asExpr() = this.(Call).getArgument(0) or this.(Call).getTarget().getName() in [ @@ -26,7 +27,8 @@ class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer { "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) + // AAlgorithm is a char*, use asIndirectExpr + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) or // argInd 2 is 'type' which can be RSA, or EC // if RSA argInd 3 is the key size, else if EC argInd 3 is the curve name @@ -38,10 +40,10 @@ class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer { // Elliptic curve case // If the argInd 3 is a derived type (pointer or array) then assume it is a curve name if this.(Call).getArgument(3).getType().getUnderlyingType() instanceof DerivedType - then valueArgNode.asExpr() = this.(Call).getArgument(3) + then valueArgNode.asIndirectExpr() = this.(Call).getArgument(3) else // All other cases - valueArgNode.asExpr() = this.(Call).getArgument(2) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(2) ) ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll index f080fc0f12a2..e279f7f1e091 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/PaddingAlgorithmValueConsumer.qll @@ -14,8 +14,9 @@ class Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorit DataFlow::Node resultNode; Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asDefiningArgument() = this.(Call).getArgument(0) and this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_padding" and + // algorithm is an int, use asExpr valueArgNode.asExpr() = this.(Call).getArgument(1) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll index c6f3fb8959c8..bcc596bb1ee6 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/SignatureAlgorithmValueConsumer.qll @@ -12,13 +12,13 @@ class EvpSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer DataFlow::Node resultNode; EvpSignatureAlgorithmValueConsumer() { - resultNode.asExpr() = this and + resultNode.asIndirectExpr() = this and ( // EVP_SIGNATURE this.(Call).getTarget().getName() = "EVP_SIGNATURE_fetch" and - valueArgNode.asExpr() = this.(Call).getArgument(1) + valueArgNode.asIndirectExpr() = this.(Call).getArgument(1) // EVP_PKEY_get1_DSA, EVP_PKEY_get1_RSA - // DSA_SIG_new, DSA_SIG_get0, RSA_sign ? + // DSA_SIG_new, DSA_SIG_get0 ? ) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/ArtifactPassthrough.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/ArtifactPassthrough.qll new file mode 100644 index 000000000000..190271372151 --- /dev/null +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/ArtifactPassthrough.qll @@ -0,0 +1,107 @@ +private import experimental.quantum.Language + +/** + * A call to `BN_bn2bin`. + * Commonly used to extract partial bytes from a signature, + * e.g., a signature from DSA_do_sign, passed to DSA_do_verify + * - int BN_bn2bin(const BIGNUM *a, unsigned char *to); + */ +class BnBn2BinCalStep extends AdditionalFlowInputStep { + Call call; + + BnBn2BinCalStep() { + call.getTarget().getName() = "BN_bn2bin" and + call.getArgument(0) = this.asIndirectExpr() + } + + override DataFlow::Node getOutput() { result.asDefiningArgument() = call.getArgument(1) } +} + +/** + * A call to `BN_bin2bn`. + * Commonly used to convert to a signature for DSA_do_verify + * - BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); + */ +class BnBin2BnCallStep extends AdditionalFlowInputStep { + Call call; + + BnBin2BnCallStep() { + call.getTarget().getName() = "BN_bin2bn" and + call.getArgument(0) = this.asIndirectExpr() + } + + override DataFlow::Node getOutput() { result.asDefiningArgument() = call.getArgument(2) } +} + +/** + * A call to `RSA_set0_key` or `DSA_SIG_set0`. + * Often used in combination with BN_bin2bn, to construct a signature. + */ +class RsaSet0KeyCallStep extends AdditionalFlowInputStep { + Call call; + + RsaSet0KeyCallStep() { + (call.getTarget().getName() = "RSA_set0_key" or call.getTarget().getName() = "DSA_SIG_set0") and + this.asIndirectExpr() in [call.getArgument(1), call.getArgument(2), call.getArgument(3)] + } + + override DataFlow::Node getOutput() { result.asDefiningArgument() = call.getArgument(0) } +} + +/** + * A call to `d2i_DSA_SIG`. This is a pass through of a signature of one form to another. + * - DSA_SIG *d2i_DSA_SIG(DSA_SIG **sig, const unsigned char **pp, long length); + */ +class D2iDsaSigCallStep extends AdditionalFlowInputStep { + Call call; + + D2iDsaSigCallStep() { + call.getTarget().getName() = "d2i_DSA_SIG" and + this.asIndirectExpr() = call.getArgument(1) + } + + override DataFlow::Node getOutput() { + // If arg 0 specified, the same pointer is returned, if not specified + // a new allocation is returned. + result.asDefiningArgument() = call.getArgument(0) or + result.asIndirectExpr() = call + } +} + +/** + * A call to `DSA_SIG_get0`. + * Converts a DSA_Sig into its components, which are commonly used with BN_bn2Bin to + * construct a char* signature. + * - void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); + */ +class DsaSigGet0CallStep extends AdditionalFlowInputStep { + Call call; + + DsaSigGet0CallStep() { + call.getTarget().getName() = "DSA_SIG_get0" and + this.asIndirectExpr() = call.getArgument(0) + } + + override DataFlow::Node getOutput() { + result.asDefiningArgument() = call.getArgument(1) + or + result.asDefiningArgument() = call.getArgument(2) + } +} + +/** + * A call to `EVP_PKEY_get1_RSA` or `EVP_PKEY_get1_DSA` + * - RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); + * - DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); + * A key input is converted into a key output, a key is not generated. + */ +class EvpPkeyGet1RsaOrDsa extends AdditionalFlowInputStep { + Call c; + + EvpPkeyGet1RsaOrDsa() { + c.getTarget().getName() = ["EVP_PKEY_get1_RSA", "EVP_PKEY_get1_DSA"] and + this.asIndirectExpr() = c.getArgument(0) + } + + override DataFlow::Node getOutput() { result.asIndirectExpr() = c } +} diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll index 10aa145804b6..1ad988d2ea6e 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll @@ -1,4 +1,4 @@ -import semmle.code.cpp.dataflow.new.DataFlow +import semmle.code.cpp.dataflow.new.TaintTracking private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers /** @@ -13,7 +13,9 @@ module AvcToCallArgConfig implements DataFlow::ConfigSig { * 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()) } + predicate isSink(DataFlow::Node sink) { + exists(Call c | c.getAnArgument() = [sink.asIndirectExpr(), sink.asExpr()]) + } } -module AvcToCallArgFlow = DataFlow::Global; +module AvcToCallArgFlow = TaintTracking::Global; diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll index 706cac65f8c4..2b3266902250 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll @@ -4,4 +4,5 @@ module OpenSslModel { import Operations.OpenSSLOperations import Random import GenericSourceCandidateLiteral + import ArtifactPassthrough } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/CipherOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/CipherOperation.qll index 44e30ddf9fc9..13d6a4ae4574 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/CipherOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/CipherOperation.qll @@ -3,24 +3,48 @@ private import OpenSSLOperationBase private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers import EVPPKeyCtxInitializer +/** + * A base class for all final cipher operation steps. + */ +abstract class FinalCipherOperationStep extends OperationStep { + override OperationStepType getStepType() { result = FinalStep() } +} + +/** + * A base configuration for all EVP cipher operations. + */ +abstract class EvpCipherOperationFinalStep extends FinalCipherOperationStep { + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } +} + /** * A base class for all EVP cipher operations. */ abstract class EvpCipherInitializer extends OperationStep { override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and + result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() and // Constants that are not equal to zero or // non-constants (e.g., variable accesses, which require data-flow to determine the value) // A zero (null) value typically indicates use of this operation step to initialize // other out parameters in a multi-step initialization. - (exists(result.asExpr().getValue()) implies result.asExpr().getValue().toInt() != 0) + ( + exists(result.asIndirectExpr().getValue()) + implies + result.asIndirectExpr().getValue().toInt() != 0 + ) } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -38,11 +62,15 @@ abstract class EvpEXInitializer extends EvpCipherInitializer { // non-constants (e.g., variable accesses, which require data-flow to determine the value) // A zero (null) value typically indicates use of this operation step to initialize // other out parameters in a multi-step initialization. - result.asExpr() = this.getArgument(3) and type = KeyIO() + result.asIndirectExpr() = this.getArgument(3) and type = KeyIO() or - result.asExpr() = this.getArgument(4) and type = IVorNonceIO() + result.asIndirectExpr() = this.getArgument(4) and type = IVorNonceIO() ) and - (exists(result.asExpr().getValue()) implies result.asExpr().getValue().toInt() != 0) + ( + exists(result.asIndirectExpr().getValue()) + implies + result.asIndirectExpr().getValue().toInt() != 0 + ) } } @@ -53,9 +81,9 @@ abstract class EvpEX2Initializer extends EvpCipherInitializer { override DataFlow::Node getInput(IOType type) { result = super.getInput(type) or - result.asExpr() = this.getArgument(2) and type = KeyIO() + result.asIndirectExpr() = this.getArgument(2) and type = KeyIO() or - result.asExpr() = this.getArgument(3) and type = IVorNonceIO() + result.asIndirectExpr() = this.getArgument(3) and type = IVorNonceIO() } } @@ -90,6 +118,7 @@ class Evp_Cipher_EX2_or_Simple_Init_Call extends EvpEX2Initializer { result = super.getInput(type) or this.getTarget().getName().toLowerCase().matches("%cipherinit%") and + // the key op subtype is an int, use asExpr result.asExpr() = this.getArgument(4) and type = KeyOperationSubtypeIO() } @@ -107,13 +136,13 @@ class EvpPkeyEncryptDecryptInit extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = OsslParamIO() + result.asIndirectExpr() = this.getArgument(1) and type = OsslParamIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -125,6 +154,7 @@ class EvpCipherInitSKeyCall extends EvpEX2Initializer { override DataFlow::Node getInput(IOType type) { result = super.getInput(type) or + // the key op subtype is an int, use asExpr result.asExpr() = this.getArgument(5) and type = KeyOperationSubtypeIO() } @@ -141,35 +171,20 @@ class EvpCipherUpdateCall extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(3) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(1) and type = CiphertextIO() + result.asDefiningArgument() = this.getArgument(1) and type = CiphertextIO() or - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = UpdateStep() } } -/** - * A base configuration for all EVP cipher operations. - */ -abstract class EvpCipherOperationFinalStep extends OperationStep { - override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() - } - - override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() - } - - override OperationStepType getStepType() { result = FinalStep() } -} - /** * A Call to EVP_Cipher. */ @@ -179,13 +194,13 @@ class EvpCipherCall extends EvpCipherOperationFinalStep { override DataFlow::Node getInput(IOType type) { super.getInput(type) = result or - result.asExpr() = this.getArgument(2) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(2) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { super.getOutput(type) = result or - result.asExpr() = this.getArgument(1) and type = CiphertextIO() + result.asDefiningArgument() = this.getArgument(1) and type = CiphertextIO() } } @@ -216,28 +231,50 @@ class EvpCipherFinalCall extends EvpCipherOperationFinalStep { */ class EvpPKeyCipherOperation extends EvpCipherOperationFinalStep { EvpPKeyCipherOperation() { - this.getTarget().getName() in ["EVP_PKEY_encrypt", "EVP_PKEY_decrypt"] + this.getTarget().getName() in ["EVP_PKEY_encrypt", "EVP_PKEY_decrypt"] and + // TODO: for now ignore this operation entirely if it is setting the cipher text to null + // this needs to be re-evalauted if this scenario sets other values worth tracking + ( + exists(this.(Call).getArgument(1).getValue()) + implies + this.(Call).getArgument(1).getValue().toInt() != 0 + ) } override DataFlow::Node getInput(IOType type) { super.getInput(type) = result or - result.asExpr() = this.getArgument(3) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { super.getOutput(type) = result or - result.asExpr() = this.getArgument(1) and type = CiphertextIO() + result.asDefiningArgument() = this.getArgument(1) and + type = CiphertextIO() and + this.getStepType() = FinalStep() // TODO: could indicate text lengths here, as well } + + override OperationStepType getStepType() { + // When the output buffer is null, the step is not a final step + // it is used to get the buffer size, if 0 consider it an initialization step + // NOTE/TODO: not tracing 0 to the arg, just looking for 0 directly in param + // the assumption is this is the common case, but we may want to make this more + // robust and support a dataflow. + result = FinalStep() and + (exists(super.getArgument(1).getValue()) implies super.getArgument(1).getValue().toInt() != 0) + or + result = InitializerStep() and + super.getArgument(1).getValue().toInt() = 0 + } } /** * An EVP cipher operation instance. * Any operation step that is a final operation step for EVP cipher operation steps. */ -class EvpCipherOperationInstance extends Crypto::KeyOperationInstance instanceof EvpCipherOperationFinalStep +class OpenSslCipherOperationInstance extends Crypto::KeyOperationInstance instanceof FinalCipherOperationStep { override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { super.getPrimaryAlgorithmValueConsumer() = result diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll index 2208407e53ca..32823cada5a2 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll @@ -1,5 +1,10 @@ /** * Initializers for EVP PKey + * These are used to create a Pkey context or set properties on a Pkey context + * e.g., key size, hash algorithms, curves, padding schemes, etc. + * Meant to capture more general purpose initializers that aren't necessarily + * tied to a specific operation. If tied to an operation (i.e., in the docs) + * we recommend defining defining all together in the same operation definition qll. * including: * https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/ * https://docs.openssl.org/3.0/man3/EVP_EncryptInit/#synopsis @@ -26,14 +31,16 @@ class EvpNewKeyCtx extends OperationStep instanceof Call { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = keyArg and type = KeyIO() + result.asIndirectExpr() = keyArg and type = KeyIO() or this.getTarget().getName() = "EVP_PKEY_CTX_new_from_pkey" and - result.asExpr() = this.getArgument(0) and + result.asIndirectExpr() = this.getArgument(0) and type = OsslLibContextIO() } - override DataFlow::Node getOutput(IOType type) { result.asExpr() = this and type = ContextIO() } + override DataFlow::Node getOutput(IOType type) { + result.asIndirectExpr() = this and type = ContextIO() + } override OperationStepType getStepType() { result = ContextCreationStep() } } @@ -47,13 +54,13 @@ class EvpCtxSetEcParamgenCurveNidInitializer extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() + result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -71,23 +78,46 @@ class EvpCtxSetEcParamgenCurveNidInitializer extends OperationStep { * - `EVP_PKEY_CTX_set_ecdh_kdf_md` */ class EvpCtxSetHashInitializer extends OperationStep { + boolean isOaep; + boolean isMgf1; + EvpCtxSetHashInitializer() { this.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_signature_md", "EVP_PKEY_CTX_set_dsa_paramgen_md", "EVP_PKEY_CTX_set_dh_kdf_md", "EVP_PKEY_CTX_set_ecdh_kdf_md" - ] + ] and + isOaep = false and + isMgf1 = false + or + this.getTarget().getName() in [ + "EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_mgf1_md" + ] and + isOaep = false and + isMgf1 = true + or + this.getTarget().getName() in [ + "EVP_PKEY_CTX_set_rsa_oaep_md_name", + "EVP_PKEY_CTX_set_rsa_oaep_md" + ] and + isOaep = true and + isMgf1 = false } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and + type = HashAlgorithmIO() and + isOaep = false and + isMgf1 = false + or + result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmOaepIO() and isOaep = true or - result.asExpr() = this.getArgument(1) and type = HashAlgorithmIO() + result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmMgf1IO() and isMgf1 = true } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -106,13 +136,13 @@ class EvpCtxSetKeySizeInitializer extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or result.asExpr() = this.getArgument(1) and type = KeySizeIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -122,16 +152,16 @@ class EvpCtxSetMacKeyInitializer extends OperationStep { EvpCtxSetMacKeyInitializer() { this.getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or result.asExpr() = this.getArgument(2) and type = KeySizeIO() or // the raw key that is configured into the output key - result.asExpr() = this.getArgument(1) and type = KeyIO() + result.asIndirectExpr() = this.getArgument(1) and type = KeyIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -143,13 +173,14 @@ class EvpCtxSetPaddingInitializer extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or + // The algorithm is an int: use asExpr result.asExpr() = this.getArgument(1) and type = PaddingAlgorithmIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -161,13 +192,13 @@ class EvpCtxSetSaltLengthInitializer extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or result.asExpr() = this.getArgument(1) and type = SaltLengthIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/HashOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/HashOperation.qll index 1878bfbe09f2..5b15dc6d76a3 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/HashOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/HashOperation.qll @@ -6,6 +6,13 @@ private import experimental.quantum.Language private import OpenSSLOperationBase private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers +/** + * A base class for final digest operations. + */ +abstract class FinalDigestOperation extends OperationStep { + override OperationStepType getStepType() { result = FinalStep() } +} + /** * A call to and EVP digest initializer, such as: * - `EVP_DigestInit` @@ -18,13 +25,13 @@ class EvpDigestInitVariantCalls extends OperationStep instanceof Call { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() + result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } @@ -38,56 +45,49 @@ class EvpDigestUpdateCall extends OperationStep instanceof Call { EvpDigestUpdateCall() { this.getTarget().getName() = "EVP_DigestUpdate" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = UpdateStep() } } -/** - * A base class for final digest operations. - */ -abstract class EvpFinalDigestOperationStep extends OperationStep { - override OperationStepType getStepType() { result = FinalStep() } -} - /** * A call to `EVP_Q_digest` * https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis */ -class EvpQDigestOperation extends EvpFinalDigestOperationStep instanceof Call { +class EvpQDigestOperation extends FinalDigestOperation instanceof Call { EvpQDigestOperation() { this.getTarget().getName() = "EVP_Q_digest" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() + result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() or - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(3) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() or result.asDefiningArgument() = this.getArgument(5) and type = DigestIO() } } -class EvpDigestOperation extends EvpFinalDigestOperationStep instanceof Call { +class EvpDigestOperation extends FinalDigestOperation instanceof Call { EvpDigestOperation() { this.getTarget().getName() = "EVP_Digest" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(4) and type = PrimaryAlgorithmIO() + result.asIndirectExpr() = this.getArgument(4) and type = PrimaryAlgorithmIO() or - result.asExpr() = this.getArgument(0) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(0) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { @@ -98,27 +98,28 @@ class EvpDigestOperation extends EvpFinalDigestOperationStep instanceof Call { /** * A call to EVP_DigestFinal variants */ -class EvpDigestFinalCall extends EvpFinalDigestOperationStep instanceof Call { +class EvpDigestFinalCall extends FinalDigestOperation instanceof Call { EvpDigestFinalCall() { this.getTarget().getName() in ["EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF"] } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() or result.asDefiningArgument() = this.getArgument(1) and type = DigestIO() + //result.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = this.getArgument(1) } } /** * An openssl digest final hash operation instance */ -class EvpDigestFinalOperationInstance extends Crypto::HashOperationInstance instanceof EvpFinalDigestOperationStep +class OpenSslDigestFinalOperationInstance extends Crypto::HashOperationInstance instanceof FinalDigestOperation { override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { super.getPrimaryAlgorithmValueConsumer() = result diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/KeyGenOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/KeyGenOperation.qll index 2c146aec97f5..e19d65c65aeb 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/KeyGenOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/KeyGenOperation.qll @@ -13,10 +13,12 @@ class ECKeyGen extends OperationStep instanceof Call { ECKeyGen() { this.(Call).getTarget().getName() = "EC_KEY_generate_key" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.(Call).getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.(Call).getArgument(0) and type = ContextIO() } - override DataFlow::Node getOutput(IOType type) { result.asExpr() = this and type = KeyIO() } + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this and type = KeyIO() + } override OperationStepType getStepType() { result = ContextCreationStep() } } @@ -33,16 +35,19 @@ class EvpKeyGenInitialize extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } } +/** + * A base class for final key generation operation steps. + */ abstract class KeyGenFinalOperationStep extends OperationStep { override OperationStepType getStepType() { result = FinalStep() } } @@ -54,26 +59,26 @@ class EvpPKeyQKeyGen extends KeyGenFinalOperationStep instanceof Call { EvpPKeyQKeyGen() { this.getTarget().getName() = "EVP_PKEY_Q_keygen" } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this and type = KeyIO() + result.asDefiningArgument() = this and type = KeyIO() } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or // When arg 3 is a derived type, it is a curve name, otherwise it is a key size for RSA if provided // and arg 2 is the algorithm type this.getArgument(3).getType().getUnderlyingType() instanceof DerivedType and - result.asExpr() = this.getArgument(3) and + result.asIndirectExpr() = this.getArgument(3) and type = PrimaryAlgorithmIO() or not this.getArgument(3).getType().getUnderlyingType() instanceof DerivedType and - result.asExpr() = this.getArgument(2) and + result.asIndirectExpr() = this.getArgument(2) and type = PrimaryAlgorithmIO() or not this.getArgument(3).getType().getUnderlyingType() instanceof DerivedType and - result.asExpr() = this.getArgument(3) and + result.asIndirectExpr() = this.getArgument(3) and type = KeySizeIO() } } @@ -84,7 +89,9 @@ class EvpPKeyQKeyGen extends KeyGenFinalOperationStep instanceof Call { class EvpRsaGen extends KeyGenFinalOperationStep instanceof Call { EvpRsaGen() { this.getTarget().getName() = "EVP_RSA_gen" } - override DataFlow::Node getOutput(IOType type) { result.asExpr() = this and type = KeyIO() } + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this and type = KeyIO() + } override DataFlow::Node getInput(IOType type) { result.asExpr() = this.getArgument(0) and type = KeySizeIO() @@ -97,7 +104,9 @@ class EvpRsaGen extends KeyGenFinalOperationStep instanceof Call { class RsaGenerateKey extends KeyGenFinalOperationStep instanceof Call { RsaGenerateKey() { this.getTarget().getName() = "RSA_generate_key" } - override DataFlow::Node getOutput(IOType type) { result.asExpr() = this and type = KeyIO() } + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this and type = KeyIO() + } override DataFlow::Node getInput(IOType type) { result.asExpr() = this.getArgument(0) and type = KeySizeIO() @@ -117,7 +126,7 @@ class RsaGenerateKeyEx extends KeyGenFinalOperationStep instanceof Call { override DataFlow::Node getInput(IOType type) { // arg 0 comes in as a blank RSA key, which we consider a context, // on output it is considered a key - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } } @@ -128,13 +137,13 @@ class EvpPkeyGen extends KeyGenFinalOperationStep instanceof Call { EvpPkeyGen() { this.getTarget().getName() in ["EVP_PKEY_generate", "EVP_PKEY_keygen"] } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } override DataFlow::Node getOutput(IOType type) { result.asDefiningArgument() = this.getArgument(1) and type = KeyIO() or - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } } @@ -146,18 +155,14 @@ class EvpNewMacKey extends KeyGenFinalOperationStep { EvpNewMacKey() { this.getTarget().getName() = "EVP_PKEY_new_mac_key" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() - or // the raw key that is configured into the output key - result.asExpr() = this.getArgument(2) and type = KeyIO() + result.asIndirectExpr() = this.getArgument(2) and type = KeyIO() or result.asExpr() = this.getArgument(3) and type = KeySizeIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this and type = KeyIO() - or - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this and type = KeyIO() } } @@ -165,7 +170,7 @@ class EvpNewMacKey extends KeyGenFinalOperationStep { /** * An `KeyGenerationOperationInstance` for the for all key gen final operation steps. */ -class KeyGenOperationInstance extends Crypto::KeyGenerationOperationInstance instanceof KeyGenFinalOperationStep +class OpenSslKeyGenOperationInstance extends Crypto::KeyGenerationOperationInstance instanceof KeyGenFinalOperationStep { override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { super.getPrimaryAlgorithmValueConsumer() = result diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll index f1ab394ad787..5c0aa98dd0c5 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll @@ -1,6 +1,6 @@ private import experimental.quantum.Language private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers -import semmle.code.cpp.dataflow.new.DataFlow +import semmle.code.cpp.dataflow.new.TaintTracking // 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. @@ -58,7 +58,11 @@ newtype TIOType = // For OSSL_PARAM and OSSL_LIB_CTX use of OsslParamIO and OsslLibContextIO ContextIO() or DigestIO() or + // For OAEP and MGF1 hashes, there is a special IO type for these hashes + // it is recommended to set the most explicit type known, not both HashAlgorithmIO() or + HashAlgorithmOaepIO() or + HashAlgorithmMgf1IO() or IVorNonceIO() or KeyIO() or KeyOperationSubtypeIO() or @@ -71,11 +75,13 @@ newtype TIOType = PaddingAlgorithmIO() or // Plaintext also includes a message for digest, signature, verification, and mac generation PlaintextIO() or + PlaintextSizeIO() or PrimaryAlgorithmIO() or RandomSourceIO() or SaltLengthIO() or SeedIO() or - SignatureIO() + SignatureIO() or + SignatureSizeIO() private string ioTypeToString(TIOType t) { t = CiphertextIO() and result = "CiphertextIO" @@ -104,6 +110,8 @@ private string ioTypeToString(TIOType t) { or t = PlaintextIO() and result = "PlaintextIO" or + t = PlaintextSizeIO() and result = "PlaintextSizeIO" + or t = PrimaryAlgorithmIO() and result = "PrimaryAlgorithmIO" or t = RandomSourceIO() and result = "RandomSourceIO" @@ -113,6 +121,8 @@ private string ioTypeToString(TIOType t) { t = SeedIO() and result = "SeedIO" or t = SignatureIO() and result = "SignatureIO" + or + t = SignatureSizeIO() and result = "SignatureSizeIO" } class IOType extends TIOType { @@ -123,13 +133,13 @@ class IOType extends TIOType { } } -//TODO: add more initializers as needed /** * The type of step in an `OperationStep`. * - `ContextCreationStep`: the creation of a context from an algorithm or key. * for example `EVP_MD_CTX_create(EVP_sha256())` or `EVP_PKEY_CTX_new(pkey, NULL)` - * - `InitializerStep`: the initialization of an operation through some sort of shared/accumulated context - * for example `EVP_DigestInit_ex(ctx, EVP_sha256(), NULL)` + * - `InitializerStep`: the initialization of an operation or state through some sort of shared/accumulated context + * for example `EVP_DigestInit_ex(ctx, EVP_sha256(), NULL)`, may also be used for pass through + * configuration, for example `EVP_PKEY_get1_RSA(key)` where a pkey is input into an RSA key return. * - `UpdateStep`: any operation that has and update/final paradigm, the update represents an intermediate step in an operation, * such as `EVP_DigestUpdate(ctx, data, len)` * - `FinalStep`: an ultimate operation step. This may be an explicit 'final' in an update/final paradigm, but not necessarily. @@ -189,7 +199,7 @@ abstract class OperationStep extends Call { */ predicate flowsToOperationStep(OperationStep sink) { sink = this or - OperationStepFlow::flow(this.getAnOutput(), sink.getAnInput()) + OperationStepCtxFlow::flow(this.getAnOutput(), [sink.getAnInput(), sink.getAnOutput()]) } /** @@ -198,7 +208,7 @@ abstract class OperationStep extends Call { */ predicate flowsFromOperationStep(OperationStep source) { source = this or - OperationStepFlow::flow(source.getAnOutput(), this.getAnInput()) + OperationStepCtxFlow::flow(source.getAnOutput(), [this.getAnInput(), this.getAnOutput()]) } /** @@ -220,10 +230,13 @@ abstract class OperationStep extends Call { result.setsValue(type) and ( // Do not consider a 'reset' to occur on updates + // but only for resets that are part of the same update/finalize + // progression (e.g., an update for an unrelated finalize is ignored) result.getStepType() = UpdateStep() or not exists(OperationStep reset | result != reset and + result != this and reset.setsValue(type) and reset.flowsToOperationStep(this) and result.flowsToOperationStep(reset) @@ -245,8 +258,11 @@ abstract class OperationStep extends Call { /** * Gets an AVC for the primary algorithm for this operation. - * A primary algorithm is an AVC that flows to a ctx input directly or - * an AVC that flows to a primary algorithm input directly. + * A primary algorithm is an AVC that either: + * 0) `this` is an AVC (consider direct algorithm consumers like RSA_sign (algorithm is implicit) or EVP_PKEY_new_mac_key (NID is first arg) ) + * 1) flows to a ctx input directly or + * 2) flows to a primary algorithm input directly or + * 3) flows to a key input directly (algorithm held in a key will be considered primary) * See `AvcContextCreationStep` for details about resetting scenarios. * Gets the first OperationStep an AVC flows to. If a context input, * the AVC is considered primary. @@ -254,19 +270,24 @@ abstract class OperationStep extends Call { * operation step (dominating operation step, see `getDominatingInitializersToStep`). */ Crypto::AlgorithmValueConsumer getPrimaryAlgorithmValueConsumer() { - exists(DataFlow::Node src, DataFlow::Node sink, IOType t, OperationStep avcSucc | - (t = PrimaryAlgorithmIO() or t = ContextIO()) and - avcSucc.flowsToOperationStep(this) and - src.asExpr() = result and - sink = avcSucc.getInput(t) and + this instanceof Crypto::AlgorithmValueConsumer and result = this + or + exists( + DataFlow::Node src, DataFlow::Node sink, IOType srcIntype, OperationStep avcConsumingPred + | + (srcIntype = ContextIO() or srcIntype = PrimaryAlgorithmIO() or srcIntype = KeyIO()) and + avcConsumingPred.flowsToOperationStep(this) and + src.asIndirectExpr() = result and + sink = avcConsumingPred.getInput(srcIntype) and AvcToOperationStepFlow::flow(src, sink) and ( - // Case 1: the avcSucc step is a dominating initialization step - t = PrimaryAlgorithmIO() and - avcSucc = this.getDominatingInitializersToStep(PrimaryAlgorithmIO()) + // Case 1: the avcConsumingPred step is a dominating primary algorithm initialization step + // or dominating key initialization step + (srcIntype = PrimaryAlgorithmIO() or srcIntype = KeyIO()) and + avcConsumingPred = this.getDominatingInitializersToStep(srcIntype) or - // Case 2: the succ is a context input (any avcSucc is valid) - t = ContextIO() + // Case 2: the pred is a context input + srcIntype = ContextIO() ) ) } @@ -277,9 +298,11 @@ abstract class OperationStep extends Call { * TODO: generalize to use this for `getPrimaryAlgorithmValueConsumer` */ Crypto::AlgorithmValueConsumer getAlgorithmValueConsumerForInput(IOType type) { + result = this and this.setsValue(type) + or exists(DataFlow::Node src, DataFlow::Node sink | AvcToOperationStepFlow::flow(src, sink) and - src.asExpr() = result and + src.asIndirectExpr() = result and sink = this.getInput(type) ) } @@ -357,7 +380,7 @@ private class CtxCopyOutArgCall extends CtxPassThroughCall { CtxCopyOutArgCall() { this.getTarget().getName().toLowerCase().matches("%copy%") and - n1.asExpr() = this.getAnArgument() and + n1.asIndirectExpr() = this.getAnArgument() and n1.getType() instanceof CtxType and n2.asDefiningArgument() = this.getAnArgument() and n2.getType() instanceof CtxType and @@ -378,16 +401,18 @@ private class CtxCopyReturnCall extends CtxPassThroughCall, CtxPointerExpr { CtxCopyReturnCall() { this.getTarget().getName().toLowerCase().matches("%dup%") and - n1.asExpr() = this.getAnArgument() and + n1.asIndirectExpr() = this.getAnArgument() and n1.getType() instanceof CtxType } override DataFlow::Node getNode1() { result = n1 } - override DataFlow::Node getNode2() { result.asExpr() = this } + override DataFlow::Node getNode2() { result.asIndirectExpr() = this } } -// TODO: is this still needed? +// TODO: is this still needed? It appears to be (tests fail without it) but +// I don't know why as EVP_PKEY_paramgen is an operation step and we pass through +// operation steps already. /** * 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 @@ -401,34 +426,10 @@ private class CtxParamGenCall extends CtxPassThroughCall { 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 } -} - -//TODO: I am not sure CallArgToCtxRet is needed anymore -/** - * If the current node 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 + //Arg 0 is *ctx + n1.asIndirectExpr() = this.getArgument(0) and + //Arg 1 is **pkey + n2.asDefiningArgument() = this.getArgument(1) } override DataFlow::Node getNode1() { result = n1 } @@ -439,7 +440,7 @@ private class CallArgToCtxRet extends CtxPassThroughCall, CtxPointerExpr { /** * A flow configuration from any non-final `OperationStep` to any other `OperationStep`. */ -module OperationStepFlowConfig implements DataFlow::ConfigSig { +module OperationStepCtxFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { exists(OperationStep s | s.getAnOutput() = source or @@ -455,22 +456,39 @@ module OperationStepFlowConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { - exists(CtxClearCall c | c.getAnArgument() = node.asExpr()) + exists(CtxClearCall c | c.getAnArgument() = [node.asExpr(), node.asIndirectExpr()]) } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + node1.(AdditionalFlowInputStep).getOutput() = node2 + or exists(CtxPassThroughCall c | c.getNode1() = node1 and c.getNode2() = node2) or - // Flow out through all outputs from an operation step if more than one output - // is defined. - exists(OperationStep s | s.getAnInput() = node1 and s.getAnOutput() = node2) + // Flow only through context and key inputs and outputs + // keys and context generally hold unifying context that link multiple steps + // Flow only out of finalize operations through key outputs, otherwise stop at final operations + exists(OperationStep s, IOType inType, IOType outType | + (s.getStepType() = FinalStep() implies outType = KeyIO()) and + ( + inType = ContextIO() + or + inType = KeyIO() + ) and + ( + outType = ContextIO() + or + outType = KeyIO() + ) and + s.getInput(inType) = node1 and + s.getOutput(outType) = node2 + ) // TODO: consideration for additional alises defined as follows: // if an output from an operation step itself flows from the output of another operation step // then the source of that flow's outputs (all of them) are potential aliases } } -module OperationStepFlow = DataFlow::Global; +module OperationStepCtxFlow = TaintTracking::Global; /** * A flow from AVC to the first `OperationStep` the AVC reaches as an input. @@ -483,7 +501,7 @@ module AvcToOperationStepFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(OperationStep s | s.getAnInput() = sink) } predicate isBarrier(DataFlow::Node node) { - exists(CtxClearCall c | c.getAnArgument() = node.asExpr()) + exists(CtxClearCall c | c.getAnArgument() = [node.asExpr(), node.asIndirectExpr()]) } /** @@ -496,7 +514,7 @@ module AvcToOperationStepFlowConfig implements DataFlow::ConfigSig { } } -module AvcToOperationStepFlow = DataFlow::Global; +module AvcToOperationStepFlow = TaintTracking::Global; module EncValToInitEncArgConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr().getValue().toInt() in [0, 1] } @@ -506,7 +524,7 @@ module EncValToInitEncArgConfig implements DataFlow::ConfigSig { } } -module EncValToInitEncArgFlow = DataFlow::Global; +module EncValToInitEncArgFlow = TaintTracking::Global; private Crypto::KeyOperationSubtype intToCipherOperationSubtype(int i) { i = 0 and diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/SignatureOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/SignatureOperation.qll index b9b498ee8df3..f5e9ad354ada 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/SignatureOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/SignatureOperation.qll @@ -6,12 +6,25 @@ private import experimental.quantum.Language private import experimental.quantum.OpenSSL.AvcFlow private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations +private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances -// TODO: verification functions /** * A base class for final signature operations. + * The operation must be known to always be a signature operation, + * and not a MAC operation. Used for both verification and signing. + * NOTE: even an operation that may be a mac or signature but is known to take in + * only signature configurations should extend `SignatureOrMacFinalOperation`. */ -abstract class EvpSignatureFinalOperation extends OperationStep { +abstract class SignatureFinalOperation extends OperationStep { + override OperationStepType getStepType() { result = FinalStep() } +} + +/** + * A base class for final signature or MAC operations. + * The operation must be known to always be a signature or MAC operation. + * Used for both verification or signing. + */ +abstract class SignatureOrMacFinalOperation extends OperationStep { override OperationStepType getStepType() { result = FinalStep() } } @@ -24,36 +37,32 @@ class EvpSignatureDigestInitializer extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or this.getTarget().getName() = "EVP_DigestSignInit_ex" and - result.asExpr() = this.getArgument(3) and + result.asIndirectExpr() = this.getArgument(3) and type = OsslLibContextIO() or - result.asExpr() = this.getArgument(2) and type = HashAlgorithmIO() + result.asIndirectExpr() = this.getArgument(2) and type = HashAlgorithmIO() or this.getTarget().getName() = "EVP_DigestSignInit" and - result.asExpr() = this.getArgument(4) and + result.asIndirectExpr() = this.getArgument(4) and type = KeyIO() or this.getTarget().getName() = "EVP_DigestSignInit_ex" and - result.asExpr() = this.getArgument(5) and + result.asIndirectExpr() = this.getArgument(5) and type = KeyIO() or this.getTarget().getName() = "EVP_DigestSignInit_ex" and - result.asExpr() = this.getArgument(6) and + result.asIndirectExpr() = this.getArgument(6) and type = OsslParamIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() or // EVP_PKEY_CTX - result.asExpr() = this.getArgument(1) and type = ContextIO() - or - this.getTarget().getName() = "EVP_DigestSignInit_ex" and - result.asExpr() = this.getArgument(6) and - type = ContextIO() + result.asDefiningArgument() = this.getArgument(1) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -66,13 +75,13 @@ class EvpSignInit extends OperationStep { EvpSignInit() { this.getTarget().getName() in ["EVP_SignInit", "EVP_SignInit_ex"] } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = HashAlgorithmIO() + result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -94,22 +103,22 @@ class EvpPkeySignInit extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or this.getTarget().getName() in ["EVP_PKEY_sign_init_ex2", "EVP_PKEY_sign_message_init"] and - result.asExpr() = this.getArgument(1) and + result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO() or this.getTarget().getName() = "EVP_PKEY_sign_init_ex" and - result.asExpr() = this.getArgument(1) and + result.asIndirectExpr() = this.getArgument(1) and type = OsslParamIO() or // Argument 2 (0 based) only exists for EVP_PKEY_sign_init_ex2 and EVP_PKEY_sign_message_init - result.asExpr() = this.getArgument(2) and type = OsslParamIO() + result.asIndirectExpr() = this.getArgument(2) and type = OsslParamIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = InitializerStep() } @@ -126,13 +135,13 @@ class EvpSignatureUpdateCall extends OperationStep { } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = UpdateStep() } @@ -141,73 +150,496 @@ class EvpSignatureUpdateCall extends OperationStep { /** * A call to EVP_SignFinal or EVP_SignFinal_ex. */ -class EvpSignFinal extends EvpSignatureFinalOperation { +class EvpSignFinal extends SignatureFinalOperation { EvpSignFinal() { this.getTarget().getName() in ["EVP_SignFinal_ex", "EVP_SignFinal"] } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(3) and type = KeyIO() + result.asIndirectExpr() = this.getArgument(3) and type = KeyIO() or // params above 3 (0-based) only exist for EVP_SignFinal_ex - result.asExpr() = this.getArgument(4) and + result.asIndirectExpr() = this.getArgument(4) and type = OsslLibContextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + result.asDefiningArgument() = this.getArgument(1) and type = SignatureIO() + or + result.asDefiningArgument() = this.getArgument(2) and type = SignatureSizeIO() + } +} + +/** + * A call to EVP_PKEY_sign. + */ +class EvpPkeySign extends SignatureFinalOperation { + EvpPkeySign() { + this.getTarget().getName() = "EVP_PKEY_sign" and + // Setting signature to NULL is not a final sign step but an + // intermediary step used to get the required buffer size. + // not tracking these calls. + ( + exists(this.(Call).getArgument(1).getValue()) + implies + this.(Call).getArgument(1).getValue().toInt() != 0 + ) + } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(1) and type = SignatureIO() + result.asDefiningArgument() = this.getArgument(1) and type = SignatureIO() } } /** - * A call to EVP_DigestSign or EVP_PKEY_sign. + * A call to EVP_DigestSign. + * This is a mac or sign operation. */ -class EvpDigestSign extends EvpSignatureFinalOperation { - EvpDigestSign() { this.getTarget().getName() in ["EVP_DigestSign", "EVP_PKEY_sign"] } +class EvpDigestSign extends SignatureOrMacFinalOperation { + EvpDigestSign() { this.getTarget().getName() = "EVP_DigestSign" } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() or - result.asExpr() = this.getArgument(3) and type = PlaintextIO() + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + result.asDefiningArgument() = this.getArgument(1) and type = SignatureIO() + } +} + +/** + * A call to EVP_PKEY_sign_message_final. + */ +class EvpPkeySignFinal extends SignatureFinalOperation { + EvpPkeySignFinal() { + this.getTarget().getName() = "EVP_PKEY_sign_message_final" and + // Setting signature to NULL is not a final sign step but an + // intermediary step used to get the required buffer size. + // not tracking these calls. + ( + exists(this.(Call).getArgument(1).getValue()) + implies + this.(Call).getArgument(1).getValue().toInt() != 0 + ) + } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + result.asDefiningArgument() = this.getArgument(1) and type = SignatureIO() or - result.asExpr() = this.getArgument(1) and type = SignatureIO() + result.asExpr() = this.getArgument(2) and type = SignatureSizeIO() } } /** - * A call to EVP_DigestSignFinal or EVP_PKEY_sign_message_final. + * A call to EVP_DigestSignFinal. + * This is a mac or sign operation. + */ +class EvpDigestSignFinal extends SignatureOrMacFinalOperation { + EvpDigestSignFinal() { + this.getTarget().getName() = "EVP_DigestSignFinal" and + // Setting signature to NULL is not a final sign step but an + // intermediary step used to get the required buffer size. + // not tracking these calls. + ( + exists(this.(Call).getArgument(1).getValue()) + implies + this.(Call).getArgument(1).getValue().toInt() != 0 + ) + } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + result.asDefiningArgument() = this.getArgument(1) and type = SignatureIO() + } + + override OperationStepType getStepType() { result = FinalStep() } +} + +/** + * A call to EVP_DigestVerifyInit or EVP_DigestVerifyInit_ex. + */ +class EvpDigestVerifyInit extends OperationStep { + EvpDigestVerifyInit() { + this.getTarget().getName() in ["EVP_DigestVerifyInit", "EVP_DigestVerifyInit_ex"] + } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(2) and type = HashAlgorithmIO() + or + this.getTarget().getName() = "EVP_DigestVerifyInit_ex" and + result.asIndirectExpr() = this.getArgument(3) and + type = OsslLibContextIO() + or + this.getTarget().getName() = "EVP_DigestVerifyInit_ex" and + result.asIndirectExpr() = this.getArgument(5) and + type = KeyIO() + or + this.getTarget().getName() = "EVP_DigestVerifyInit" and + result.asIndirectExpr() = this.getArgument(4) and + type = KeyIO() + or + this.getTarget().getName() = "EVP_DigestVerifyInit_ex" and + result.asIndirectExpr() = this.getArgument(6) and + type = OsslParamIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + result.asDefiningArgument() = this.getArgument(1) and type = ContextIO() + } + + override OperationStepType getStepType() { result = InitializerStep() } +} + +/** + * A call to EVP_DigestVerifyUpdate. */ -class EvpDigestAndPkeySignFinal extends EvpSignatureFinalOperation { - EvpDigestAndPkeySignFinal() { +class EvpDigestVerifyUpdate extends OperationStep { + EvpDigestVerifyUpdate() { this.getTarget().getName() = "EVP_DigestVerifyUpdate" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = UpdateStep() } +} + +/** + * A call to EVP_DigestVerifyFinal + */ +class EvpDigestVerifyFinal extends SignatureFinalOperation { + EvpDigestVerifyFinal() { this.getTarget().getName() = "EVP_DigestVerifyFinal" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = SignatureIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } +} + +/** + * A call to EVP_DigestVerify + */ +class EvpDigestVerify extends SignatureFinalOperation { + EvpDigestVerify() { this.getTarget().getName() = "EVP_DigestVerify" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = SignatureIO() + or + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } +} + +/** + * A call to `EVP_PKEY_verify_init`, `EVP_PKEY_verify_init_ex`, + * `EVP_PKEY_verify_init_ex2`, or `EVP_PKEY_verify_message_init` + * https://docs.openssl.org/master/man3/EVP_PKEY_verify/#synopsis + */ +class EvpVerifyInit extends OperationStep { + EvpVerifyInit() { this.getTarget().getName() in [ - "EVP_DigestSignFinal", - "EVP_PKEY_sign_message_final" + "EVP_PKEY_verify_init", "EVP_PKEY_verify_init_ex", "EVP_PKEY_verify_init_ex2", + "EVP_PKEY_verify_message_init" ] } override DataFlow::Node getInput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + this.getTarget().getName() = "EVP_PKEY_verify_init_ex" and + result.asIndirectExpr() = this.getArgument(1) and + type = OsslParamIO() + or + this.getTarget().getName() in ["EVP_PKEY_verify_init_ex2", "EVP_PKEY_verify_message_init"] and + result.asIndirectExpr() = this.getArgument(1) and + type = PrimaryAlgorithmIO() + or + this.getTarget().getName() in ["EVP_PKEY_verify_init_ex2", "EVP_PKEY_verify_message_init"] and + result.asIndirectExpr() = this.getArgument(2) and + type = OsslParamIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = InitializerStep() } +} + +/** + * A call to `EVP_PKEY_CTX_set_signature` + * https://docs.openssl.org/master/man3/EVP_PKEY_verify/ + */ +class EvpCtxSetSignatureInitializer extends OperationStep { + EvpCtxSetSignatureInitializer() { this.getTarget().getName() = "EVP_PKEY_CTX_set_signature" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = SignatureIO() + or + result.asExpr() = this.getArgument(2) and type = SignatureSizeIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = InitializerStep() } +} + +/** + * A call to `EVP_PKEY_verify_message_update`. + */ +class EvpVerifyMessageUpdate extends OperationStep { + EvpVerifyMessageUpdate() { this.getTarget().getName() = "EVP_PKEY_verify_message_update" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() + or + result.asExpr() = this.getArgument(2) and type = PlaintextSizeIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = UpdateStep() } +} + +/** + * A call to `EVP_PKEY_verify_message_final`. + */ +class EvpVerifyMessageFinal extends SignatureFinalOperation { + EvpVerifyMessageFinal() { this.getTarget().getName() = "EVP_PKEY_verify_message_final" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() } override DataFlow::Node getOutput(IOType type) { - result.asExpr() = this.getArgument(0) and type = ContextIO() + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } +} + +/** + * A call to `EVP_PKEY_verify` + */ +class EvpVerify extends SignatureFinalOperation { + EvpVerify() { this.getTarget().getName() = "EVP_PKEY_verify" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = SignatureIO() + or + result.asExpr() = this.getArgument(2) and type = SignatureSizeIO() or - result.asExpr() = this.getArgument(1) and type = SignatureIO() + result.asIndirectExpr() = this.getArgument(3) and type = PlaintextIO() + or + result.asExpr() = this.getArgument(4) and type = PlaintextSizeIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } +} + +/** + * A call to `RSA_sign` or `RSA_verify`. + * https://docs.openssl.org/3.0/man3/RSA_sign/ + */ +class RsaSignorVerify extends SignatureFinalOperation { + RsaSignorVerify() { this.getTarget().getName() in ["RSA_sign", "RSA_verify"] } + + override DataFlow::Node getInput(IOType type) { + // Arg 0 is an NID (so asExpr not asIndirectExpr) + result.asExpr() = this.getArgument(0) and type = HashAlgorithmIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() + or + result.asExpr() = this.getArgument(2) and type = PlaintextSizeIO() + or + this.getTarget().getName() = "RSA_verify" and + result.asIndirectExpr() = this.getArgument(3) and + type = SignatureIO() + or + this.getTarget().getName() = "RSA_verify" and + result.asIndirectExpr() = this.getArgument(4) and + type = SignatureSizeIO() + or + result.asIndirectExpr() = this.getArgument(5) and type = KeyIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + or + this.getTarget().getName() = "RSA_sign" and + result.asDefiningArgument() = this.getArgument(3) and + type = SignatureIO() + or + this.getTarget().getName() = "RSA_sign" and + type = SignatureSizeIO() and + result.asDefiningArgument() = this.getArgument(4) + } +} + +/** + * A call to `DSA_do_sign` or `DSA_do_verify` + */ +class DsaDoSignOrVerify extends SignatureFinalOperation { + DsaDoSignOrVerify() { this.getTarget().getName() in ["DSA_do_sign", "DSA_do_verify"] } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = PlaintextIO() + or + result.asExpr() = this.getArgument(1) and type = PlaintextSizeIO() + or + this.getTarget().getName() = "DSA_do_sign" and + result.asIndirectExpr() = this.getArgument(2) and + type = KeyIO() + or + this.getTarget().getName() = "DSA_do_verify" and + result.asIndirectExpr() = this.getArgument(2) and + type = SignatureIO() + or + this.getTarget().getName() = "DSA_do_verify" and + result.asIndirectExpr() = this.getArgument(3) and + type = KeyIO() + } + + override DataFlow::Node getOutput(IOType type) { + this.getTarget().getName() = "DSA_do_sign" and + result.asIndirectExpr() = this and + type = SignatureIO() + } +} + +/** + * A Call to `EVP_VerifyInit` or `EVP_VerifyInit_ex` + * - int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); + * - int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); + */ +class EVP_VerifyInitCall extends OperationStep { + EVP_VerifyInitCall() { this.getTarget().getName() in ["EVP_VerifyInit", "EVP_VerifyInit_ex"] } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = InitializerStep() } +} + +/** + * A call to `EVP_VerifyUpdate` + * - int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); + */ +class EVP_VerifyUpdateCall extends OperationStep { + EVP_VerifyUpdateCall() { this.getTarget().getName() = "EVP_VerifyUpdate" } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = PlaintextIO() + or + result.asIndirectExpr() = this.getArgument(2) and type = PlaintextSizeIO() + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() + } + + override OperationStepType getStepType() { result = UpdateStep() } +} + +/** + * A call to `EVP_VerifyFinal` or `EVP_VerifyFinal_ex` + * - int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + * unsigned int siglen, EVP_PKEY *pkey, + * OSSL_LIB_CTX *libctx, const char *propq); + *- int EVP_VerifyFinal(EVP_MD_CTX *ctx, unsigned char *sigbuf, unsigned int siglen, + * EVP_PKEY *pkey); * + */ +class EVP_VerifyFinalCall extends SignatureFinalOperation { + EVP_VerifyFinalCall() { this.getTarget().getName() in ["EVP_VerifyFinal", "EVP_VerifyFinal_ex"] } + + override DataFlow::Node getInput(IOType type) { + result.asIndirectExpr() = this.getArgument(0) and type = ContextIO() + or + result.asIndirectExpr() = this.getArgument(1) and type = SignatureIO() + or + result.asExpr() = this.getArgument(2) and type = SignatureSizeIO() + or + result.asIndirectExpr() = this.getArgument(3) and type = KeyIO() + or + result.asIndirectExpr() = this.getArgument(4) and type = OsslLibContextIO() + // TODO: arg 5 propq? + } + + override DataFlow::Node getOutput(IOType type) { + result.asDefiningArgument() = this.getArgument(0) and type = ContextIO() } override OperationStepType getStepType() { result = FinalStep() } } /** - * An EVP signature operation instance. + * An instance of a signature operation. + * This is an OpenSSL specific class that extends the base SignatureOperationInstance. */ -class EvpSignatureOperationInstance extends Crypto::SignatureOperationInstance instanceof EvpSignatureFinalOperation +class OpenSslSignatureOperationInstance extends Crypto::SignatureOperationInstance instanceof SignatureFinalOperation { override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { super.getPrimaryAlgorithmValueConsumer() = result @@ -217,7 +649,7 @@ class EvpSignatureOperationInstance extends Crypto::SignatureOperationInstance i * Signing, verification or unknown. */ override Crypto::KeyOperationSubtype getKeyOperationSubtype() { - // TODO: if this KeyOperationSubtype does not match initialization call's KeyOperationSubtype then we found a bug + // NOTE: if this KeyOperationSubtype does not match initialization call's KeyOperationSubtype then we found a bug if super.getTarget().getName().toLowerCase().matches("%sign%") then result instanceof Crypto::TSignMode else @@ -227,18 +659,18 @@ class EvpSignatureOperationInstance extends Crypto::SignatureOperationInstance i } override Crypto::ConsumerInputDataFlowNode getNonceConsumer() { - // TODO: some signing operations may have explicit nonce generators - none() + // some signing operations may have explicit nonce generators + super.getDominatingInitializersToStep(IVorNonceIO()).getInput(IVorNonceIO()) = result } - /** - * 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() { super.getDominatingInitializersToStep(KeyIO()).getInput(KeyIO()) = result } + override Crypto::ConsumerInputDataFlowNode getSignatureConsumer() { + super.getDominatingInitializersToStep(SignatureIO()).getInput(SignatureIO()) = result + } + override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { super.getOutputStepFlowingToStep(SignatureIO()).getOutput(SignatureIO()) = result } @@ -247,14 +679,80 @@ class EvpSignatureOperationInstance extends Crypto::SignatureOperationInstance i super.getDominatingInitializersToStep(PlaintextIO()).getInput(PlaintextIO()) = result } + override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { + super + .getDominatingInitializersToStep(HashAlgorithmIO()) + .getAlgorithmValueConsumerForInput(HashAlgorithmIO()) = result + or + // Handle cases where the hash is set through the primary algorithm + // RSA-SHA256 for example + // NOTE: assuming the hash would not be overridden, or if it is it is undefined + // i.e., if the above dominating initializer exists and the primary algorithm + // specifies a hash, consider both valid hash AVCs. + // TODO: can this behavior be build into the get dominating initializers? + super.getPrimaryAlgorithmValueConsumer() = result and + exists(OpenSslAlgorithmInstance i | + i.getAvc() = result and i instanceof Crypto::HashAlgorithmInstance + ) + } + + override predicate hasHashAlgorithmConsumer() { + exists(super.getDominatingInitializersToStep(HashAlgorithmIO())) + } +} + +/** + * A class for signature or MAC operation instances. + * This is an OpenSSL specific class that extends the base SignatureOrMacOperationInstance. + */ +class OpenSslSignatureOrMacOperationInstance extends Crypto::SignatureOrMacOperationInstance instanceof SignatureOrMacFinalOperation +{ + override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { + super.getPrimaryAlgorithmValueConsumer() = result + } + /** - * TODO: only signing operations for now, change when verificaiton is added + * Signing, verification or unknown. */ - override Crypto::ConsumerInputDataFlowNode getSignatureConsumer() { none() } + override Crypto::KeyOperationSubtype getKeyOperationSubtype() { + result instanceof Crypto::TSignMode or result instanceof Crypto::TMacMode + } + + override Crypto::ConsumerInputDataFlowNode getNonceConsumer() { + // some signing operations may have explicit nonce generators + super.getDominatingInitializersToStep(IVorNonceIO()).getInput(IVorNonceIO()) = result + } + + override Crypto::ConsumerInputDataFlowNode getKeyConsumer() { + super.getDominatingInitializersToStep(KeyIO()).getInput(KeyIO()) = result + } + + override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { + super.getOutputStepFlowingToStep(SignatureIO()).getOutput(SignatureIO()) = result + } + + override Crypto::ConsumerInputDataFlowNode getInputConsumer() { + super.getDominatingInitializersToStep(PlaintextIO()).getInput(PlaintextIO()) = result + } override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { super .getDominatingInitializersToStep(HashAlgorithmIO()) .getAlgorithmValueConsumerForInput(HashAlgorithmIO()) = result + or + // Handle cases where the hash is set through the primary algorithm + // RSA-SHA256 for example + // NOTE: assuming the hash would not be overridden, or if it is it is undefined + // i.e., if the above dominating initializer exists and the primary algorithm + // specifies a hash, consider both valid hash AVCs. + // TODO: can this behavior be build into the get dominating initializers? + super.getPrimaryAlgorithmValueConsumer() = result and + exists(OpenSslAlgorithmInstance i | + i.getAvc() = result and i instanceof Crypto::HashAlgorithmInstance + ) + } + + override predicate hasHashAlgorithmConsumer() { + exists(super.getDominatingInitializersToStep(HashAlgorithmIO())) } } diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected b/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected index 27be8e5cfba5..5870bdecd8ed 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected +++ b/cpp/ql/test/experimental/library-tests/quantum/node_edges.expected @@ -13,7 +13,8 @@ | 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:81:49:81:58 | Message | Source | openssl_basic.c:35:36:35:45 | KeyOperationOutput | +| openssl_basic.c:81:49:81:58 | Message | Source | openssl_basic.c:40:38:40:53 | KeyOperationOutput | | 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 | @@ -30,24 +31,39 @@ | 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 | Key | Algorithm | openssl_basic.c:155:22:155:41 | Key | -| openssl_basic.c:155:22:155:41 | KeyGeneration | Algorithm | openssl_basic.c:155:22:155:41 | KeyGeneration | +| openssl_basic.c:155:22:155:41 | Key | Algorithm | openssl_basic.c:155:43:155:55 | HMACAlgorithm | +| openssl_basic.c:155:22:155:41 | KeyGeneration | Algorithm | openssl_basic.c:155:43:155:55 | HMACAlgorithm | | openssl_basic.c:155:22:155:41 | KeyGeneration | KeyInput | openssl_basic.c:155:64:155:66 | Key | | 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:155:43:155:55 | HMACAlgorithm | H | openssl_basic.c:160:39:160:48 | HashAlgorithm | | openssl_basic.c:155:64:155:66 | Key | Source | openssl_basic.c:179:43:179:76 | Constant | | 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 | KeyGeneration | Algorithm | openssl_pkey.c:21:10:21:28 | KeyGeneration | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | Algorithm | openssl_basic.c:155:43:155:55 | HMACAlgorithm | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | HashAlgorithm | openssl_basic.c:160:39:160:48 | HashAlgorithm | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | Input | openssl_basic.c:163:35:163:41 | Message | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | Key | openssl_basic.c:160:59:160:62 | Key | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | Nonce | openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | Output | openssl_basic.c:167:34:167:36 | SignatureOutput | +| openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | Mode | openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | +| openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | Padding | openssl_basic.c:249:51:249:72 | PaddingAlgorithm | +| openssl_basic.c:238:9:238:25 | KeyGeneration | Algorithm | openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | +| openssl_basic.c:238:9:238:25 | KeyGeneration | Output | openssl_basic.c:238:39:238:43 | Key | +| openssl_basic.c:238:39:238:43 | Key | Algorithm | openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | +| openssl_basic.c:243:52:243:55 | Key | Source | openssl_basic.c:238:39:238:43 | Key | +| openssl_basic.c:249:51:249:72 | PaddingAlgorithm | MD | openssl_basic.c:250:51:250:60 | HashAlgorithm | +| openssl_basic.c:249:51:249:72 | PaddingAlgorithm | MGF1Hash | openssl_basic.c:251:51:251:60 | HashAlgorithm | +| openssl_basic.c:262:24:262:39 | EncryptOperation | Algorithm | openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | +| openssl_basic.c:262:24:262:39 | EncryptOperation | Input | openssl_basic.c:263:64:263:70 | Message | +| openssl_basic.c:262:24:262:39 | EncryptOperation | Key | openssl_basic.c:243:52:243:55 | Key | +| openssl_basic.c:262:24:262:39 | EncryptOperation | Nonce | openssl_basic.c:262:24:262:39 | EncryptOperation | +| openssl_basic.c:262:24:262:39 | EncryptOperation | Output | openssl_basic.c:262:54:262:63 | KeyOperationOutput | +| openssl_basic.c:263:64:263:70 | Message | Source | openssl_basic.c:231:27:231:49 | Constant | +| openssl_pkey.c:21:10:21:28 | KeyGeneration | Algorithm | openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | | openssl_pkey.c:21:10:21:28 | KeyGeneration | Output | openssl_pkey.c:21:30:21:32 | Key | | 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:21:30:21:32 | Key | Algorithm | openssl_pkey.c:21:30:21:32 | Key | +| openssl_pkey.c:21:30:21:32 | Key | Algorithm | 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 | @@ -60,105 +76,174 @@ | 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:135:9:135:27 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | -| openssl_signature.c:135:9:135:27 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | -| openssl_signature.c:135:9:135:27 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | -| openssl_signature.c:135:9:135:27 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | -| openssl_signature.c:135:9:135:27 | SignOperation | Input | openssl_signature.c:134:38:134:44 | Message | -| openssl_signature.c:135:9:135:27 | SignOperation | Key | openssl_signature.c:133:52:133:55 | Key | -| openssl_signature.c:135:9:135:27 | SignOperation | Output | openssl_signature.c:135:37:135:40 | SignatureOutput | -| 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:197:9:197:27 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | -| openssl_signature.c:197:9:197:27 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | -| openssl_signature.c:197:9:197:27 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | -| openssl_signature.c:197:9:197:27 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | -| openssl_signature.c:197:9:197:27 | SignOperation | Input | openssl_signature.c:196:38:196:44 | Message | -| openssl_signature.c:197:9:197:27 | SignOperation | Key | openssl_signature.c:190:57:190:60 | Key | -| openssl_signature.c:197:9:197:27 | SignOperation | Output | openssl_signature.c:197:37:197:40 | SignatureOutput | -| 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:263:9:263:21 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | -| openssl_signature.c:263:9:263:21 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | -| openssl_signature.c:263:9:263:21 | SignOperation | HashAlgorithm | openssl_signature.c:684:24:684:33 | HashAlgorithm | -| openssl_signature.c:263:9:263:21 | SignOperation | HashAlgorithm | openssl_signature.c:740:24:740:33 | HashAlgorithm | -| openssl_signature.c:263:9:263:21 | SignOperation | Input | openssl_signature.c:263:54:263:59 | Message | -| openssl_signature.c:263:9:263:21 | SignOperation | Key | openssl_signature.c:260:39:260:42 | Key | -| openssl_signature.c:263:9:263:21 | SignOperation | Output | openssl_signature.c:263:33:263:36 | SignatureOutput | -| openssl_signature.c:263:54:263:59 | Message | Source | openssl_signature.c:263:54:263:59 | Message | -| 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:327:9:327:35 | SignOperation | Algorithm | openssl_signature.c:543:35:543:46 | KeyOperationAlgorithm | -| openssl_signature.c:327:9:327:35 | SignOperation | Algorithm | openssl_signature.c:565:50:565:54 | KeyOperationAlgorithm | -| openssl_signature.c:327:9:327:35 | SignOperation | Algorithm | openssl_signature.c:702:60:702:71 | KeyOperationAlgorithm | -| openssl_signature.c:327:9:327:35 | SignOperation | Algorithm | openssl_signature.c:758:60:758:64 | KeyOperationAlgorithm | -| openssl_signature.c:327:9:327:35 | SignOperation | HashAlgorithm | openssl_signature.c:327:9:327:35 | SignOperation | -| openssl_signature.c:327:9:327:35 | SignOperation | Input | openssl_signature.c:326:48:326:54 | Message | -| openssl_signature.c:327:9:327:35 | SignOperation | Key | openssl_signature.c:321:39:321:42 | Key | -| openssl_signature.c:327:9:327:35 | SignOperation | Output | openssl_signature.c:327:47:327:50 | SignatureOutput | -| 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:575:32:575:37 | Key | Source | openssl_signature.c:575:32:575:37 | Key | -| 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 | KeyInput | openssl_signature.c:575:32:575:37 | Key | -| 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 | +| openssl_signature.c:25:34:25:40 | Message | Source | openssl_signature.c:615:37:615:74 | Constant | +| openssl_signature.c:25:34:25:40 | Message | Source | openssl_signature.c:732:37:732:66 | Constant | +| openssl_signature.c:26:9:26:26 | HashOperation | Algorithm | openssl_signature.c:616:24:616:33 | HashAlgorithm | +| openssl_signature.c:26:9:26:26 | HashOperation | Algorithm | openssl_signature.c:733:24:733:31 | HashAlgorithm | +| openssl_signature.c:26:9:26:26 | HashOperation | Digest | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:26:9:26:26 | HashOperation | Message | openssl_signature.c:25:34:25:40 | Message | +| openssl_signature.c:26:36:26:41 | Digest | Source | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:63:32:63:38 | Message | Source | openssl_signature.c:651:37:651:61 | Constant | +| openssl_signature.c:68:28:68:36 | Message | Source | openssl_signature.c:651:37:651:61 | Constant | +| openssl_signature.c:73:9:73:21 | SignOperation | Algorithm | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:73:9:73:21 | SignOperation | HashAlgorithm | openssl_signature.c:652:24:652:33 | HashAlgorithm | +| openssl_signature.c:73:9:73:21 | SignOperation | Input | openssl_signature.c:63:32:63:38 | Message | +| openssl_signature.c:73:9:73:21 | SignOperation | Input | openssl_signature.c:68:28:68:36 | Message | +| openssl_signature.c:73:9:73:21 | SignOperation | Key | openssl_signature.c:73:53:73:56 | Key | +| openssl_signature.c:73:9:73:21 | SignOperation | Output | openssl_signature.c:73:31:73:40 | SignatureOutput | +| openssl_signature.c:73:53:73:56 | Key | Source | openssl_signature.c:666:34:666:37 | Key | +| openssl_signature.c:98:34:98:40 | Message | Source | openssl_signature.c:651:37:651:61 | Constant | +| openssl_signature.c:99:34:99:42 | Message | Source | openssl_signature.c:651:37:651:61 | Constant | +| openssl_signature.c:100:9:100:23 | VerifyOperation | Algorithm | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:100:9:100:23 | VerifyOperation | HashAlgorithm | openssl_signature.c:652:24:652:33 | HashAlgorithm | +| openssl_signature.c:100:9:100:23 | VerifyOperation | Input | openssl_signature.c:98:34:98:40 | Message | +| openssl_signature.c:100:9:100:23 | VerifyOperation | Input | openssl_signature.c:99:34:99:42 | Message | +| openssl_signature.c:100:9:100:23 | VerifyOperation | Key | openssl_signature.c:100:73:100:76 | Key | +| openssl_signature.c:100:9:100:23 | VerifyOperation | Signature | openssl_signature.c:100:33:100:41 | SignatureInput | +| openssl_signature.c:100:33:100:41 | SignatureInput | Source | openssl_signature.c:73:31:73:40 | SignatureOutput | +| openssl_signature.c:100:73:100:76 | Key | Source | openssl_signature.c:666:34:666:37 | Key | +| openssl_signature.c:126:52:126:55 | Key | Source | openssl_signature.c:707:34:707:37 | Key | +| openssl_signature.c:127:38:127:44 | Message | Source | openssl_signature.c:692:37:692:67 | Constant | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | Algorithm | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | HashAlgorithm | openssl_signature.c:693:24:693:33 | HashAlgorithm | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | Input | openssl_signature.c:127:38:127:44 | Message | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | Key | openssl_signature.c:126:52:126:55 | Key | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | Nonce | openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | Output | openssl_signature.c:135:37:135:46 | SignatureOutput | +| openssl_signature.c:158:54:158:57 | Key | Source | openssl_signature.c:707:34:707:37 | Key | +| openssl_signature.c:159:40:159:46 | Message | Source | openssl_signature.c:692:37:692:67 | Constant | +| openssl_signature.c:160:9:160:29 | VerifyOperation | Algorithm | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:160:9:160:29 | VerifyOperation | HashAlgorithm | openssl_signature.c:693:24:693:33 | HashAlgorithm | +| openssl_signature.c:160:9:160:29 | VerifyOperation | Input | openssl_signature.c:159:40:159:46 | Message | +| openssl_signature.c:160:9:160:29 | VerifyOperation | Key | openssl_signature.c:158:54:158:57 | Key | +| openssl_signature.c:160:9:160:29 | VerifyOperation | Signature | openssl_signature.c:160:39:160:47 | SignatureInput | +| openssl_signature.c:160:39:160:47 | SignatureInput | Source | openssl_signature.c:135:37:135:46 | SignatureOutput | +| openssl_signature.c:182:57:182:60 | Key | Source | openssl_signature.c:791:34:791:37 | Key | +| openssl_signature.c:187:38:187:44 | Message | Source | openssl_signature.c:777:37:777:73 | Constant | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | Algorithm | openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | HashAlgorithm | openssl_signature.c:778:24:778:31 | HashAlgorithm | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | Input | openssl_signature.c:187:38:187:44 | Message | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | Key | openssl_signature.c:182:57:182:60 | Key | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | Nonce | openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | Output | openssl_signature.c:195:37:195:46 | SignatureOutput | +| openssl_signature.c:218:59:218:62 | Key | Source | openssl_signature.c:791:34:791:37 | Key | +| openssl_signature.c:224:40:224:46 | Message | Source | openssl_signature.c:777:37:777:73 | Constant | +| openssl_signature.c:225:9:225:29 | VerifyOperation | Algorithm | openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:225:9:225:29 | VerifyOperation | HashAlgorithm | openssl_signature.c:778:24:778:31 | HashAlgorithm | +| openssl_signature.c:225:9:225:29 | VerifyOperation | Input | openssl_signature.c:224:40:224:46 | Message | +| openssl_signature.c:225:9:225:29 | VerifyOperation | Key | openssl_signature.c:218:59:218:62 | Key | +| openssl_signature.c:225:9:225:29 | VerifyOperation | Signature | openssl_signature.c:225:39:225:47 | SignatureInput | +| openssl_signature.c:225:39:225:47 | SignatureInput | Source | openssl_signature.c:195:37:195:46 | SignatureOutput | +| openssl_signature.c:250:39:250:42 | Key | Source | openssl_signature.c:751:34:751:37 | Key | +| openssl_signature.c:260:9:260:21 | SignOperation | Algorithm | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:260:9:260:21 | SignOperation | HashAlgorithm | openssl_signature.c:733:24:733:31 | HashAlgorithm | +| openssl_signature.c:260:9:260:21 | SignOperation | Input | openssl_signature.c:260:60:260:65 | Message | +| openssl_signature.c:260:9:260:21 | SignOperation | Key | openssl_signature.c:250:39:250:42 | Key | +| openssl_signature.c:260:9:260:21 | SignOperation | Output | openssl_signature.c:260:33:260:42 | SignatureOutput | +| openssl_signature.c:260:60:260:65 | Message | Source | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:282:39:282:42 | Key | Source | openssl_signature.c:751:34:751:37 | Key | +| openssl_signature.c:285:9:285:23 | VerifyOperation | Algorithm | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:285:9:285:23 | VerifyOperation | HashAlgorithm | openssl_signature.c:733:24:733:31 | HashAlgorithm | +| openssl_signature.c:285:9:285:23 | VerifyOperation | Input | openssl_signature.c:285:61:285:66 | Message | +| openssl_signature.c:285:9:285:23 | VerifyOperation | Key | openssl_signature.c:282:39:282:42 | Key | +| openssl_signature.c:285:9:285:23 | VerifyOperation | Signature | openssl_signature.c:285:35:285:43 | SignatureInput | +| openssl_signature.c:285:35:285:43 | SignatureInput | Source | openssl_signature.c:260:33:260:42 | SignatureOutput | +| openssl_signature.c:285:61:285:66 | Message | Source | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:311:39:311:42 | Key | Source | openssl_signature.c:829:34:829:37 | Key | +| openssl_signature.c:316:48:316:54 | Message | Source | openssl_signature.c:817:37:817:63 | Constant | +| openssl_signature.c:324:9:324:35 | SignOperation | Algorithm | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:324:9:324:35 | SignOperation | Algorithm | openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | +| openssl_signature.c:324:9:324:35 | SignOperation | HashAlgorithm | openssl_signature.c:838:85:838:96 | HashAlgorithm | +| openssl_signature.c:324:9:324:35 | SignOperation | Input | openssl_signature.c:316:48:316:54 | Message | +| openssl_signature.c:324:9:324:35 | SignOperation | Key | openssl_signature.c:311:39:311:42 | Key | +| openssl_signature.c:324:9:324:35 | SignOperation | Output | openssl_signature.c:324:47:324:56 | SignatureOutput | +| openssl_signature.c:347:39:347:42 | Key | Source | openssl_signature.c:829:34:829:37 | Key | +| openssl_signature.c:353:42:353:50 | SignatureInput | Source | openssl_signature.c:324:47:324:56 | SignatureOutput | +| openssl_signature.c:355:50:355:56 | Message | Source | openssl_signature.c:817:37:817:63 | Constant | +| openssl_signature.c:356:9:356:37 | VerifyOperation | Algorithm | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:356:9:356:37 | VerifyOperation | Algorithm | openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | +| openssl_signature.c:356:9:356:37 | VerifyOperation | HashAlgorithm | openssl_signature.c:839:87:839:98 | HashAlgorithm | +| openssl_signature.c:356:9:356:37 | VerifyOperation | Input | openssl_signature.c:355:50:355:56 | Message | +| openssl_signature.c:356:9:356:37 | VerifyOperation | Key | openssl_signature.c:347:39:347:42 | Key | +| openssl_signature.c:356:9:356:37 | VerifyOperation | Signature | openssl_signature.c:353:42:353:50 | SignatureInput | +| openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | Mode | openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | +| openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | Padding | openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | +| openssl_signature.c:384:9:384:16 | SignOperation | Algorithm | openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | +| openssl_signature.c:384:9:384:16 | SignOperation | Algorithm | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:384:9:384:16 | SignOperation | HashAlgorithm | openssl_signature.c:595:37:595:46 | HashAlgorithm | +| openssl_signature.c:384:9:384:16 | SignOperation | Input | openssl_signature.c:384:28:384:34 | Message | +| openssl_signature.c:384:9:384:16 | SignOperation | Key | openssl_signature.c:385:48:385:54 | Key | +| openssl_signature.c:384:9:384:16 | SignOperation | Output | openssl_signature.c:384:50:384:59 | SignatureOutput | +| openssl_signature.c:384:28:384:34 | Message | Source | openssl_signature.c:566:37:566:74 | Constant | +| openssl_signature.c:385:48:385:54 | Key | Source | openssl_signature.c:579:34:579:37 | Key | +| openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | Mode | openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | +| openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | Padding | openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | +| openssl_signature.c:403:12:403:21 | VerifyOperation | Algorithm | openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | +| openssl_signature.c:403:12:403:21 | VerifyOperation | Algorithm | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:403:12:403:21 | VerifyOperation | HashAlgorithm | openssl_signature.c:597:41:597:50 | HashAlgorithm | +| openssl_signature.c:403:12:403:21 | VerifyOperation | Input | openssl_signature.c:403:33:403:39 | Message | +| openssl_signature.c:403:12:403:21 | VerifyOperation | Key | openssl_signature.c:404:51:404:57 | Key | +| openssl_signature.c:403:12:403:21 | VerifyOperation | Signature | openssl_signature.c:403:55:403:63 | SignatureInput | +| openssl_signature.c:403:33:403:39 | Message | Source | openssl_signature.c:566:37:566:74 | Constant | +| openssl_signature.c:403:55:403:63 | SignatureInput | Source | openssl_signature.c:384:50:384:59 | SignatureOutput | +| openssl_signature.c:404:51:404:57 | Key | Source | openssl_signature.c:579:34:579:37 | Key | +| openssl_signature.c:428:11:428:21 | SignOperation | Algorithm | openssl_signature.c:428:11:428:21 | KeyOperationAlgorithm | +| openssl_signature.c:428:11:428:21 | SignOperation | Algorithm | openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | +| openssl_signature.c:428:11:428:21 | SignOperation | HashAlgorithm | openssl_signature.c:428:11:428:21 | SignOperation | +| openssl_signature.c:428:11:428:21 | SignOperation | Input | openssl_signature.c:428:23:428:28 | Message | +| openssl_signature.c:428:11:428:21 | SignOperation | Key | openssl_signature.c:428:43:428:49 | Key | +| openssl_signature.c:428:11:428:21 | SignOperation | Output | openssl_signature.c:428:11:428:21 | SignatureOutput | +| openssl_signature.c:428:23:428:28 | Message | Source | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:428:43:428:49 | Key | Source | openssl_signature.c:546:34:546:37 | Key | +| openssl_signature.c:484:15:484:27 | VerifyOperation | Algorithm | openssl_signature.c:484:15:484:27 | KeyOperationAlgorithm | +| openssl_signature.c:484:15:484:27 | VerifyOperation | Algorithm | openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | +| openssl_signature.c:484:15:484:27 | VerifyOperation | HashAlgorithm | openssl_signature.c:484:15:484:27 | VerifyOperation | +| openssl_signature.c:484:15:484:27 | VerifyOperation | Input | openssl_signature.c:484:29:484:34 | Message | +| openssl_signature.c:484:15:484:27 | VerifyOperation | Key | openssl_signature.c:484:54:484:60 | Key | +| openssl_signature.c:484:15:484:27 | VerifyOperation | Signature | openssl_signature.c:484:49:484:51 | SignatureInput | +| openssl_signature.c:484:29:484:34 | Message | Source | openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:484:49:484:51 | SignatureInput | Source | openssl_signature.c:428:11:428:21 | SignatureOutput | +| openssl_signature.c:484:54:484:60 | Key | Source | openssl_signature.c:546:34:546:37 | Key | +| openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | +| openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | +| openssl_signature.c:516:9:516:23 | KeyGeneration | Algorithm | openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | +| openssl_signature.c:516:9:516:23 | KeyGeneration | Output | openssl_signature.c:516:34:516:37 | Key | +| openssl_signature.c:516:34:516:37 | Key | Algorithm | openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | +| openssl_signature.c:543:32:543:37 | Key | Source | openssl_signature.c:543:32:543:37 | Key | +| openssl_signature.c:546:9:546:23 | KeyGeneration | Algorithm | openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | +| openssl_signature.c:546:9:546:23 | KeyGeneration | KeyInput | openssl_signature.c:543:32:543:37 | Key | +| openssl_signature.c:546:9:546:23 | KeyGeneration | Output | openssl_signature.c:546:34:546:37 | Key | +| openssl_signature.c:546:34:546:37 | Key | Algorithm | openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | +| openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:579:9:579:23 | KeyGeneration | Algorithm | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:579:9:579:23 | KeyGeneration | Output | openssl_signature.c:579:34:579:37 | Key | +| openssl_signature.c:579:34:579:37 | Key | Algorithm | openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:666:9:666:23 | KeyGeneration | Algorithm | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:666:9:666:23 | KeyGeneration | Output | openssl_signature.c:666:34:666:37 | Key | +| openssl_signature.c:666:34:666:37 | Key | Algorithm | openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:707:9:707:23 | KeyGeneration | Algorithm | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:707:9:707:23 | KeyGeneration | Output | openssl_signature.c:707:34:707:37 | Key | +| openssl_signature.c:707:34:707:37 | Key | Algorithm | openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:751:9:751:23 | KeyGeneration | Algorithm | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:751:9:751:23 | KeyGeneration | Output | openssl_signature.c:751:34:751:37 | Key | +| openssl_signature.c:751:34:751:37 | Key | Algorithm | openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:185:44:185:64 | PaddingAlgorithm | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:222:44:222:64 | PaddingAlgorithm | +| openssl_signature.c:791:9:791:23 | KeyGeneration | Algorithm | openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:791:9:791:23 | KeyGeneration | Output | openssl_signature.c:791:34:791:37 | Key | +| openssl_signature.c:791:34:791:37 | Key | Algorithm | openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | Mode | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | Padding | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:829:9:829:23 | KeyGeneration | Algorithm | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:829:9:829:23 | KeyGeneration | Output | openssl_signature.c:829:34:829:37 | Key | +| openssl_signature.c:829:34:829:37 | Key | Algorithm | openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | Padding | openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | +| openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | Padding | openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | diff --git a/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected b/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected index 52a7c61502bd..4f435517eef4 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected +++ b/cpp/ql/test/experimental/library-tests/quantum/node_properties.expected @@ -21,18 +21,34 @@ | 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 | Asymmetric | 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:155:43:155:55 | HMACAlgorithm | Name | HMAC | openssl_basic.c:155:43:155:55 | openssl_basic.c:155:43:155:55 | +| openssl_basic.c:155:43:155:55 | HMACAlgorithm | RawName | 855 | openssl_basic.c:155:43:155:55 | openssl_basic.c:155:43:155:55 | | openssl_basic.c:155:64:155:66 | Key | KeyType | Unknown | openssl_basic.c:155:64:155:66 | openssl_basic.c:155:64:155:66 | | 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:167:9:167:27 | SignatureOrMACOperation | KeyOperationSubtype | Mac | openssl_basic.c:167:9:167:27 | openssl_basic.c:167:9:167:27 | +| openssl_basic.c:167:9:167:27 | SignatureOrMACOperation | 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_basic.c:231:27:231:49 | Constant | Description | Encrypt me with OAEP! | openssl_basic.c:231:27:231:49 | openssl_basic.c:231:27:231:49 | +| openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | Name | RSA | openssl_basic.c:235:51:235:55 | openssl_basic.c:235:51:235:55 | +| openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | RawName | RSA | openssl_basic.c:235:51:235:55 | openssl_basic.c:235:51:235:55 | +| openssl_basic.c:237:54:237:57 | Constant | Description | 2048 | openssl_basic.c:237:54:237:57 | openssl_basic.c:237:54:237:57 | +| openssl_basic.c:238:39:238:43 | Key | KeyType | Asymmetric | openssl_basic.c:238:39:238:43 | openssl_basic.c:238:39:238:43 | +| openssl_basic.c:243:52:243:55 | Key | KeyType | Unknown | openssl_basic.c:243:52:243:55 | openssl_basic.c:243:52:243:55 | +| openssl_basic.c:249:51:249:72 | PaddingAlgorithm | Name | OAEP | openssl_basic.c:249:51:249:72 | openssl_basic.c:249:51:249:72 | +| openssl_basic.c:249:51:249:72 | PaddingAlgorithm | RawName | 4 | openssl_basic.c:249:51:249:72 | openssl_basic.c:249:51:249:72 | +| openssl_basic.c:250:51:250:60 | HashAlgorithm | DigestSize | 256 | openssl_basic.c:250:51:250:60 | openssl_basic.c:250:51:250:60 | +| openssl_basic.c:250:51:250:60 | HashAlgorithm | Name | SHA2 | openssl_basic.c:250:51:250:60 | openssl_basic.c:250:51:250:60 | +| openssl_basic.c:250:51:250:60 | HashAlgorithm | RawName | EVP_sha256 | openssl_basic.c:250:51:250:60 | openssl_basic.c:250:51:250:60 | +| openssl_basic.c:251:51:251:60 | HashAlgorithm | DigestSize | 256 | openssl_basic.c:251:51:251:60 | openssl_basic.c:251:51:251:60 | +| openssl_basic.c:251:51:251:60 | HashAlgorithm | Name | SHA2 | openssl_basic.c:251:51:251:60 | openssl_basic.c:251:51:251:60 | +| openssl_basic.c:251:51:251:60 | HashAlgorithm | RawName | EVP_sha256 | openssl_basic.c:251:51:251:60 | openssl_basic.c:251:51:251:60 | +| openssl_basic.c:262:24:262:39 | EncryptOperation | KeyOperationSubtype | Encrypt | openssl_basic.c:262:24:262:39 | openssl_basic.c:262:24:262:39 | | 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:21:30:21:32 | Key | KeyType | Asymmetric | openssl_pkey.c:21:30:21:32 | openssl_pkey.c:21:30:21:32 | @@ -43,44 +59,116 @@ | 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:135:9:135:27 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:135:9:135:27 | openssl_signature.c:135:9:135:27 | -| 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:197:9:197:27 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:197:9:197:27 | openssl_signature.c:197:9:197:27 | -| 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:263:9:263:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:263:9:263:21 | openssl_signature.c:263:9:263:21 | -| 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:327:9:327:35 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:327:9:327:35 | openssl_signature.c:327:9:327:35 | -| 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:575:32:575:37 | Key | KeyType | Unknown | openssl_signature.c:575:32:575:37 | openssl_signature.c:575:32:575:37 | -| 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 | +| openssl_signature.c:73:9:73:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:73:9:73:21 | openssl_signature.c:73:9:73:21 | +| openssl_signature.c:73:53:73:56 | Key | KeyType | Unknown | openssl_signature.c:73:53:73:56 | openssl_signature.c:73:53:73:56 | +| openssl_signature.c:100:9:100:23 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:100:9:100:23 | openssl_signature.c:100:9:100:23 | +| openssl_signature.c:100:73:100:76 | Key | KeyType | Unknown | openssl_signature.c:100:73:100:76 | openssl_signature.c:100:73:100:76 | +| openssl_signature.c:126:52:126:55 | Key | KeyType | Unknown | openssl_signature.c:126:52:126:55 | openssl_signature.c:126:52:126:55 | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | KeyOperationSubtype | Mac | openssl_signature.c:135:9:135:27 | openssl_signature.c:135:9:135:27 | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | KeyOperationSubtype | Sign | openssl_signature.c:135:9:135:27 | openssl_signature.c:135:9:135:27 | +| openssl_signature.c:158:54:158:57 | Key | KeyType | Unknown | openssl_signature.c:158:54:158:57 | openssl_signature.c:158:54:158:57 | +| openssl_signature.c:160:9:160:29 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:160:9:160:29 | openssl_signature.c:160:9:160:29 | +| openssl_signature.c:182:57:182:60 | Key | KeyType | Unknown | openssl_signature.c:182:57:182:60 | openssl_signature.c:182:57:182:60 | +| openssl_signature.c:185:44:185:64 | PaddingAlgorithm | Name | PSS | openssl_signature.c:185:44:185:64 | openssl_signature.c:185:44:185:64 | +| openssl_signature.c:185:44:185:64 | PaddingAlgorithm | RawName | 6 | openssl_signature.c:185:44:185:64 | openssl_signature.c:185:44:185:64 | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | KeyOperationSubtype | Mac | openssl_signature.c:195:9:195:27 | openssl_signature.c:195:9:195:27 | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | KeyOperationSubtype | Sign | openssl_signature.c:195:9:195:27 | openssl_signature.c:195:9:195:27 | +| openssl_signature.c:218:59:218:62 | Key | KeyType | Unknown | openssl_signature.c:218:59:218:62 | openssl_signature.c:218:59:218:62 | +| openssl_signature.c:222:44:222:64 | PaddingAlgorithm | Name | PSS | openssl_signature.c:222:44:222:64 | openssl_signature.c:222:44:222:64 | +| openssl_signature.c:222:44:222:64 | PaddingAlgorithm | RawName | 6 | openssl_signature.c:222:44:222:64 | openssl_signature.c:222:44:222:64 | +| openssl_signature.c:225:9:225:29 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:225:9:225:29 | openssl_signature.c:225:9:225:29 | +| openssl_signature.c:250:39:250:42 | Key | KeyType | Unknown | openssl_signature.c:250:39:250:42 | openssl_signature.c:250:39:250:42 | +| openssl_signature.c:260:9:260:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:260:9:260:21 | openssl_signature.c:260:9:260:21 | +| openssl_signature.c:282:39:282:42 | Key | KeyType | Unknown | openssl_signature.c:282:39:282:42 | openssl_signature.c:282:39:282:42 | +| openssl_signature.c:285:9:285:23 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:285:9:285:23 | openssl_signature.c:285:9:285:23 | +| openssl_signature.c:311:39:311:42 | Key | KeyType | Unknown | openssl_signature.c:311:39:311:42 | openssl_signature.c:311:39:311:42 | +| openssl_signature.c:324:9:324:35 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:324:9:324:35 | openssl_signature.c:324:9:324:35 | +| openssl_signature.c:347:39:347:42 | Key | KeyType | Unknown | openssl_signature.c:347:39:347:42 | openssl_signature.c:347:39:347:42 | +| openssl_signature.c:356:9:356:37 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:356:9:356:37 | openssl_signature.c:356:9:356:37 | +| openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:384:9:384:16 | openssl_signature.c:384:9:384:16 | +| openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | RawName | RSA_sign | openssl_signature.c:384:9:384:16 | openssl_signature.c:384:9:384:16 | +| openssl_signature.c:384:9:384:16 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:384:9:384:16 | openssl_signature.c:384:9:384:16 | +| openssl_signature.c:385:48:385:54 | Key | KeyType | Unknown | openssl_signature.c:385:48:385:54 | openssl_signature.c:385:48:385:54 | +| openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:403:12:403:21 | openssl_signature.c:403:12:403:21 | +| openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | RawName | RSA_verify | openssl_signature.c:403:12:403:21 | openssl_signature.c:403:12:403:21 | +| openssl_signature.c:403:12:403:21 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:403:12:403:21 | openssl_signature.c:403:12:403:21 | +| openssl_signature.c:404:51:404:57 | Key | KeyType | Unknown | openssl_signature.c:404:51:404:57 | openssl_signature.c:404:51:404:57 | +| openssl_signature.c:428:11:428:21 | KeyOperationAlgorithm | Name | DSA | openssl_signature.c:428:11:428:21 | openssl_signature.c:428:11:428:21 | +| openssl_signature.c:428:11:428:21 | KeyOperationAlgorithm | RawName | DSA_do_sign | openssl_signature.c:428:11:428:21 | openssl_signature.c:428:11:428:21 | +| openssl_signature.c:428:11:428:21 | SignOperation | KeyOperationSubtype | Sign | openssl_signature.c:428:11:428:21 | openssl_signature.c:428:11:428:21 | +| openssl_signature.c:428:43:428:49 | Key | KeyType | Unknown | openssl_signature.c:428:43:428:49 | openssl_signature.c:428:43:428:49 | +| openssl_signature.c:484:15:484:27 | KeyOperationAlgorithm | Name | DSA | openssl_signature.c:484:15:484:27 | openssl_signature.c:484:15:484:27 | +| openssl_signature.c:484:15:484:27 | KeyOperationAlgorithm | RawName | DSA_do_verify | openssl_signature.c:484:15:484:27 | openssl_signature.c:484:15:484:27 | +| openssl_signature.c:484:15:484:27 | VerifyOperation | KeyOperationSubtype | Verify | openssl_signature.c:484:15:484:27 | openssl_signature.c:484:15:484:27 | +| openssl_signature.c:484:54:484:60 | Key | KeyType | Unknown | openssl_signature.c:484:54:484:60 | openssl_signature.c:484:54:484:60 | +| openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:511:35:511:46 | openssl_signature.c:511:35:511:46 | +| openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:511:35:511:46 | openssl_signature.c:511:35:511:46 | +| openssl_signature.c:515:51:515:54 | Constant | Description | 2048 | openssl_signature.c:515:51:515:54 | openssl_signature.c:515:51:515:54 | +| openssl_signature.c:516:34:516:37 | Key | KeyType | Asymmetric | openssl_signature.c:516:34:516:37 | openssl_signature.c:516:34:516:37 | +| openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | Name | DSA | openssl_signature.c:533:50:533:54 | openssl_signature.c:533:50:533:54 | +| openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | RawName | dsa | openssl_signature.c:533:50:533:54 | openssl_signature.c:533:50:533:54 | +| openssl_signature.c:537:55:537:58 | Constant | Description | 2048 | openssl_signature.c:537:55:537:58 | openssl_signature.c:537:55:537:58 | +| openssl_signature.c:543:32:543:37 | Key | KeyType | Unknown | openssl_signature.c:543:32:543:37 | openssl_signature.c:543:32:543:37 | +| openssl_signature.c:546:34:546:37 | Key | KeyType | Asymmetric | openssl_signature.c:546:34:546:37 | openssl_signature.c:546:34:546:37 | +| openssl_signature.c:566:37:566:74 | Constant | Description | testLowLevelRSASignAndVerify message | openssl_signature.c:566:37:566:74 | openssl_signature.c:566:37:566:74 | +| openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:574:35:574:46 | openssl_signature.c:574:35:574:46 | +| openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:574:35:574:46 | openssl_signature.c:574:35:574:46 | +| openssl_signature.c:578:51:578:54 | Constant | Description | 2048 | openssl_signature.c:578:51:578:54 | openssl_signature.c:578:51:578:54 | +| openssl_signature.c:579:34:579:37 | Key | KeyType | Asymmetric | openssl_signature.c:579:34:579:37 | openssl_signature.c:579:34:579:37 | +| openssl_signature.c:595:37:595:46 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:595:37:595:46 | openssl_signature.c:595:37:595:46 | +| openssl_signature.c:595:37:595:46 | HashAlgorithm | Name | SHA2 | openssl_signature.c:595:37:595:46 | openssl_signature.c:595:37:595:46 | +| openssl_signature.c:595:37:595:46 | HashAlgorithm | RawName | 672 | openssl_signature.c:595:37:595:46 | openssl_signature.c:595:37:595:46 | +| openssl_signature.c:597:41:597:50 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:597:41:597:50 | openssl_signature.c:597:41:597:50 | +| openssl_signature.c:597:41:597:50 | HashAlgorithm | Name | SHA2 | openssl_signature.c:597:41:597:50 | openssl_signature.c:597:41:597:50 | +| openssl_signature.c:597:41:597:50 | HashAlgorithm | RawName | 672 | openssl_signature.c:597:41:597:50 | openssl_signature.c:597:41:597:50 | +| openssl_signature.c:615:37:615:74 | Constant | Description | testLowLevelDSASignAndVerify message | openssl_signature.c:615:37:615:74 | openssl_signature.c:615:37:615:74 | +| openssl_signature.c:616:24:616:33 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:616:24:616:33 | openssl_signature.c:616:24:616:33 | +| openssl_signature.c:616:24:616:33 | HashAlgorithm | Name | SHA2 | openssl_signature.c:616:24:616:33 | openssl_signature.c:616:24:616:33 | +| openssl_signature.c:616:24:616:33 | HashAlgorithm | RawName | EVP_sha256 | openssl_signature.c:616:24:616:33 | openssl_signature.c:616:24:616:33 | +| openssl_signature.c:651:37:651:61 | Constant | Description | testEVP_SignAPI message | openssl_signature.c:651:37:651:61 | openssl_signature.c:651:37:651:61 | +| openssl_signature.c:652:24:652:33 | HashAlgorithm | DigestSize | 224 | openssl_signature.c:652:24:652:33 | openssl_signature.c:652:24:652:33 | +| openssl_signature.c:652:24:652:33 | HashAlgorithm | Name | SHA2 | openssl_signature.c:652:24:652:33 | openssl_signature.c:652:24:652:33 | +| openssl_signature.c:652:24:652:33 | HashAlgorithm | RawName | EVP_sha224 | openssl_signature.c:652:24:652:33 | openssl_signature.c:652:24:652:33 | +| openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:661:35:661:46 | openssl_signature.c:661:35:661:46 | +| openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:661:35:661:46 | openssl_signature.c:661:35:661:46 | +| openssl_signature.c:665:51:665:54 | Constant | Description | 2048 | openssl_signature.c:665:51:665:54 | openssl_signature.c:665:51:665:54 | +| openssl_signature.c:666:34:666:37 | Key | KeyType | Asymmetric | openssl_signature.c:666:34:666:37 | openssl_signature.c:666:34:666:37 | +| openssl_signature.c:692:37:692:67 | Constant | Description | testEVP_DigestSignAPI message | openssl_signature.c:692:37:692:67 | openssl_signature.c:692:37:692:67 | +| openssl_signature.c:693:24:693:33 | HashAlgorithm | DigestSize | 224 | openssl_signature.c:693:24:693:33 | openssl_signature.c:693:24:693:33 | +| openssl_signature.c:693:24:693:33 | HashAlgorithm | Name | SHA2 | openssl_signature.c:693:24:693:33 | openssl_signature.c:693:24:693:33 | +| openssl_signature.c:693:24:693:33 | HashAlgorithm | RawName | EVP_sha224 | openssl_signature.c:693:24:693:33 | openssl_signature.c:693:24:693:33 | +| openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:702:35:702:46 | openssl_signature.c:702:35:702:46 | +| openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:702:35:702:46 | openssl_signature.c:702:35:702:46 | +| openssl_signature.c:706:51:706:54 | Constant | Description | 2048 | openssl_signature.c:706:51:706:54 | openssl_signature.c:706:51:706:54 | +| openssl_signature.c:707:34:707:37 | Key | KeyType | Asymmetric | openssl_signature.c:707:34:707:37 | openssl_signature.c:707:34:707:37 | +| openssl_signature.c:732:37:732:66 | Constant | Description | testEVP_PKEY_signAPI message | openssl_signature.c:732:37:732:66 | openssl_signature.c:732:37:732:66 | +| openssl_signature.c:733:24:733:31 | HashAlgorithm | DigestSize | 160 | openssl_signature.c:733:24:733:31 | openssl_signature.c:733:24:733:31 | +| openssl_signature.c:733:24:733:31 | HashAlgorithm | Name | SHA1 | openssl_signature.c:733:24:733:31 | openssl_signature.c:733:24:733:31 | +| openssl_signature.c:733:24:733:31 | HashAlgorithm | RawName | EVP_sha1 | openssl_signature.c:733:24:733:31 | openssl_signature.c:733:24:733:31 | +| openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:746:35:746:46 | openssl_signature.c:746:35:746:46 | +| openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:746:35:746:46 | openssl_signature.c:746:35:746:46 | +| openssl_signature.c:750:51:750:54 | Constant | Description | 2048 | openssl_signature.c:750:51:750:54 | openssl_signature.c:750:51:750:54 | +| openssl_signature.c:751:34:751:37 | Key | KeyType | Asymmetric | openssl_signature.c:751:34:751:37 | openssl_signature.c:751:34:751:37 | +| openssl_signature.c:777:37:777:73 | Constant | Description | testEVP_DigestSign_with_ctx message | openssl_signature.c:777:37:777:73 | openssl_signature.c:777:37:777:73 | +| openssl_signature.c:778:24:778:31 | HashAlgorithm | DigestSize | 160 | openssl_signature.c:778:24:778:31 | openssl_signature.c:778:24:778:31 | +| openssl_signature.c:778:24:778:31 | HashAlgorithm | Name | SHA1 | openssl_signature.c:778:24:778:31 | openssl_signature.c:778:24:778:31 | +| openssl_signature.c:778:24:778:31 | HashAlgorithm | RawName | EVP_sha1 | openssl_signature.c:778:24:778:31 | openssl_signature.c:778:24:778:31 | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:786:35:786:46 | openssl_signature.c:786:35:786:46 | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:786:35:786:46 | openssl_signature.c:786:35:786:46 | +| openssl_signature.c:790:51:790:54 | Constant | Description | 2048 | openssl_signature.c:790:51:790:54 | openssl_signature.c:790:51:790:54 | +| openssl_signature.c:791:34:791:37 | Key | KeyType | Asymmetric | openssl_signature.c:791:34:791:37 | openssl_signature.c:791:34:791:37 | +| openssl_signature.c:817:37:817:63 | Constant | Description | testEVP_PKEY_sign_message | openssl_signature.c:817:37:817:63 | openssl_signature.c:817:37:817:63 | +| openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:824:35:824:46 | openssl_signature.c:824:35:824:46 | +| openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | RawName | 6 | openssl_signature.c:824:35:824:46 | openssl_signature.c:824:35:824:46 | +| openssl_signature.c:828:51:828:54 | Constant | Description | 2048 | openssl_signature.c:828:51:828:54 | openssl_signature.c:828:51:828:54 | +| openssl_signature.c:829:34:829:37 | Key | KeyType | Asymmetric | openssl_signature.c:829:34:829:37 | openssl_signature.c:829:34:829:37 | +| openssl_signature.c:838:85:838:96 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:838:85:838:96 | openssl_signature.c:838:85:838:96 | +| openssl_signature.c:838:85:838:96 | HashAlgorithm | Name | SHA2 | openssl_signature.c:838:85:838:96 | openssl_signature.c:838:85:838:96 | +| openssl_signature.c:838:85:838:96 | HashAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:838:85:838:96 | openssl_signature.c:838:85:838:96 | +| openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:838:85:838:96 | openssl_signature.c:838:85:838:96 | +| openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:838:85:838:96 | openssl_signature.c:838:85:838:96 | +| openssl_signature.c:839:87:839:98 | HashAlgorithm | DigestSize | 256 | openssl_signature.c:839:87:839:98 | openssl_signature.c:839:87:839:98 | +| openssl_signature.c:839:87:839:98 | HashAlgorithm | Name | SHA2 | openssl_signature.c:839:87:839:98 | openssl_signature.c:839:87:839:98 | +| openssl_signature.c:839:87:839:98 | HashAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:839:87:839:98 | openssl_signature.c:839:87:839:98 | +| openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | Name | RSA | openssl_signature.c:839:87:839:98 | openssl_signature.c:839:87:839:98 | +| openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | RawName | RSA-SHA256 | openssl_signature.c:839:87:839:98 | openssl_signature.c:839:87:839:98 | diff --git a/cpp/ql/test/experimental/library-tests/quantum/nodes.expected b/cpp/ql/test/experimental/library-tests/quantum/nodes.expected index 223f7bfca6c5..62877e561820 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/nodes.expected +++ b/cpp/ql/test/experimental/library-tests/quantum/nodes.expected @@ -24,17 +24,29 @@ | 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:155:43:155:55 | HMACAlgorithm | | openssl_basic.c:155:64:155:66 | Key | | 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:9:167:27 | SignatureOrMACOperation | | 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_basic.c:231:27:231:49 | Constant | +| openssl_basic.c:235:51:235:55 | KeyOperationAlgorithm | +| openssl_basic.c:237:54:237:57 | Constant | +| openssl_basic.c:238:9:238:25 | KeyGeneration | +| openssl_basic.c:238:39:238:43 | Key | +| openssl_basic.c:243:52:243:55 | Key | +| openssl_basic.c:249:51:249:72 | PaddingAlgorithm | +| openssl_basic.c:250:51:250:60 | HashAlgorithm | +| openssl_basic.c:251:51:251:60 | HashAlgorithm | +| openssl_basic.c:262:24:262:39 | EncryptOperation | +| openssl_basic.c:262:54:262:63 | KeyOperationOutput | +| openssl_basic.c:263:64:263:70 | Message | | openssl_pkey.c:21:10:21:28 | KeyGeneration | | openssl_pkey.c:21:10:21:28 | KeyOperationAlgorithm | | openssl_pkey.c:21:30:21:32 | Key | @@ -47,54 +59,121 @@ | 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:135:9:135:27 | SignOperation | -| openssl_signature.c:135:37:135:40 | SignatureOutput | -| 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:197:9:197:27 | SignOperation | -| openssl_signature.c:197:37:197:40 | SignatureOutput | -| 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:263:9:263:21 | SignOperation | -| openssl_signature.c:263:33:263:36 | SignatureOutput | -| openssl_signature.c:263:54:263:59 | Message | -| 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:327:9:327:35 | SignOperation | -| openssl_signature.c:327:47:327:50 | SignatureOutput | -| 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:575:32:575:37 | Key | -| 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 | +| openssl_signature.c:25:34:25:40 | Message | +| openssl_signature.c:26:9:26:26 | HashOperation | +| openssl_signature.c:26:36:26:41 | Digest | +| openssl_signature.c:63:32:63:38 | Message | +| openssl_signature.c:68:28:68:36 | Message | +| openssl_signature.c:73:9:73:21 | SignOperation | +| openssl_signature.c:73:31:73:40 | SignatureOutput | +| openssl_signature.c:73:53:73:56 | Key | +| openssl_signature.c:98:34:98:40 | Message | +| openssl_signature.c:99:34:99:42 | Message | +| openssl_signature.c:100:9:100:23 | VerifyOperation | +| openssl_signature.c:100:33:100:41 | SignatureInput | +| openssl_signature.c:100:73:100:76 | Key | +| openssl_signature.c:126:52:126:55 | Key | +| openssl_signature.c:127:38:127:44 | Message | +| openssl_signature.c:135:9:135:27 | SignatureOrMACOperation | +| openssl_signature.c:135:37:135:46 | SignatureOutput | +| openssl_signature.c:158:54:158:57 | Key | +| openssl_signature.c:159:40:159:46 | Message | +| openssl_signature.c:160:9:160:29 | VerifyOperation | +| openssl_signature.c:160:39:160:47 | SignatureInput | +| openssl_signature.c:182:57:182:60 | Key | +| openssl_signature.c:185:44:185:64 | PaddingAlgorithm | +| openssl_signature.c:187:38:187:44 | Message | +| openssl_signature.c:195:9:195:27 | SignatureOrMACOperation | +| openssl_signature.c:195:37:195:46 | SignatureOutput | +| openssl_signature.c:218:59:218:62 | Key | +| openssl_signature.c:222:44:222:64 | PaddingAlgorithm | +| openssl_signature.c:224:40:224:46 | Message | +| openssl_signature.c:225:9:225:29 | VerifyOperation | +| openssl_signature.c:225:39:225:47 | SignatureInput | +| openssl_signature.c:250:39:250:42 | Key | +| openssl_signature.c:260:9:260:21 | SignOperation | +| openssl_signature.c:260:33:260:42 | SignatureOutput | +| openssl_signature.c:260:60:260:65 | Message | +| openssl_signature.c:282:39:282:42 | Key | +| openssl_signature.c:285:9:285:23 | VerifyOperation | +| openssl_signature.c:285:35:285:43 | SignatureInput | +| openssl_signature.c:285:61:285:66 | Message | +| openssl_signature.c:311:39:311:42 | Key | +| openssl_signature.c:316:48:316:54 | Message | +| openssl_signature.c:324:9:324:35 | SignOperation | +| openssl_signature.c:324:47:324:56 | SignatureOutput | +| openssl_signature.c:347:39:347:42 | Key | +| openssl_signature.c:353:42:353:50 | SignatureInput | +| openssl_signature.c:355:50:355:56 | Message | +| openssl_signature.c:356:9:356:37 | VerifyOperation | +| openssl_signature.c:384:9:384:16 | KeyOperationAlgorithm | +| openssl_signature.c:384:9:384:16 | SignOperation | +| openssl_signature.c:384:28:384:34 | Message | +| openssl_signature.c:384:50:384:59 | SignatureOutput | +| openssl_signature.c:385:48:385:54 | Key | +| openssl_signature.c:403:12:403:21 | KeyOperationAlgorithm | +| openssl_signature.c:403:12:403:21 | VerifyOperation | +| openssl_signature.c:403:33:403:39 | Message | +| openssl_signature.c:403:55:403:63 | SignatureInput | +| openssl_signature.c:404:51:404:57 | Key | +| openssl_signature.c:428:11:428:21 | KeyOperationAlgorithm | +| openssl_signature.c:428:11:428:21 | SignOperation | +| openssl_signature.c:428:11:428:21 | SignatureOutput | +| openssl_signature.c:428:23:428:28 | Message | +| openssl_signature.c:428:43:428:49 | Key | +| openssl_signature.c:484:15:484:27 | KeyOperationAlgorithm | +| openssl_signature.c:484:15:484:27 | VerifyOperation | +| openssl_signature.c:484:29:484:34 | Message | +| openssl_signature.c:484:49:484:51 | SignatureInput | +| openssl_signature.c:484:54:484:60 | Key | +| openssl_signature.c:511:35:511:46 | KeyOperationAlgorithm | +| openssl_signature.c:515:51:515:54 | Constant | +| openssl_signature.c:516:9:516:23 | KeyGeneration | +| openssl_signature.c:516:34:516:37 | Key | +| openssl_signature.c:533:50:533:54 | KeyOperationAlgorithm | +| openssl_signature.c:537:55:537:58 | Constant | +| openssl_signature.c:543:32:543:37 | Key | +| openssl_signature.c:546:9:546:23 | KeyGeneration | +| openssl_signature.c:546:34:546:37 | Key | +| openssl_signature.c:566:37:566:74 | Constant | +| openssl_signature.c:574:35:574:46 | KeyOperationAlgorithm | +| openssl_signature.c:578:51:578:54 | Constant | +| openssl_signature.c:579:9:579:23 | KeyGeneration | +| openssl_signature.c:579:34:579:37 | Key | +| openssl_signature.c:595:37:595:46 | HashAlgorithm | +| openssl_signature.c:597:41:597:50 | HashAlgorithm | +| openssl_signature.c:615:37:615:74 | Constant | +| openssl_signature.c:616:24:616:33 | HashAlgorithm | +| openssl_signature.c:651:37:651:61 | Constant | +| openssl_signature.c:652:24:652:33 | HashAlgorithm | +| openssl_signature.c:661:35:661:46 | KeyOperationAlgorithm | +| openssl_signature.c:665:51:665:54 | Constant | +| openssl_signature.c:666:9:666:23 | KeyGeneration | +| openssl_signature.c:666:34:666:37 | Key | +| openssl_signature.c:692:37:692:67 | Constant | +| openssl_signature.c:693:24:693:33 | HashAlgorithm | +| openssl_signature.c:702:35:702:46 | KeyOperationAlgorithm | +| openssl_signature.c:706:51:706:54 | Constant | +| openssl_signature.c:707:9:707:23 | KeyGeneration | +| openssl_signature.c:707:34:707:37 | Key | +| openssl_signature.c:732:37:732:66 | Constant | +| openssl_signature.c:733:24:733:31 | HashAlgorithm | +| openssl_signature.c:746:35:746:46 | KeyOperationAlgorithm | +| openssl_signature.c:750:51:750:54 | Constant | +| openssl_signature.c:751:9:751:23 | KeyGeneration | +| openssl_signature.c:751:34:751:37 | Key | +| openssl_signature.c:777:37:777:73 | Constant | +| openssl_signature.c:778:24:778:31 | HashAlgorithm | +| openssl_signature.c:786:35:786:46 | KeyOperationAlgorithm | +| openssl_signature.c:790:51:790:54 | Constant | +| openssl_signature.c:791:9:791:23 | KeyGeneration | +| openssl_signature.c:791:34:791:37 | Key | +| openssl_signature.c:817:37:817:63 | Constant | +| openssl_signature.c:824:35:824:46 | KeyOperationAlgorithm | +| openssl_signature.c:828:51:828:54 | Constant | +| openssl_signature.c:829:9:829:23 | KeyGeneration | +| openssl_signature.c:829:34:829:37 | Key | +| openssl_signature.c:838:85:838:96 | HashAlgorithm | +| openssl_signature.c:838:85:838:96 | KeyOperationAlgorithm | +| openssl_signature.c:839:87:839:98 | HashAlgorithm | +| openssl_signature.c:839:87:839:98 | KeyOperationAlgorithm | diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c b/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c index f1ffbfa24d36..04504070ddd7 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c +++ b/cpp/ql/test/experimental/library-tests/quantum/openssl_basic.c @@ -1,7 +1,7 @@ #include "openssl/evp.h" #include "openssl/obj_mac.h" #include "openssl/rand.h" - +#include "openssl/rsa.h" size_t strlen(const char* str); // Sample OpenSSL code that demonstrates various cryptographic operations @@ -218,4 +218,58 @@ int test_main() { calculate_hmac_sha256(key, 32, plaintext, plaintext_len, hmac); return 0; -} \ No newline at end of file +} + +/** + * Simplified signature test + */ +int test_rsa_oaep_basic(void) { + EVP_PKEY_CTX *keygen_ctx = NULL, *encrypt_ctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char *ciphertext = NULL; + size_t ciphertext_len = 0; + const char *message = "Encrypt me with OAEP!"; + int ret = 1; + + // Generate RSA key + keygen_ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!keygen_ctx || EVP_PKEY_keygen_init(keygen_ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_keygen_bits(keygen_ctx, 2048) <= 0 || + EVP_PKEY_generate(keygen_ctx, &pkey) <= 0) { + goto cleanup; + } + + // Create encryption context + encrypt_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!encrypt_ctx || EVP_PKEY_encrypt_init(encrypt_ctx) <= 0) { + goto cleanup; + } + + // Set OAEP padding + if (EVP_PKEY_CTX_set_rsa_padding(encrypt_ctx, RSA_PKCS1_OAEP_PADDING) <= 0 || + EVP_PKEY_CTX_set_rsa_oaep_md(encrypt_ctx, EVP_sha256()) <= 0 || + EVP_PKEY_CTX_set_rsa_mgf1_md(encrypt_ctx, EVP_sha256()) <= 0) { + goto cleanup; + } + + // Determine buffer size + if (EVP_PKEY_encrypt(encrypt_ctx, NULL, &ciphertext_len, + (const unsigned char *)message, strlen(message)) <= 0) { + goto cleanup; + } + + ciphertext = OPENSSL_malloc(ciphertext_len); + if (!ciphertext || EVP_PKEY_encrypt(encrypt_ctx, ciphertext, &ciphertext_len, + (const unsigned char *)message, strlen(message)) <= 0) { + goto cleanup; + } + + ret = 0; + +cleanup: + EVP_PKEY_CTX_free(keygen_ctx); + EVP_PKEY_CTX_free(encrypt_ctx); + EVP_PKEY_free(pkey); + OPENSSL_free(ciphertext); + return ret; +} \ No newline at end of file diff --git a/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c b/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c index f8be74416423..6d72c5366dde 100644 --- a/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c +++ b/cpp/ql/test/experimental/library-tests/quantum/openssl_signature.c @@ -4,6 +4,9 @@ #include #include + + + /* ============================================================================= * UTILITY FUNCTIONS - Common operations shared across signature APIs * ============================================================================= @@ -38,16 +41,6 @@ static unsigned char* allocate_signature_buffer(size_t *sig_len, const EVP_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) @@ -180,8 +173,7 @@ int verify_using_evp_digestverify(const unsigned char *message, size_t message_l */ 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_PKEY *pkey, const EVP_MD *md) { EVP_MD_CTX *md_ctx = NULL; EVP_PKEY_CTX *pkey_ctx = NULL; int ret = 0; @@ -190,8 +182,7 @@ int sign_using_digestsign_with_ctx(const unsigned char *message, size_t message_ EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) { goto cleanup; } - - if (param_setter && param_setter(pkey_ctx) != 1) goto cleanup; + EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING); if (EVP_DigestSignUpdate(md_ctx, message, message_len) != 1 || EVP_DigestSignFinal(md_ctx, NULL, signature_len) != 1) { @@ -218,8 +209,7 @@ int sign_using_digestsign_with_ctx(const unsigned char *message, size_t message_ */ 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_PKEY *pkey, const EVP_MD *md) { EVP_MD_CTX *md_ctx = NULL; EVP_PKEY_CTX *pkey_ctx = NULL; int ret = 0; @@ -228,9 +218,9 @@ int verify_using_digestverify_with_ctx(const unsigned char *message, size_t mess EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) { goto cleanup; } - - if (param_setter && param_setter(pkey_ctx) != 1) goto cleanup; - + + EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING); + if (EVP_DigestVerifyUpdate(md_ctx, message, message_len) != 1 || EVP_DigestVerifyFinal(md_ctx, signature, signature_len) != 1) { goto cleanup; @@ -313,7 +303,7 @@ int verify_using_evp_pkey_verify(const unsigned char *digest, size_t digest_len, */ 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 *pkey, const char *alg_name) { EVP_PKEY_CTX *pkey_ctx = NULL; EVP_SIGNATURE *alg = NULL; int ret = 0; @@ -349,7 +339,7 @@ int sign_using_evp_pkey_sign_message(const unsigned char *message, size_t messag */ 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 *pkey, const char *alg_name) { EVP_PKEY_CTX *pkey_ctx = NULL; EVP_SIGNATURE *alg = NULL; int ret = 0; @@ -373,10 +363,10 @@ int verify_using_evp_pkey_verify_message(const unsigned char *message, size_t me return ret; } -/* ============================================================================= - * LOW-LEVEL RSA API - Algorithm-specific functions (deprecated) - * ============================================================================= - */ +// /* ============================================================================= +// * LOW-LEVEL RSA API - Algorithm-specific functions (deprecated) +// * ============================================================================= +// */ /** * Sign using low-level RSA_sign API (deprecated, RSA-only) @@ -384,18 +374,14 @@ int verify_using_evp_pkey_verify_message(const unsigned char *message, size_t me */ 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; + RSA *rsa_key, int hash_nid) { 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, + + if (RSA_sign(hash_nid, message, message_len, *signature, (unsigned int*)signature_len, rsa_key) == 1) { ret = 1; } else { @@ -412,20 +398,16 @@ int sign_using_rsa_sign(const unsigned char *message, size_t message_len, */ 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, + RSA *rsa_key, int hash_nid) { + + return RSA_verify(hash_nid, message, message_len, signature, (unsigned int)signature_len, rsa_key); } -/* ============================================================================= - * LOW-LEVEL DSA API - Algorithm-specific functions (deprecated) - * ============================================================================= - */ +// /* ============================================================================= +// * LOW-LEVEL DSA API - Algorithm-specific functions (deprecated) +// * ============================================================================= +// */ /** * Sign using low-level DSA_do_sign API (deprecated, DSA-only) @@ -514,20 +496,6 @@ int verify_using_dsa_verify(const unsigned char *message, size_t message_len, * ============================================================================= */ -/** - * 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 * ============================================================================= @@ -592,228 +560,289 @@ static EVP_PKEY* generate_dsa_key(void) { * ============================================================================= */ -/** - * 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"; +int testLowLevelRSASignAndVerify(){ + EVP_PKEY *key = NULL; + RSA *rsa_key = NULL; + const unsigned char message[] = "testLowLevelRSASignAndVerify message"; 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; + unsigned char *sig = NULL; + size_t sig_len = 0; int success = 1; + EVP_PKEY_CTX *key_ctx = NULL; + + + key_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!key_ctx) return NULL; - printf("\nTesting signature APIs with %s:\n", algo_name); + 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; + } - /* 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)) { + EVP_PKEY_CTX_free(key_ctx); + if (!key) return 0; + + rsa_key = EVP_PKEY_get1_RSA(key); + + if (!rsa_key) { + EVP_PKEY_free(key); + success = 0; + } + + if (sign_using_rsa_sign(message, message_len, &sig, &sig_len, + rsa_key, NID_sha256) && + verify_using_rsa_verify(message, message_len, sig, sig_len, + rsa_key, NID_sha256)) { printf("PASS\n"); } else { printf("FAIL\n"); success = 0; } + + /* Cleanup */ + OPENSSL_free(sig); + EVP_PKEY_free(key); + + return success; +} + + +int testLowLevelDSASignAndVerify(){ + EVP_PKEY *key = NULL; + DSA *dsa_key = NULL; + const unsigned char message[] = "testLowLevelDSASignAndVerify message"; + const EVP_MD *md = EVP_sha256(); + int success = 1; + + EVP_PKEY_CTX *param_ctx = NULL, *key_ctx = NULL; + EVP_PKEY *params = NULL; + + const size_t message_len = strlen((char *)message); + unsigned char *sig = NULL; + size_t sig_len = 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)) { + key = generate_dsa_key(); + dsa_key = EVP_PKEY_get1_DSA(key); + + if (!dsa_key) { + EVP_PKEY_free(key); + success = 0; + } + + if (sign_using_dsa_sign(message, message_len, &sig, &sig_len, dsa_key, md) && + verify_using_dsa_verify(message, message_len, sig, sig_len, dsa_key, md)) { printf("PASS\n"); } else { printf("FAIL\n"); success = 0; } + + /* Cleanup */ + OPENSSL_free(sig); + EVP_PKEY_free(key); + + return success; +} + +int testEVP_SignAPI(){ + EVP_PKEY *key = NULL; + const unsigned char message[] = "testEVP_SignAPI message"; + const EVP_MD *md = EVP_sha224(); + + const size_t message_len = strlen((char *)message); + + unsigned char *sig = NULL; + size_t sig_len = 0; + int success = 1; + EVP_PKEY_CTX *key_ctx = NULL; + + key_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!key_ctx) return NULL; - /* 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)) { + 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); + if (!key) return 0; + + + /* Test 1: EVP_Sign API */ + printf("1. EVP_Sign API: "); + if (sign_using_evp_sign(message, message_len, &sig, &sig_len, key, md) && + verify_using_evp_verify(message, message_len, sig, sig_len, key, md)) { printf("PASS\n"); } else { printf("FAIL\n"); success = 0; } + OPENSSL_free(sig); + EVP_PKEY_free(key); + return success; +} + + +int testEVP_DigestSignAPI(){ + EVP_PKEY *key = NULL; + const unsigned char message[] = "testEVP_DigestSignAPI message"; + const EVP_MD *md = EVP_sha224(); + + const size_t message_len = strlen((char *)message); + + unsigned char *sig = NULL; + size_t sig_len = 0; + int success = 1; + EVP_PKEY_CTX *key_ctx = 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; + } - /* 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)) { + EVP_PKEY_CTX_free(key_ctx); + if (!key) return 0; + + + /* Test 2: EVP_DigestSign API */ + printf("2. EVP_DigestSign API: "); + if (sign_using_evp_digestsign(message, message_len, &sig, &sig_len, key, md) && + verify_using_evp_digestverify(message, message_len, sig, sig_len, key, md)) { printf("PASS\n"); } else { printf("FAIL\n"); success = 0; } + OPENSSL_free(sig); + EVP_PKEY_free(key); + return success; +} + +int testEVP_PKEY_signAPI(){ + EVP_PKEY *key = NULL; + const unsigned char message[] = "testEVP_PKEY_signAPI message"; + const EVP_MD *md = EVP_sha1(); + + const size_t message_len = strlen((char *)message); - /* 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)) { + unsigned char *sig = NULL; + size_t sig_len = 0; + int success = 1; + + EVP_PKEY_CTX *key_ctx = NULL; + + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len; + + 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); + if (!key) return 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, &sig, &sig_len, key, md) && + verify_using_evp_pkey_verify(digest, digest_len, sig, sig_len, key, md)) { 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); - + + OPENSSL_free(sig); + EVP_PKEY_free(key); return success; } -/** - * Test RSA-specific signature APIs including low-level RSA functions - */ -int test_signature_apis_rsa(void) { +int testEVP_DigestSign_with_ctx(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 unsigned char message[] = "testEVP_DigestSign_with_ctx message"; + const EVP_MD *md = EVP_sha1(); + const size_t message_len = strlen((char *)message); - unsigned char *sig5 = NULL; - size_t sig_len5 = 0; + unsigned char *sig = NULL; + size_t sig_len = 0; int success = 1; + EVP_PKEY_CTX *key_ctx = NULL; + + key_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!key_ctx) return NULL; - printf("\nGenerating RSA key pair...\n"); - key = generate_rsa_key(); - if (!key) return 0; - - rsa_key = get_rsa_from_pkey(key); - if (!rsa_key) { + 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); - return 0; - } - - /* Test generic APIs */ - if (!test_signature_apis(key, md, set_rsa_pss_padding, "RSA-SHA256")) { - success = 0; + key = NULL; } - /* 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)) { + EVP_PKEY_CTX_free(key_ctx); + if (!key) return 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, &sig, &sig_len, + key, md) && + verify_using_digestverify_with_ctx(message, message_len, sig, sig_len, + key, 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); + OPENSSL_free(sig); EVP_PKEY_free(key); - return success; } -/** - * Test DSA-specific signature APIs including low-level DSA functions - */ -int test_signature_apis_dsa(void) { +int testEVP_PKEY_sign_message(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 unsigned char message[] = "testEVP_PKEY_sign_message"; const size_t message_len = strlen((char *)message); - unsigned char *sig5 = NULL; - size_t sig_len5 = 0; + unsigned char *sig = NULL; + size_t sig_len = 0; int success = 1; + EVP_PKEY_CTX *key_ctx = NULL; + + key_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!key_ctx) return NULL; - printf("\nGenerating DSA key pair...\n"); - key = generate_dsa_key(); - if (!key) return 0; - - dsa_key = get_dsa_from_pkey(key); - if (!dsa_key) { + 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); - return 0; - } - - /* Test generic APIs */ - if (!test_signature_apis(key, md, no_parameter_setter, "dsa")) { - success = 0; + key = NULL; } - /* 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)) { + EVP_PKEY_CTX_free(key_ctx); + if (!key) return 0; + + printf("6. EVP_PKEY_sign_message API: "); + if (sign_using_evp_pkey_sign_message(message, message_len, &sig, &sig_len, key, "RSA-SHA256") && + verify_using_evp_pkey_verify_message(message, message_len, sig, sig_len, key, "RSA-SHA256")) { 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); + OPENSSL_free(sig); 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 +} \ 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 dc86c4637505..f6f5ba71ec2a 100644 --- a/java/ql/lib/experimental/quantum/JCA.qll +++ b/java/ql/lib/experimental/quantum/JCA.qll @@ -205,12 +205,6 @@ module JCAModel { ) } - bindingset[name] - predicate mac_name_to_mac_type_known(Crypto::TMacType type, string name) { - type = Crypto::HMAC() and - name.toUpperCase().matches("HMAC%") - } - bindingset[name] predicate key_agreement_name_to_type_known(Crypto::TKeyAgreementType type, string name) { type = Crypto::DH() and @@ -1480,7 +1474,7 @@ module JCAModel { module MacInitCallToMacOperationFlow = DataFlow::Global; - class KnownMacAlgorithm extends Crypto::MacAlgorithmInstance instanceof StringLiteral { + class KnownMacAlgorithm extends Crypto::KeyOperationAlgorithmInstance instanceof StringLiteral { MacGetInstanceAlgorithmValueConsumer consumer; KnownMacAlgorithm() { @@ -1490,13 +1484,30 @@ module JCAModel { MacGetInstanceAlgorithmValueConsumer getConsumer() { result = consumer } - override string getRawMacAlgorithmName() { result = super.getValue() } + override string getRawAlgorithmName() { result = super.getValue() } - override Crypto::MacType getMacType() { - if mac_name_to_mac_type_known(_, super.getValue()) - then mac_name_to_mac_type_known(result, super.getValue()) - else result = Crypto::OtherMacType() + override Crypto::KeyOpAlg::AlgorithmType getAlgorithmType() { + if super.getValue().toUpperCase().matches("HMAC%") + then result = KeyOpAlg::TMac(KeyOpAlg::HMAC()) + else + if super.getValue().toUpperCase().matches("CMAC%") + then result = KeyOpAlg::TMac(KeyOpAlg::CMAC()) + else result = KeyOpAlg::TMac(KeyOpAlg::OtherMacAlgorithmType()) + } + + override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { + // TODO: trace to any key size initializer? + none() } + + override int getKeySizeFixed() { + // TODO: are there known fixed key sizes to consider? + none() + } + + override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() } + + override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() } } class MacGetInstanceCall extends MethodCall { @@ -1566,7 +1577,7 @@ module JCAModel { ) } - override Crypto::ConsumerInputDataFlowNode getMessageConsumer() { + override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result.asExpr() = super.getArgument(0) and super.getMethod().getParameterType(0).hasName("byte[]") } diff --git a/shared/quantum/codeql/quantum/experimental/Model.qll b/shared/quantum/codeql/quantum/experimental/Model.qll index d8b1402b5e88..ec09468b5d2f 100644 --- a/shared/quantum/codeql/quantum/experimental/Model.qll +++ b/shared/quantum/codeql/quantum/experimental/Model.qll @@ -409,8 +409,6 @@ module CryptographyBase Input> { or exists(KeyDerivationOperationInstance op | inputNode = op.getInputConsumer()) or - exists(MacOperationInstance op | inputNode = op.getMessageConsumer()) - or exists(HashOperationInstance op | inputNode = op.getInputConsumer()) ) and this = Input::dfn_to_element(inputNode) @@ -545,8 +543,6 @@ module CryptographyBase Input> { or exists(KeyGenerationOperationInstance op | inputNode = op.getKeyValueConsumer()) or - exists(MacOperationInstance op | inputNode = op.getKeyConsumer()) - or exists(KeyAgreementSecretGenerationOperationInstance op | inputNode = op.getServerKeyConsumer() or inputNode = op.getPeerKeyConsumer() @@ -562,9 +558,10 @@ module CryptographyBase Input> { /** * A key-based cryptographic operation instance, encompassing: - * 1. **Ciphers**: Encryption and decryption, both symmetric and asymmetric - * 1. **Signing**: Signing and verifying, **NOT** including MACs (see `MACOperationInstance`) - * 1. **Key encapsulation**: Key wrapping and unwrapping + * - **Ciphers**: Encryption and decryption, both symmetric and asymmetric + * - **Signing**: Signing and verifying + * - **MACs**: Mac generation + * - **Key encapsulation**: Key wrapping and unwrapping * * This class represents a generic key operation that transforms input data * using a cryptographic key, producing an output artifact such as ciphertext, @@ -598,7 +595,8 @@ module CryptographyBase Input> { /** * Gets the consumer of the primary message input for this key operation. * For example: plaintext (for encryption), ciphertext (for decryption), - * message to be signed, or wrapped key to be unwrapped. + * a message to be signed or verified, the message on which a mac is generated, + * or a wrapped key to be unwrapped. */ abstract ConsumerInputDataFlowNode getInputConsumer(); @@ -614,25 +612,6 @@ module CryptographyBase Input> { abstract ArtifactOutputDataFlowNode getOutputArtifact(); } - /** - * A key operation instance representing a signature being generated or verified. - */ - abstract class SignatureOperationInstance extends KeyOperationInstance { - /** - * Gets the consumer of the signature that is being verified in case of a - * 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(); - } - /** * A key-based algorithm instance used in cryptographic operations such as encryption, decryption, * signing, verification, and key wrapping. @@ -651,6 +630,7 @@ module CryptographyBase Input> { * - `TSymmetricCipher(OtherSymmetricCipherType())` * - `TAsymmetricCipher(OtherAsymmetricCipherType())` * - `TSignature(OtherSignatureAlgorithmType())` + * - `TMacAlgorithm(OtherMacAlgorithmType())` * - `TKeyEncapsulation(OtherKEMAlgorithmType())` * * If the category of algorithm is not known, the following type should be used: @@ -710,6 +690,41 @@ module CryptographyBase Input> { predicate shouldHavePaddingScheme() { any() } } + abstract class HmacAlgorithmInstance extends KeyOperationAlgorithmInstance { + HmacAlgorithmInstance() { this.getAlgorithmType() = KeyOpAlg::TMac(KeyOpAlg::HMAC()) } + + /** + * Gets the hash algorithm used by this HMAC algorithm. + */ + abstract AlgorithmValueConsumer getHashAlgorithmValueConsumer(); + + /** + * CMACs will have algorithms that have modes of operation but that + * is associated with the cipher algorithm, that is itself + * associated to the MAC algorithm. + */ + override predicate shouldHaveModeOfOperation() { none() } + + override ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() } + + /** + * CMACs may have padding but the padding is associated with the cipher algorithm, + * that is itself associated to the MAC algorithm. + */ + override predicate shouldHavePaddingScheme() { none() } + + override PaddingAlgorithmInstance getPaddingAlgorithm() { none() } + } + + abstract class CmacAlgorithmInstance extends KeyOperationAlgorithmInstance { + CmacAlgorithmInstance() { this.getAlgorithmType() = KeyOpAlg::TMac(KeyOpAlg::CMAC()) } + + /** + * Gets the cipher algorithm used by this CMAC algorithm. + */ + abstract AlgorithmValueConsumer getCipherAlgorithmValueConsumer(); + } + abstract class ModeOfOperationAlgorithmInstance extends AlgorithmInstance { /** * Gets the type of this mode of operation, e.g., "ECB" or "CBC". @@ -760,40 +775,47 @@ module CryptographyBase Input> { abstract HashAlgorithmInstance getMgf1HashAlgorithm(); } - abstract class MacAlgorithmInstance extends AlgorithmInstance { + /** + * A parent class for signature and MAC operations. + * Signatures and macs are the asymmetric and symmetric analogs of each other, + * and some APIs can reuse a single operation to do either signing on mac. + * Users should extend this class when an operation can be either a signature or a MAC, + * and where the instance is not obviously one or the other from use. + */ + abstract class SignatureOrMacOperationInstance extends KeyOperationInstance { /** - * Gets the type of this MAC algorithm, e.g., "HMAC" or "CMAC". + * Gets the consumer of a hash algorithm. + * This is intended for mac/signing operations they are explicitly configured + * with a hash algorithm. If the operation is not configured with an explicit + * hash algorithm, users do not need to provide a consumer (set none()). */ - abstract MacType getMacType(); + abstract AlgorithmValueConsumer getHashAlgorithmValueConsumer(); /** - * 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. + * Holds if this operation has a hash algorithm consumer. + * I.e., holds if the operation is configured to perform a hash + * on a message before signing and algorithm is passed in. + * The hash algorithm consumer must be specified through + * `getHashAlgorithmValueConsumer()`. */ - abstract string getRawMacAlgorithmName(); + abstract predicate hasHashAlgorithmConsumer(); } - abstract class MacOperationInstance extends OperationInstance { - /** - * Gets the message input used in this operation. - */ - abstract ConsumerInputDataFlowNode getMessageConsumer(); - + /** + * A key operation instance representing a signature being generated or verified. + * Note: These instances are known to always be signature operations. + * If an API allows an operation to be used for both MAC and signature, + * it should be modeled as a `SignatureOrMacOperationInstance` instead, + * even if all configuration paths to the current operation only configure it as a signature operation. + */ + abstract class SignatureOperationInstance extends SignatureOrMacOperationInstance { /** - * Gets the key used in this operation. + * Gets the consumer of the signature when this operation is a verification operation. */ - abstract ConsumerInputDataFlowNode getKeyConsumer(); + abstract ConsumerInputDataFlowNode getSignatureConsumer(); } - abstract class HmacAlgorithmInstance extends MacAlgorithmInstance { - HmacAlgorithmInstance() { this.getMacType() = HMAC() } - - /** - * Gets the hash algorithm used by this HMAC algorithm. - */ - abstract AlgorithmValueConsumer getHashAlgorithmValueConsumer(); - } + abstract class MacOperationInstance extends SignatureOrMacOperationInstance { } abstract class EllipticCurveInstance extends AlgorithmInstance { /** @@ -1063,11 +1085,6 @@ module CryptographyBase Input> { exists(KeyOperationInstance op | op.getAnAlgorithmValueConsumer() = avc) } - private predicate isMacAvc(AlgorithmValueConsumer avc) { - exists(MacOperationInstance op | op.getAnAlgorithmValueConsumer() = avc) or - exists(Pbkdf2AlgorithmInstance alg | avc = alg.getHmacAlgorithmValueConsumer()) - } - private predicate isKeyDerivationAvc(AlgorithmValueConsumer avc) { exists(KeyDerivationOperationInstance op | op.getAnAlgorithmValueConsumer() = avc) } @@ -1091,9 +1108,6 @@ module CryptographyBase Input> { final private class HashAlgorithmInstanceOrValueConsumer = AlgorithmInstanceOrValueConsumer::Union; - final private class MacAlgorithmInstanceOrValueConsumer = - AlgorithmInstanceOrValueConsumer::Union; - final private class KeyDerivationAlgorithmInstanceOrValueConsumer = AlgorithmInstanceOrValueConsumer::Union; @@ -1128,13 +1142,11 @@ module CryptographyBase Input> { TPaddingAlgorithm(PaddingAlgorithmInstance e) or // All other operations THashOperation(HashOperationInstance e) or - TMacOperation(MacOperationInstance e) or TKeyAgreementOperation(KeyAgreementSecretGenerationOperationInstance e) or // All other algorithms TEllipticCurve(EllipticCurveInstanceOrValueConsumer e) or THashAlgorithm(HashAlgorithmInstanceOrValueConsumer e) or TKeyDerivationAlgorithm(KeyDerivationAlgorithmInstanceOrValueConsumer e) or - TMacAlgorithm(MacAlgorithmInstanceOrValueConsumer e) or TKeyAgreementAlgorithm(KeyAgreementAlgorithmInstanceOrValueConsumer e) or // Generic source nodes, i.e., sources of data that are not resolvable to a specific known asset. TGenericSourceNode(GenericSourceInstance e) { @@ -1582,57 +1594,36 @@ module CryptographyBase Input> { /** * A MAC operation that produces a MAC value. */ - final class MacOperationNode extends OperationNode, TMacOperation { - MacOperationInstance instance; - - MacOperationNode() { this = TMacOperation(instance) } + final class MacOperationNode extends SignatureOrMacOperationNode { + MacOperationNode() { + this.getKeyOperationSubtype() = TMacMode() and + // If the type could be a mac, then we will not consider it a mac operation exclusively. + not exists(KeyOperationSubtype t | t = this.getKeyOperationSubtype() and t = TMacMode()) + } final override string getInternalType() { result = "MACOperation" } override LocatableElement asElement() { result = instance } - override predicate isCandidateAlgorithmNode(AlgorithmNode node) { - node instanceof MacAlgorithmNode - } - MessageArtifactNode getAMessage() { - result.asElement() = instance.getMessageConsumer().getConsumer() + result.asElement() = instance.getInputConsumer().getConsumer() } - KeyArtifactNode getAKey() { result.asElement() = instance.getKeyConsumer().getConsumer() } - override NodeBase getChild(string edgeName) { result = super.getChild(edgeName) or // [KNOWN_OR_UNKNOWN] edgeName = "Message" and - if exists(this.getAMessage()) then result = this.getAMessage() else result = this - or - // [KNOWN_OR_UNKNOWN] - edgeName = "Key" and - if exists(this.getAKey()) then result = this.getAKey() else result = this + (if exists(this.getAMessage()) then result = this.getAMessage() else result = this) } } - /** - * A MAC algorithm, such as HMAC or CMAC. - */ - class MacAlgorithmNode extends AlgorithmNode, TMacAlgorithm { - MacAlgorithmInstanceOrValueConsumer instance; - - MacAlgorithmNode() { this = TMacAlgorithm(instance) } - - final override string getInternalType() { result = "MACAlgorithm" } - - override LocatableElement asElement() { result = instance } - - final override string getRawAlgorithmName() { - result = instance.asAlg().getRawMacAlgorithmName() + abstract class MacAlgorithmNode extends KeyOperationAlgorithmNode { + MacAlgorithmNode() { + instance.(KeyOperationAlgorithmInstance).getAlgorithmType() = KeyOpAlg::TMac(_) } - MacType getMacType() { result = instance.asAlg().getMacType() } - - override string getAlgorithmName() { result = this.getMacType().toString() } + override string getInternalType() { result = "MACAlgorithm" } } final class HmacAlgorithmNode extends MacAlgorithmNode { @@ -1640,6 +1631,8 @@ module CryptographyBase Input> { HmacAlgorithmNode() { hmacInstance = instance.asAlg() } + override string getInternalType() { result = "HMACAlgorithm" } + NodeBase getHashAlgorithmOrUnknown() { result.asElement() = hmacInstance.getHashAlgorithmValueConsumer().getASource() } @@ -1655,6 +1648,7 @@ module CryptographyBase Input> { } } + // TODO: CMAC model class KeyAgreementOperationNode extends OperationNode, TKeyAgreementOperation { KeyAgreementSecretGenerationOperationInstance instance; @@ -1871,6 +1865,7 @@ module CryptographyBase Input> { TUnwrapMode() or TSignMode() or TVerifyMode() or + TMacMode() or TUnknownKeyOperationMode() /** @@ -1890,6 +1885,8 @@ module CryptographyBase Input> { or result = "Verify" and this = TVerifyMode() or + result = "Mac" and this = TMacMode() + or result = "Unknown" and this = TUnknownKeyOperationMode() } } @@ -2001,14 +1998,44 @@ module CryptographyBase Input> { override string getInternalType() { result = nodeName } } - class SignatureOperationNode extends KeyOperationNode { + class SignatureOrMacOperationNode extends KeyOperationNode { + override SignatureOrMacOperationInstance instance; + + SignatureOrMacOperationNode() { + this.getKeyOperationSubtype() = TSignMode() + or + this.getKeyOperationSubtype() = TVerifyMode() + or + this.getKeyOperationSubtype() = TMacMode() + } + + override string getInternalType() { result = "SignatureOrMACOperation" } + + HashAlgorithmNode getHashAlgorithm() { + result = instance.getHashAlgorithmValueConsumer().getAKnownSourceNode() + } + + override NodeBase getChild(string key) { + result = super.getChild(key) + or + // [KNOWN_OR_UNKNOWN] + key = "HashAlgorithm" and + (if exists(this.getHashAlgorithm()) then result = this.getHashAlgorithm() else result = this) + } + } + + class SignatureOperationNode extends SignatureOrMacOperationNode { override SignatureOperationInstance instance; string nodeName; SignatureOperationNode() { - this.getKeyOperationSubtype() = TSignMode() and nodeName = "SignOperation" - or - this.getKeyOperationSubtype() = TVerifyMode() and nodeName = "VerifyOperation" + ( + this.getKeyOperationSubtype() = TSignMode() and nodeName = "SignOperation" + or + this.getKeyOperationSubtype() = TVerifyMode() and nodeName = "VerifyOperation" + ) and + // If the type could be a mac, then we will not consider it a signature operation exclusively. + not exists(KeyOperationSubtype t | t = this.getKeyOperationSubtype() and t = TMacMode()) } override string getInternalType() { result = nodeName } @@ -2017,10 +2044,6 @@ module CryptographyBase Input> { result.asElement() = instance.getSignatureConsumer().getConsumer() } - HashAlgorithmNode getHashAlgorithm() { - result = instance.getHashAlgorithmValueConsumer().getAKnownSourceNode() - } - override NodeBase getChild(string key) { result = super.getChild(key) or diff --git a/shared/quantum/codeql/quantum/experimental/Standardization.qll b/shared/quantum/codeql/quantum/experimental/Standardization.qll index 29c5b58d343a..929c92aefff1 100644 --- a/shared/quantum/codeql/quantum/experimental/Standardization.qll +++ b/shared/quantum/codeql/quantum/experimental/Standardization.qll @@ -14,6 +14,7 @@ module Types { TSymmetricCipher(TSymmetricCipherType t) or TAsymmetricCipher(TAsymmetricCipherType t) or TSignature(TSignatureAlgorithmType t) or + TMac(TMacAlgorithmType t) or TKeyEncapsulation(TKemAlgorithmType t) or TUnknownKeyOperationAlgorithmType() @@ -55,6 +56,11 @@ module Types { FRODO_KEM() or OtherKemAlgorithmType() + newtype TMacAlgorithmType = + HMAC() or + CMAC() or + OtherMacAlgorithmType() + newtype TCipherStructureType = Block() or Stream() or @@ -143,6 +149,13 @@ module Types { or this = TKeyEncapsulation(OtherKemAlgorithmType()) and result = "UnknownKEM" or + // MAC algorithms + this = TMac(HMAC()) and result = "HMAC" + or + this = TMac(CMAC()) and result = "CMAC" + or + this = TMac(OtherMacAlgorithmType()) and result = "UnknownMac" + or // Unknown this = TUnknownKeyOperationAlgorithmType() and result = "Unknown" } @@ -305,21 +318,6 @@ module Types { } } - newtype TMacType = - HMAC() or - CMAC() or - OtherMacType() - - class MacType extends TMacType { - string toString() { - this = HMAC() and result = "HMAC" - or - this = CMAC() and result = "CMAC" - or - this = OtherMacType() and result = "UnknownMacType" - } - } - // Key agreement algorithms newtype TKeyAgreementType = DH() or // Diffie-Hellman