Changed casing on TCipherType, Added some initial fixes for hash support, started developing openssl hashing modeling.

This commit is contained in:
REDMOND\brodes
2025-03-07 10:02:36 -05:00
parent b9bd199432
commit 32d29ffde3
6 changed files with 185 additions and 42 deletions

View File

@@ -3,7 +3,7 @@ import experimental.Quantum.Language
import EVPCipherConsumers
import OpenSSLAlgorithmGetter
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
exists(string name, string algType | algType.toLowerCase().matches("%encryption") |
resolveAlgorithmFromLiteral(e, name, algType) and
(
@@ -21,9 +21,9 @@ predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
or
name.matches("CAST5") and type instanceof Crypto::CAST5
or
name.matches("2DES") and type instanceof Crypto::DOUBLEDES
name.matches("2DES") and type instanceof Crypto::DoubleDES
or
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TRIPLEDES
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TripleDES
or
name.matches("DES") and type instanceof Crypto::DES
or
@@ -52,7 +52,6 @@ predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
)
}
class CipherKnownAlgorithmLiteralAlgorithmInstance extends Crypto::CipherAlgorithmInstance instanceof Literal
{
OpenSSLAlgorithmGetterCall cipherGetterCall;
@@ -81,7 +80,9 @@ class CipherKnownAlgorithmLiteralAlgorithmInstance extends Crypto::CipherAlgorit
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
override Crypto::TCipherType getCipherFamily() { literalToCipherFamilyType(this, result) }
override Crypto::TCipherType getCipherFamily() {
literalToCipherFamilyType(this, result)
}
}
// override Crypto::TCipherType getCipherFamily() {
// if this.cipherNameMappingKnown(_, super.getAlgorithmName())

View File

@@ -0,0 +1,65 @@
import cpp
import experimental.Quantum.Language
import EVPCipherConsumers
import OpenSSLAlgorithmGetter
predicate literalToHashFamilyType(Literal e, Crypto::THashType type) {
exists(string name, string algType | algType.toLowerCase().matches("%hash") |
resolveAlgorithmFromLiteral(e, name, algType) and
(
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
or
name.matches("BLAKE2S") and type instanceof Crypto::BLAKE2S
or
name.matches("RIPEMD160") and type instanceof Crypto::RIPEMD160
or
name.matches("MD2") and type instanceof Crypto::MD2
or
name.matches("MD4") and type instanceof Crypto::MD4
or
name.matches("MD5") and type instanceof Crypto::MD5
or
name.matches("POLY1305") and type instanceof Crypto::POLY1305
or
name.matches(["SHA1", "SHA"]) and type instanceof Crypto::SHA1
or
name.matches("SHA2") and type instanceof Crypto::SHA2
or
name.matches("SHA3") and type instanceof Crypto::SHA3
or
name.matches("SHAKE") and type instanceof Crypto::SHAKE
or
name.matches("SM3") and type instanceof Crypto::SM3
or
name.matches("WHIRLPOOL") and type instanceof Crypto::WHIRLPOOL
// TODO: what about MD_GOST?
)
)
}
class HashKnownAlgorithmLiteralAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof Literal
{
OpenSSLAlgorithmGetterCall cipherGetterCall;
HashKnownAlgorithmLiteralAlgorithmInstance() {
exists(DataFlow::Node src, DataFlow::Node sink |
sink = cipherGetterCall.getValueArgNode() and
src.asExpr() = this and
KnownAlgorithmLiteralToAlgorithmGetterFlow::flow(src, sink) and
// Not just any known value, but specifically a known cipher operation
exists(string algType |
resolveAlgorithmFromLiteral(src.asExpr(), _, algType) and
algType.toLowerCase().matches("hash")
)
)
}
// TODO: should this not be part of the abstract algorithm definition?
Crypto::AlgorithmConsumer getConsumer() {
AlgGetterToAlgConsumerFlow::flow(cipherGetterCall.getResultNode(), DataFlow::exprNode(result))
}
override Crypto::THashType getHashFamily() { literalToHashFamilyType(this, result) }
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
}

View File

@@ -0,0 +1,5 @@
import experimental.Quantum.Language
import CtxFlow as CTXFlow
//https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis

View File

@@ -162,9 +162,9 @@ class EVPCipherGetterCall extends OpenSSLAlgorithmGetterCall {
Expr resultExpr;
EVPCipherGetterCall() {
// Flow out through the return pointer itself (trace the pointer, not what it is pointing to)
resultExpr = this and
resultNode.asExpr() = this and
isPossibleOpenSSLFunction(this.getTarget()) and
(
this.getTarget().getName() in ["EVP_get_cipherbyname", "EVP_get_cipherbyobj"] and
valueArgExpr = this.getArgument(0) and
@@ -188,6 +188,38 @@ class EVPCipherGetterCall extends OpenSSLAlgorithmGetterCall {
override Expr getResultExpr() { result = resultExpr }
}
class EVPDigestGetterCall extends OpenSSLAlgorithmGetterCall {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
Expr valueArgExpr;
Expr resultExpr;
EVPDigestGetterCall() {
resultExpr = this and
resultNode.asExpr() = this and
isPossibleOpenSSLFunction(this.getTarget()) and
(
this.getTarget().getName() in [
"EVP_get_digestbyname", "EVP_get_digestbyobj", "EVP_get_digestbynid"
] and
valueArgExpr = this.getArgument(0) and
valueArgNode.asExpr() = valueArgExpr
or
this.getTarget().getName() = "EVP_MD_fetch" and
valueArgExpr = this.getArgument(1) and
valueArgNode.asExpr() = valueArgExpr
)
}
override DataFlow::Node getValueArgNode() { result = valueArgNode }
override DataFlow::Node getResultNode() { result = resultNode }
override Expr getValueArgExpr() { result = valueArgExpr }
override Expr getResultExpr() { result = resultExpr }
}
// /**
// * Predicates/classes for identifying algorithm sinks.
// * An Algorithm Sink is a function that takes an algorithm as an argument.