diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll index f53812093c42..a232ffa6f3a7 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/OpenSSL.qll @@ -6,4 +6,5 @@ module OpenSSLModel { import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers import experimental.quantum.OpenSSL.Operations.OpenSSLOperations + import experimental.quantum.OpenSSL.Random } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll index f22bcae69275..263985857374 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPCipherOperation.qll @@ -74,8 +74,8 @@ class EVP_Cipher_Call extends EVP_Cipher_Operation { } // NOTE: not modeled as cipher operations, these are intermediate calls -class EVP_Update_Call extends Call { - EVP_Update_Call() { +class EVP_Cipher_Update_Call extends Call { + EVP_Cipher_Update_Call() { this.(Call).getTarget().getName() in [ "EVP_EncryptUpdate", "EVP_DecryptUpdate", "EVP_CipherUpdate" ] @@ -88,15 +88,15 @@ class EVP_Update_Call extends Call { Expr getContextArg() { result = this.(Call).getArgument(0) } } -class EVP_Final_Call extends EVP_Cipher_Operation { - EVP_Final_Call() { +class EVP_Cipher_Final_Call extends EVP_Cipher_Operation { + EVP_Cipher_Final_Call() { this.(Call).getTarget().getName() in [ "EVP_EncryptFinal_ex", "EVP_DecryptFinal_ex", "EVP_CipherFinal_ex", "EVP_EncryptFinal", "EVP_DecryptFinal", "EVP_CipherFinal" ] } - EVP_Update_Call getUpdateCalls() { + EVP_Cipher_Update_Call getUpdateCalls() { CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg()) } diff --git a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll index a187b62a7bdd..6d0013df9d58 100644 --- a/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll +++ b/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPHashOperation.qll @@ -16,6 +16,16 @@ abstract class EVP_Hash_Operation extends OpenSSLOperation, Crypto::HashOperatio EVP_Hash_Initializer getInitCall() { CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg()) } + + /** + * By default, the algorithm value comes from the init call. + * There are variants where this isn't true, in which case the + * subclass should override this method. + */ + override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { + AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(), + DataFlow::exprNode(this.getInitCall().getAlgorithmArg())) + } } private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig { @@ -88,30 +98,34 @@ class EVP_Digest_Operation extends EVP_Hash_Operation { override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() } } -// // override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() { -// // AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(), -// // DataFlow::exprNode(this.getInitCall().getAlgorithmArg())) -// // } -// // ***** TODO *** complete modelinlg for hash operations, but have consideration for terminal and non-terminal (non intermedaite) steps -// // see the JCA. May need to update the cipher operations similarly -// // ALSO SEE cipher for how we currently model initialization of the algorithm through an init call -// class EVP_DigestUpdate_Operation extends EVP_Hash_Operation { -// EVP_DigestUpdate_Operation() { -// this.(Call).getTarget().getName() = "EVP_DigestUpdate" and -// isPossibleOpenSSLFunction(this.(Call).getTarget()) -// } -// override Crypto::AlgorithmConsumer getAlgorithmConsumer() { -// this.getInitCall().getAlgorithmArg() = result -// } -// } -// class EVP_DigestFinal_Variants_Operation extends EVP_Hash_Operation { -// EVP_DigestFinal_Variants_Operation() { -// this.(Call).getTarget().getName() in [ -// "EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF" -// ] and -// isPossibleOpenSSLFunction(this.(Call).getTarget()) -// } -// override Crypto::AlgorithmConsumer getAlgorithmConsumer() { -// this.getInitCall().getAlgorithmArg() = result -// } -// } + +// NOTE: not modeled as hash operations, these are intermediate calls +class EVP_Digest_Update_Call extends Call { + EVP_Digest_Update_Call() { this.(Call).getTarget().getName() in ["EVP_DigestUpdate"] } + + Expr getInputArg() { result = this.(Call).getArgument(1) } + + DataFlow::Node getInputNode() { result.asExpr() = this.getInputArg() } + + Expr getContextArg() { result = this.(Call).getArgument(0) } +} + +class EVP_Digest_Final_Call extends EVP_Hash_Operation { + EVP_Digest_Final_Call() { + this.(Call).getTarget().getName() in [ + "EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF" + ] + } + + EVP_Digest_Update_Call getUpdateCalls() { + CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg()) + } + + override Expr getInputArg() { result = this.getUpdateCalls().getInputArg() } + + override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() } + + override Expr getOutputArg() { result = this.(Call).getArgument(1) } + + override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = this.getOutputNode() } +}