-
Notifications
You must be signed in to change notification settings - Fork 2k
Quantum: Add Open Quantum Safe (OQS) provider signing model #19574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| import cpp | ||
| private import experimental.quantum.Language | ||
| private import KnownAlgorithmConstants | ||
| private import Crypto::KeyOpAlg as KeyOpAlg | ||
| private import OpenSSLAlgorithmInstanceBase | ||
| private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase | ||
| private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer | ||
| private import AlgToAVCFlow | ||
|
|
||
|
|
||
| /** | ||
| * Gets the signature algorithm type based on the normalized algorithm name. | ||
| */ | ||
| private predicate knownOpenSSLConstantToSignatureFamilyType( | ||
| KnownOpenSSLSignatureAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type | ||
| ) { | ||
| exists(string name | | ||
| name = e.getNormalizedName() and | ||
|
GrosQuildu marked this conversation as resolved.
|
||
| ( | ||
| name.matches("rsa%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA()) | ||
| or | ||
| name.matches("dsa%") and type = KeyOpAlg::TSignature(KeyOpAlg::DSA()) | ||
| or | ||
| name.matches("ecdsa%") and type = KeyOpAlg::TSignature(KeyOpAlg::ECDSA()) | ||
| or | ||
| name.matches("ed25519%") and type = KeyOpAlg::TSignature(KeyOpAlg::Ed25519()) | ||
| or | ||
| name.matches("ed448%") and type = KeyOpAlg::TSignature(KeyOpAlg::Ed448()) | ||
| // or | ||
| // name.matches("sm2%") and type = KeyOpAlg::TSignature(KeyOpAlg::SM2()) | ||
| // or | ||
| // name.matches("ml-dsa%") and type = KeyOpAlg::TSignature(KeyOpAlg::MLDSA()) | ||
| // or | ||
| // name.matches("slh-dsa%") and type = KeyOpAlg::TSignature(KeyOpAlg::SLHDSA()) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * A signature algorithm instance derived from an OpenSSL constant. | ||
| */ | ||
| class KnownOpenSSLSignatureConstantAlgorithmInstance extends OpenSSLAlgorithmInstance, | ||
Check warningCode scanning / CodeQL Acronyms should be PascalCase/camelCase. Warning
Acronyms in KnownOpenSSLSignatureConstantAlgorithmInstance should be PascalCase/camelCase.
|
||
| Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLSignatureAlgorithmConstant | ||
| { | ||
| OpenSSLAlgorithmValueConsumer getterCall; | ||
|
|
||
| KnownOpenSSLSignatureConstantAlgorithmInstance() { | ||
| // Two possibilities: | ||
| // 1) The source is a literal and flows to a getter, then we know we have an instance | ||
| // 2) The source is a KnownOpenSSLAlgorithm call, and we know we have an instance immediately from that | ||
|
|
||
|
GrosQuildu marked this conversation as resolved.
|
||
| // Possibility 1: | ||
| this instanceof Literal and | ||
| exists(DataFlow::Node src, DataFlow::Node sink | | ||
| // Sink is an argument to a signature getter call | ||
| sink = getterCall.getInputNode() and | ||
| // Source is `this` | ||
| src.asExpr() = this and | ||
| // This traces to a getter | ||
| KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) | ||
| ) | ||
| or | ||
| // Possibility 2: | ||
| this instanceof DirectAlgorithmValueConsumer and getterCall = this | ||
| } | ||
|
|
||
| override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { | ||
| none() | ||
| } | ||
|
|
||
| override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { | ||
| none() | ||
| } | ||
|
|
||
| override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() } | ||
|
|
||
| override int getKeySizeFixed() { | ||
| // this.(KnownOpenSSLSignatureAlgorithmConstant).getExplicitKeySize() = result | ||
| none() | ||
| } | ||
|
|
||
| override KeyOpAlg::Algorithm getAlgorithmType() { | ||
| knownOpenSSLConstantToSignatureFamilyType(this, result) | ||
| or | ||
| not knownOpenSSLConstantToSignatureFamilyType(this, _) and | ||
| result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType()) | ||
| } | ||
|
|
||
| override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall } | ||
Check warningCode scanning / CodeQL Acronyms should be PascalCase/camelCase. Warning
Acronyms in getAVC should be PascalCase/camelCase.
|
||
|
|
||
| override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { | ||
| // TODO: trace to any key size initializer, symmetric and asymmetric | ||
| none() | ||
| } | ||
|
|
||
| override predicate shouldHaveModeOfOperation() { | ||
| none() | ||
| } | ||
|
|
||
| override predicate shouldHavePaddingScheme() { | ||
| none() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import cpp | ||
| private import experimental.quantum.Language | ||
| private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants | ||
| private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase | ||
| private import OpenSSLAlgorithmValueConsumerBase | ||
|
|
||
| abstract class SignatureAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { } | ||
|
|
||
| class EVPSignatureAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { | ||
Check warningCode scanning / CodeQL Acronyms should be PascalCase/camelCase. Warning
Acronyms in EVPSignatureAlgorithmValueConsumer should be PascalCase/camelCase.
|
||
| DataFlow::Node valueArgNode; | ||
| DataFlow::Node resultNode; | ||
| Function consumer; | ||
Check noticeCode scanning / CodeQL Field only used in CharPred Note
Field is only used in CharPred.
|
||
|
|
||
| EVPSignatureAlgorithmValueConsumer() { | ||
| resultNode.asExpr() = this and | ||
| this.(Call).getTarget() = consumer and | ||
| ( | ||
| // EVP_SIGNATURE | ||
| consumer.getName() = "EVP_SIGNATURE_fetch" and | ||
| valueArgNode.asExpr() = this.(Call).getArgument(1) | ||
| or | ||
| consumer.getName() = "EVP_SIGNATURE_is_a" and | ||
|
GrosQuildu marked this conversation as resolved.
|
||
| valueArgNode.asExpr() = this.(Call).getArgument(1) | ||
| // EVP_PKEY_get1_DSA, DSA_SIG_new, EVP_RSA_gen | ||
| ) | ||
| } | ||
|
|
||
| override DataFlow::Node getResultNode() { result = resultNode } | ||
|
|
||
| override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode } | ||
|
|
||
| // override DataFlow::Node getInputNode() { result = valueArgNode } | ||
| override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { | ||
| exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i) | ||
| //TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to | ||
| // OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set. | ||
| } | ||
| } | ||
Check warning
Code scanning / CodeQL
Acronyms should be PascalCase/camelCase. Warning