Crypto: Adding initial openssl tests, fixing a bug in hash modeling found through tests, and updating CODEOWNERS for quantum tests

This commit is contained in:
REDMOND\brodes
2025-05-22 14:35:14 -04:00
parent 007683f06a
commit 41f008d4f3
20 changed files with 9028 additions and 10 deletions

View File

@@ -29,7 +29,19 @@ import semmle.code.cpp.dataflow.new.DataFlow
* - EVP_PKEY_CTX
*/
private class CtxType extends Type {
CtxType() { this.getUnspecifiedType().stripType().getName().matches("evp_%ctx_%st") }
CtxType() {
// It is possible for users to use the underlying type of the CTX variables
// these have a name matching 'evp_%ctx_%st
this.getUnspecifiedType().stripType().getName().matches("evp_%ctx_%st")
or
// In principal the above check should be sufficient, but in case of build mode none issues
// i.e., if a typedef cannot be resolved,
// or issues with properly stubbing test cases, we also explicitly check for the wrapping type defs
// i.e., patterns matching 'EVP_%_CTX'
exists(Type base | base = this or base = this.(DerivedType).getBaseType() |
base.getName().matches("EVP_%_CTX")
)
}
}
/**

View File

@@ -10,7 +10,7 @@ private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
}
predicate isSink(DataFlow::Node sink) {
exists(EVP_Cipher_Operation c | c.getInitCall().getAlgorithmArg() = sink.asExpr())
exists(EVP_Cipher_Operation c | c.getAlgorithmArg() = sink.asExpr())
}
}
@@ -32,6 +32,8 @@ private module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsu
abstract class EVP_Cipher_Operation extends OpenSSLOperation, Crypto::KeyOperationInstance {
Expr getContextArg() { result = this.(Call).getArgument(0) }
Expr getAlgorithmArg() { this.getInitCall().getAlgorithmArg() = result }
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {

View File

@@ -12,6 +12,8 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
abstract class EVP_Hash_Operation extends OpenSSLOperation, Crypto::HashOperationInstance {
Expr getContextArg() { result = this.(Call).getArgument(0) }
Expr getAlgorithmArg() { result = this.getInitCall().getAlgorithmArg() }
EVP_Hash_Initializer getInitCall() {
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
}
@@ -23,7 +25,7 @@ abstract class EVP_Hash_Operation extends OpenSSLOperation, Crypto::HashOperatio
*/
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
DataFlow::exprNode(this.getInitCall().getAlgorithmArg()))
DataFlow::exprNode(this.getAlgorithmArg()))
}
}
@@ -33,7 +35,7 @@ private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
}
predicate isSink(DataFlow::Node sink) {
exists(EVP_Hash_Operation c | c.getInitCall().getAlgorithmArg() = sink.asExpr())
exists(EVP_Hash_Operation c | c.getAlgorithmArg() = sink.asExpr())
}
}
@@ -64,6 +66,8 @@ class EVP_Q_Digest_Operation extends EVP_Hash_Operation {
// simply return 'this', see modeled hash algorithm consuers for EVP_Q_Digest
this = result
}
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
}
class EVP_Digest_Operation extends EVP_Hash_Operation {
@@ -72,17 +76,14 @@ class EVP_Digest_Operation extends EVP_Hash_Operation {
// There is no context argument for this function
override Expr getContextArg() { none() }
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
DataFlow::exprNode(this.(Call).getArgument(4)))
}
override EVP_Hash_Initializer getInitCall() {
// This variant of digest does not use an init
// and even if it were used, the init would be ignored/undefined
none()
}
override Expr getAlgorithmArg() { result = this.(Call).getArgument(4) }
override Expr getOutputArg() { result = this.(Call).getArgument(2) }
override Expr getInputArg() { result = this.(Call).getArgument(0) }