Adding block mode models to openssl.

This commit is contained in:
REDMOND\brodes
2025-03-11 15:20:05 -04:00
parent 71eae39feb
commit 8a7671dc2a

View File

@@ -4,12 +4,12 @@ import EVPCipherConsumers
import OpenSSLAlgorithmGetter
/**
* Given a literal `e`, converts this to a cipher family type.
* The literal must be a known literal representing a cipher algorithm.
* If the literal does not represent any known cipher algorithm,
* this predicate will not hold (i.e., it will not bind an unknown to an unknown cipher type)
* Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSSLConstantToCipherFamilyType(KnownOpenSSLAlgorithmConstant e, Crypto::TCipherType type) {
predicate knownOpenSSLConstantToCipherFamilyType(
KnownOpenSSLAlgorithmConstant e, Crypto::TCipherType type
) {
exists(string name | e.getAlgType().toLowerCase().matches("%encryption") |
name = e.getNormalizedName() and
(
@@ -90,16 +90,92 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends Crypto::CipherAlgorith
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
none() // TODO: provider defaults
// if there is a block mode associated with the same element, then that's the block mode
// note, if none are associated, we may need to parse if the cipher is a block cipher
// to determine if this is an unknown vs not relevant.
result = this
}
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
override Crypto::TCipherType getCipherFamily() {
knownOpenSSLConstantToCipherFamilyType(this, result)
override Crypto::TCipherType getCipherFamily() {
knownOpenSSLConstantToCipherFamilyType(this, result)
or
not knownOpenSSLConstantToCipherFamilyType(this, _) and result = Crypto::OtherCipherType()
}
}
}
/**
* Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSSLConstantToBlockModeFamilyType(
KnownOpenSSLAlgorithmConstant e, Crypto::TBlockCipherModeOperationType type
) {
exists(string name | e.getAlgType().toLowerCase().matches("block_mode") |
name = e.getNormalizedName() and
(
name.matches("CBC") and type instanceof Crypto::CBC
or
name.matches("CFB%") and type instanceof Crypto::CFB
or
name.matches("CTR") and type instanceof Crypto::CTR
or
name.matches("GCM") and type instanceof Crypto::GCM
or
name.matches("OFB") and type instanceof Crypto::OFB
or
name.matches("XTS") and type instanceof Crypto::XTS
or
name.matches("CCM") and type instanceof Crypto::CCM
or
name.matches("GCM") and type instanceof Crypto::GCM
or
name.matches("CCM") and type instanceof Crypto::CCM
or
name.matches("ECB") and type instanceof Crypto::ECB
)
)
}
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLAlgorithmConstant
{
OpenSSLAlgorithmGetterCall getterCall;
KnownOpenSSLBlockModeConstantAlgorithmInstance() {
// Not just any known value, but specifically a known cipher operation
this.(KnownOpenSSLAlgorithmConstant).getAlgType().toLowerCase().matches("block_mode") and
(
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof Literal and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmGetterCall).getValueArgNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmGetterFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof DirectGetterCall and getterCall = this
)
}
override Crypto::TBlockCipherModeOperationType getModeType() {
knownOpenSSLConstantToBlockModeFamilyType(this, result)
or
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
}
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
// the same as the raw name for now.
override string getRawModeAlgorithmName() { result = this.(Literal).getValue().toString() }
override string getRawAlgorithmName() { result = this.getRawModeAlgorithmName() }
}