mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #19814 from bdrodes/codescanning_fixes_cpp
Crypto: Fix QL-for-QL alerts and refactor type standardization
This commit is contained in:
@@ -56,7 +56,7 @@ module ArtifactFlowConfig implements DataFlow::ConfigSig {
|
||||
module ArtifactFlow = DataFlow::Global<ArtifactFlowConfig>;
|
||||
|
||||
/**
|
||||
* Artifact output to node input configuration
|
||||
* An artifact output to node input configuration
|
||||
*/
|
||||
abstract class AdditionalFlowInputStep extends DataFlow::Node {
|
||||
abstract DataFlow::Node getOutput();
|
||||
@@ -91,9 +91,8 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
|
||||
|
||||
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
|
||||
ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral }
|
||||
|
||||
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof OpenSslGenericSourceCandidateLiteral
|
||||
{
|
||||
override DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
|
||||
override predicate flowsTo(Crypto::FlowAwareElement other) {
|
||||
|
||||
@@ -48,7 +48,7 @@ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
|
||||
module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
|
||||
|
||||
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
|
||||
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
@@ -60,8 +60,8 @@ module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
|
||||
}
|
||||
}
|
||||
|
||||
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
|
||||
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
|
||||
|
||||
class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
|
||||
OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
|
||||
@@ -114,11 +114,11 @@ class CopyAndDupAlgorithmPassthroughCall extends AlgorithmPassthroughCall {
|
||||
override DataFlow::Node getOutNode() { result = outNode }
|
||||
}
|
||||
|
||||
class NIDToPointerPassthroughCall extends AlgorithmPassthroughCall {
|
||||
class NidToPointerPassthroughCall extends AlgorithmPassthroughCall {
|
||||
DataFlow::Node inNode;
|
||||
DataFlow::Node outNode;
|
||||
|
||||
NIDToPointerPassthroughCall() {
|
||||
NidToPointerPassthroughCall() {
|
||||
this.getTarget().getName() in ["OBJ_nid2obj", "OBJ_nid2ln", "OBJ_nid2sn"] and
|
||||
inNode.asExpr() = this.getArgument(0) and
|
||||
outNode.asExpr() = this
|
||||
@@ -150,11 +150,11 @@ class PointerToPointerPassthroughCall extends AlgorithmPassthroughCall {
|
||||
override DataFlow::Node getOutNode() { result = outNode }
|
||||
}
|
||||
|
||||
class PointerToNIDPassthroughCall extends AlgorithmPassthroughCall {
|
||||
class PointerToNidPassthroughCall extends AlgorithmPassthroughCall {
|
||||
DataFlow::Node inNode;
|
||||
DataFlow::Node outNode;
|
||||
|
||||
PointerToNIDPassthroughCall() {
|
||||
PointerToNidPassthroughCall() {
|
||||
this.getTarget().getName() in ["OBJ_obj2nid", "OBJ_ln2nid", "OBJ_sn2nid", "OBJ_txt2nid"] and
|
||||
(
|
||||
inNode.asIndirectExpr() = this.getArgument(0)
|
||||
|
||||
@@ -5,36 +5,35 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import AlgToAVCFlow
|
||||
private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSslConstantToBlockModeFamilyType(
|
||||
KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
|
||||
KnownOpenSslBlockModeAlgorithmExpr e, KeyOpAlg::ModeOfOperationType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("CBC") and type instanceof Crypto::CBC
|
||||
name = "CBC" and type instanceof KeyOpAlg::CBC
|
||||
or
|
||||
name.matches("CFB%") and type instanceof Crypto::CFB
|
||||
name = "CFB%" and type instanceof KeyOpAlg::CFB
|
||||
or
|
||||
name.matches("CTR") and type instanceof Crypto::CTR
|
||||
name = "CTR" and type instanceof KeyOpAlg::CTR
|
||||
or
|
||||
name.matches("GCM") and type instanceof Crypto::GCM
|
||||
name = "GCM" and type instanceof KeyOpAlg::GCM
|
||||
or
|
||||
name.matches("OFB") and type instanceof Crypto::OFB
|
||||
name = "OFB" and type instanceof KeyOpAlg::OFB
|
||||
or
|
||||
name.matches("XTS") and type instanceof Crypto::XTS
|
||||
name = "XTS" and type instanceof KeyOpAlg::XTS
|
||||
or
|
||||
name.matches("CCM") and type instanceof Crypto::CCM
|
||||
name = "CCM" and type instanceof KeyOpAlg::CCM
|
||||
or
|
||||
name.matches("GCM") and type instanceof Crypto::GCM
|
||||
name = "CCM" and type instanceof KeyOpAlg::CCM
|
||||
or
|
||||
name.matches("CCM") and type instanceof Crypto::CCM
|
||||
or
|
||||
name.matches("ECB") and type instanceof Crypto::ECB
|
||||
name = "ECB" and type instanceof KeyOpAlg::ECB
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -64,10 +63,10 @@ class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmIns
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::TBlockCipherModeOfOperationType getModeType() {
|
||||
override KeyOpAlg::ModeOfOperationType getModeType() {
|
||||
knownOpenSslConstantToBlockModeFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
||||
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = KeyOpAlg::OtherMode()
|
||||
}
|
||||
|
||||
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
|
||||
|
||||
@@ -33,9 +33,9 @@ predicate knownOpenSslConstantToCipherFamilyType(
|
||||
or
|
||||
name.matches("CAST5%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::CAST5())
|
||||
or
|
||||
name.matches("2DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DoubleDES())
|
||||
name.matches("2DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DOUBLE_DES())
|
||||
or
|
||||
name.matches("3DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TripleDES())
|
||||
name.matches("3DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
|
||||
or
|
||||
name.matches("DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DES())
|
||||
or
|
||||
@@ -113,7 +113,7 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
|
||||
this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result
|
||||
}
|
||||
|
||||
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
override KeyOpAlg::AlgorithmType getAlgorithmType() {
|
||||
knownOpenSslConstantToCipherFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToCipherFamilyType(this, _) and
|
||||
|
||||
@@ -39,8 +39,14 @@ class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorith
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override Crypto::TEllipticCurveType getEllipticCurveType() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _, result)
|
||||
override Crypto::EllipticCurveFamilyType getEllipticCurveFamilyType() {
|
||||
if
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _,
|
||||
_)
|
||||
then
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _,
|
||||
result)
|
||||
else result = Crypto::OtherEllipticCurveType()
|
||||
}
|
||||
|
||||
override string getParsedEllipticCurveName() {
|
||||
@@ -48,7 +54,7 @@ class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorith
|
||||
}
|
||||
|
||||
override int getKeySize() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
|
||||
.getNormalizedName(), result, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,21 +11,21 @@ predicate knownOpenSslConstantToHashFamilyType(
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
|
||||
name = "BLAKE2B" and type instanceof Crypto::BLAKE2B
|
||||
or
|
||||
name.matches("BLAKE2S") and type instanceof Crypto::BLAKE2S
|
||||
name = "BLAKE2S" and type instanceof Crypto::BLAKE2S
|
||||
or
|
||||
name.matches("GOST%") and type instanceof Crypto::GOSTHash
|
||||
name.matches("GOST%") and type instanceof Crypto::GOST_HASH
|
||||
or
|
||||
name.matches("MD2") and type instanceof Crypto::MD2
|
||||
name = "MD2" and type instanceof Crypto::MD2
|
||||
or
|
||||
name.matches("MD4") and type instanceof Crypto::MD4
|
||||
name = "MD4" and type instanceof Crypto::MD4
|
||||
or
|
||||
name.matches("MD5") and type instanceof Crypto::MD5
|
||||
name = "MD5" and type instanceof Crypto::MD5
|
||||
or
|
||||
name.matches("MDC2") and type instanceof Crypto::MDC2
|
||||
name = "MDC2" and type instanceof Crypto::MDC2
|
||||
or
|
||||
name.matches("POLY1305") and type instanceof Crypto::POLY1305
|
||||
name = "POLY1305" and type instanceof Crypto::POLY1305
|
||||
or
|
||||
name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1
|
||||
or
|
||||
@@ -33,13 +33,13 @@ predicate knownOpenSslConstantToHashFamilyType(
|
||||
or
|
||||
name.matches("SHA3-%") and type instanceof Crypto::SHA3
|
||||
or
|
||||
name.matches(["SHAKE"]) and type instanceof Crypto::SHAKE
|
||||
name = "SHAKE" and type instanceof Crypto::SHAKE
|
||||
or
|
||||
name.matches("SM3") and type instanceof Crypto::SM3
|
||||
name = "SM3" and type instanceof Crypto::SM3
|
||||
or
|
||||
name.matches("RIPEMD160") and type instanceof Crypto::RIPEMD160
|
||||
name = "RIPEMD160" and type instanceof Crypto::RIPEMD160
|
||||
or
|
||||
name.matches("WHIRLPOOL") and type instanceof Crypto::WHIRLPOOL
|
||||
name = "WHIRLPOOL" and type instanceof Crypto::WHIRLPOOL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -210,7 +210,8 @@ string getAlgorithmAlias(string alias) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds aliases of known alagorithms defined by users (through obj_name_add and various macros pointing to this function)
|
||||
* Holds for aliases of known algorithms defined by users
|
||||
* (through obj_name_add and various macros pointing to this function).
|
||||
*
|
||||
* The `target` and `alias` are converted to lowercase to be of a standard form.
|
||||
*/
|
||||
@@ -222,7 +223,7 @@ predicate customAliases(string target, string alias) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A hard-coded mapping of known algorithm aliases in OpenSsl.
|
||||
* Holds for a hard-coded mapping of known algorithm aliases in OpenSsl.
|
||||
* This was derived by applying the same kind of logic foun din `customAliases` to the
|
||||
* OpenSsl code base directly.
|
||||
*
|
||||
|
||||
@@ -7,7 +7,7 @@ private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations
|
||||
private import AlgToAVCFlow
|
||||
|
||||
class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::MACAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
|
||||
Crypto::MacAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
@@ -39,14 +39,14 @@ class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override Crypto::TMACType getMacType() {
|
||||
this instanceof KnownOpenSslHMacAlgorithmExpr and result instanceof Crypto::THMAC
|
||||
override Crypto::MacType getMacType() {
|
||||
this instanceof KnownOpenSslHMacAlgorithmExpr and result = Crypto::HMAC()
|
||||
or
|
||||
this instanceof KnownOpenSslCMacAlgorithmExpr and result instanceof Crypto::TCMAC
|
||||
this instanceof KnownOpenSslCMacAlgorithmExpr and result = Crypto::CMAC()
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HMACAlgorithmInstance,
|
||||
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmInstance,
|
||||
KnownOpenSslMacConstantAlgorithmInstance
|
||||
{
|
||||
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
|
||||
|
||||
@@ -5,6 +5,7 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import AlgToAVCFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
|
||||
|
||||
/**
|
||||
* A class to define padding specific integer values.
|
||||
@@ -28,18 +29,18 @@ class OpenSslPaddingLiteral extends Literal {
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSslConstantToPaddingFamilyType(
|
||||
KnownOpenSslPaddingAlgorithmExpr e, Crypto::TPaddingType type
|
||||
KnownOpenSslPaddingAlgorithmExpr e, KeyOpAlg::PaddingSchemeType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("OAEP") and type = Crypto::OAEP()
|
||||
name = "OAEP" and type = KeyOpAlg::OAEP()
|
||||
or
|
||||
name.matches("PSS") and type = Crypto::PSS()
|
||||
name = "PSS" and type = KeyOpAlg::PSS()
|
||||
or
|
||||
name.matches("PKCS7") and type = Crypto::PKCS7()
|
||||
name = "PKCS7" and type = KeyOpAlg::PKCS7()
|
||||
or
|
||||
name.matches("PKCS1V15") and type = Crypto::PKCS1_v1_5()
|
||||
name = "PKCS1V15" and type = KeyOpAlg::PKCS1_V1_5()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -85,7 +86,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a padding-specific consumer
|
||||
RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
) and
|
||||
isPaddingSpecificConsumer = true
|
||||
}
|
||||
@@ -98,24 +99,24 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
Crypto::TPaddingType getKnownPaddingType() {
|
||||
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
|
||||
KeyOpAlg::PaddingSchemeType getKnownPaddingType() {
|
||||
this.(Literal).getValue().toInt() in [1, 7, 8] and result = KeyOpAlg::PKCS1_V1_5()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 3 and result = Crypto::NoPadding()
|
||||
this.(Literal).getValue().toInt() = 3 and result = KeyOpAlg::NoPadding()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 4 and result = Crypto::OAEP()
|
||||
this.(Literal).getValue().toInt() = 4 and result = KeyOpAlg::OAEP()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 5 and result = Crypto::ANSI_X9_23()
|
||||
this.(Literal).getValue().toInt() = 5 and result = KeyOpAlg::ANSI_X9_23()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 6 and result = Crypto::PSS()
|
||||
this.(Literal).getValue().toInt() = 6 and result = KeyOpAlg::PSS()
|
||||
}
|
||||
|
||||
override Crypto::TPaddingType getPaddingType() {
|
||||
override KeyOpAlg::PaddingSchemeType getPaddingType() {
|
||||
isPaddingSpecificConsumer = true and
|
||||
(
|
||||
result = this.getKnownPaddingType()
|
||||
or
|
||||
not exists(this.getKnownPaddingType()) and result = Crypto::OtherPadding()
|
||||
not exists(this.getKnownPaddingType()) and result = KeyOpAlg::OtherPadding()
|
||||
)
|
||||
or
|
||||
isPaddingSpecificConsumer = false and
|
||||
@@ -143,7 +144,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
// this instanceof Literal and
|
||||
// this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8]
|
||||
// // TODO: trace to padding-specific consumers
|
||||
// RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow
|
||||
// RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow
|
||||
// }
|
||||
// override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
// override Crypto::TPaddingType getPaddingType() {
|
||||
@@ -161,18 +162,18 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
// else result = Crypto::OtherPadding()
|
||||
// }
|
||||
// }
|
||||
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
|
||||
class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance,
|
||||
KnownOpenSslPaddingConstantAlgorithmInstance
|
||||
{
|
||||
OAEPPaddingAlgorithmInstance() {
|
||||
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP()
|
||||
OaepPaddingAlgorithmInstance() {
|
||||
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = KeyOpAlg::OAEP()
|
||||
}
|
||||
|
||||
override Crypto::HashAlgorithmInstance getOAEPEncodingHashAlgorithm() {
|
||||
override Crypto::HashAlgorithmInstance getOaepEncodingHashAlgorithm() {
|
||||
none() //TODO
|
||||
}
|
||||
|
||||
override Crypto::HashAlgorithmInstance getMGF1HashAlgorithm() {
|
||||
override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() {
|
||||
none() //TODO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmIns
|
||||
none()
|
||||
}
|
||||
|
||||
override KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
override KeyOpAlg::AlgorithmType getAlgorithmType() {
|
||||
knownOpenSslConstantToSignatureFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToSignatureFamilyType(this, _) and
|
||||
|
||||
@@ -4,10 +4,10 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
|
||||
/**
|
||||
* Cases like EVP_MD5(),
|
||||
* there is no input, rather it directly gets an algorithm
|
||||
* and returns it.
|
||||
* Also includes operations directly using an algorithm
|
||||
* A call that is considered to inherently 'consume' an algorithm value.
|
||||
* E.g., cases like EVP_MD5(),
|
||||
* where there is no input, rather it directly gets an algorithm
|
||||
* and returns it. Also includes operations directly using an algorithm
|
||||
* like AES_encrypt().
|
||||
*/
|
||||
class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanceof OpenSslAlgorithmCall
|
||||
|
||||
@@ -7,7 +7,7 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmI
|
||||
abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
/**
|
||||
* EVP_Q_Digest directly consumes algorithm constant values
|
||||
* An EVP_Q_Digest directly consumes algorithm constant values
|
||||
*/
|
||||
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
|
||||
|
||||
@@ -91,7 +91,8 @@ class Evp_Cipher_Update_Call extends EvpUpdate {
|
||||
}
|
||||
|
||||
/**
|
||||
* see: https://docs.openssl.org/master/man3/EVP_EncryptInit/#synopsis
|
||||
* The EVP Cipher operations.
|
||||
* See: https://docs.openssl.org/master/man3/EVP_EncryptInit/#synopsis
|
||||
* Base configuration for all EVP cipher operations.
|
||||
*/
|
||||
abstract class Evp_Cipher_Operation extends EvpOperation, Crypto::KeyOperationInstance {
|
||||
@@ -163,6 +164,7 @@ class Evp_Cipher_Final_Call extends EvpFinal, Evp_Cipher_Operation {
|
||||
}
|
||||
|
||||
/**
|
||||
* The EVP encryption/decryption operations.
|
||||
* https://docs.openssl.org/3.2/man3/EVP_PKEY_decrypt/
|
||||
* https://docs.openssl.org/3.2/man3/EVP_PKEY_encrypt
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@ import semmle.code.java.controlflow.Dominance
|
||||
|
||||
module JCAModel {
|
||||
import Language
|
||||
import Crypto::KeyOpAlg as KeyOpAlg
|
||||
import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
|
||||
|
||||
abstract class CipherAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer { }
|
||||
|
||||
@@ -115,7 +115,7 @@ module JCAModel {
|
||||
}
|
||||
|
||||
bindingset[name]
|
||||
Crypto::THashType hash_name_to_type_known(string name, int digestLength) {
|
||||
Crypto::HashType hash_name_to_type_known(string name, int digestLength) {
|
||||
name = "SHA-1" and result instanceof Crypto::SHA1 and digestLength = 160
|
||||
or
|
||||
name = ["SHA-256", "SHA-384", "SHA-512"] and
|
||||
@@ -152,24 +152,22 @@ module JCAModel {
|
||||
}
|
||||
|
||||
bindingset[name]
|
||||
private predicate mode_name_to_type_known(
|
||||
Crypto::TBlockCipherModeOfOperationType type, string name
|
||||
) {
|
||||
type = Crypto::ECB() and name = "ECB"
|
||||
private predicate mode_name_to_type_known(KeyOpAlg::ModeOfOperationType type, string name) {
|
||||
type = KeyOpAlg::ECB() and name = "ECB"
|
||||
or
|
||||
type = Crypto::CBC() and name = "CBC"
|
||||
type = KeyOpAlg::CBC() and name = "CBC"
|
||||
or
|
||||
type = Crypto::GCM() and name = "GCM"
|
||||
type = KeyOpAlg::GCM() and name = "GCM"
|
||||
or
|
||||
type = Crypto::CTR() and name = "CTR"
|
||||
type = KeyOpAlg::CTR() and name = "CTR"
|
||||
or
|
||||
type = Crypto::XTS() and name = "XTS"
|
||||
type = KeyOpAlg::XTS() and name = "XTS"
|
||||
or
|
||||
type = Crypto::CCM() and name = "CCM"
|
||||
type = KeyOpAlg::CCM() and name = "CCM"
|
||||
or
|
||||
type = Crypto::SIV() and name = "SIV"
|
||||
type = KeyOpAlg::SIV() and name = "SIV"
|
||||
or
|
||||
type = Crypto::OCB() and name = "OCB"
|
||||
type = KeyOpAlg::OCB() and name = "OCB"
|
||||
}
|
||||
|
||||
bindingset[name]
|
||||
@@ -182,7 +180,7 @@ module JCAModel {
|
||||
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DES())
|
||||
or
|
||||
upper = "TRIPLEDES" and
|
||||
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TripleDES())
|
||||
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
|
||||
or
|
||||
upper = "IDEA" and
|
||||
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::IDEA())
|
||||
@@ -205,8 +203,8 @@ module JCAModel {
|
||||
}
|
||||
|
||||
bindingset[name]
|
||||
predicate mac_name_to_mac_type_known(Crypto::TMACType type, string name) {
|
||||
type = Crypto::THMAC() and
|
||||
predicate mac_name_to_mac_type_known(Crypto::TMacType type, string name) {
|
||||
type = Crypto::HMAC() and
|
||||
name.toUpperCase().matches("HMAC%")
|
||||
}
|
||||
|
||||
@@ -298,18 +296,18 @@ module JCAModel {
|
||||
override string getRawPaddingAlgorithmName() { result = super.getPadding() }
|
||||
|
||||
bindingset[name]
|
||||
private predicate paddingToNameMappingKnown(Crypto::TPaddingType type, string name) {
|
||||
type instanceof Crypto::NoPadding and name = "NOPADDING"
|
||||
private predicate paddingToNameMappingKnown(KeyOpAlg::PaddingSchemeType type, string name) {
|
||||
type instanceof KeyOpAlg::NoPadding and name = "NOPADDING"
|
||||
or
|
||||
type instanceof Crypto::PKCS7 and name = ["PKCS5Padding", "PKCS7Padding"] // TODO: misnomer in the JCA?
|
||||
type instanceof KeyOpAlg::PKCS7 and name = ["PKCS5Padding", "PKCS7Padding"] // TODO: misnomer in the JCA?
|
||||
or
|
||||
type instanceof Crypto::OAEP and name.matches("OAEP%") // TODO: handle OAEPWith%
|
||||
type instanceof KeyOpAlg::OAEP and name.matches("OAEP%") // TODO: handle OAEPWith%
|
||||
}
|
||||
|
||||
override Crypto::TPaddingType getPaddingType() {
|
||||
override KeyOpAlg::PaddingSchemeType getPaddingType() {
|
||||
if this.paddingToNameMappingKnown(_, super.getPadding())
|
||||
then this.paddingToNameMappingKnown(result, super.getPadding())
|
||||
else result instanceof Crypto::OtherPadding
|
||||
else result instanceof KeyOpAlg::OtherPadding
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,10 +318,10 @@ module JCAModel {
|
||||
|
||||
override string getRawModeAlgorithmName() { result = super.getMode() }
|
||||
|
||||
override Crypto::TBlockCipherModeOfOperationType getModeType() {
|
||||
override KeyOpAlg::ModeOfOperationType getModeType() {
|
||||
if mode_name_to_type_known(_, super.getMode())
|
||||
then mode_name_to_type_known(result, super.getMode())
|
||||
else result instanceof Crypto::OtherMode
|
||||
else result instanceof KeyOpAlg::OtherMode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +345,7 @@ module JCAModel {
|
||||
|
||||
override string getRawAlgorithmName() { result = super.getValue() }
|
||||
|
||||
override KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
override KeyOpAlg::AlgorithmType getAlgorithmType() {
|
||||
if cipher_name_to_type_known(_, super.getAlgorithmName())
|
||||
then cipher_name_to_type_known(result, super.getAlgorithmName())
|
||||
else result instanceof KeyOpAlg::TUnknownKeyOperationAlgorithmType
|
||||
@@ -373,12 +371,12 @@ module JCAModel {
|
||||
oaep_padding_string_components(any(CipherStringLiteral s).getPadding(), hash, mfg)
|
||||
}
|
||||
|
||||
class OAEPPaddingHashAlgorithmInstance extends OAEPPaddingAlgorithmInstance,
|
||||
class OaepPaddingHashAlgorithmInstance extends OaepPaddingAlgorithmInstance,
|
||||
Crypto::HashAlgorithmInstance instanceof CipherStringLiteral
|
||||
{
|
||||
string hashName;
|
||||
|
||||
OAEPPaddingHashAlgorithmInstance() {
|
||||
OaepPaddingHashAlgorithmInstance() {
|
||||
oaep_padding_string_components(super.getPadding(), hashName, _)
|
||||
}
|
||||
|
||||
@@ -389,12 +387,12 @@ module JCAModel {
|
||||
override int getFixedDigestLength() { exists(hash_name_to_type_known(hashName, result)) }
|
||||
}
|
||||
|
||||
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
|
||||
class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance,
|
||||
CipherStringLiteralPaddingAlgorithmInstance
|
||||
{
|
||||
override Crypto::HashAlgorithmInstance getOAEPEncodingHashAlgorithm() { result = this }
|
||||
override Crypto::HashAlgorithmInstance getOaepEncodingHashAlgorithm() { result = this }
|
||||
|
||||
override Crypto::HashAlgorithmInstance getMGF1HashAlgorithm() { none() } // TODO
|
||||
override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() { none() } // TODO
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1156,9 +1154,7 @@ module JCAModel {
|
||||
}
|
||||
|
||||
module KeySpecInstantiationToGenerateSecretFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
exists(KeySpecInstantiation call | src.asExpr() = call)
|
||||
}
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof KeySpecInstantiation }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(SecretKeyFactoryGenerateSecretCall call | sink.asExpr() = call.getKeySpecArg())
|
||||
@@ -1207,29 +1203,29 @@ module JCAModel {
|
||||
predicate isIntermediate() { none() }
|
||||
}
|
||||
|
||||
class KDFAlgorithmStringLiteral extends Crypto::KeyDerivationAlgorithmInstance instanceof StringLiteral
|
||||
class KdfAlgorithmStringLiteral extends Crypto::KeyDerivationAlgorithmInstance instanceof StringLiteral
|
||||
{
|
||||
SecretKeyFactoryKDFAlgorithmValueConsumer consumer;
|
||||
|
||||
KDFAlgorithmStringLiteral() {
|
||||
KdfAlgorithmStringLiteral() {
|
||||
kdf_names(this.getValue()) and
|
||||
KDFAlgorithmStringToGetInstanceFlow::flow(DataFlow::exprNode(this), consumer.getInputNode())
|
||||
}
|
||||
|
||||
override string getRawKDFAlgorithmName() { result = super.getValue() }
|
||||
override string getRawKdfAlgorithmName() { result = super.getValue() }
|
||||
|
||||
override Crypto::TKeyDerivationType getKDFType() {
|
||||
override Crypto::TKeyDerivationType getKdfType() {
|
||||
result = kdf_name_to_kdf_type(super.getValue(), _)
|
||||
}
|
||||
|
||||
SecretKeyFactoryKDFAlgorithmValueConsumer getConsumer() { result = consumer }
|
||||
}
|
||||
|
||||
class PBKDF2AlgorithmStringLiteral extends KDFAlgorithmStringLiteral,
|
||||
Crypto::PBKDF2AlgorithmInstance, Crypto::HMACAlgorithmInstance, Crypto::HashAlgorithmInstance,
|
||||
class Pbkdf2AlgorithmStringLiteral extends KdfAlgorithmStringLiteral,
|
||||
Crypto::Pbkdf2AlgorithmInstance, Crypto::HmacAlgorithmInstance, Crypto::HashAlgorithmInstance,
|
||||
Crypto::AlgorithmValueConsumer
|
||||
{
|
||||
PBKDF2AlgorithmStringLiteral() { super.getKDFType() instanceof Crypto::PBKDF2 }
|
||||
Pbkdf2AlgorithmStringLiteral() { super.getKdfType() instanceof Crypto::PBKDF2 }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { none() }
|
||||
|
||||
@@ -1244,16 +1240,16 @@ module JCAModel {
|
||||
}
|
||||
|
||||
override string getRawMacAlgorithmName() {
|
||||
result = super.getRawKDFAlgorithmName().splitAt("PBKDF2With", 1)
|
||||
result = super.getRawKdfAlgorithmName().splitAt("PBKDF2With", 1)
|
||||
}
|
||||
|
||||
override string getRawHashAlgorithmName() {
|
||||
result = super.getRawKDFAlgorithmName().splitAt("WithHmac", 1)
|
||||
result = super.getRawKdfAlgorithmName().splitAt("WithHmac", 1)
|
||||
}
|
||||
|
||||
override Crypto::TMACType getMacType() { result instanceof Crypto::THMAC }
|
||||
override Crypto::MacType getMacType() { result = Crypto::HMAC() }
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getHMACAlgorithmValueConsumer() { result = this }
|
||||
override Crypto::AlgorithmValueConsumer getHmacAlgorithmValueConsumer() { result = this }
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { result = this }
|
||||
}
|
||||
@@ -1267,7 +1263,7 @@ module JCAModel {
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(KDFAlgorithmStringLiteral l | l.getConsumer() = this and result = l)
|
||||
exists(KdfAlgorithmStringLiteral l | l.getConsumer() = this and result = l)
|
||||
}
|
||||
|
||||
SecretKeyFactoryGetInstanceCall getInstantiation() { result = call }
|
||||
@@ -1442,105 +1438,103 @@ module JCAModel {
|
||||
* MACs
|
||||
*/
|
||||
|
||||
module MACKnownAlgorithmToConsumerConfig implements DataFlow::ConfigSig {
|
||||
module MacKnownAlgorithmToConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { mac_names(src.asExpr().(StringLiteral).getValue()) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MACGetInstanceCall call | sink.asExpr() = call.getAlgorithmArg())
|
||||
exists(MacGetInstanceCall call | sink.asExpr() = call.getAlgorithmArg())
|
||||
}
|
||||
}
|
||||
|
||||
module MACKnownAlgorithmToConsumerFlow = DataFlow::Global<MACKnownAlgorithmToConsumerConfig>;
|
||||
module MacKnownAlgorithmToConsumerFlow = DataFlow::Global<MacKnownAlgorithmToConsumerConfig>;
|
||||
|
||||
module MACGetInstanceToMACOperationFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof MACGetInstanceCall }
|
||||
module MacGetInstanceToMacOperationFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof MacGetInstanceCall }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MACOperationCall call | sink.asExpr() = call.(MethodCall).getQualifier()) or
|
||||
exists(MACInitCall call | sink.asExpr() = call.(MethodCall).getQualifier())
|
||||
exists(MacOperationCall call | sink.asExpr() = call.(MethodCall).getQualifier()) or
|
||||
exists(MacInitCall call | sink.asExpr() = call.(MethodCall).getQualifier())
|
||||
}
|
||||
}
|
||||
|
||||
module MACGetInstanceToMACOperationFlow =
|
||||
DataFlow::Global<MACGetInstanceToMACOperationFlowConfig>;
|
||||
module MacGetInstanceToMacOperationFlow =
|
||||
DataFlow::Global<MacGetInstanceToMacOperationFlowConfig>;
|
||||
|
||||
module MACInitCallToMACOperationFlowConfig implements DataFlow::ConfigSig {
|
||||
module MacInitCallToMacOperationFlowConfig implements DataFlow::ConfigSig {
|
||||
// TODO: use flow state with one config
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
exists(MACInitCall init | src.asExpr() = init.getQualifier())
|
||||
exists(MacInitCall init | src.asExpr() = init.getQualifier())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MACOperationCall call | sink.asExpr() = call.(MethodCall).getQualifier())
|
||||
exists(MacOperationCall call | sink.asExpr() = call.(MethodCall).getQualifier())
|
||||
}
|
||||
}
|
||||
|
||||
module MACInitCallToMACOperationFlow = DataFlow::Global<MACInitCallToMACOperationFlowConfig>;
|
||||
module MacInitCallToMacOperationFlow = DataFlow::Global<MacInitCallToMacOperationFlowConfig>;
|
||||
|
||||
class KnownMACAlgorithm extends Crypto::MACAlgorithmInstance instanceof StringLiteral {
|
||||
MACGetInstanceAlgorithmValueConsumer consumer;
|
||||
class KnownMacAlgorithm extends Crypto::MacAlgorithmInstance instanceof StringLiteral {
|
||||
MacGetInstanceAlgorithmValueConsumer consumer;
|
||||
|
||||
KnownMACAlgorithm() {
|
||||
KnownMacAlgorithm() {
|
||||
mac_names(this.getValue()) and
|
||||
MACKnownAlgorithmToConsumerFlow::flow(DataFlow::exprNode(this), consumer.getInputNode())
|
||||
MacKnownAlgorithmToConsumerFlow::flow(DataFlow::exprNode(this), consumer.getInputNode())
|
||||
}
|
||||
|
||||
MACGetInstanceAlgorithmValueConsumer getConsumer() { result = consumer }
|
||||
MacGetInstanceAlgorithmValueConsumer getConsumer() { result = consumer }
|
||||
|
||||
override string getRawMacAlgorithmName() { result = super.getValue() }
|
||||
|
||||
override Crypto::TMACType getMacType() {
|
||||
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 instanceof Crypto::TOtherMACType
|
||||
else result = Crypto::OtherMacType()
|
||||
}
|
||||
}
|
||||
|
||||
class MACGetInstanceCall extends MethodCall {
|
||||
MACGetInstanceCall() { this.getCallee().hasQualifiedName("javax.crypto", "Mac", "getInstance") }
|
||||
class MacGetInstanceCall extends MethodCall {
|
||||
MacGetInstanceCall() { this.getCallee().hasQualifiedName("javax.crypto", "Mac", "getInstance") }
|
||||
|
||||
Expr getAlgorithmArg() { result = this.getArgument(0) }
|
||||
|
||||
MACOperationCall getOperation() {
|
||||
MACGetInstanceToMACOperationFlow::flow(DataFlow::exprNode(this),
|
||||
MacOperationCall getOperation() {
|
||||
MacGetInstanceToMacOperationFlow::flow(DataFlow::exprNode(this),
|
||||
DataFlow::exprNode(result.(MethodCall).getQualifier()))
|
||||
}
|
||||
|
||||
MACInitCall getInitCall() {
|
||||
MACGetInstanceToMACOperationFlow::flow(DataFlow::exprNode(this),
|
||||
MacInitCall getInitCall() {
|
||||
MacGetInstanceToMacOperationFlow::flow(DataFlow::exprNode(this),
|
||||
DataFlow::exprNode(result.getQualifier()))
|
||||
}
|
||||
}
|
||||
|
||||
class MACInitCall extends MethodCall {
|
||||
MACInitCall() { this.getCallee().hasQualifiedName("javax.crypto", "Mac", "init") }
|
||||
class MacInitCall extends MethodCall {
|
||||
MacInitCall() { this.getCallee().hasQualifiedName("javax.crypto", "Mac", "init") }
|
||||
|
||||
Expr getKeyArg() {
|
||||
result = this.getArgument(0) and this.getMethod().getParameterType(0).hasName("Key")
|
||||
}
|
||||
|
||||
MACOperationCall getOperation() {
|
||||
MACInitCallToMACOperationFlow::flow(DataFlow::exprNode(this.getQualifier()),
|
||||
MacOperationCall getOperation() {
|
||||
MacInitCallToMacOperationFlow::flow(DataFlow::exprNode(this.getQualifier()),
|
||||
DataFlow::exprNode(result.(MethodCall).getQualifier()))
|
||||
}
|
||||
}
|
||||
|
||||
class MACGetInstanceAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer {
|
||||
MACGetInstanceCall call;
|
||||
|
||||
MACGetInstanceAlgorithmValueConsumer() { this = call.getAlgorithmArg() }
|
||||
class MacGetInstanceAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer {
|
||||
MacGetInstanceAlgorithmValueConsumer() { this = any(MacGetInstanceCall c).getAlgorithmArg() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(KnownMACAlgorithm l | l.getConsumer() = this and result = l)
|
||||
exists(KnownMacAlgorithm l | l.getConsumer() = this and result = l)
|
||||
}
|
||||
}
|
||||
|
||||
class MACOperationCall extends Crypto::MACOperationInstance instanceof MethodCall {
|
||||
class MacOperationCall extends Crypto::MacOperationInstance instanceof MethodCall {
|
||||
Expr output;
|
||||
|
||||
MACOperationCall() {
|
||||
MacOperationCall() {
|
||||
super.getMethod().getDeclaringType().hasQualifiedName("javax.crypto", "Mac") and
|
||||
(
|
||||
super.getMethod().hasStringSignature(["doFinal()", "doFinal(byte[])"]) and this = output
|
||||
@@ -1551,13 +1545,13 @@ module JCAModel {
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
exists(MACGetInstanceCall instantiation |
|
||||
exists(MacGetInstanceCall instantiation |
|
||||
instantiation.getOperation() = this and result = instantiation.getAlgorithmArg()
|
||||
)
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
|
||||
exists(MACGetInstanceCall instantiation, MACInitCall initCall |
|
||||
exists(MacGetInstanceCall instantiation, MacInitCall initCall |
|
||||
instantiation.getOperation() = this and
|
||||
initCall.getOperation() = this and
|
||||
instantiation.getInitCall() = initCall and
|
||||
@@ -1599,15 +1593,18 @@ module JCAModel {
|
||||
|
||||
override string getRawEllipticCurveName() { result = super.getValue() }
|
||||
|
||||
override Crypto::TEllipticCurveType getEllipticCurveType() {
|
||||
if Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), _, _)
|
||||
override Crypto::EllipticCurveFamilyType getEllipticCurveFamilyType() {
|
||||
if
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), _, _)
|
||||
then
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), _, result)
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), _,
|
||||
result)
|
||||
else result = Crypto::OtherEllipticCurveType()
|
||||
}
|
||||
|
||||
override int getKeySize() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), result, _)
|
||||
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getRawEllipticCurveName(),
|
||||
result, _)
|
||||
}
|
||||
|
||||
EllipticCurveAlgorithmValueConsumer getConsumer() { result = consumer }
|
||||
|
||||
@@ -7,7 +7,7 @@ import experimental.quantum.Language
|
||||
class AESGCMAlgorithmNode extends Crypto::KeyOperationAlgorithmNode {
|
||||
AESGCMAlgorithmNode() {
|
||||
this.getAlgorithmType() = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::AES()) and
|
||||
this.getModeOfOperation().getModeType() = Crypto::GCM()
|
||||
this.getModeOfOperation().getModeType() = Crypto::KeyOpAlg::GCM()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@ import java
|
||||
import experimental.quantum.Language
|
||||
|
||||
from Crypto::KeyOperationAlgorithmNode a
|
||||
where a.getAlgorithmType() instanceof Crypto::KeyOpAlg::AsymmetricCipherAlgorithm
|
||||
where a.getAlgorithmType() instanceof Crypto::KeyOpAlg::AsymmetricCipherAlgorithmType
|
||||
select a, a.getAlgorithmName()
|
||||
|
||||
@@ -13,6 +13,6 @@ import experimental.quantum.Language
|
||||
// TODO: should there be a cipher algorithm node?
|
||||
from Crypto::KeyOperationAlgorithmNode a
|
||||
where
|
||||
a.getAlgorithmType() instanceof Crypto::KeyOpAlg::AsymmetricCipherAlgorithm or
|
||||
a.getAlgorithmType() instanceof Crypto::KeyOpAlg::SymmetricCipherAlgorithm
|
||||
a.getAlgorithmType() instanceof Crypto::KeyOpAlg::AsymmetricCipherAlgorithmType or
|
||||
a.getAlgorithmType() instanceof Crypto::KeyOpAlg::SymmetricCipherAlgorithmType
|
||||
select a, a.getAlgorithmName()
|
||||
|
||||
@@ -11,5 +11,5 @@ import java
|
||||
import experimental.quantum.Language
|
||||
|
||||
from Crypto::KeyOperationAlgorithmNode a
|
||||
where a.getAlgorithmType() instanceof Crypto::KeyOpAlg::SymmetricCipherAlgorithm
|
||||
where a.getAlgorithmType() instanceof Crypto::KeyOpAlg::SymmetricCipherAlgorithmType
|
||||
select a, a.getAlgorithmName()
|
||||
|
||||
@@ -29,6 +29,8 @@ signature module InputSig<LocationSig Location> {
|
||||
}
|
||||
|
||||
module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
import Standardization::Types
|
||||
|
||||
final class LocatableElement = Input::LocatableElement;
|
||||
|
||||
final class UnknownLocation = Input::UnknownLocation;
|
||||
@@ -355,7 +357,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
* * An artifact's properties (such as being a nonce) are not necessarily inherent; they are determined by the context in which the artifact is consumed.
|
||||
* The consumer node is therefore essential in defining these properties for inputs.
|
||||
* * This approach reduces ambiguity by avoiding separate notions of "artifact source" and "consumer", as the node itself encapsulates both roles.
|
||||
* * Instances of nodes do not necessarily have to come from a consumer, allowing additional modelling of an artifact to occur outside of the consumer.
|
||||
* * Instances of nodes do not necessarily have to come from a consumer, allowing additional modeling of an artifact to occur outside of the consumer.
|
||||
*/
|
||||
abstract class ArtifactConsumer extends ConsumerElement {
|
||||
/**
|
||||
@@ -403,7 +405,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
or
|
||||
exists(KeyDerivationOperationInstance op | inputNode = op.getInputConsumer())
|
||||
or
|
||||
exists(MACOperationInstance op | inputNode = op.getMessageConsumer())
|
||||
exists(MacOperationInstance op | inputNode = op.getMessageConsumer())
|
||||
or
|
||||
exists(HashOperationInstance op | inputNode = op.getInputConsumer())
|
||||
) and
|
||||
@@ -537,7 +539,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
(
|
||||
exists(KeyOperationInstance op | inputNode = op.getKeyConsumer())
|
||||
or
|
||||
exists(MACOperationInstance op | inputNode = op.getKeyConsumer())
|
||||
exists(MacOperationInstance op | inputNode = op.getKeyConsumer())
|
||||
or
|
||||
exists(KeyAgreementSecretGenerationOperationInstance op |
|
||||
inputNode = op.getServerKeyConsumer() or
|
||||
@@ -552,192 +554,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
final override ConsumerInputDataFlowNode getInputNode() { result = inputNode }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `KeyOpAlg` module defines key operation algorithms types (e.g., symmetric ciphers, signatures, etc.)
|
||||
* and provides mapping of those types to string names and structural properties.
|
||||
*/
|
||||
module KeyOpAlg {
|
||||
/**
|
||||
* An algorithm used in key operations.
|
||||
*/
|
||||
newtype TAlgorithm =
|
||||
TSymmetricCipher(TSymmetricCipherType t) or
|
||||
TAsymmetricCipher(TAsymmetricCipherType t) or
|
||||
TSignature(TSignatureAlgorithmType t) or
|
||||
TKeyEncapsulation(TKEMAlgorithmType t) or
|
||||
TUnknownKeyOperationAlgorithmType()
|
||||
|
||||
// Parameterized algorithm types
|
||||
newtype TSymmetricCipherType =
|
||||
AES() or
|
||||
ARIA() or
|
||||
BLOWFISH() or
|
||||
CAMELLIA() or
|
||||
CAST5() or
|
||||
CHACHA20() or
|
||||
DES() or
|
||||
DESX() or
|
||||
GOST() or
|
||||
IDEA() or
|
||||
KUZNYECHIK() or
|
||||
MAGMA() or
|
||||
TripleDES() or
|
||||
DoubleDES() or
|
||||
RC2() or
|
||||
RC4() or
|
||||
RC5() or
|
||||
SEED() or
|
||||
SM4() or
|
||||
OtherSymmetricCipherType()
|
||||
|
||||
newtype TAsymmetricCipherType =
|
||||
RSA() or
|
||||
OtherAsymmetricCipherType()
|
||||
|
||||
newtype TSignatureAlgorithmType =
|
||||
DSA() or
|
||||
ECDSA() or
|
||||
EDDSA() or // e.g., ED25519 or ED448
|
||||
OtherSignatureAlgorithmType()
|
||||
|
||||
newtype TKEMAlgorithmType =
|
||||
Kyber() or
|
||||
FrodoKEM() or
|
||||
OtherKEMAlgorithmType()
|
||||
|
||||
newtype TCipherStructureType =
|
||||
Block() or
|
||||
Stream() or
|
||||
UnknownCipherStructureType()
|
||||
|
||||
class CipherStructureType extends TCipherStructureType {
|
||||
string toString() {
|
||||
result = "Block" and this = Block()
|
||||
or
|
||||
result = "Stream" and this = Stream()
|
||||
or
|
||||
result = "Unknown" and this = UnknownCipherStructureType()
|
||||
}
|
||||
}
|
||||
|
||||
predicate fixedImplicitCipherKeySize(TAlgorithm type, int size) {
|
||||
type = TSymmetricCipher(DES()) and size = 56
|
||||
or
|
||||
type = TSymmetricCipher(DESX()) and size = 184
|
||||
or
|
||||
type = TSymmetricCipher(DoubleDES()) and size = 112
|
||||
or
|
||||
type = TSymmetricCipher(TripleDES()) and size = 168
|
||||
or
|
||||
type = TSymmetricCipher(CHACHA20()) and size = 256
|
||||
or
|
||||
type = TSymmetricCipher(IDEA()) and size = 128
|
||||
or
|
||||
type = TSymmetricCipher(KUZNYECHIK()) and size = 256
|
||||
or
|
||||
type = TSymmetricCipher(MAGMA()) and size = 256
|
||||
or
|
||||
type = TSymmetricCipher(SM4()) and size = 128
|
||||
or
|
||||
type = TSymmetricCipher(SEED()) and size = 128
|
||||
}
|
||||
|
||||
predicate symmetric_cipher_to_name_and_structure(
|
||||
TSymmetricCipherType type, string name, CipherStructureType s
|
||||
) {
|
||||
type = AES() and name = "AES" and s = Block()
|
||||
or
|
||||
type = ARIA() and name = "ARIA" and s = Block()
|
||||
or
|
||||
type = BLOWFISH() and name = "Blowfish" and s = Block()
|
||||
or
|
||||
type = CAMELLIA() and name = "Camellia" and s = Block()
|
||||
or
|
||||
type = CAST5() and name = "CAST5" and s = Block()
|
||||
or
|
||||
type = CHACHA20() and name = "ChaCha20" and s = Stream()
|
||||
or
|
||||
type = DES() and name = "DES" and s = Block()
|
||||
or
|
||||
type = DESX() and name = "DESX" and s = Block()
|
||||
or
|
||||
type = GOST() and name = "GOST" and s = Block()
|
||||
or
|
||||
type = IDEA() and name = "IDEA" and s = Block()
|
||||
or
|
||||
type = KUZNYECHIK() and name = "Kuznyechik" and s = Block()
|
||||
or
|
||||
type = MAGMA() and name = "Magma" and s = Block()
|
||||
or
|
||||
type = TripleDES() and name = "TripleDES" and s = Block()
|
||||
or
|
||||
type = DoubleDES() and name = "DoubleDES" and s = Block()
|
||||
or
|
||||
type = RC2() and name = "RC2" and s = Block()
|
||||
or
|
||||
type = RC4() and name = "RC4" and s = Stream()
|
||||
or
|
||||
type = RC5() and name = "RC5" and s = Block()
|
||||
or
|
||||
type = SEED() and name = "SEED" and s = Block()
|
||||
or
|
||||
type = SM4() and name = "SM4" and s = Block()
|
||||
or
|
||||
type = OtherSymmetricCipherType() and
|
||||
name = "UnknownSymmetricCipher" and
|
||||
s = UnknownCipherStructureType()
|
||||
}
|
||||
|
||||
predicate type_to_name(Algorithm type, string name) {
|
||||
// Symmetric cipher algorithm
|
||||
symmetric_cipher_to_name_and_structure(type.(SymmetricCipherAlgorithm).getType(), name, _)
|
||||
or
|
||||
// Asymmetric cipher algorithms
|
||||
type = TAsymmetricCipher(RSA()) and name = "RSA"
|
||||
or
|
||||
type = TAsymmetricCipher(OtherAsymmetricCipherType()) and name = "UnknownAsymmetricCipher"
|
||||
or
|
||||
// Signature algorithms
|
||||
type = TSignature(DSA()) and name = "DSA"
|
||||
or
|
||||
type = TSignature(ECDSA()) and name = "ECDSA"
|
||||
or
|
||||
type = TSignature(EDDSA()) and name = "EDSA"
|
||||
or
|
||||
type = TSignature(OtherSignatureAlgorithmType()) and name = "UnknownSignature"
|
||||
or
|
||||
// Key Encapsulation Mechanisms
|
||||
type = TKeyEncapsulation(Kyber()) and name = "Kyber"
|
||||
or
|
||||
type = TKeyEncapsulation(FrodoKEM()) and name = "FrodoKEM"
|
||||
or
|
||||
type = TKeyEncapsulation(OtherKEMAlgorithmType()) and name = "UnknownKEM"
|
||||
or
|
||||
// Unknown
|
||||
type = TUnknownKeyOperationAlgorithmType() and name = "Unknown"
|
||||
}
|
||||
|
||||
class Algorithm extends TAlgorithm {
|
||||
string toString() { type_to_name(this, result) }
|
||||
}
|
||||
|
||||
class SymmetricCipherAlgorithm extends Algorithm, TSymmetricCipher {
|
||||
TSymmetricCipherType type;
|
||||
|
||||
SymmetricCipherAlgorithm() { this = TSymmetricCipher(type) }
|
||||
|
||||
TSymmetricCipherType getType() { result = type }
|
||||
}
|
||||
|
||||
class AsymmetricCipherAlgorithm extends Algorithm, TAsymmetricCipher {
|
||||
TAsymmetricCipherType type;
|
||||
|
||||
AsymmetricCipherAlgorithm() { this = TAsymmetricCipher(type) }
|
||||
|
||||
TAsymmetricCipherType getType() { result = type }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A key-based cryptographic operation instance, encompassing:
|
||||
* 1. **Ciphers**: Encryption and decryption, both symmetric and asymmetric
|
||||
@@ -836,7 +652,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
*
|
||||
* This predicate should always hold.
|
||||
*/
|
||||
abstract KeyOpAlg::Algorithm getAlgorithmType();
|
||||
abstract KeyOpAlg::AlgorithmType getAlgorithmType();
|
||||
|
||||
/**
|
||||
* Gets the mode of operation, such as "CBC", "GCM", or "ECB".
|
||||
@@ -888,19 +704,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
predicate shouldHavePaddingScheme() { any() }
|
||||
}
|
||||
|
||||
newtype TBlockCipherModeOfOperationType =
|
||||
ECB() or // Not secure, widely used
|
||||
CBC() or // Vulnerable to padding oracle attacks
|
||||
CFB() or
|
||||
GCM() or // Widely used AEAD mode (TLS 1.3, SSH, IPsec)
|
||||
CTR() or // Fast stream-like encryption (SSH, disk encryption)
|
||||
XTS() or // Standard for full-disk encryption (BitLocker, LUKS, FileVault)
|
||||
CCM() or // Used in lightweight cryptography (IoT, WPA2)
|
||||
SIV() or // Misuse-resistant encryption, used in secure storage
|
||||
OCB() or // Efficient AEAD mode
|
||||
OFB() or
|
||||
OtherMode()
|
||||
|
||||
abstract class ModeOfOperationAlgorithmInstance extends AlgorithmInstance {
|
||||
/**
|
||||
* Gets the type of this mode of operation, e.g., "ECB" or "CBC".
|
||||
@@ -909,7 +712,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
*
|
||||
* If a type cannot be determined, the result is `OtherMode`.
|
||||
*/
|
||||
abstract TBlockCipherModeOfOperationType getModeType();
|
||||
abstract KeyOpAlg::ModeOfOperationType getModeType();
|
||||
|
||||
/**
|
||||
* Gets the isolated name as it appears in source, e.g., "CBC" in "AES/CBC/PKCS7Padding".
|
||||
@@ -934,33 +737,28 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
*
|
||||
* If a type cannot be determined, the result is `OtherPadding`.
|
||||
*/
|
||||
abstract TPaddingType getPaddingType();
|
||||
abstract KeyOpAlg::PaddingSchemeType getPaddingType();
|
||||
}
|
||||
|
||||
abstract class OAEPPaddingAlgorithmInstance extends PaddingAlgorithmInstance {
|
||||
OAEPPaddingAlgorithmInstance() { this.getPaddingType() instanceof OAEP }
|
||||
abstract class OaepPaddingAlgorithmInstance extends PaddingAlgorithmInstance {
|
||||
OaepPaddingAlgorithmInstance() { this.getPaddingType() instanceof KeyOpAlg::OAEP }
|
||||
|
||||
/**
|
||||
* Gets the hash algorithm used in this padding scheme.
|
||||
*/
|
||||
abstract HashAlgorithmInstance getOAEPEncodingHashAlgorithm();
|
||||
abstract HashAlgorithmInstance getOaepEncodingHashAlgorithm();
|
||||
|
||||
/**
|
||||
* Gets the hash algorithm used by MGF1 (assumption: MGF1 is the only MGF used by OAEP)
|
||||
*/
|
||||
abstract HashAlgorithmInstance getMGF1HashAlgorithm();
|
||||
abstract HashAlgorithmInstance getMgf1HashAlgorithm();
|
||||
}
|
||||
|
||||
newtype TMACType =
|
||||
THMAC() or
|
||||
TCMAC() or
|
||||
TOtherMACType()
|
||||
|
||||
abstract class MACAlgorithmInstance extends AlgorithmInstance {
|
||||
abstract class MacAlgorithmInstance extends AlgorithmInstance {
|
||||
/**
|
||||
* Gets the type of this MAC algorithm, e.g., "HMAC" or "CMAC".
|
||||
*/
|
||||
abstract TMACType getMacType();
|
||||
abstract MacType getMacType();
|
||||
|
||||
/**
|
||||
* Gets the isolated name as it appears in source, e.g., "HMAC-SHA256" in "HMAC-SHA256/UnrelatedInformation".
|
||||
@@ -970,7 +768,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
abstract string getRawMacAlgorithmName();
|
||||
}
|
||||
|
||||
abstract class MACOperationInstance extends OperationInstance {
|
||||
abstract class MacOperationInstance extends OperationInstance {
|
||||
/**
|
||||
* Gets the message input used in this operation.
|
||||
*/
|
||||
@@ -982,8 +780,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
abstract ConsumerInputDataFlowNode getKeyConsumer();
|
||||
}
|
||||
|
||||
abstract class HMACAlgorithmInstance extends MACAlgorithmInstance {
|
||||
HMACAlgorithmInstance() { this.getMacType() instanceof THMAC }
|
||||
abstract class HmacAlgorithmInstance extends MacAlgorithmInstance {
|
||||
HmacAlgorithmInstance() { this.getMacType() = HMAC() }
|
||||
|
||||
/**
|
||||
* Gets the hash algorithm used by this HMAC algorithm.
|
||||
@@ -999,7 +797,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
*/
|
||||
abstract string getRawEllipticCurveName();
|
||||
|
||||
abstract TEllipticCurveType getEllipticCurveType();
|
||||
abstract TEllipticCurveFamilyType getEllipticCurveFamilyType();
|
||||
|
||||
abstract int getKeySize();
|
||||
|
||||
@@ -1060,8 +858,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Users should not extend this class directly, but instead use
|
||||
* `KeyCreationOperationInstance` or `KeyDerivationOperationInstance`.
|
||||
* An operation that generates, derives, or loads a cryptographic key.
|
||||
*
|
||||
* Library modeling should not extend this class directly but rather extend
|
||||
* `KeyGenerationOperationInstance`, `KeyDerivationOperationInstance`, or `KeyLoadOperationInstance`.
|
||||
*/
|
||||
abstract class KeyCreationOperationInstance extends OperationInstance {
|
||||
abstract string getKeyCreationTypeDescription();
|
||||
@@ -1087,6 +887,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation that derives a key from an input password or other data.
|
||||
*/
|
||||
abstract class KeyDerivationOperationInstance extends KeyCreationOperationInstance {
|
||||
final override KeyArtifactType getOutputKeyType() { result instanceof TSymmetricKeyType }
|
||||
|
||||
@@ -1120,16 +923,16 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
/**
|
||||
* Gets the type of this key derivation algorithm, e.g., "PBKDF2" or "HKDF".
|
||||
*/
|
||||
abstract TKeyDerivationType getKDFType();
|
||||
abstract TKeyDerivationType getKdfType();
|
||||
|
||||
/**
|
||||
* Gets the isolated name as it appears in source, e.g., "PBKDF2WithHmacSHA256" in "PBKDF2WithHmacSHA256/UnrelatedInformation".
|
||||
*/
|
||||
abstract string getRawKDFAlgorithmName();
|
||||
abstract string getRawKdfAlgorithmName();
|
||||
}
|
||||
|
||||
abstract class PBKDF2AlgorithmInstance extends KeyDerivationAlgorithmInstance {
|
||||
PBKDF2AlgorithmInstance() { this.getKDFType() instanceof PBKDF2 }
|
||||
abstract class Pbkdf2AlgorithmInstance extends KeyDerivationAlgorithmInstance {
|
||||
Pbkdf2AlgorithmInstance() { this.getKdfType() instanceof PBKDF2 }
|
||||
|
||||
/**
|
||||
* Gets the HMAC algorithm used by this PBKDF2 algorithm.
|
||||
@@ -1137,11 +940,11 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
* Note: Other PRFs are not supported, as most cryptographic libraries
|
||||
* only support HMAC for PBKDF2's PRF input.
|
||||
*/
|
||||
abstract AlgorithmValueConsumer getHMACAlgorithmValueConsumer();
|
||||
abstract AlgorithmValueConsumer getHmacAlgorithmValueConsumer();
|
||||
}
|
||||
|
||||
abstract class ScryptAlgorithmInstance extends KeyDerivationAlgorithmInstance {
|
||||
ScryptAlgorithmInstance() { this.getKDFType() instanceof SCRYPT }
|
||||
ScryptAlgorithmInstance() { this.getKdfType() instanceof SCRYPT }
|
||||
|
||||
/**
|
||||
* Gets the HMAC algorithm used by this PBKDF2 algorithm.
|
||||
@@ -1149,7 +952,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
* Note: Other PRFs are not supported, as most cryptographic libraries
|
||||
* only support HMAC for PBKDF2's PRF input.
|
||||
*/
|
||||
abstract AlgorithmValueConsumer getHMACAlgorithmValueConsumer();
|
||||
abstract AlgorithmValueConsumer getHmacAlgorithmValueConsumer();
|
||||
}
|
||||
|
||||
abstract class KeyGenerationOperationInstance extends KeyCreationOperationInstance {
|
||||
@@ -1160,24 +963,14 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
final override string getKeyCreationTypeDescription() { result = "KeyLoad" }
|
||||
}
|
||||
|
||||
// Key agreement algorithms
|
||||
newtype TKeyAgreementType =
|
||||
DH() or // Diffie-Hellman
|
||||
EDH() or // Ephemeral Diffie-Hellman
|
||||
ECDH() or // Elliptic Curve Diffie-Hellman
|
||||
// NOTE: for now ESDH is considered simply EDH
|
||||
//ESDH() or // Ephemeral-Static Diffie-Hellman
|
||||
// Note: x25519 and x448 are applications of ECDH
|
||||
OtherKeyAgreementType()
|
||||
|
||||
abstract class KeyAgreementAlgorithmInstance extends AlgorithmInstance {
|
||||
abstract TKeyAgreementType getKeyAgreementType();
|
||||
|
||||
abstract string getRawKeyAgreementAlgorithmName();
|
||||
}
|
||||
|
||||
abstract class ECDHKeyAgreementAlgorithmInstance extends KeyAgreementAlgorithmInstance {
|
||||
ECDHKeyAgreementAlgorithmInstance() { this.getKeyAgreementType() instanceof ECDH }
|
||||
abstract class EcdhKeyAgreementAlgorithmInstance extends KeyAgreementAlgorithmInstance {
|
||||
EcdhKeyAgreementAlgorithmInstance() { this.getKeyAgreementType() instanceof ECDH }
|
||||
|
||||
/**
|
||||
* Gets the consumer for the elliptic curve used in the key agreement operation.
|
||||
@@ -1216,7 +1009,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
* This concept is used to model consumers that have no known source as an algorithm node.
|
||||
*
|
||||
* The `isCandidateAVCSig` predicate is used to restrict the set of consumers that expect inputs of `AlgorithmInstanceType`.
|
||||
* These "total unknown" algorithm nodes would otherwise not exist if not modelled as a consumer node.
|
||||
* These "total unknown" algorithm nodes would otherwise not exist if not modeled as a consumer node.
|
||||
*/
|
||||
module AlgorithmInstanceOrValueConsumer<
|
||||
AlgorithmInstanceType Alg, isCandidateAVCSig/1 isCandidateAVC>
|
||||
@@ -1237,58 +1030,58 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
|
||||
Alg asAlg() { result = this }
|
||||
|
||||
AlgorithmValueConsumer asAVC() { result = this and not this instanceof Alg }
|
||||
AlgorithmValueConsumer asAvc() { result = this and not this instanceof Alg }
|
||||
}
|
||||
}
|
||||
|
||||
private predicate isHashAVC(AlgorithmValueConsumer avc) {
|
||||
private predicate isHashAvc(AlgorithmValueConsumer avc) {
|
||||
exists(HashOperationInstance op | op.getAnAlgorithmValueConsumer() = avc) or
|
||||
exists(HMACAlgorithmInstance alg | avc = alg.getAConsumer())
|
||||
exists(HmacAlgorithmInstance alg | avc = alg.getAConsumer())
|
||||
}
|
||||
|
||||
private predicate isKeyOperationAlgorithmAVC(AlgorithmValueConsumer avc) {
|
||||
private predicate isKeyOperationAlgorithmAvc(AlgorithmValueConsumer avc) {
|
||||
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 isMacAvc(AlgorithmValueConsumer avc) {
|
||||
exists(MacOperationInstance op | op.getAnAlgorithmValueConsumer() = avc) or
|
||||
exists(Pbkdf2AlgorithmInstance alg | avc = alg.getHmacAlgorithmValueConsumer())
|
||||
}
|
||||
|
||||
private predicate isKeyDerivationAVC(AlgorithmValueConsumer avc) {
|
||||
private predicate isKeyDerivationAvc(AlgorithmValueConsumer avc) {
|
||||
exists(KeyDerivationOperationInstance op | op.getAnAlgorithmValueConsumer() = avc)
|
||||
}
|
||||
|
||||
private predicate isEllipticCurveAVC(AlgorithmValueConsumer avc) {
|
||||
exists(ECDHKeyAgreementAlgorithmInstance alg |
|
||||
private predicate isEllipticCurveAvc(AlgorithmValueConsumer avc) {
|
||||
exists(EcdhKeyAgreementAlgorithmInstance alg |
|
||||
avc = alg.getEllipticCurveAlgorithmValueConsumer()
|
||||
) or
|
||||
exists(KeyGenerationOperationInstance op | op.getAnAlgorithmValueConsumer() = avc)
|
||||
}
|
||||
|
||||
private predicate isKeyAgreementAVC(AlgorithmValueConsumer avc) {
|
||||
private predicate isKeyAgreementAvc(AlgorithmValueConsumer avc) {
|
||||
exists(KeyAgreementSecretGenerationOperationInstance op |
|
||||
op.getAnAlgorithmValueConsumer() = avc
|
||||
)
|
||||
}
|
||||
|
||||
final private class KeyOperationAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<KeyOperationAlgorithmInstance, isKeyOperationAlgorithmAVC/1>::Union;
|
||||
AlgorithmInstanceOrValueConsumer<KeyOperationAlgorithmInstance, isKeyOperationAlgorithmAvc/1>::Union;
|
||||
|
||||
final private class HashAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<HashAlgorithmInstance, isHashAVC/1>::Union;
|
||||
AlgorithmInstanceOrValueConsumer<HashAlgorithmInstance, isHashAvc/1>::Union;
|
||||
|
||||
final private class MACAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<MACAlgorithmInstance, isMACAVC/1>::Union;
|
||||
final private class MacAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<MacAlgorithmInstance, isMacAvc/1>::Union;
|
||||
|
||||
final private class KeyDerivationAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<KeyDerivationAlgorithmInstance, isKeyDerivationAVC/1>::Union;
|
||||
AlgorithmInstanceOrValueConsumer<KeyDerivationAlgorithmInstance, isKeyDerivationAvc/1>::Union;
|
||||
|
||||
final private class EllipticCurveInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<EllipticCurveInstance, isEllipticCurveAVC/1>::Union;
|
||||
AlgorithmInstanceOrValueConsumer<EllipticCurveInstance, isEllipticCurveAvc/1>::Union;
|
||||
|
||||
final private class KeyAgreementAlgorithmInstanceOrValueConsumer =
|
||||
AlgorithmInstanceOrValueConsumer<KeyAgreementAlgorithmInstance, isKeyAgreementAVC/1>::Union;
|
||||
AlgorithmInstanceOrValueConsumer<KeyAgreementAlgorithmInstance, isKeyAgreementAvc/1>::Union;
|
||||
|
||||
private newtype TNode =
|
||||
// Output artifacts (data that is not an operation or algorithm, e.g., a key)
|
||||
@@ -1315,17 +1108,17 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
TPaddingAlgorithm(PaddingAlgorithmInstance e) or
|
||||
// All other operations
|
||||
THashOperation(HashOperationInstance e) or
|
||||
TMACOperation(MACOperationInstance 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
|
||||
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) {
|
||||
// An element modelled as a `GenericSourceInstance` can also be modelled as a `KnownElement`
|
||||
// An element modeled as a `GenericSourceInstance` can also be modeled as a `KnownElement`
|
||||
// For example, a string literal "AES" could be a generic constant but also an algorithm instance.
|
||||
//
|
||||
// Therefore, only create generic nodes tied to instances which are not also a `KnownElement`...
|
||||
@@ -1769,17 +1562,17 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
/**
|
||||
* A MAC operation that produces a MAC value.
|
||||
*/
|
||||
final class MACOperationNode extends OperationNode, TMACOperation {
|
||||
MACOperationInstance instance;
|
||||
final class MacOperationNode extends OperationNode, TMacOperation {
|
||||
MacOperationInstance instance;
|
||||
|
||||
MACOperationNode() { this = TMACOperation(instance) }
|
||||
MacOperationNode() { this = TMacOperation(instance) }
|
||||
|
||||
final override string getInternalType() { result = "MACOperation" }
|
||||
|
||||
override LocatableElement asElement() { result = instance }
|
||||
|
||||
override predicate isCandidateAlgorithmNode(AlgorithmNode node) {
|
||||
node instanceof MACAlgorithmNode
|
||||
node instanceof MacAlgorithmNode
|
||||
}
|
||||
|
||||
MessageArtifactNode getAMessage() {
|
||||
@@ -1804,10 +1597,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
/**
|
||||
* A MAC algorithm, such as HMAC or CMAC.
|
||||
*/
|
||||
class MACAlgorithmNode extends AlgorithmNode, TMACAlgorithm {
|
||||
MACAlgorithmInstanceOrValueConsumer instance;
|
||||
class MacAlgorithmNode extends AlgorithmNode, TMacAlgorithm {
|
||||
MacAlgorithmInstanceOrValueConsumer instance;
|
||||
|
||||
MACAlgorithmNode() { this = TMACAlgorithm(instance) }
|
||||
MacAlgorithmNode() { this = TMacAlgorithm(instance) }
|
||||
|
||||
final override string getInternalType() { result = "MACAlgorithm" }
|
||||
|
||||
@@ -1817,20 +1610,15 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
result = instance.asAlg().getRawMacAlgorithmName()
|
||||
}
|
||||
|
||||
TMACType getMacType() { result = instance.asAlg().getMacType() }
|
||||
MacType getMacType() { result = instance.asAlg().getMacType() }
|
||||
|
||||
final private predicate macToNameMapping(TMACType type, string name) {
|
||||
type instanceof THMAC and
|
||||
name = "HMAC"
|
||||
}
|
||||
|
||||
override string getAlgorithmName() { this.macToNameMapping(this.getMacType(), result) }
|
||||
override string getAlgorithmName() { result = this.getMacType().toString() }
|
||||
}
|
||||
|
||||
final class HMACAlgorithmNode extends MACAlgorithmNode {
|
||||
HMACAlgorithmInstance hmacInstance;
|
||||
final class HmacAlgorithmNode extends MacAlgorithmNode {
|
||||
HmacAlgorithmInstance hmacInstance;
|
||||
|
||||
HMACAlgorithmNode() { hmacInstance = instance.asAlg() }
|
||||
HmacAlgorithmNode() { hmacInstance = instance.asAlg() }
|
||||
|
||||
NodeBase getHashAlgorithmOrUnknown() {
|
||||
result.asElement() = hmacInstance.getHashAlgorithmValueConsumer().getASource()
|
||||
@@ -1993,22 +1781,22 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
override LocatableElement asElement() { result = instance }
|
||||
|
||||
final override string getRawAlgorithmName() {
|
||||
result = instance.asAlg().getRawKDFAlgorithmName()
|
||||
result = instance.asAlg().getRawKdfAlgorithmName()
|
||||
}
|
||||
|
||||
override string getAlgorithmName() { result = this.getRawAlgorithmName() } // TODO: standardize?
|
||||
}
|
||||
|
||||
/**
|
||||
* PBKDF2 key derivation function
|
||||
* A PBKDF2 (key derivation function) algorithm node.
|
||||
*/
|
||||
class PBKDF2AlgorithmNode extends KeyDerivationAlgorithmNode {
|
||||
PBKDF2AlgorithmInstance pbkdf2Instance;
|
||||
class Pbkdf2AlgorithmNode extends KeyDerivationAlgorithmNode {
|
||||
Pbkdf2AlgorithmInstance pbkdf2Instance;
|
||||
|
||||
PBKDF2AlgorithmNode() { pbkdf2Instance = instance.asAlg() }
|
||||
Pbkdf2AlgorithmNode() { pbkdf2Instance = instance.asAlg() }
|
||||
|
||||
HMACAlgorithmNode getHMACAlgorithm() {
|
||||
result.asElement() = pbkdf2Instance.getHMACAlgorithmValueConsumer().getASource()
|
||||
HmacAlgorithmNode getHmacAlgorithm() {
|
||||
result.asElement() = pbkdf2Instance.getHmacAlgorithmValueConsumer().getASource()
|
||||
}
|
||||
|
||||
override NodeBase getChild(string key) {
|
||||
@@ -2016,12 +1804,12 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
or
|
||||
// [KNOWN_OR_UNKNOWN]
|
||||
key = "PRF" and
|
||||
if exists(this.getHMACAlgorithm()) then result = this.getHMACAlgorithm() else result = this
|
||||
if exists(this.getHmacAlgorithm()) then result = this.getHmacAlgorithm() else result = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* scrypt key derivation function
|
||||
* An SCRYPT key derivation algorithm node.
|
||||
*/
|
||||
class ScryptAlgorithmNode extends KeyDerivationAlgorithmNode {
|
||||
ScryptAlgorithmInstance scryptInstance;
|
||||
@@ -2223,7 +2011,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Block cipher modes of operation algorithms
|
||||
* A block cipher mode of operation algorithm node.
|
||||
*/
|
||||
class ModeOfOperationAlgorithmNode extends AlgorithmNode, TModeOfOperationAlgorithm {
|
||||
ModeOfOperationAlgorithmInstance instance;
|
||||
@@ -2243,42 +2031,11 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
*
|
||||
* If a type cannot be determined, the result is `OtherMode`.
|
||||
*/
|
||||
TBlockCipherModeOfOperationType getModeType() { result = instance.getModeType() }
|
||||
KeyOpAlg::ModeOfOperationType getModeType() { result = instance.getModeType() }
|
||||
|
||||
final private predicate modeToNameMapping(TBlockCipherModeOfOperationType type, string name) {
|
||||
type = ECB() and name = "ECB"
|
||||
or
|
||||
type = CBC() and name = "CBC"
|
||||
or
|
||||
type = GCM() and name = "GCM"
|
||||
or
|
||||
type = CTR() and name = "CTR"
|
||||
or
|
||||
type = XTS() and name = "XTS"
|
||||
or
|
||||
type = CCM() and name = "CCM"
|
||||
or
|
||||
type = SIV() and name = "SIV"
|
||||
or
|
||||
type = OCB() and name = "OCB"
|
||||
or
|
||||
type = CFB() and name = "CFB"
|
||||
or
|
||||
type = OFB() and name = "OFB"
|
||||
}
|
||||
|
||||
override string getAlgorithmName() { this.modeToNameMapping(this.getModeType(), result) }
|
||||
override string getAlgorithmName() { result = this.getModeType().toString() }
|
||||
}
|
||||
|
||||
newtype TPaddingType =
|
||||
PKCS1_v1_5() or // RSA encryption/signing padding
|
||||
PSS() or
|
||||
PKCS7() or // Standard block cipher padding (PKCS5 for 8-byte blocks)
|
||||
ANSI_X9_23() or // Zero-padding except last byte = padding length
|
||||
NoPadding() or // Explicit no-padding
|
||||
OAEP() or // RSA OAEP padding
|
||||
OtherPadding()
|
||||
|
||||
class PaddingAlgorithmNode extends AlgorithmNode, TPaddingAlgorithm {
|
||||
PaddingAlgorithmInstance instance;
|
||||
|
||||
@@ -2288,38 +2045,24 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
|
||||
override LocatableElement asElement() { result = instance }
|
||||
|
||||
TPaddingType getPaddingType() { result = instance.getPaddingType() }
|
||||
KeyOpAlg::PaddingSchemeType getPaddingType() { result = instance.getPaddingType() }
|
||||
|
||||
final private predicate paddingToNameMapping(TPaddingType type, string name) {
|
||||
type = ANSI_X9_23() and name = "ANSI_X9_23"
|
||||
or
|
||||
type = NoPadding() and name = "NoPadding"
|
||||
or
|
||||
type = OAEP() and name = "OAEP"
|
||||
or
|
||||
type = PKCS1_v1_5() and name = "PKCS1_v1_5"
|
||||
or
|
||||
type = PKCS7() and name = "PKCS7"
|
||||
or
|
||||
type = PSS() and name = "PSS"
|
||||
}
|
||||
|
||||
override string getAlgorithmName() { this.paddingToNameMapping(this.getPaddingType(), result) }
|
||||
override string getAlgorithmName() { result = this.getPaddingType().toString() }
|
||||
|
||||
override string getRawAlgorithmName() { result = instance.getRawPaddingAlgorithmName() }
|
||||
}
|
||||
|
||||
class OAEPPaddingAlgorithmNode extends PaddingAlgorithmNode {
|
||||
override OAEPPaddingAlgorithmInstance instance;
|
||||
override OaepPaddingAlgorithmInstance instance;
|
||||
|
||||
OAEPPaddingAlgorithmNode() { this = TPaddingAlgorithm(instance) }
|
||||
|
||||
HashAlgorithmNode getOAEPEncodingHashAlgorithm() {
|
||||
result.asElement() = instance.getOAEPEncodingHashAlgorithm()
|
||||
result.asElement() = instance.getOaepEncodingHashAlgorithm()
|
||||
}
|
||||
|
||||
HashAlgorithmNode getMGF1HashAlgorithm() {
|
||||
result.asElement() = instance.getMGF1HashAlgorithm()
|
||||
result.asElement() = instance.getMgf1HashAlgorithm()
|
||||
}
|
||||
|
||||
override NodeBase getChild(string edgeName) {
|
||||
@@ -2349,14 +2092,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
override string getInternalType() { result = "KeyOperationAlgorithm" }
|
||||
|
||||
final KeyOpAlg::CipherStructureType getSymmetricCipherStructure() {
|
||||
KeyOpAlg::symmetric_cipher_to_name_and_structure(this.getAlgorithmType()
|
||||
.(KeyOpAlg::SymmetricCipherAlgorithm)
|
||||
.getType(), _, result)
|
||||
result = this.getAlgorithmType().(KeyOpAlg::SymmetricCipherAlgorithmType).getStructureType()
|
||||
}
|
||||
|
||||
final override string getAlgorithmName() {
|
||||
KeyOpAlg::type_to_name(this.getAlgorithmType(), result)
|
||||
}
|
||||
final override string getAlgorithmName() { result = this.getAlgorithmType().toString() }
|
||||
|
||||
final override string getRawAlgorithmName() { result = instance.asAlg().getRawAlgorithmName() }
|
||||
|
||||
@@ -2366,7 +2105,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
int getKeySizeFixed() {
|
||||
result = instance.asAlg().getKeySizeFixed()
|
||||
or
|
||||
KeyOpAlg::fixedImplicitCipherKeySize(instance.asAlg().getAlgorithmType(), result)
|
||||
result = instance.asAlg().getAlgorithmType().getImplicitKeySize()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2379,7 +2118,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
/**
|
||||
* Gets the type of this key operation algorithm, e.g., "SymmetricEncryption(_)" or ""
|
||||
*/
|
||||
KeyOpAlg::Algorithm getAlgorithmType() { result = instance.asAlg().getAlgorithmType() }
|
||||
KeyOpAlg::AlgorithmType getAlgorithmType() { result = instance.asAlg().getAlgorithmType() }
|
||||
|
||||
predicate isAsymmetric() {
|
||||
this.getAlgorithmType() instanceof KeyOpAlg::TAsymmetricCipher
|
||||
@@ -2485,24 +2224,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
}
|
||||
}
|
||||
|
||||
newtype THashType =
|
||||
BLAKE2B() or
|
||||
BLAKE2S() or
|
||||
GOSTHash() or
|
||||
MD2() or
|
||||
MD4() or
|
||||
MD5() or
|
||||
MDC2() or
|
||||
POLY1305() or
|
||||
SHA1() or
|
||||
SHA2() or
|
||||
SHA3() or
|
||||
SHAKE() or
|
||||
SM3() or
|
||||
RIPEMD160() or
|
||||
WHIRLPOOL() or
|
||||
OtherHashType()
|
||||
|
||||
/**
|
||||
* A hashing algorithm that transforms variable-length input into a fixed-size hash value.
|
||||
*/
|
||||
@@ -2517,42 +2238,14 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
|
||||
override string getRawAlgorithmName() { result = instance.asAlg().getRawHashAlgorithmName() }
|
||||
|
||||
final private predicate hashTypeToNameMapping(THashType type, string name) {
|
||||
type = BLAKE2B() and name = "BLAKE2B"
|
||||
or
|
||||
type = BLAKE2S() and name = "BLAKE2S"
|
||||
or
|
||||
type = RIPEMD160() and name = "RIPEMD160"
|
||||
or
|
||||
type = MD2() and name = "MD2"
|
||||
or
|
||||
type = MD4() and name = "MD4"
|
||||
or
|
||||
type = MD5() and name = "MD5"
|
||||
or
|
||||
type = POLY1305() and name = "POLY1305"
|
||||
or
|
||||
type = SHA1() and name = "SHA1"
|
||||
or
|
||||
type = SHA2() and name = "SHA2"
|
||||
or
|
||||
type = SHA3() and name = "SHA3"
|
||||
or
|
||||
type = SHAKE() and name = "SHAKE"
|
||||
or
|
||||
type = SM3() and name = "SM3"
|
||||
or
|
||||
type = WHIRLPOOL() and name = "WHIRLPOOL"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of this hashing algorithm, e.g., MD5 or SHA.
|
||||
*
|
||||
* When modeling a new hashing algorithm, use this predicate to specify the type of the algorithm.
|
||||
*/
|
||||
THashType getHashFamily() { result = instance.asAlg().getHashFamily() }
|
||||
HashType getHashFamily() { result = instance.asAlg().getHashFamily() }
|
||||
|
||||
override string getAlgorithmName() { this.hashTypeToNameMapping(this.getHashFamily(), result) }
|
||||
override string getAlgorithmName() { result = this.getHashFamily().toString() }
|
||||
|
||||
int getDigestLength() {
|
||||
result = instance.asAlg().getFixedDigestLength() or
|
||||
@@ -2572,116 +2265,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elliptic curve algorithms
|
||||
*/
|
||||
newtype TEllipticCurveType =
|
||||
NIST() or
|
||||
SEC() or
|
||||
NUMS() or
|
||||
PRIME() or
|
||||
BRAINPOOL() or
|
||||
CURVE25519() or
|
||||
CURVE448() or
|
||||
C2() or
|
||||
SM2() or
|
||||
ES() or
|
||||
OtherEllipticCurveType()
|
||||
|
||||
private predicate isBrainpoolCurve(string curveName, int keySize) {
|
||||
// ALL BRAINPOOL CURVES
|
||||
keySize in [160, 192, 224, 256, 320, 384, 512] and
|
||||
(
|
||||
curveName = "BRAINPOOLP" + keySize + "R1"
|
||||
or
|
||||
curveName = "BRAINPOOLP" + keySize + "T1"
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isSecCurve(string curveName, int keySize) {
|
||||
// ALL SEC CURVES
|
||||
keySize in [112, 113, 128, 131, 160, 163, 192, 193, 224, 233, 239, 256, 283, 384, 409, 521, 571] and
|
||||
exists(string suff | suff in ["R1", "R2", "K1"] |
|
||||
curveName = "SECT" + keySize + suff or
|
||||
curveName = "SECP" + keySize + suff
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isC2Curve(string curveName, int keySize) {
|
||||
// ALL C2 CURVES
|
||||
keySize in [163, 176, 191, 208, 239, 272, 304, 359, 368, 431] and
|
||||
exists(string pre, string suff |
|
||||
pre in ["PNB", "ONB", "TNB"] and suff in ["V1", "V2", "V3", "V4", "V5", "W1", "R1"]
|
||||
|
|
||||
curveName = "C2" + pre + keySize + suff
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isPrimeCurve(string curveName, int keySize) {
|
||||
// ALL PRIME CURVES
|
||||
keySize in [192, 239, 256] and
|
||||
exists(string suff | suff in ["V1", "V2", "V3"] | curveName = "PRIME" + keySize + suff)
|
||||
}
|
||||
|
||||
private predicate isNumsCurve(string curveName, int keySize) {
|
||||
// ALL NUMS CURVES
|
||||
keySize in [256, 384, 512] and
|
||||
exists(string suff | suff = "T1" | curveName = "NUMSP" + keySize + suff)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `name` corresponds to a known elliptic curve.
|
||||
*
|
||||
* Note: As an exception, this predicate may be used for library modelling, as curve names are largely standardized.
|
||||
*
|
||||
* When modelling, verify that this predicate offers sufficient coverage for the library and handle edge-cases.
|
||||
*/
|
||||
bindingset[curveName]
|
||||
predicate isEllipticCurveAlgorithmName(string curveName) {
|
||||
ellipticCurveNameToKeySizeAndFamilyMapping(curveName, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Relates elliptic curve names to their key size and family.
|
||||
*
|
||||
* Note: As an exception, this predicate may be used for library modelling, as curve names are largely standardized.
|
||||
*
|
||||
* When modelling, verify that this predicate offers sufficient coverage for the library and handle edge-cases.
|
||||
*/
|
||||
bindingset[rawName]
|
||||
predicate ellipticCurveNameToKeySizeAndFamilyMapping(
|
||||
string rawName, int keySize, TEllipticCurveType curveFamily
|
||||
) {
|
||||
exists(string curveName | curveName = rawName.toUpperCase() |
|
||||
isSecCurve(curveName, keySize) and curveFamily = SEC()
|
||||
or
|
||||
isBrainpoolCurve(curveName, keySize) and curveFamily = BRAINPOOL()
|
||||
or
|
||||
isC2Curve(curveName, keySize) and curveFamily = C2()
|
||||
or
|
||||
isPrimeCurve(curveName, keySize) and curveFamily = PRIME()
|
||||
or
|
||||
isNumsCurve(curveName, keySize) and curveFamily = NUMS()
|
||||
or
|
||||
curveName = "ES256" and keySize = 256 and curveFamily = ES()
|
||||
or
|
||||
curveName = "CURVE25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
or
|
||||
curveName = "CURVE448" and keySize = 448 and curveFamily = CURVE448()
|
||||
or
|
||||
// TODO: separate these into key agreement logic or sign/verify (ECDSA / ECDH)
|
||||
// or
|
||||
// curveName = "X25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
// or
|
||||
// curveName = "ED25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
// or
|
||||
// curveName = "ED448" and keySize = 448 and curveFamily = CURVE448()
|
||||
// or
|
||||
// curveName = "X448" and keySize = 448 and curveFamily = CURVE448()
|
||||
curveName = "SM2" and keySize in [256, 512] and curveFamily = SM2()
|
||||
)
|
||||
}
|
||||
|
||||
final class EllipticCurveNode extends AlgorithmNode, TEllipticCurve {
|
||||
EllipticCurveInstanceOrValueConsumer instance;
|
||||
|
||||
@@ -2707,7 +2290,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
|
||||
override string getAlgorithmName() { result = this.getRawAlgorithmName() }
|
||||
|
||||
TEllipticCurveType getEllipticCurveType() { result = instance.asAlg().getEllipticCurveType() }
|
||||
EllipticCurveFamilyType getEllipticCurveFamilyType() {
|
||||
result = instance.asAlg().getEllipticCurveFamilyType()
|
||||
}
|
||||
|
||||
override predicate properties(string key, string value, Location location) {
|
||||
super.properties(key, value, location)
|
||||
|
||||
477
shared/quantum/codeql/quantum/experimental/Standardization.qll
Normal file
477
shared/quantum/codeql/quantum/experimental/Standardization.qll
Normal file
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* The `KeyOpAlg` module defines key operation algorithms types (e.g., symmetric ciphers, signatures, etc.)
|
||||
* and provides mapping of those types to string names and structural properties.
|
||||
*/
|
||||
module Types {
|
||||
module KeyOpAlg {
|
||||
/**
|
||||
* An algorithm used in key operations.
|
||||
*/
|
||||
newtype TAlgorithm =
|
||||
TSymmetricCipher(TSymmetricCipherType t) or
|
||||
TAsymmetricCipher(TAsymmetricCipherType t) or
|
||||
TSignature(TSignatureAlgorithmType t) or
|
||||
TKeyEncapsulation(TKemAlgorithmType t) or
|
||||
TUnknownKeyOperationAlgorithmType()
|
||||
|
||||
// Parameterized algorithm types
|
||||
newtype TSymmetricCipherType =
|
||||
AES() or
|
||||
ARIA() or
|
||||
BLOWFISH() or
|
||||
CAMELLIA() or
|
||||
CAST5() or
|
||||
CHACHA20() or
|
||||
DES() or
|
||||
DESX() or
|
||||
GOST() or
|
||||
IDEA() or
|
||||
KUZNYECHIK() or
|
||||
MAGMA() or
|
||||
TRIPLE_DES() or
|
||||
DOUBLE_DES() or
|
||||
RC2() or
|
||||
RC4() or
|
||||
RC5() or
|
||||
SEED() or
|
||||
SM4() or
|
||||
OtherSymmetricCipherType()
|
||||
|
||||
newtype TAsymmetricCipherType =
|
||||
RSA() or
|
||||
OtherAsymmetricCipherType()
|
||||
|
||||
newtype TSignatureAlgorithmType =
|
||||
DSA() or
|
||||
ECDSA() or
|
||||
EDDSA() or // e.g., ED25519 or ED448
|
||||
OtherSignatureAlgorithmType()
|
||||
|
||||
newtype TKemAlgorithmType =
|
||||
KYBER() or
|
||||
FRODO_KEM() or
|
||||
OtherKemAlgorithmType()
|
||||
|
||||
newtype TCipherStructureType =
|
||||
Block() or
|
||||
Stream() or
|
||||
UnknownCipherStructureType()
|
||||
|
||||
class CipherStructureType extends TCipherStructureType {
|
||||
string toString() {
|
||||
result = "Block" and this = Block()
|
||||
or
|
||||
result = "Stream" and this = Stream()
|
||||
or
|
||||
result = "Unknown" and this = UnknownCipherStructureType()
|
||||
}
|
||||
}
|
||||
|
||||
private predicate symmetric_cipher_to_name_and_structure(
|
||||
TSymmetricCipherType type, string name, CipherStructureType s
|
||||
) {
|
||||
type = AES() and name = "AES" and s = Block()
|
||||
or
|
||||
type = ARIA() and name = "ARIA" and s = Block()
|
||||
or
|
||||
type = BLOWFISH() and name = "Blowfish" and s = Block()
|
||||
or
|
||||
type = CAMELLIA() and name = "Camellia" and s = Block()
|
||||
or
|
||||
type = CAST5() and name = "CAST5" and s = Block()
|
||||
or
|
||||
type = CHACHA20() and name = "ChaCha20" and s = Stream()
|
||||
or
|
||||
type = DES() and name = "DES" and s = Block()
|
||||
or
|
||||
type = DESX() and name = "DESX" and s = Block()
|
||||
or
|
||||
type = GOST() and name = "GOST" and s = Block()
|
||||
or
|
||||
type = IDEA() and name = "IDEA" and s = Block()
|
||||
or
|
||||
type = KUZNYECHIK() and name = "Kuznyechik" and s = Block()
|
||||
or
|
||||
type = MAGMA() and name = "Magma" and s = Block()
|
||||
or
|
||||
type = TRIPLE_DES() and name = "TripleDES" and s = Block()
|
||||
or
|
||||
type = DOUBLE_DES() and name = "DoubleDES" and s = Block()
|
||||
or
|
||||
type = RC2() and name = "RC2" and s = Block()
|
||||
or
|
||||
type = RC4() and name = "RC4" and s = Stream()
|
||||
or
|
||||
type = RC5() and name = "RC5" and s = Block()
|
||||
or
|
||||
type = SEED() and name = "SEED" and s = Block()
|
||||
or
|
||||
type = SM4() and name = "SM4" and s = Block()
|
||||
or
|
||||
type = OtherSymmetricCipherType() and
|
||||
name = "UnknownSymmetricCipher" and
|
||||
s = UnknownCipherStructureType()
|
||||
}
|
||||
|
||||
class AlgorithmType extends TAlgorithm {
|
||||
string toString() {
|
||||
// Symmetric cipher algorithm
|
||||
symmetric_cipher_to_name_and_structure(this.(SymmetricCipherAlgorithmType).getType(),
|
||||
result, _)
|
||||
or
|
||||
// Asymmetric cipher algorithms
|
||||
this = TAsymmetricCipher(RSA()) and result = "RSA"
|
||||
or
|
||||
this = TAsymmetricCipher(OtherAsymmetricCipherType()) and result = "UnknownAsymmetricCipher"
|
||||
or
|
||||
// Signature algorithms
|
||||
this = TSignature(DSA()) and result = "DSA"
|
||||
or
|
||||
this = TSignature(ECDSA()) and result = "ECDSA"
|
||||
or
|
||||
this = TSignature(EDDSA()) and result = "EDSA"
|
||||
or
|
||||
this = TSignature(OtherSignatureAlgorithmType()) and result = "UnknownSignature"
|
||||
or
|
||||
// Key Encapsulation Mechanisms
|
||||
this = TKeyEncapsulation(KYBER()) and result = "Kyber"
|
||||
or
|
||||
this = TKeyEncapsulation(FRODO_KEM()) and result = "FrodoKEM"
|
||||
or
|
||||
this = TKeyEncapsulation(OtherKemAlgorithmType()) and result = "UnknownKEM"
|
||||
or
|
||||
// Unknown
|
||||
this = TUnknownKeyOperationAlgorithmType() and result = "Unknown"
|
||||
}
|
||||
|
||||
int getImplicitKeySize() {
|
||||
this = TSymmetricCipher(DES()) and result = 56
|
||||
or
|
||||
this = TSymmetricCipher(DESX()) and result = 184
|
||||
or
|
||||
this = TSymmetricCipher(DOUBLE_DES()) and result = 112
|
||||
or
|
||||
this = TSymmetricCipher(TRIPLE_DES()) and result = 168
|
||||
or
|
||||
this = TSymmetricCipher(CHACHA20()) and result = 256
|
||||
or
|
||||
this = TSymmetricCipher(IDEA()) and result = 128
|
||||
or
|
||||
this = TSymmetricCipher(KUZNYECHIK()) and result = 256
|
||||
or
|
||||
this = TSymmetricCipher(MAGMA()) and result = 256
|
||||
or
|
||||
this = TSymmetricCipher(SM4()) and result = 128
|
||||
or
|
||||
this = TSymmetricCipher(SEED()) and result = 128
|
||||
}
|
||||
}
|
||||
|
||||
class SymmetricCipherAlgorithmType extends AlgorithmType, TSymmetricCipher {
|
||||
TSymmetricCipherType type;
|
||||
|
||||
SymmetricCipherAlgorithmType() { this = TSymmetricCipher(type) }
|
||||
|
||||
TSymmetricCipherType getType() { result = type }
|
||||
|
||||
TCipherStructureType getStructureType() {
|
||||
symmetric_cipher_to_name_and_structure(type, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
class AsymmetricCipherAlgorithmType extends AlgorithmType, TAsymmetricCipher {
|
||||
TAsymmetricCipherType type;
|
||||
|
||||
AsymmetricCipherAlgorithmType() { this = TAsymmetricCipher(type) }
|
||||
|
||||
TAsymmetricCipherType getType() { result = type }
|
||||
}
|
||||
|
||||
newtype TModeOfOperationType =
|
||||
ECB() or // Not secure, widely used
|
||||
CBC() or // Vulnerable to padding oracle attacks
|
||||
CFB() or
|
||||
GCM() or // Widely used AEAD mode (TLS 1.3, SSH, IPsec)
|
||||
CTR() or // Fast stream-like encryption (SSH, disk encryption)
|
||||
XTS() or // Standard for full-disk encryption (BitLocker, LUKS, FileVault)
|
||||
CCM() or // Used in lightweight cryptography (IoT, WPA2)
|
||||
SIV() or // Misuse-resistant encryption, used in secure storage
|
||||
OCB() or // Efficient AEAD mode
|
||||
OFB() or
|
||||
OtherMode()
|
||||
|
||||
class ModeOfOperationType extends TModeOfOperationType {
|
||||
string toString() {
|
||||
this = ECB() and result = "ECB"
|
||||
or
|
||||
this = CBC() and result = "CBC"
|
||||
or
|
||||
this = GCM() and result = "GCM"
|
||||
or
|
||||
this = CTR() and result = "CTR"
|
||||
or
|
||||
this = XTS() and result = "XTS"
|
||||
or
|
||||
this = CCM() and result = "CCM"
|
||||
or
|
||||
this = SIV() and result = "SIV"
|
||||
or
|
||||
this = OCB() and result = "OCB"
|
||||
or
|
||||
this = CFB() and result = "CFB"
|
||||
or
|
||||
this = OFB() and result = "OFB"
|
||||
}
|
||||
}
|
||||
|
||||
newtype TPaddingSchemeType =
|
||||
PKCS1_V1_5() or // RSA encryption/signing padding
|
||||
PSS() or
|
||||
PKCS7() or // Standard block cipher padding (PKCS5 for 8-byte blocks)
|
||||
ANSI_X9_23() or // Zero-padding except last byte = padding length
|
||||
NoPadding() or // Explicit no-padding
|
||||
OAEP() or // RSA OAEP padding
|
||||
OtherPadding()
|
||||
|
||||
class PaddingSchemeType extends TPaddingSchemeType {
|
||||
string toString() {
|
||||
this = ANSI_X9_23() and result = "ANSI_X9_23"
|
||||
or
|
||||
this = NoPadding() and result = "NoPadding"
|
||||
or
|
||||
this = OAEP() and result = "OAEP"
|
||||
or
|
||||
this = PKCS1_V1_5() and result = "PKCS1_v1_5"
|
||||
or
|
||||
this = PKCS7() and result = "PKCS7"
|
||||
or
|
||||
this = PSS() and result = "PSS"
|
||||
or
|
||||
this = OtherPadding() and result = "UnknownPadding"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newtype THashType =
|
||||
BLAKE2B() or
|
||||
BLAKE2S() or
|
||||
GOST_HASH() or
|
||||
MD2() or
|
||||
MD4() or
|
||||
MD5() or
|
||||
MDC2() or
|
||||
POLY1305() or
|
||||
SHA1() or
|
||||
SHA2() or
|
||||
SHA3() or
|
||||
SHAKE() or
|
||||
SM3() or
|
||||
RIPEMD160() or
|
||||
WHIRLPOOL() or
|
||||
OtherHashType()
|
||||
|
||||
class HashType extends THashType {
|
||||
final string toString() {
|
||||
this = BLAKE2B() and result = "BLAKE2B"
|
||||
or
|
||||
this = BLAKE2S() and result = "BLAKE2S"
|
||||
or
|
||||
this = RIPEMD160() and result = "RIPEMD160"
|
||||
or
|
||||
this = MD2() and result = "MD2"
|
||||
or
|
||||
this = MD4() and result = "MD4"
|
||||
or
|
||||
this = MD5() and result = "MD5"
|
||||
or
|
||||
this = POLY1305() and result = "POLY1305"
|
||||
or
|
||||
this = SHA1() and result = "SHA1"
|
||||
or
|
||||
this = SHA2() and result = "SHA2"
|
||||
or
|
||||
this = SHA3() and result = "SHA3"
|
||||
or
|
||||
this = SHAKE() and result = "SHAKE"
|
||||
or
|
||||
this = SM3() and result = "SM3"
|
||||
or
|
||||
this = WHIRLPOOL() and result = "WHIRLPOOL"
|
||||
or
|
||||
this = OtherHashType() and result = "UnknownHash"
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
EDH() or // Ephemeral Diffie-Hellman
|
||||
ECDH() or // Elliptic Curve Diffie-Hellman
|
||||
// NOTE: for now ESDH is considered simply EDH
|
||||
//ESDH() or // Ephemeral-Static Diffie-Hellman
|
||||
// Note: x25519 and x448 are applications of ECDH
|
||||
OtherKeyAgreementType()
|
||||
|
||||
class KeyAgreementType extends TKeyAgreementType {
|
||||
string toString() {
|
||||
this = DH() and result = "DH"
|
||||
or
|
||||
this = EDH() and result = "EDH"
|
||||
or
|
||||
this = ECDH() and result = "ECDH"
|
||||
or
|
||||
this = OtherKeyAgreementType() and result = "UnknownKeyAgreementType"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elliptic curve algorithms
|
||||
*/
|
||||
newtype TEllipticCurveFamilyType =
|
||||
NIST() or
|
||||
SEC() or
|
||||
NUMS() or
|
||||
PRIME() or
|
||||
BRAINPOOL() or
|
||||
CURVE25519() or
|
||||
CURVE448() or
|
||||
C2() or
|
||||
SM2() or
|
||||
ES() or
|
||||
OtherEllipticCurveType()
|
||||
|
||||
class EllipticCurveFamilyType extends TEllipticCurveFamilyType {
|
||||
string toString() {
|
||||
this = NIST() and result = "NIST"
|
||||
or
|
||||
this = SEC() and result = "SEC"
|
||||
or
|
||||
this = NUMS() and result = "NUMS"
|
||||
or
|
||||
this = PRIME() and result = "PRIME"
|
||||
or
|
||||
this = BRAINPOOL() and result = "BRAINPOOL"
|
||||
or
|
||||
this = CURVE25519() and result = "CURVE25519"
|
||||
or
|
||||
this = CURVE448() and result = "CURVE448"
|
||||
or
|
||||
this = C2() and result = "C2"
|
||||
or
|
||||
this = SM2() and result = "SM2"
|
||||
or
|
||||
this = ES() and result = "ES"
|
||||
or
|
||||
this = OtherEllipticCurveType() and result = "UnknownEllipticCurveType"
|
||||
}
|
||||
}
|
||||
|
||||
private predicate isBrainpoolCurve(string curveName, int keySize) {
|
||||
// ALL BRAINPOOL CURVES
|
||||
keySize in [160, 192, 224, 256, 320, 384, 512] and
|
||||
(
|
||||
curveName = "BRAINPOOLP" + keySize + "R1"
|
||||
or
|
||||
curveName = "BRAINPOOLP" + keySize + "T1"
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isSecCurve(string curveName, int keySize) {
|
||||
// ALL SEC CURVES
|
||||
keySize in [112, 113, 128, 131, 160, 163, 192, 193, 224, 233, 239, 256, 283, 384, 409, 521, 571] and
|
||||
exists(string suff | suff in ["R1", "R2", "K1"] |
|
||||
curveName = "SECT" + keySize + suff or
|
||||
curveName = "SECP" + keySize + suff
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isC2Curve(string curveName, int keySize) {
|
||||
// ALL C2 CURVES
|
||||
keySize in [163, 176, 191, 208, 239, 272, 304, 359, 368, 431] and
|
||||
exists(string pre, string suff |
|
||||
pre in ["PNB", "ONB", "TNB"] and suff in ["V1", "V2", "V3", "V4", "V5", "W1", "R1"]
|
||||
|
|
||||
curveName = "C2" + pre + keySize + suff
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isPrimeCurve(string curveName, int keySize) {
|
||||
// ALL PRIME CURVES
|
||||
keySize in [192, 239, 256] and
|
||||
exists(string suff | suff in ["V1", "V2", "V3"] | curveName = "PRIME" + keySize + suff)
|
||||
}
|
||||
|
||||
private predicate isNumsCurve(string curveName, int keySize) {
|
||||
// ALL NUMS CURVES
|
||||
keySize in [256, 384, 512] and
|
||||
exists(string suff | suff = "T1" | curveName = "NUMSP" + keySize + suff)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `name` corresponds to a known elliptic curve.
|
||||
*
|
||||
* Note: As an exception, this predicate may be used for library modeling, as curve names are largely standardized.
|
||||
*
|
||||
* When modeling, verify that this predicate offers sufficient coverage for the library and handle edge-cases.
|
||||
*/
|
||||
bindingset[curveName]
|
||||
predicate isEllipticCurveAlgorithmName(string curveName) {
|
||||
ellipticCurveNameToKnownKeySizeAndFamilyMapping(curveName, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Relates elliptic curve names to their key size and family.
|
||||
*
|
||||
* Note: As an exception, this predicate may be used for library modeling, as curve names are largely standardized.
|
||||
*
|
||||
* When modeling, verify that this predicate offers sufficient coverage for the library and handle edge-cases.
|
||||
*/
|
||||
bindingset[rawName]
|
||||
predicate ellipticCurveNameToKnownKeySizeAndFamilyMapping(
|
||||
string rawName, int keySize, TEllipticCurveFamilyType curveFamily
|
||||
) {
|
||||
exists(string curveName | curveName = rawName.toUpperCase() |
|
||||
isSecCurve(curveName, keySize) and curveFamily = SEC()
|
||||
or
|
||||
isBrainpoolCurve(curveName, keySize) and curveFamily = BRAINPOOL()
|
||||
or
|
||||
isC2Curve(curveName, keySize) and curveFamily = C2()
|
||||
or
|
||||
isPrimeCurve(curveName, keySize) and curveFamily = PRIME()
|
||||
or
|
||||
isNumsCurve(curveName, keySize) and curveFamily = NUMS()
|
||||
or
|
||||
curveName = "ES256" and keySize = 256 and curveFamily = ES()
|
||||
or
|
||||
curveName = "CURVE25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
or
|
||||
curveName = "CURVE448" and keySize = 448 and curveFamily = CURVE448()
|
||||
or
|
||||
// TODO: separate these into key agreement logic or sign/verify (ECDSA / ECDH)
|
||||
// or
|
||||
// curveName = "X25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
// or
|
||||
// curveName = "ED25519" and keySize = 255 and curveFamily = CURVE25519()
|
||||
// or
|
||||
// curveName = "ED448" and keySize = 448 and curveFamily = CURVE448()
|
||||
// or
|
||||
// curveName = "X448" and keySize = 448 and curveFamily = CURVE448()
|
||||
curveName = "SM2" and keySize in [256, 512] and curveFamily = SM2()
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user