Compare commits

...

32 Commits

Author SHA1 Message Date
Fredrik Dahlgren
a50a92673c Updated Bouncy Castle signer unit tests 2025-07-04 10:20:02 +02:00
Fredrik Dahlgren
2098a64c2a Fixed QL for QL recommendation 2025-07-04 10:18:57 +02:00
Fredrik Dahlgren
bcbd29b8e3 Updated unit tests to list graph nodes, edges, and properties 2025-07-02 16:36:53 +02:00
Fredrik Dahlgren
cdb8f91c86 Removed transient output artifact instances 2025-06-27 16:36:38 +02:00
Fredrik Dahlgren
357ae9206a Updated Bouncy Castle algorithm instances
- Signature operations are now handled by a single algorithm instance
- All key generation operations except generic EC key generation
  operations are now handled by a single algorithm instance
- Ed25519 and Ed448 key generation have the algorithm set to Ed25519 and
  Ed448 respectively
- For generic EC key generation operations the algorithm is given by the
  corresponding curve (since these could be used for either ECDSA or ECDH)
2025-06-19 10:27:51 +02:00
Fredrik Dahlgren
1e5bb5ff14 Updated tests to pass with new key generation modeling 2025-06-16 11:34:01 +02:00
Fredrik Dahlgren
80a29f91d3 Fixed QL for QL findings 2025-06-12 17:05:22 +02:00
Fredrik Dahlgren
7969bdf8ae Added test cases for Bouncy Castle block cipher modes
This commit also reorganizes the Bouncy Castle test cases into separate
sub-directories for signature and cipher modes.
2025-06-12 13:44:57 +02:00
Fredrik Dahlgren
f97be14fe7 Fixed argument to block cipher mode method being tagged as input 2025-06-12 13:44:56 +02:00
Fredrik Dahlgren
192bb7f9a9 Added support for block cipher modes 2025-06-12 13:44:56 +02:00
Fredrik Dahlgren
2eecda3501 Removed duplicate condition in Model.qll
Co-authored-by: Arthur Baars <aibaars@github.com>
2025-06-12 13:44:56 +02:00
Fredrik Dahlgren
99b4cb1b7d Fixed QL for QL findings 2025-06-12 13:44:56 +02:00
Fredrik Dahlgren
1a445b2c7e Fixed merge conflict resolution issues 2025-06-12 13:44:56 +02:00
Fredrik Dahlgren
3840e93445 Added support for HSS 2025-06-12 13:44:55 +02:00
Fredrik Dahlgren
b64fdc0418 Added BouncyCastle license file to stubs 2025-06-12 13:44:55 +02:00
Fredrik Dahlgren
eb89ee1a36 Updated BouncyCastle tests and corresponding stubs 2025-06-12 13:44:55 +02:00
Fredrik Dahlgren
653ef24f74 Added LMS and ML-DSA names to Model.qll 2025-06-12 13:44:55 +02:00
Fredrik Dahlgren
8b06c3284e Added support for EllipticCurveConsumingAlgorithm 2025-06-12 13:44:54 +02:00
Fredrik Dahlgren
0406d5c45d Added documentation for the isConsumedEllipticCurve workaround 2025-06-12 13:44:54 +02:00
Fredrik Dahlgren
f17bc7e995 Added EllipticCurveConsumingAlgorithmInstance to Model.qll
This commit adds EllipticCurveConsumingAlgorithmInstance to the shared
model, allowing us to model and graph elliptic curve algorithms.
2025-06-12 13:44:54 +02:00
Fredrik Dahlgren
4a34a5c176 Created additional stubs for ECDSA 2025-06-12 13:44:54 +02:00
Fredrik Dahlgren
b57bf9ad20 Updated signature operations test query 2025-06-12 13:44:54 +02:00
Fredrik Dahlgren
efd3266b1c Added signature input nodes to signature verify operation nodes 2025-06-12 13:44:53 +02:00
Fredrik Dahlgren
fca90b3292 Added support for BouncyCast ECDSA
This commit adds support for ECDSA. This includes tracking the
instantiated curve parameters using data flow.

It also adds SignatureArtifactInstance and SignatureOperationInstance
types to the shared model.
2025-06-12 13:44:53 +02:00
Fredrik Dahlgren
d7f1c701b2 Added unit tests for BouncyCastle EdDSA signatures and key generators 2025-06-12 13:44:53 +02:00
Fredrik Dahlgren
4aecf8b667 Added stubs for BouncyCastle EdDSA signature algorithms and key generators 2025-06-12 13:44:53 +02:00
Fredrik Dahlgren
9c602f8e38 Updated returned key sizes to be integers 2025-06-12 13:44:53 +02:00
Fredrik Dahlgren
45416d28cb Refactored algorithm instances
This commit also adds associated elliptic curves to the key generation
and key nodes.
2025-06-12 13:44:52 +02:00
Fredrik Dahlgren
d8cdd3c2d1 Added support for BouncyCastle key generation algorithms
This commit adds the `KeyGenerationOperationInstance` and
`KeyGenerationAlgorithmInstance` types to the BouncyCastle model.

It also adds data flow support from key pairs to the corresponding
public and private components.
2025-06-12 13:44:52 +02:00
Fredrik Dahlgren
e9c6c3350a Multiple bug fixes in BouncyCastle signature model 2025-06-12 13:44:52 +02:00
Fredrik Dahlgren
c588d11297 Removed unused getIntermediateUse function 2025-06-12 13:44:52 +02:00
Fredrik Dahlgren
43e5e40823 Added initial support for BouncyCastle signers 2025-06-12 13:44:51 +02:00
71 changed files with 3520 additions and 2 deletions

View File

@@ -0,0 +1,3 @@
import BouncyCastle.OperationInstances
import BouncyCastle.AlgorithmInstances
import BouncyCastle.AlgorithmValueConsumers

View File

@@ -0,0 +1,358 @@
private import java
private import experimental.quantum.Language
private import AlgorithmValueConsumers
private import OperationInstances
private import FlowAnalysis
/**
* A string literal that represents an elliptic curve name.
*/
class EllipticCurveStringLiteralInstance extends Crypto::EllipticCurveInstance instanceof StringLiteral
{
EllipticCurveStringLiteralInstance() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(super.getValue().toUpperCase(), _, _)
}
override string getRawEllipticCurveName() { result = super.getValue() }
Crypto::AlgorithmValueConsumer getConsumer() {
result = EllipticCurveStringLiteralToConsumerFlow::getConsumerFromLiteral(this, _, _)
}
override Crypto::TEllipticCurveType getEllipticCurveType() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName().toUpperCase(),
_, result)
}
override int getKeySize() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName().toUpperCase(),
result, _)
}
}
/**
* A signature algorithm instance where the algorithm is implicitly defined by
* the constructed type.
*/
class ImplicitSignatureClassInstanceExpr extends Crypto::KeyOperationAlgorithmInstance,
ImplicitAlgorithmValueConsumer instanceof ClassInstanceExpr
{
ImplicitSignatureClassInstanceExpr() { super.getConstructedType() instanceof Signers::Signer }
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
signatureNameToAlgorithmMapping(this.getRawAlgorithmName(), result)
}
override int getKeySizeFixed() {
signatureNameToKeySizeMapping(this.getRawAlgorithmName(), result)
}
override string getRawAlgorithmName() {
typeNameToRawAlgorithmNameMapping(super.getConstructedType().getName(), result)
}
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getParametersInput() { none() }
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getEllipticCurveInput() { none() }
}
/**
* A key generation algorithm instance where algorithm is a key operation (e.g.
* a signature algorithm) implicitly defined by the constructed type.
*/
class ImplicitKeyGenerationClassInstanceExpr extends Crypto::KeyOperationAlgorithmInstance,
ImplicitAlgorithmValueConsumer instanceof ClassInstanceExpr
{
ImplicitKeyGenerationClassInstanceExpr() {
super.getConstructedType() instanceof Generators::KeyGenerator and
super.getConstructedType().getName().matches(["Ed25519%", "Ed448%", "LMS%", "HSS%"])
}
override string getRawAlgorithmName() {
typeNameToRawAlgorithmNameMapping(super.getConstructedType().getName(), result)
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
generatorNameToAlgorithmMapping(this.getRawAlgorithmName(), result)
}
override int getKeySizeFixed() {
generatorNameToKeySizeMapping(this.getRawAlgorithmName(), result)
}
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getParametersInput() { none() }
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getEllipticCurveInput() { none() }
}
/**
* A block cipher used in a mode of operation. The algorithm is implicitly
* defined by the type.
*/
class BlockCipherAlgorithmInstance extends Crypto::KeyOperationAlgorithmInstance instanceof ClassInstanceExpr
{
// We track the block cipher mode here to ensure that going from the block
// cipher instance to the block cipher mode instance and back always yields
// the same instance.
//
// Since the block cipher algorithm instance is always resolved using data
// flow from the block cipher mode, we don't loose any information by
// requiring that this flow exists.
BlockCipherModeAlgorithmInstance mode;
BlockCipherAlgorithmInstance() {
super.getConstructedType() instanceof Modes::BlockCipher and
mode = BlockCipherToBlockCipherModeFlow::getBlockCipherModeFromBlockCipher(this, _, _)
}
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
if blockCipherNameToAlgorithmMapping(this.getRawAlgorithmName(), _)
then blockCipherNameToAlgorithmMapping(this.getRawAlgorithmName(), result)
else result = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::OtherSymmetricCipherType())
}
// TODO: Implement this.
override int getKeySizeFixed() { none() }
override string getRawAlgorithmName() {
typeNameToRawAlgorithmNameMapping(super.getType().getName(), result)
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { result = mode }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() {
result = BlockCipherToPaddingModeFlow::getPaddingModeFromBlockCipher(this)
}
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
// Gets a consumer of this block cipher algorithm instance.
Crypto::AlgorithmValueConsumer getConsumer() { result = mode.getBlockCipherArg() }
}
/**
* A block cipher mode instance.
*/
class BlockCipherModeAlgorithmInstance extends Crypto::ModeOfOperationAlgorithmInstance,
ImplicitAlgorithmValueConsumer instanceof ClassInstanceExpr
{
BlockCipherModeAlgorithmInstance() {
super.getConstructedType() instanceof Modes::UnpaddedBlockCipherMode
}
override string getRawModeAlgorithmName() {
result = super.getConstructedType().getName().splitAt("BlockCipher", 0)
}
override Crypto::TBlockCipherModeOfOperationType getModeType() {
if modeNameToModeTypeMapping(this.getRawModeAlgorithmName(), _)
then modeNameToModeTypeMapping(this.getRawModeAlgorithmName(), result)
else result = Crypto::OtherMode()
}
Expr getBlockCipherArg() {
exists(Expr arg |
arg = super.getAnArgument() and
arg.getType() instanceof Modes::BlockCipher and
result = arg
)
}
Crypto::AlgorithmValueConsumer getConsumer() { result = this }
}
/**
* A padding mode instance implicitly determined by the constructor.
*/
class PaddingAlgorithmInstance extends Crypto::PaddingAlgorithmInstance instanceof ClassInstanceExpr
{
PaddingAlgorithmInstance() { super.getConstructedType() instanceof Modes::PaddingMode }
override Crypto::TPaddingType getPaddingType() {
paddingNameToTypeMapping(this.getRawPaddingAlgorithmName(), result)
}
override string getRawPaddingAlgorithmName() {
result = super.getConstructedType().getName().splitAt("Padding", 0)
}
}
/**
* Private predicates mapping type names to raw names, key sizes and algorithms.
*/
bindingset[typeName]
private predicate typeNameToRawAlgorithmNameMapping(string typeName, string algorithmName) {
// Ed25519, Ed25519ph, and Ed25519ctx key generators and signers
typeName.matches("Ed25519%") and
algorithmName = "Ed25519"
or
// Ed448 and Ed448ph key generators and signers
typeName.matches("Ed448%") and
algorithmName = "Ed448"
or
// ECDSA
typeName.matches("ECDSA%") and
algorithmName = "ECDSA"
or
// DSA
typeName.matches("DSA%") and
algorithmName = "DSA"
or
// LMS
typeName.matches("LMS%") and
algorithmName = "LMS"
or
// HSS
typeName.matches("HSS%") and
algorithmName = "HSS"
or
typeName.matches("AES%") and
algorithmName = "AES"
or
typeName.matches("Aria%") and
algorithmName = "Aria"
or
typeName.matches("Blowfish%") and
algorithmName = "Blowfish"
or
typeName.matches("DES%") and
algorithmName = "DES"
or
typeName.matches("TripleDES%") and
algorithmName = "TripleDES"
}
private predicate modeNameToModeTypeMapping(
string modeName, Crypto::TBlockCipherModeOfOperationType modeType
) {
modeName = "CBC" and
modeType = Crypto::CBC()
or
modeName = "CCM" and
modeType = Crypto::CCM()
or
modeName = "CFB" and
modeType = Crypto::CFB()
or
modeName = "CTR" and
modeType = Crypto::CTR()
or
modeName = "ECB" and
modeType = Crypto::ECB()
or
modeName = "GCM" and
modeType = Crypto::GCM()
or
modeName = "OCB" and
modeType = Crypto::OCB()
or
modeName = "OFB" and
modeType = Crypto::OFB()
or
modeName = "XTS" and
modeType = Crypto::XTS()
}
private predicate paddingNameToTypeMapping(string paddingName, Crypto::TPaddingType paddingType) {
paddingName = "NoPadding" and
paddingType = Crypto::NoPadding()
or
paddingName = "PKCS7" and
paddingType = Crypto::PKCS7()
or
paddingName = "ISO10126" and
paddingType = Crypto::OtherPadding()
or
paddingName = "ZeroByte" and
paddingType = Crypto::OtherPadding()
}
private predicate signatureNameToAlgorithmMapping(
string signatureName, Crypto::KeyOpAlg::Algorithm algorithmType
) {
signatureName = "Ed25519" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed25519())
or
signatureName = "Ed448" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed448())
or
signatureName = "ECDSA" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::ECDSA())
or
signatureName = "LMS" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::LMS())
or
signatureName = "HSS" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::HSS())
}
private predicate signatureNameToKeySizeMapping(string signatureName, int keySize) {
signatureName = "Ed25519" and
keySize = 256
or
signatureName = "Ed448" and
keySize = 448
}
private predicate generatorNameToAlgorithmMapping(
string generatorName, Crypto::KeyOpAlg::Algorithm algorithmType
) {
generatorName = "Ed25519" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed25519())
or
generatorName = "Ed448" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed448())
or
generatorName = "LMS" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::LMS())
or
generatorName = "HSS" and
algorithmType = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::HSS())
}
private predicate generatorNameToKeySizeMapping(string generatorName, int keySize) {
generatorName = "Ed25519" and
keySize = 256
or
generatorName = "Ed448" and
keySize = 448
}
private predicate blockCipherNameToAlgorithmMapping(
string cipherName, Crypto::KeyOpAlg::Algorithm algorithmType
) {
cipherName = "AES" and
algorithmType = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::AES())
or
cipherName = "Aria" and
algorithmType = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::ARIA())
or
cipherName = "Blowfish" and
algorithmType = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::BLOWFISH())
or
cipherName = "DES" and
algorithmType = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::DES())
or
cipherName = "TripleDES" and
algorithmType = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::TripleDES())
}

View File

@@ -0,0 +1,47 @@
private import java
private import experimental.quantum.Language
private import AlgorithmValueConsumers
private import AlgorithmInstances
abstract class EllipticCurveAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer { }
/**
* An AVC for an elliptic curve algorithm where the algorithm is defined by an
* elliptic curve string literal.
*/
class EllipticCurveStringLiteralArg extends EllipticCurveAlgorithmValueConsumer instanceof Expr {
EllipticCurveStringLiteralArg() {
this = any(Params::ParametersInstantiation params).getAlgorithmArg()
}
override Crypto::ConsumerInputDataFlowNode getInputNode() { result.asExpr() = this }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
result.(EllipticCurveStringLiteralInstance).getConsumer() = this
}
}
/**
* An AVC representing the block cipher argument passed to an block cipher mode
* constructor.
*/
class BlockCipherAlgorithmArg extends Crypto::AlgorithmValueConsumer instanceof Expr {
BlockCipherAlgorithmArg() {
this = any(BlockCipherModeAlgorithmInstance mode).getBlockCipherArg()
}
override Crypto::ConsumerInputDataFlowNode getInputNode() { result.asExpr() = this }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
result.(BlockCipherAlgorithmInstance).getConsumer() = this
}
}
/**
* An AVC for an algorithm that is implicitly defined by the instance.
*/
abstract class ImplicitAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer {
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { result = this }
override Crypto::ConsumerInputDataFlowNode getInputNode() { none() }
}

View File

@@ -0,0 +1,590 @@
private import java
private import semmle.code.java.dataflow.DataFlow
private import experimental.quantum.Language
private import AlgorithmValueConsumers
/**
* A signature for the `getInstance()` method calls used in JCA, or direct
* constructor calls used in BouncyCastle.
*/
signature class NewCallSig instanceof Call {
/**
* Gets a parameter argument that is used to initialize the object.
*/
DataFlow::Node getParametersInput();
/**
* Gets a `ECCurve` argument that is used to initialize the object.
*/
DataFlow::Node getEllipticCurveInput();
}
signature class InitCallSig instanceof MethodCall {
/**
* Gets a parameter argument that is used to initialize the object.
*/
DataFlow::Node getParametersInput();
}
signature class UseCallSig instanceof MethodCall {
/**
* Holds if the use is not a final use, such as an `update()` call before `doFinal()`.
*/
predicate isIntermediate();
}
/**
* A generic analysis module for analyzing data flow from class instantiation,
* to `init()`, to `doOperation()` in BouncyCastle, and similar patterns in
* other libraries.
*
* Example:
* ```
* gen = new KeyGenerator(...);
* gen.init(...);
* gen.generateKeyPair(...);
* ```
*/
module NewToInitToUseFlow<NewCallSig New, InitCallSig Init, UseCallSig Use> {
private newtype TFlowState =
TUninitialized() or
TInitialized(Init call) or
TIntermediateUse(Use call)
abstract private class InitFlowState extends TFlowState {
string toString() {
this = TUninitialized() and result = "Uninitialized"
or
this = TInitialized(_) and result = "Initialized"
or
this = TIntermediateUse(_) and result = "Intermediate"
}
}
// The flow state is uninitialized if the `init` call is not yet made.
private class UninitializedFlowState extends InitFlowState, TUninitialized { }
private class InitializedFlowState extends InitFlowState, TInitialized {
Init call;
DataFlow::Node node1;
DataFlow::Node node2; // The receiver of the `init` call
InitializedFlowState() {
this = TInitialized(call) and
node2.asExpr() = call.(MethodCall).getQualifier() and
DataFlow::localFlowStep(node1, node2) and
node1 != node2
}
Init getInitCall() { result = call }
DataFlow::Node getFstNode() { result = node1 }
DataFlow::Node getSndNode() { result = node2 }
}
private class IntermediateUseState extends InitFlowState, TIntermediateUse {
Use call;
DataFlow::Node node1; // The receiver of the method call
DataFlow::Node node2;
IntermediateUseState() {
this = TIntermediateUse(call) and
call.isIntermediate() and
node1.asExpr() = call.(MethodCall).getQualifier() and
node2 = node1
}
Use getUseCall() { result = call }
DataFlow::Node getFstNode() { result = node1 }
DataFlow::Node getSndNode() { result = node2 }
}
private module NewToInitToUseConfig implements DataFlow::StateConfigSig {
class FlowState = InitFlowState;
predicate isSource(DataFlow::Node src, FlowState state) {
state instanceof UninitializedFlowState and
src.asExpr() instanceof New
or
// Needed to determine the init call from a (final) use.
src = state.(InitializedFlowState).getSndNode()
or
// Needed to determine all intermediate uses from a (final) use.
src = state.(IntermediateUseState).getSndNode()
}
// TODO: Document this, but this is intentional (to avoid cross products).
predicate isSink(DataFlow::Node sink, FlowState state) { none() }
predicate isSink(DataFlow::Node sink) {
exists(Init c | c.(MethodCall).getQualifier() = sink.asExpr())
or
exists(Use c | not c.isIntermediate() and c.(MethodCall).getQualifier() = sink.asExpr())
}
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
state1 = state1 and
(
node1 = state2.(InitializedFlowState).getFstNode() and
node2 = state2.(InitializedFlowState).getSndNode()
or
node1 = state2.(IntermediateUseState).getFstNode() and
node2 = state2.(IntermediateUseState).getSndNode()
)
}
predicate isBarrier(DataFlow::Node node, FlowState state) {
exists(Init call | node.asExpr() = call.(MethodCall).getQualifier() |
// Ensures that the receiver of a call to `init` is tracked as initialized.
not state instanceof InitializedFlowState
or
// Ensures that call tracked by the state is the last call to `init`.
state.(InitializedFlowState).getInitCall() != call
)
}
}
private module NewToInitToUseFlow = DataFlow::GlobalWithState<NewToInitToUseConfig>;
New getNewFromUse(Use use, NewToInitToUseFlow::PathNode src, NewToInitToUseFlow::PathNode sink) {
src.getNode().asExpr() = result and
sink.getNode().asExpr() = use.(MethodCall).getQualifier() and
NewToInitToUseFlow::flowPath(src, sink)
}
New getNewFromInit(Init init, NewToInitToUseFlow::PathNode src, NewToInitToUseFlow::PathNode sink) {
src.getNode().asExpr() = result and
sink.getNode().asExpr() = init.(MethodCall).getQualifier() and
NewToInitToUseFlow::flowPath(src, sink)
}
Init getInitFromNew(New new, NewToInitToUseFlow::PathNode src, NewToInitToUseFlow::PathNode sink) {
src.getNode().asExpr() = new and
sink.getNode().asExpr() = result.(MethodCall).getQualifier() and
NewToInitToUseFlow::flowPath(src, sink)
}
Init getInitFromUse(Use use, NewToInitToUseFlow::PathNode src, NewToInitToUseFlow::PathNode sink) {
src.getNode().asExpr() = result.(MethodCall).getQualifier() and
sink.getNode().asExpr() = use.(MethodCall).getQualifier() and
NewToInitToUseFlow::flowPath(src, sink)
}
predicate hasInit(Use use) { exists(getInitFromUse(use, _, _)) }
Use getAnIntermediateUseFromFinalUse(
Use final, NewToInitToUseFlow::PathNode src, NewToInitToUseFlow::PathNode sink
) {
not final.isIntermediate() and
result.isIntermediate() and
src.getNode().asExpr() = result.(MethodCall).getQualifier() and
sink.getNode().asExpr() = final.(MethodCall).getQualifier() and
NewToInitToUseFlow::flowPath(src, sink)
}
}
/**
* An `ECCurve` instance constructed by a call to either of the methods
* `X9ECParameters.getCurve()` or `ECNamedCurveParameterSpec.getCurve()`.
*/
private class CurveInstantiation extends MethodCall {
CurveInstantiation() {
this.getCallee().getDeclaringType() instanceof Params::Parameters and
this.getCallee().getName() = "getCurve"
}
DataFlow::Node getInputNode() { result.asExpr() = this.getQualifier() }
DataFlow::Node getOutputNode() { result.asExpr() = this }
}
/**
* A flow analysis module for analyzing data flow from the instantiation of a
* parameter object to an `init()` call in BouncyCastle, and similar patterns in
* other libraries.
*
* Example:
* ```
* params = new ECKeyGenerationParameters(...);
* gen = new ECKeyPairGenerator();
* gen.init(params);
* ```
*
* TODO: Rewrite using stateful data flow to track whether or not the node
* represents a parameter object or a curve.
*/
module ParametersToInitFlow<NewCallSig New, InitCallSig Init> {
private module ParametersToInitConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof New }
predicate isSink(DataFlow::Node sink) { exists(Init init | sink = init.getParametersInput()) }
/**
* Holds for parameters created from other parameters.
*
* As an example, below we want to track the flow from the `X9ECParameters`
* constructor call to the `keyPairGenerator.init()` call to be able to
* determine the curve associated with the generator.
*
* Example:
* ```
* X9ECParameters ecParams = SECNamedCurves.getByName("secp256r1");
* ECDomainParameters domainParams = new ECDomainParameters(ecParams);
* ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, ...);
* ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
* keyPairGenerator.init(keyGenParams);
* ```
*
* We also want to track flow from parameters to the `init()` call
* via a curve instantiation. E.g. via a call to `getCurve()` as follows:
*
* Example:
* ```
* X9ECParameters ecParams = SECNamedCurves.getByName("secp256r1");
* ECCurve curve = ecParams.getCurve();
* ECDomainParameters domainParams = new ECDomainParameters(curve, ...);
* ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, ...);
* ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
* keyPairGenerator.init(keyGenParams);
*/
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// Flow from a parameter node to a new parameter node.
node1.asExpr().getType() instanceof Params::Parameters and
node1 = node2.asExpr().(New).getParametersInput()
or
// Flow from a curve node to a parameter node.
node1.asExpr().getType() instanceof Params::Curve and
node1 = node2.asExpr().(New).getEllipticCurveInput()
or
// Flow from a parameter node instance to a curve node.
exists(CurveInstantiation c |
node1 = c.getInputNode() and
node2 = c.getOutputNode()
)
}
}
private module ParametersToInitFlow = DataFlow::Global<ParametersToInitConfig>;
/**
* Gets a parameter instantiation from a call to `init()`.
*/
New getParametersFromInit(
Init init, ParametersToInitFlow::PathNode src, ParametersToInitFlow::PathNode sink
) {
src.getNode().asExpr() = result and
sink.getNode() = init.getParametersInput() and
ParametersToInitFlow::flowPath(src, sink)
}
}
/**
* A model for data flow from a key pair to the public and private components of
* the key pair.
*/
class KeyAdditionalFlowSteps extends MethodCall {
KeyAdditionalFlowSteps() {
this.getCallee().getDeclaringType().getPackage().getName() = "org.bouncycastle.crypto" and
this.getCallee().getDeclaringType().getName().matches("%KeyPair") and
(
this.getCallee().getName().matches("getPublic")
or
this.getCallee().getName().matches("getPrivate")
)
}
DataFlow::Node getInputNode() { result.asExpr() = this.getQualifier() }
DataFlow::Node getOutputNode() { result.asExpr() = this }
}
/**
* A model for data flow from an ECDSA signature to the scalars r and s passed
* to `verifySignature()`. The ECDSA signature is represented as a `BigInteger`
* array, where the first element is the scalar r and the second element is the
* scalar s.
*/
class EcdsaSignatureAdditionalFlowSteps extends ArrayAccess {
EcdsaSignatureAdditionalFlowSteps() {
this.getArray().getType().getName() = "BigInteger[]" and
// It is reasonable to assume that the indices are integer literals
this.getIndexExpr().(IntegerLiteral).getValue().toInt() = [0, 1]
}
DataFlow::Node getInputNode() {
// The ECDSA signature is represented as a `BigInteger` array.
result.asExpr() = this.getArray()
}
DataFlow::Node getOutputNode() {
// r or s is the `BigInteger` element accessed by this array access.
result.asExpr() = this
}
}
predicate additionalFlowSteps(DataFlow::Node node1, DataFlow::Node node2) {
exists(KeyAdditionalFlowSteps fs |
node1 = fs.getInputNode() and
node2 = fs.getOutputNode()
)
or
exists(EcdsaSignatureAdditionalFlowSteps fs |
node1 = fs.getInputNode() and
node2 = fs.getOutputNode()
)
}
/**
* An additional flow step for a cryptographic artifact.
*/
class ArtifactAdditionalFlowStep extends AdditionalFlowInputStep {
DataFlow::Node output;
ArtifactAdditionalFlowStep() { additionalFlowSteps(this, output) }
override DataFlow::Node getOutput() { result = output }
}
module EllipticCurveStringLiteralToConsumerFlow {
/**
* A flow from a known elliptic curve name to an elliptic curve algorithm consumer.
*/
private module EllipticCurveStringLiteralToAlgorithmValueConsumerConfig implements
DataFlow::ConfigSig
{
// NOTE: We do not reference EllipticCurveStringLiteralInstance directly
// here to avoid non-monotonic recursion.
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof StringLiteral }
predicate isSink(DataFlow::Node sink) {
exists(Crypto::AlgorithmValueConsumer consumer | sink = consumer.getInputNode())
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node2.asExpr().(MethodCall).getCallee().getName() = "getCurve" and
node2.asExpr().(MethodCall).getQualifier() = node1.asExpr()
}
}
private module EllipticCurveStringLiteralToAlgorithmValueConsumerFlow =
DataFlow::Global<EllipticCurveStringLiteralToAlgorithmValueConsumerConfig>;
Crypto::AlgorithmValueConsumer getConsumerFromLiteral(
StringLiteral literal, EllipticCurveStringLiteralToAlgorithmValueConsumerFlow::PathNode src,
EllipticCurveStringLiteralToAlgorithmValueConsumerFlow::PathNode sink
) {
src.getNode().asExpr() = literal and
sink.getNode() = result.getInputNode() and
EllipticCurveStringLiteralToAlgorithmValueConsumerFlow::flowPath(src, sink)
}
}
/**
* A flow analysis module for analyzing data flow from a boolean literal to an
* argument to `init()`.
*
* This is used to determine the boolean value of `forSigning` and `encrypting`
* arguments to `init()`, which in turn determine the key operation sub type for
* the corresponding key operation instances.
*/
module BooleanLiteralToInitFlow {
/**
* A flow from a boolean literal to a method call argument.
*/
private module BooleanLiteralToInitConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof BooleanLiteral }
predicate isSink(DataFlow::Node sink) {
exists(MethodCall init | sink.asExpr() = init.getAnArgument())
}
}
private module BooleanLiteralToInitFlow = DataFlow::Global<BooleanLiteralToInitConfig>;
boolean getBooleanValue(
Expr arg, BooleanLiteralToInitFlow::PathNode src, BooleanLiteralToInitFlow::PathNode sink
) {
exists(BooleanLiteral lit |
src.getNode().asExpr() = lit and
sink.getNode().asExpr() = arg and
BooleanLiteralToInitFlow::flowPath(src, sink) and
lit.getBooleanValue() = result
)
}
predicate hasBooleanValue(
Expr arg, BooleanLiteralToInitFlow::PathNode src, BooleanLiteralToInitFlow::PathNode sink
) {
exists(getBooleanValue(arg, src, sink))
}
}
/**
* A flow analysis module for tracking block cipher modes to block cipher modes
* with padding.
*
* Example:
* ```
* CBCBlockCipher mode = new CBCBlockCipher(engine);
* PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(mode, ...);
* ```
*/
module BlockCipherModeToBlockCipherModeFlow {
/**
* A flow from a block cipher mode to a block cipher mode with padding.
*/
private module BlockCipherModeToBlockCipherModeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof
Modes::UnpaddedBlockCipherMode
}
predicate isSink(DataFlow::Node sink) {
exists(ClassInstanceExpr new |
new.getConstructedType() instanceof Modes::PaddedBlockCipherMode and
sink.asExpr() = new.getAnArgument()
)
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// Flow from a block cipher mode passed as an argument to another block cipher mode.
node2.asExpr().(ClassInstanceExpr).getConstructedType() instanceof Modes::BlockCipherMode and
node1.asExpr() = node2.asExpr().(ClassInstanceExpr).getAnArgument()
}
}
private module BlockCipherModeToBlockCipherModeFlow =
DataFlow::Global<BlockCipherModeToBlockCipherModeConfig>;
ClassInstanceExpr getUnpaddedModeFromPaddedMode(
ClassInstanceExpr padded, BlockCipherModeToBlockCipherModeFlow::PathNode src,
BlockCipherModeToBlockCipherModeFlow::PathNode sink
) {
src.getNode().asExpr() = result and
sink.getNode().asExpr() = padded.getAnArgument() and
BlockCipherModeToBlockCipherModeFlow::flowPath(src, sink)
}
ClassInstanceExpr getPaddedModeFromUnpaddedMode(
ClassInstanceExpr unpadded, BlockCipherModeToBlockCipherModeFlow::PathNode src,
BlockCipherModeToBlockCipherModeFlow::PathNode sink
) {
src.getNode().asExpr() = unpadded and
sink.getNode().asExpr() = result.getAnArgument() and
BlockCipherModeToBlockCipherModeFlow::flowPath(src, sink)
}
}
/**
* A flow analysis module for analyzing data flow from a block cipher instance
* to a corresponding block cipher mode instance.
*/
module BlockCipherToBlockCipherModeFlow {
/**
* A flow from a block cipher instance to a block cipher mode instance.
*/
private module BlockCipherToBlockCipherModeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof Modes::BlockCipher
}
predicate isSink(DataFlow::Node sink) {
exists(ClassInstanceExpr new |
new.getConstructedType() instanceof Modes::BlockCipherMode and
sink.asExpr() = new.getAnArgument()
)
}
}
private module BlockCipherToBlockCipherModeFlow =
DataFlow::Global<BlockCipherToBlockCipherModeConfig>;
ClassInstanceExpr getBlockCipherModeFromBlockCipher(
ClassInstanceExpr cipher, BlockCipherToBlockCipherModeFlow::PathNode src,
BlockCipherToBlockCipherModeFlow::PathNode sink
) {
src.getNode().asExpr() = cipher and
sink.getNode().asExpr() = result.getAnArgument() and
BlockCipherToBlockCipherModeFlow::flowPath(src, sink)
}
}
/**
* A flow analysis module for analyzing data flow from a block cipher instance
* to a corresponding padding mode instance.
*/
module BlockCipherToPaddingModeFlow {
/**
* A flow from a block cipher instance to a block cipher mode instance.
*/
private module BlockCipherToBlockCipherModeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof Modes::BlockCipher
}
predicate isSink(DataFlow::Node sink) {
exists(ClassInstanceExpr new |
new.getConstructedType() instanceof Modes::BlockCipherMode and
sink.asExpr() = new.getAnArgument()
)
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// Flow from a block cipher mode passed as an argument to another block cipher mode.
node2.asExpr().(ClassInstanceExpr).getConstructedType() instanceof Modes::BlockCipherMode and
node1.asExpr() = node2.asExpr().(ClassInstanceExpr).getAnArgument()
}
}
private module BlockCipherToBlockCipherModeFlow =
DataFlow::Global<BlockCipherToBlockCipherModeConfig>;
/**
* A flow from a padding mode instance to a block cipher mode instance.
*/
private module PaddingModeToBlockCipherModeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof Modes::PaddingMode
}
predicate isSink(DataFlow::Node sink) {
exists(ClassInstanceExpr new |
new.getConstructedType() instanceof Modes::BlockCipherMode and
sink.asExpr() = new.getAnArgument()
)
}
}
private module PaddingModeToBlockCipherModeFlow =
DataFlow::Global<PaddingModeToBlockCipherModeConfig>;
private ClassInstanceExpr getBlockCipherModeFromBlockCipher(
ClassInstanceExpr cipher, BlockCipherToBlockCipherModeFlow::PathNode src,
BlockCipherToBlockCipherModeFlow::PathNode sink
) {
src.getNode().asExpr() = cipher and
sink.getNode().asExpr() = result.getAnArgument() and
BlockCipherToBlockCipherModeFlow::flowPath(src, sink)
}
private ClassInstanceExpr getBlockCipherModeFromPaddingMode(
ClassInstanceExpr padding, PaddingModeToBlockCipherModeFlow::PathNode src,
PaddingModeToBlockCipherModeFlow::PathNode sink
) {
src.getNode().asExpr() = padding and
sink.getNode().asExpr() = result.getAnArgument() and
PaddingModeToBlockCipherModeFlow::flowPath(src, sink)
}
ClassInstanceExpr getPaddingModeFromBlockCipher(ClassInstanceExpr cipher) {
exists(ClassInstanceExpr mode |
mode = getBlockCipherModeFromBlockCipher(cipher, _, _) and
mode = getBlockCipherModeFromPaddingMode(result, _, _)
)
}
}

View File

@@ -0,0 +1,741 @@
private import java
private import experimental.quantum.Language
private import FlowAnalysis
private import AlgorithmInstances
module Params {
/**
* A model of the `Parameters` class in Bouncy Castle.
*/
class Parameters extends Class {
Parameters() {
// Matches `org.bouncycastle.crypto.params`, `org.bouncycastle.asn1.x9`, etc.
this.getPackage().getName().matches("org.bouncycastle.%") and
this.getName().matches(["%Parameter", "%Parameters", "%ParameterSpec", "ParametersWith%"])
}
}
class Curve extends Class {
Curve() {
this.getPackage().hasName("org.bouncycastle.math.ec") and
this.hasName("ECCurve")
}
}
class KeyParameters extends Parameters {
KeyParameters() {
this.getPackage()
.hasName(["org.bouncycastle.crypto.params", "org.bouncycastle.pqc.crypto.lms"]) and
this.getName().matches(["%KeyParameter", "%KeyParameters"])
}
}
/**
* A call that returns a BouncyCastle parameters object. This type is used
* to model data flow to resolve algorithm instances like elliptic curves.
*
* Examples:
* ```
* curveParams = SECNamedCurves.getByName(...);
* domainParams = new ECDomainParameters(...);
* ```
*/
class ParametersInstantiation extends Call {
ParametersInstantiation() {
// Class instantiations
this.(ConstructorCall).getConstructedType() instanceof Parameters
or
// (Static) factory methods
this.(MethodCall)
.getCallee()
.getDeclaringType()
.getPackage()
.getName()
.matches("org.bouncycastle.%") and
this.(MethodCall).getType() instanceof Parameters
}
// Can be overridden by subclasses which take a key argument.
Expr getKeyArg() { none() }
// Can be overridden by subclasses which take a nonce argument.
Expr getNonceArg() { none() }
// Can be overridden by subclasses which take a key size argument.
Expr getKeySizeArg() { none() }
// Can be overridden by subclasses which take an algorithm argument.
Expr getAlgorithmArg() { none() }
Expr getAParametersArg() {
result = this.getAnArgument() and
result.getType() instanceof Parameters
}
Expr getAnEllipticCurveArg() {
result = this.getAnArgument() and
result.getType() instanceof Curve
}
Crypto::ConsumerInputDataFlowNode getKeyConsumer() { result.asExpr() = this.getKeyArg() }
Crypto::ConsumerInputDataFlowNode getNonceConsumer() { result.asExpr() = this.getNonceArg() }
Crypto::ConsumerInputDataFlowNode getAKeySizeConsumer() {
result.asExpr() = this.getKeySizeArg()
}
Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
result.getInputNode().asExpr() = this.getAlgorithmArg()
}
DataFlow::Node getParametersInput() { result.asExpr() = this.getAParametersArg() }
DataFlow::Node getEllipticCurveInput() { result.asExpr() = this.getAnEllipticCurveArg() }
}
/**
* A named elliptic curve passed to `X9ECParameters.getCurve()`.
*/
class X9ECParametersInstantiation extends ParametersInstantiation {
X9ECParametersInstantiation() { this.(Expr).getType().getName() = "X9ECParameters" }
override Expr getAlgorithmArg() {
this.(MethodCall).getQualifier().getType().getName() = "SECNamedCurves" and
this.(MethodCall).getCallee().getName() = "getByName" and
result = this.getArgument(0)
}
}
/**
* A named elliptic curve passed to `ECNamedCurveTable.getParameterSpec()`.
*/
class ECNamedCurveParameterSpecInstantiation extends ParametersInstantiation {
ECNamedCurveParameterSpecInstantiation() {
this.(Expr).getType().getName() = "ECNamedCurveParameterSpec"
}
override Expr getAlgorithmArg() {
this.(MethodCall).getQualifier().getType().getName() = "ECNamedCurveTable" and
this.(MethodCall).getCallee().getName() = "getParameterSpec" and
result = this.getArgument(0)
}
}
/**
* An `AEADParameters` instantiation.
*
* This type is used to model data flow from a nonce to a cipher operation.
*/
class AeadParametersInstantiation extends ParametersInstantiation {
AeadParametersInstantiation() {
this.(ConstructorCall).getConstructedType().getName() = "AEADParameters"
}
override Expr getNonceArg() { result = this.(ConstructorCall).getArgument(2) }
}
/**
* A `ParametersWithIV` instantiation.
*
* This type is used to model data flow from a nonce to a cipher operation.
*/
class ParametersWithIvInstantiation extends ParametersInstantiation {
ParametersWithIvInstantiation() {
this.(ConstructorCall).getConstructedType().getName() = "ParametersWithIV"
}
override Expr getNonceArg() { result = this.(ConstructorCall).getArgument(1) }
}
/**
* A `KeyParameter` instantiation.
*
* This type is used to model data flow from a key to a cipher operation.
*/
class KeyParameterInstantiation extends ParametersInstantiation {
KeyParameterInstantiation() {
this.(ConstructorCall).getConstructedType().getName() = "KeyParameter"
}
override Expr getKeyArg() { result = this.(ConstructorCall).getArgument(0) }
}
}
/**
* Models for the signature algorithms defined by the `org.bouncycastle.crypto.signers` package.
*/
module Signers {
/**
* A model of the `Signer` class in Bouncy Castle.
*
* This class represents a BouncyCastle signer with a streaming API. For signers
* with a one-shot API, see `OneShotSigner` below.
*/
class Signer extends Class {
Signer() {
this.getPackage().getName() =
["org.bouncycastle.crypto.signers", "org.bouncycastle.pqc.crypto.lms"] and
this.getName().matches("%Signer")
}
MethodCall getAnInitCall() { result = this.getAMethodCall("init") }
MethodCall getAUseCall() {
result = this.getAMethodCall(["update", "generateSignature", "verifySignature"])
}
MethodCall getAMethodCall(string name) {
result.getCallee().hasQualifiedName(this.getPackage().getName(), this.getName(), name)
}
// Overridden by subclasses to provide the message argument.
Expr getMessageArg(MethodCall call) {
call.getCallee().getName() = "update" and
result = call.getArgument(0)
}
// Overridden by subclasses to provide the signature argument.
Expr getSignatureArg(MethodCall call) {
call.getCallee().getName() = "verifySignature" and
result = call.getArgument(0)
}
// Overridden by subclasses to provide the signature output.
Expr getSignatureOutput(MethodCall call) {
call.getCallee().getName() = "generateSignature" and
result = call
}
}
/**
* A signer with a one shot API (where the entire message is passed to either
* `generateSignature()` or `verifySignature`.).
*/
class OneShotSigner extends Signer {
OneShotSigner() { this.getName().matches(["DSASigner", "ECDSA%", "LMS%", "HSS%"]) }
override Expr getMessageArg(MethodCall call) {
// For ECDSA and LMS, the message is passed directly to `generateSignature()`.
call.getCallee().getName().matches(["generateSignature", "verifySignature"]) and
result = call.getArgument(0)
}
override Expr getSignatureArg(MethodCall call) {
// For ECDSA, r and s are passed to `verifySignature()` as separate arguments.
// For LMS, the signature is passed as a single argument in position 1.
call.getCallee().getName() = "verifySignature" and
result = call.getArgument([1, 2])
}
}
/**
* BouncyCastle algorithms are instantiated by calling the constructor of the
* corresponding class, which also represents the algorithm instance.
*/
private class SignerNewCall = ImplicitSignatureClassInstanceExpr;
/**
* The type is instantiated by a constructor call and initialized by a call to
* `init()` which takes two arguments. The first argument is a flag indicating
* whether the operation is signing data or verifying a signature, and the
* second is the key to use.
*/
private class SignerInitCall extends MethodCall {
SignerInitCall() { this = any(Signer signer).getAnInitCall() }
Expr getForSigningArg() { result = this.getArgument(0) }
Expr getKeyArg() {
this.getParametersArg().getType() instanceof Params::KeyParameters and
result = this.getParametersArg()
}
// The second argument is used to provide parameters (like the key) to the signer.
Expr getParametersArg() { result = this.getArgument(1) }
DataFlow::Node getParametersInput() { result.asExpr() = this.getParametersArg() }
}
/**
* The `update()` method is used to pass message data to the signer, and the
* `generateSignature()` or `verifySignature()` methods are used to produce or
* verify the signature, respectively.
*/
private class SignerUseCall extends MethodCall {
Signer signer;
SignerUseCall() { this = signer.getAUseCall() }
predicate isIntermediate() { this.getCallee().getName() = "update" }
Expr getMessageInput() { result = signer.getMessageArg(this) }
Expr getSignatureInput() { result = signer.getSignatureArg(this) }
Expr getSignatureOutput() { result = signer.getSignatureOutput(this) }
}
// Instantiate the flow analysis module for the `Signer` class.
private module SignerFlow = NewToInitToUseFlow<SignerNewCall, SignerInitCall, SignerUseCall>;
/**
* A signing operation instance is a call to either `update()`, `generateSignature()`,
* or `verifySignature()` on a `Signer` instance.
*/
class SignatureOperationInstance extends Crypto::SignatureOperationInstance instanceof SignerUseCall
{
SignatureOperationInstance() { not this.isIntermediate() }
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
result = SignerFlow::getNewFromUse(this, _, _)
}
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
// This is less expensive and more robust than resolving the subtype using
// dataflow from the `forSigning` argument to `init()`.
if super.getMethod().getName() = "generateSignature"
then result = Crypto::TSignMode()
else
if super.getMethod().getName() = "verifySignature"
then result = Crypto::TVerifyMode()
else result = Crypto::TUnknownKeyOperationMode()
}
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
result.asExpr() = this.getInitCall().getKeyArg()
}
override Crypto::ConsumerInputDataFlowNode getNonceConsumer() { none() }
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
// Inputs to signers with streaming APIs
result.asExpr() = this.getAnUpdateCall().getMessageInput()
or
// Inputs to signers with one shot APIs
result.asExpr() = super.getMessageInput()
}
override Crypto::ConsumerInputDataFlowNode getSignatureConsumer() {
result.asExpr() = super.getSignatureInput()
}
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
// Signature output
result.asExpr() = super.getSignatureOutput()
}
SignerInitCall getInitCall() { result = SignerFlow::getInitFromUse(this, _, _) }
SignerUseCall getAnUpdateCall() {
result = SignerFlow::getAnIntermediateUseFromFinalUse(this, _, _)
}
}
}
/**
* Models for the key generation algorithms defined by the `org.bouncycastle.crypto.generators` package.
*/
module Generators {
/**
* A model of the `KeyGenerator` and `KeyPairGenerator` classes in Bouncy Castle.
*/
class KeyGenerator extends Class {
Crypto::KeyArtifactType type;
KeyGenerator() {
this.getPackage().getName() =
["org.bouncycastle.crypto.generators", "org.bouncycastle.pqc.crypto.lms"] and
(
this.getName().matches("%KeyGenerator") and type instanceof Crypto::TSymmetricKeyType
or
this.getName().matches("%KeyPairGenerator") and type instanceof Crypto::TAsymmetricKeyType
)
}
MethodCall getAnInitCall() { result = this.getAMethodCall("init") }
MethodCall getAUseCall() { result = this.getAMethodCall(["generateKey", "generateKeyPair"]) }
MethodCall getAMethodCall(string name) {
result.getCallee().hasQualifiedName(this.getPackage().getName(), this.getName(), name)
}
Crypto::KeyArtifactType getKeyType() { result = type }
}
/**
* An asymmetric key pair.
*
* This type is used to model data flow from a key pair to the private and
* public components of the key pair.
*/
class KeyPair extends RefType {
KeyPair() {
this.getPackage().getName() = "org.bouncycastle.crypto" and
this.getName() = "%KeyPair" // `AsymmetricCipherKeyPair` or `EphemeralKeyPair`
}
MethodCall getPublicKeyCall() { result = this.getAMethodCall("getPublic") }
MethodCall getPrivateKeyCall() { result = this.getAMethodCall("getPrivate") }
MethodCall getAMethodCall(string name) {
result.getCallee().hasQualifiedName("org.bouncycastle.crypto", this.getName(), name)
}
}
/**
* BouncyCastle algorithms are instantiated by calling the constructor of the
* corresponding class, which also represents the algorithm instance.
*/
private class KeyGeneratorNewCall extends ClassInstanceExpr {
KeyGeneratorNewCall() { this.getConstructedType() instanceof KeyGenerator }
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getParametersInput() { none() }
// Used for data flow from elliptic curve string literals to the algorithm
// instance.
DataFlow::Node getEllipticCurveInput() { none() }
}
/**
* A call to a key generator `init()` method.
*
* The type is instantiated by a constructor call and initialized by a call to
* `init()` which takes a single `KeyGenerationParameters` argument.
*/
private class KeyGeneratorInitCall extends MethodCall {
KeyGeneratorInitCall() { this = any(KeyGenerator gen).getAnInitCall() }
Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
// The `KeyGenerationParameters` argument used to configure the key generator.
DataFlow::Node getParametersInput() { result.asExpr() = this.getArgument(0) }
}
/**
* A call to either `generateKey()` and `generateKeyPair()`.
*/
private class KeyGeneratorUseCall extends MethodCall {
KeyGenerator gen;
KeyGeneratorUseCall() { this = gen.getAUseCall() }
// This is used to define the `NewToInitToUse` data flow. Since key
// generators don't have `update()` methods, this is always false.
predicate isIntermediate() { none() }
Crypto::KeyArtifactType getKeyType() { result = gen.getKeyType() }
Expr getOutput() { result = this }
}
private module KeyGeneratorFlow =
NewToInitToUseFlow<KeyGeneratorNewCall, KeyGeneratorInitCall, KeyGeneratorUseCall>;
private module ParametersFlow =
ParametersToInitFlow<Params::ParametersInstantiation, KeyGeneratorInitCall>;
/**
* A key generation operation instance is a call to `generateKey()` or
* `generateKeyPair()` on a key generator defined under
* `org.bouncycastle.crypto.generators`.
*/
class KeyGenerationOperationInstance extends Crypto::KeyGenerationOperationInstance instanceof KeyGeneratorUseCall
{
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
// For most Bouncy Castle key generators, the algorithm is implicitly
// defined by the type, and so we use the constructor call to represent
// the AVC.
//
// TODO: Avoid using data flow for this and use the operation instance to
// represent the AVC and algorithm instance whenever it makes sense.
result = KeyGeneratorFlow::getNewFromUse(this, _, _)
}
override Crypto::ArtifactOutputDataFlowNode getOutputKeyArtifact() {
result.asExpr() = super.getOutput()
}
override Crypto::KeyArtifactType getOutputKeyType() { result = super.getKeyType() }
override int getKeySizeFixed() {
// Either the algorithm is a key operation algorithm or an elliptic curve.
// For elliptic curve, the key size depends on the curve, so we don't
// return anything.
result =
this.getAnAlgorithmValueConsumer()
.getAKnownAlgorithmSource()
.(Crypto::KeyOperationAlgorithmInstance)
.getKeySizeFixed()
}
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
result = KeyGeneratorFlow::getInitFromUse(this, _, _).getKeySizeConsumer()
}
Params::ParametersInstantiation getParameters() {
exists(KeyGeneratorInitCall init |
init = KeyGeneratorFlow::getInitFromUse(this, _, _) and
result = ParametersFlow::getParametersFromInit(init, _, _)
)
}
}
/**
* A generic elliptic curve key generation operation using `ECKeyPairGenerator`.
*/
class EllipticCurveKeyGenerationOperationInstance extends KeyGenerationOperationInstance instanceof KeyGeneratorUseCall
{
EllipticCurveKeyGenerationOperationInstance() {
super.getQualifier().getType().getName().matches("EC%")
}
// We attempt to resolve the elliptic curve algorithm from the
// `KeyGenerationParameters` argument to `init()`.
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
exists(KeyGeneratorInitCall init |
init = KeyGeneratorFlow::getInitFromUse(this, _, _) and
result = ParametersFlow::getParametersFromInit(init, _, _).getAnAlgorithmValueConsumer()
)
}
}
}
module Modes {
import FlowAnalysis
abstract class BlockCipherMode extends Class {
abstract MethodCall getAnInitCall();
abstract MethodCall getAUseCall();
}
/**
* An unpadded block cipher mode like CTR or GCM.
*/
class UnpaddedBlockCipherMode extends BlockCipherMode {
UnpaddedBlockCipherMode() {
this.getPackage().getName() = "org.bouncycastle.crypto.modes" and
this.getName().matches("%BlockCipher")
}
override MethodCall getAnInitCall() { result = this.getAMethodCall("init") }
override MethodCall getAUseCall() {
result =
this.getAMethodCall([
"processBlock", "processBlocks", "returnByte", "processBytes", "doFinal"
])
}
MethodCall getAMethodCall(string name) {
result.getQualifier().getType() instanceof UnpaddedBlockCipherMode and
result.getMethod().getName() = name
}
}
/**
* A block cipher padding mode, like PKCS7.
*/
class PaddingMode extends Class {
PaddingMode() {
this.getPackage().getName() = "org.bouncycastle.crypto.paddings" and
this.getName().matches("%Padding")
}
}
/**
* A block cipher mode that uses a padding scheme, like CBC.
*/
class PaddedBlockCipherMode extends BlockCipherMode {
PaddedBlockCipherMode() {
this.getPackage().getName() = "org.bouncycastle.crypto.paddings" and
this.getName() = "PaddedBufferedBlockCipher"
}
override MethodCall getAnInitCall() { result = this.getAMethodCall("init") }
override MethodCall getAUseCall() {
result =
this.getAMethodCall([
"processBlock", "processBlocks", "returnByte", "processBytes", "doFinal"
])
}
MethodCall getAMethodCall(string name) {
result.getQualifier().getType() instanceof PaddedBlockCipherMode and
result.getMethod().getName() = name
}
}
/**
* A block cipher engine, like `AESEngine`.
*/
class BlockCipher extends Class {
BlockCipher() {
this.getPackage().getName() = "org.bouncycastle.crypto.engines" and
this.getName().matches("%Engine")
}
}
/**
* A block cipher mode instantiation.
*
* This class represents both unpadded block cipher mode instantiations (like
* `GCMBlockCipher` and `CBCBlockCipher`), as well as padded block cipher mode
* instantiations (like `PaddedBufferedBlockCipher`). Both can be used to
* encrypt and decrypt data.
*/
private class BlockCipherModeNewCall extends ClassInstanceExpr {
BlockCipherModeNewCall() { this.getType() instanceof BlockCipherMode }
Crypto::AlgorithmValueConsumer getBlockCipherConsumer() {
result = this.getUnpaddedBlockCipherMode().getBlockCipherArg()
}
BlockCipherModeNewCall getUnpaddedBlockCipherMode() {
this.getConstructedType() instanceof UnpaddedBlockCipherMode and
result = this
or
this.getConstructedType() instanceof PaddedBlockCipherMode and
result = BlockCipherModeToBlockCipherModeFlow::getUnpaddedModeFromPaddedMode(this, _, _)
}
Expr getBlockCipherArg() {
exists(Expr arg |
arg = this.getAnArgument() and
arg.getType() instanceof Modes::BlockCipher and
result = arg
)
}
DataFlow::Node getParametersInput() { none() }
DataFlow::Node getEllipticCurveInput() { none() }
}
/**
* A call to a block cipher mode `init()` method.
*
* The type is instantiated by a constructor call and initialized by a call to
* `init()` which takes a single `KeyGenerationParameters` argument.
*/
private class BlockCipherModeInitCall extends MethodCall {
BlockCipherModeInitCall() { this = any(BlockCipherMode mode).getAnInitCall() }
// This is true if the mode is being initialized for encryption.
Expr getEncryptingArg() { result = this.getArgument(0) }
Crypto::KeyOperationSubtype getKeyOperationSubtype() {
// The key operation sub-type is determined by the `encrypting` argument to `init()`.
if BooleanLiteralToInitFlow::hasBooleanValue(this.getEncryptingArg(), _, _)
then
if BooleanLiteralToInitFlow::getBooleanValue(this.getEncryptingArg(), _, _) = true
then result = Crypto::TEncryptMode()
else result = Crypto::TDecryptMode()
else result = Crypto::TUnknownKeyOperationMode()
}
Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
// The `CipherParameters` argument used to configure the cipher.
DataFlow::Node getParametersInput() { result.asExpr() = this.getArgument(1) }
}
/**
* A `processX()`, `returnByte()` or `doFinal()` method call to encrypt or
* decrypt data.
*/
private class BlockCipherModeUseCall extends MethodCall {
BlockCipherModeUseCall() { this = any(BlockCipherMode mode).getAUseCall() }
predicate isIntermediate() { not this.getCallee().getName() = "doFinal" }
Expr getInput() { result = this.getArgument(0) and this.isIntermediate() }
Expr getOutput() {
this.getCallee().getName() = "processBlock" and
result = this.getArgument(2) // The `out` byte array argument.
or
this.getCallee().getName() = "processBlocks" and
result = this.getArgument(3) // The `out` byte array argument.
or
this.getCallee().getName() = "processBytes" and
result = this.getArgument(3) // The `out` byte array argument.
or
this.getCallee().getName() = "returnByte" and
result = this // The return value.
or
this.getCallee().getName() = "doFinal" and
result = this.getArgument(0) // The `out` byte array argument.
}
}
module BlockCipherModeFlow =
NewToInitToUseFlow<BlockCipherModeNewCall, BlockCipherModeInitCall, BlockCipherModeUseCall>;
module ParametersFlow =
ParametersToInitFlow<Params::ParametersInstantiation, BlockCipherModeInitCall>;
/**
* A block cipher mode operation is a call to a finalizing method (like
* `doFinal()`) on the block cipher mode instance. The encryption algorithm and
* padding mode are determined from the parameters passed to `init()`.
*/
class BlockCipherModeOperationInstance extends Crypto::KeyOperationInstance instanceof BlockCipherModeUseCall
{
BlockCipherModeOperationInstance() { not this.isIntermediate() }
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
// The class instantiation (returned by `getNewFromUse()`) represents the
// block cipher *mode* algorithm instance. Here, we need to return the
// block cipher algorithm instance which is resolved from the algorithm
// mode using data flow (in `getBlockCipherAlgorithmConsumer()`).
result = this.getNewCall().getBlockCipherConsumer()
}
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
// The key operation sub-type is determined by the `encrypting` argument to `init()`.
result = this.getInitCall().getKeyOperationSubtype()
or
not exists(this.getInitCall()) and
result = Crypto::TUnknownKeyOperationMode()
}
BlockCipherModeNewCall getNewCall() { result = BlockCipherModeFlow::getNewFromUse(this, _, _) }
BlockCipherModeInitCall getInitCall() {
result = BlockCipherModeFlow::getInitFromUse(this, _, _)
}
BlockCipherModeUseCall getAUseCall() {
result = BlockCipherModeFlow::getAnIntermediateUseFromFinalUse(this, _, _)
or
result = this
}
Params::ParametersInstantiation getParameters() {
result = ParametersFlow::getParametersFromInit(this.getInitCall(), _, _)
}
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
result.asExpr() = super.getOutput()
}
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
result.asExpr() = this.getAUseCall().getInput()
}
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
result = this.getParameters().getKeyConsumer()
}
override Crypto::ConsumerInputDataFlowNode getNonceConsumer() {
result = this.getParameters().getNonceConsumer()
}
}
}

View File

@@ -216,3 +216,4 @@ module ArtifactFlow = DataFlow::Global<ArtifactFlowConfig>;
// Import library-specific modeling
import JCA
import BouncyCastle

View File

@@ -0,0 +1,71 @@
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* Example of AES-CBC encryption and decryption using Bouncy Castle's low-level API.
*/
public class AESCBCEncryption {
byte[] encrypt(byte[] plaintext, byte[] key, byte[] iv) throws Exception {
AESEngine engine = new AESEngine();
CBCBlockCipher mode = new CBCBlockCipher(engine);
PKCS7Padding padding = new PKCS7Padding();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(mode, padding);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV params = new ParametersWithIV(keyParam, iv);
cipher.init(true, params); // true for encryption
byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)];
int outputLen = cipher.processBytes(plaintext, 0, plaintext.length, ciphertext, 0);
outputLen += cipher.doFinal(ciphertext, outputLen);
if (outputLen != ciphertext.length) {
ciphertext = Arrays.copyOf(ciphertext, outputLen);
}
return ciphertext;
}
byte[] decrypt(byte[] ciphertext, byte[] key, byte[] iv) throws Exception {
AESEngine engine = new AESEngine();
CBCBlockCipher mode = new CBCBlockCipher(engine);
PKCS7Padding padding = new PKCS7Padding();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(mode, padding);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV params = new ParametersWithIV(keyParam, iv);
cipher.init(false, params); // false for decryption
byte[] plaintext = new byte[cipher.getOutputSize(ciphertext.length)];
int outputLen = cipher.processBytes(ciphertext, 0, ciphertext.length, plaintext, 0);
outputLen += cipher.doFinal(plaintext, outputLen);
if (outputLen != plaintext.length) {
plaintext = Arrays.copyOf(plaintext, outputLen);
}
return plaintext;
}
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
SecureRandom random = new SecureRandom();
byte[] key = new byte[32];
random.nextBytes(key);
byte[] iv = new byte[16];
random.nextBytes(iv);
byte[] message = "Hello AES-CBC mode!".getBytes("UTF-8");
byte[] ciphertext = new AESCBCEncryption().encrypt(message, key, iv);
byte[] plaintext = new AESCBCEncryption().decrypt(ciphertext, key, iv);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,70 @@
import java.security.SecureRandom;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import java.util.Arrays;
/**
* Example of AES-GCM encryption and decryption using Bouncy Castle's low-level API.
*/
public class AESGCMEncryption {
byte[] encrypt(byte[] plaintext, byte[] key, byte[] nonce, byte[] aad) throws Exception {
AESEngine engine = new AESEngine();
GCMBlockCipher cipher = new GCMBlockCipher(engine);
AEADParameters params = new AEADParameters(
new KeyParameter(key),
128, // Authentication tag size in bits
nonce,
aad);
cipher.init(true, params); // true for encryption
byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)];
int outputLen = cipher.processBytes(plaintext, 0, plaintext.length, ciphertext, 0);
outputLen += cipher.doFinal(ciphertext, outputLen);
if (outputLen != ciphertext.length) {
ciphertext = Arrays.copyOf(ciphertext, outputLen);
}
return ciphertext;
}
byte[] decrypt(byte[] ciphertext, byte[] key, byte[] nonce, byte[] aad) throws Exception {
AESEngine engine = new AESEngine();
GCMBlockCipher cipher = new GCMBlockCipher(engine);
AEADParameters params = new AEADParameters(
new KeyParameter(key),
128, // Authentication tag size in bits
nonce,
aad);
cipher.init(false, params); // false for decryption
byte[] plaintext = new byte[cipher.getOutputSize(ciphertext.length)];
int outputLen = cipher.processBytes(ciphertext, 0, ciphertext.length, plaintext, 0);
outputLen += cipher.doFinal(plaintext, outputLen);
if (outputLen != plaintext.length) {
plaintext = Arrays.copyOf(plaintext, outputLen);
}
return plaintext;
}
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
SecureRandom random = new SecureRandom();
byte[] key = new byte[32];
random.nextBytes(key);
byte[] nonce = new byte[12];
random.nextBytes(nonce);
byte[] message = "This is a message to be encrypted.".getBytes("UTF-8");
byte[] aad = "This is additional authenticated data".getBytes("UTF-8");
byte[] ciphertext = new AESGCMEncryption().encrypt(message, key, nonce, aad);
byte[] plaintext = new AESGCMEncryption().decrypt(ciphertext, key, nonce, aad);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,40 @@
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm | Mode | AESCBCEncryption.java:18:31:18:56 | ModeOfOperation |
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm | Padding | AESCBCEncryption.java:19:32:19:49 | PaddingAlgorithm |
| AESCBCEncryption.java:22:50:22:52 | Key | Source | AESCBCEncryption.java:60:30:60:32 | RandomNumberGeneration |
| AESCBCEncryption.java:23:66:23:67 | Nonce | Source | AESCBCEncryption.java:62:30:62:31 | RandomNumberGeneration |
| AESCBCEncryption.java:27:45:27:53 | Message | Source | AESCBCEncryption.java:64:30:64:50 | Constant |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation | Algorithm | AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation | Input | AESCBCEncryption.java:27:45:27:53 | Message |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation | Key | AESCBCEncryption.java:22:50:22:52 | Key |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation | Nonce | AESCBCEncryption.java:23:66:23:67 | Nonce |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation | Output | AESCBCEncryption.java:28:37:28:46 | KeyOperationOutput |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm | Mode | AESCBCEncryption.java:37:31:37:56 | ModeOfOperation |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm | Padding | AESCBCEncryption.java:38:32:38:49 | PaddingAlgorithm |
| AESCBCEncryption.java:41:50:41:52 | Key | Source | AESCBCEncryption.java:60:30:60:32 | RandomNumberGeneration |
| AESCBCEncryption.java:42:66:42:67 | Nonce | Source | AESCBCEncryption.java:62:30:62:31 | RandomNumberGeneration |
| AESCBCEncryption.java:46:45:46:54 | Message | Source | AESCBCEncryption.java:28:37:28:46 | KeyOperationOutput |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation | Algorithm | AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation | Input | AESCBCEncryption.java:46:45:46:54 | Message |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation | Key | AESCBCEncryption.java:41:50:41:52 | Key |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation | Nonce | AESCBCEncryption.java:42:66:42:67 | Nonce |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation | Output | AESCBCEncryption.java:47:37:47:45 | KeyOperationOutput |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm | Mode | AESGCMEncryption.java:16:33:16:58 | ModeOfOperation |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm | Padding | AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:18:34:18:36 | Key | Source | AESGCMEncryption.java:58:30:58:32 | RandomNumberGeneration |
| AESGCMEncryption.java:20:17:20:21 | Nonce | Source | AESGCMEncryption.java:60:30:60:34 | RandomNumberGeneration |
| AESGCMEncryption.java:25:45:25:53 | Message | Source | AESGCMEncryption.java:62:30:62:65 | Constant |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation | Algorithm | AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation | Input | AESGCMEncryption.java:25:45:25:53 | Message |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation | Key | AESGCMEncryption.java:18:34:18:36 | Key |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation | Nonce | AESGCMEncryption.java:20:17:20:21 | Nonce |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation | Output | AESGCMEncryption.java:26:37:26:46 | KeyOperationOutput |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm | Mode | AESGCMEncryption.java:35:33:35:58 | ModeOfOperation |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm | Padding | AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:37:34:37:36 | Key | Source | AESGCMEncryption.java:58:30:58:32 | RandomNumberGeneration |
| AESGCMEncryption.java:39:17:39:21 | Nonce | Source | AESGCMEncryption.java:60:30:60:34 | RandomNumberGeneration |
| AESGCMEncryption.java:44:45:44:54 | Message | Source | AESGCMEncryption.java:26:37:26:46 | KeyOperationOutput |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation | Algorithm | AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation | Input | AESGCMEncryption.java:44:45:44:54 | Message |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation | Key | AESGCMEncryption.java:37:34:37:36 | Key |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation | Nonce | AESGCMEncryption.java:39:17:39:21 | Nonce |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation | Output | AESGCMEncryption.java:45:37:45:45 | KeyOperationOutput |

View File

@@ -0,0 +1,5 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n, string key
select n, key, n.getChild(key)

View File

@@ -0,0 +1,36 @@
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 | PaddingAlgorithm | Name | PKCS7 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 | PaddingAlgorithm | RawName | PKCS7 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 |
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm | Name | AES | AESCBCEncryption.java:17:28:17:42 | AESCBCEncryption.java:17:28:17:42 |
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm | RawName | AES | AESCBCEncryption.java:17:28:17:42 | AESCBCEncryption.java:17:28:17:42 |
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm | Structure | Block | AESCBCEncryption.java:17:28:17:42 | AESCBCEncryption.java:17:28:17:42 |
| AESCBCEncryption.java:18:31:18:56 | ModeOfOperation | Name | CBC | AESCBCEncryption.java:18:31:18:56 | AESCBCEncryption.java:18:31:18:56 |
| AESCBCEncryption.java:18:31:18:56 | ModeOfOperation | RawName | CBC | AESCBCEncryption.java:18:31:18:56 | AESCBCEncryption.java:18:31:18:56 |
| AESCBCEncryption.java:19:32:19:49 | PaddingAlgorithm | Name | PKCS7 | AESCBCEncryption.java:19:32:19:49 | AESCBCEncryption.java:19:32:19:49 |
| AESCBCEncryption.java:19:32:19:49 | PaddingAlgorithm | RawName | PKCS7 | AESCBCEncryption.java:19:32:19:49 | AESCBCEncryption.java:19:32:19:49 |
| AESCBCEncryption.java:22:50:22:52 | Key | KeyType | Unknown | AESCBCEncryption.java:22:50:22:52 | AESCBCEncryption.java:22:50:22:52 |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm | Name | AES | AESCBCEncryption.java:36:28:36:42 | AESCBCEncryption.java:36:28:36:42 |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm | RawName | AES | AESCBCEncryption.java:36:28:36:42 | AESCBCEncryption.java:36:28:36:42 |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm | Structure | Block | AESCBCEncryption.java:36:28:36:42 | AESCBCEncryption.java:36:28:36:42 |
| AESCBCEncryption.java:37:31:37:56 | ModeOfOperation | Name | CBC | AESCBCEncryption.java:37:31:37:56 | AESCBCEncryption.java:37:31:37:56 |
| AESCBCEncryption.java:37:31:37:56 | ModeOfOperation | RawName | CBC | AESCBCEncryption.java:37:31:37:56 | AESCBCEncryption.java:37:31:37:56 |
| AESCBCEncryption.java:38:32:38:49 | PaddingAlgorithm | Name | PKCS7 | AESCBCEncryption.java:38:32:38:49 | AESCBCEncryption.java:38:32:38:49 |
| AESCBCEncryption.java:38:32:38:49 | PaddingAlgorithm | RawName | PKCS7 | AESCBCEncryption.java:38:32:38:49 | AESCBCEncryption.java:38:32:38:49 |
| AESCBCEncryption.java:41:50:41:52 | Key | KeyType | Unknown | AESCBCEncryption.java:41:50:41:52 | AESCBCEncryption.java:41:50:41:52 |
| AESCBCEncryption.java:60:30:60:32 | RandomNumberGeneration | Description | java.security.SecureRandom | AESCBCEncryption.java:60:30:60:32 | AESCBCEncryption.java:60:30:60:32 |
| AESCBCEncryption.java:62:30:62:31 | RandomNumberGeneration | Description | java.security.SecureRandom | AESCBCEncryption.java:62:30:62:31 | AESCBCEncryption.java:62:30:62:31 |
| AESCBCEncryption.java:64:30:64:50 | Constant | Description | "Hello AES-CBC mode!" | AESCBCEncryption.java:64:30:64:50 | AESCBCEncryption.java:64:30:64:50 |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm | Name | AES | AESGCMEncryption.java:15:28:15:42 | AESGCMEncryption.java:15:28:15:42 |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm | RawName | AES | AESGCMEncryption.java:15:28:15:42 | AESGCMEncryption.java:15:28:15:42 |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm | Structure | Block | AESGCMEncryption.java:15:28:15:42 | AESGCMEncryption.java:15:28:15:42 |
| AESGCMEncryption.java:16:33:16:58 | ModeOfOperation | Name | GCM | AESGCMEncryption.java:16:33:16:58 | AESGCMEncryption.java:16:33:16:58 |
| AESGCMEncryption.java:16:33:16:58 | ModeOfOperation | RawName | GCM | AESGCMEncryption.java:16:33:16:58 | AESGCMEncryption.java:16:33:16:58 |
| AESGCMEncryption.java:18:34:18:36 | Key | KeyType | Unknown | AESGCMEncryption.java:18:34:18:36 | AESGCMEncryption.java:18:34:18:36 |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm | Name | AES | AESGCMEncryption.java:34:28:34:42 | AESGCMEncryption.java:34:28:34:42 |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm | RawName | AES | AESGCMEncryption.java:34:28:34:42 | AESGCMEncryption.java:34:28:34:42 |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm | Structure | Block | AESGCMEncryption.java:34:28:34:42 | AESGCMEncryption.java:34:28:34:42 |
| AESGCMEncryption.java:35:33:35:58 | ModeOfOperation | Name | GCM | AESGCMEncryption.java:35:33:35:58 | AESGCMEncryption.java:35:33:35:58 |
| AESGCMEncryption.java:35:33:35:58 | ModeOfOperation | RawName | GCM | AESGCMEncryption.java:35:33:35:58 | AESGCMEncryption.java:35:33:35:58 |
| AESGCMEncryption.java:37:34:37:36 | Key | KeyType | Unknown | AESGCMEncryption.java:37:34:37:36 | AESGCMEncryption.java:37:34:37:36 |
| AESGCMEncryption.java:58:30:58:32 | RandomNumberGeneration | Description | java.security.SecureRandom | AESGCMEncryption.java:58:30:58:32 | AESGCMEncryption.java:58:30:58:32 |
| AESGCMEncryption.java:60:30:60:34 | RandomNumberGeneration | Description | java.security.SecureRandom | AESGCMEncryption.java:60:30:60:34 | AESGCMEncryption.java:60:30:60:34 |
| AESGCMEncryption.java:62:30:62:65 | Constant | Description | "This is a message to be encrypted." | AESGCMEncryption.java:62:30:62:65 | AESGCMEncryption.java:62:30:62:65 |

View File

@@ -0,0 +1,6 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n, string key, string value, Location location
where n.properties(key, value, location)
select n, key, value, location

View File

@@ -0,0 +1,37 @@
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java:9:24:9:41 | PaddingAlgorithm |
| AESCBCEncryption.java:17:28:17:42 | KeyOperationAlgorithm |
| AESCBCEncryption.java:18:31:18:56 | ModeOfOperation |
| AESCBCEncryption.java:19:32:19:49 | PaddingAlgorithm |
| AESCBCEncryption.java:22:50:22:52 | Key |
| AESCBCEncryption.java:23:66:23:67 | Nonce |
| AESCBCEncryption.java:27:45:27:53 | Message |
| AESCBCEncryption.java:28:22:28:58 | EncryptOperation |
| AESCBCEncryption.java:28:37:28:46 | KeyOperationOutput |
| AESCBCEncryption.java:36:28:36:42 | KeyOperationAlgorithm |
| AESCBCEncryption.java:37:31:37:56 | ModeOfOperation |
| AESCBCEncryption.java:38:32:38:49 | PaddingAlgorithm |
| AESCBCEncryption.java:41:50:41:52 | Key |
| AESCBCEncryption.java:42:66:42:67 | Nonce |
| AESCBCEncryption.java:46:45:46:54 | Message |
| AESCBCEncryption.java:47:22:47:57 | DecryptOperation |
| AESCBCEncryption.java:47:37:47:45 | KeyOperationOutput |
| AESCBCEncryption.java:60:30:60:32 | RandomNumberGeneration |
| AESCBCEncryption.java:62:30:62:31 | RandomNumberGeneration |
| AESCBCEncryption.java:64:30:64:50 | Constant |
| AESGCMEncryption.java:15:28:15:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:16:33:16:58 | ModeOfOperation |
| AESGCMEncryption.java:18:34:18:36 | Key |
| AESGCMEncryption.java:20:17:20:21 | Nonce |
| AESGCMEncryption.java:25:45:25:53 | Message |
| AESGCMEncryption.java:26:22:26:58 | EncryptOperation |
| AESGCMEncryption.java:26:37:26:46 | KeyOperationOutput |
| AESGCMEncryption.java:34:28:34:42 | KeyOperationAlgorithm |
| AESGCMEncryption.java:35:33:35:58 | ModeOfOperation |
| AESGCMEncryption.java:37:34:37:36 | Key |
| AESGCMEncryption.java:39:17:39:21 | Nonce |
| AESGCMEncryption.java:44:45:44:54 | Message |
| AESGCMEncryption.java:45:22:45:57 | DecryptOperation |
| AESGCMEncryption.java:45:37:45:45 | KeyOperationOutput |
| AESGCMEncryption.java:58:30:58:32 | RandomNumberGeneration |
| AESGCMEncryption.java:60:30:60:34 | RandomNumberGeneration |
| AESGCMEncryption.java:62:30:62:65 | Constant |

View File

@@ -0,0 +1,5 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n
select n

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/bcprov-lts8on-2.73.7

View File

@@ -0,0 +1,123 @@
import java.security.Security;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
/**
* Test Bouncy Castle's low-level ECDSA API
*/
public class ECDSASignAndVerify {
public static void main(String[] args) {
// Add Bouncy Castle provider
Security.addProvider(new BouncyCastleProvider());
try {
byte[] message = "Hello, ECDSA signature!".getBytes("UTF-8");
// Test different key generation methods
signWithKeyPair(generateKeyPair1(), message);
signWithKeyPair(generateKeyPair2(), message);
signWithKeyPair(generateKeyPair3(), message);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Method 1: Generate key pair with SECNamedCurves
*/
private static AsymmetricCipherKeyPair generateKeyPair1() throws Exception {
// Get P-256 curve parameters using BouncyCastle's SECNamedCurves
String curveName = "secp256r1";
X9ECParameters ecParams = SECNamedCurves.getByName(curveName);
ECDomainParameters domainParams = new ECDomainParameters(ecParams);
// Generate a key pair
SecureRandom random = new SecureRandom();
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, random);
keyPairGenerator.init(keyGenParams);
return keyPairGenerator.generateKeyPair();
}
/**
* Method 2: Generate key pair with explicit curve construction
*/
private static AsymmetricCipherKeyPair generateKeyPair2() throws Exception {
// Get the X9.62 parameters and construct domain parameters explicitly
String curveName = "secp256k1";
X9ECParameters x9Params = SECNamedCurves.getByName(curveName);
ECCurve curve = x9Params.getCurve();
ECPoint g = x9Params.getG();
java.math.BigInteger n = x9Params.getN();
java.math.BigInteger h = x9Params.getH();
// Create domain parameters with explicit values
ECDomainParameters domainParams = new ECDomainParameters(curve, g, n, h);
SecureRandom random = new SecureRandom();
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, random);
keyPairGenerator.init(keyGenParams);
return keyPairGenerator.generateKeyPair();
}
/**
* Method 3: Generate key pair using ECNamedCurveTable
*/
private static AsymmetricCipherKeyPair generateKeyPair3() throws Exception {
// Get curve parameters using ECNamedCurveTable
String curveName = "secp384r1";
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curveName);
ECDomainParameters domainParams = new ECDomainParameters(
ecSpec.getCurve(),
ecSpec.getG(),
ecSpec.getN(),
ecSpec.getH()
);
SecureRandom random = new SecureRandom();
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, random);
keyPairGenerator.init(keyGenParams);
return keyPairGenerator.generateKeyPair();
}
/**
* Test signing and verification with BouncyCastle low-level key pair
*/
private static void signWithKeyPair(AsymmetricCipherKeyPair keyPair, byte[] message) throws Exception {
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();
ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
// Sign the message
ECDSASigner signer = new ECDSASigner();
signer.init(true, privateKey); // true for signing
java.math.BigInteger[] signature = signer.generateSignature(message);
// Verify the signature
ECDSASigner verifier = new ECDSASigner();
verifier.init(false, publicKey); // false for verification
boolean verified = verifier.verifySignature(message, signature[0], signature[1]);
}
}

View File

@@ -0,0 +1,47 @@
import java.security.KeyPair;
import java.security.Security;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.signers.Ed25519Signer;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Ed25519SignAndVerify {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
// Generate a key pair
SecureRandom random = new SecureRandom();
Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(new Ed25519KeyGenerationParameters(random));
AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) keyPair.getPrivate();
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) keyPair.getPublic();
byte[] message = "Hello, Ed25519 signature!".getBytes("UTF-8");
// Sign the message
Ed25519Signer signer = new Ed25519Signer();
signer.init(true, privateKey); // true for signing
signer.update(message, 0, message.length);
byte[] signature = signer.generateSignature();
System.out.println("Signature generated!");
// Verify the signature
Ed25519Signer verifier = new Ed25519Signer();
verifier.init(false, publicKey); // false for verification
verifier.update(message, 0, message.length);
boolean verified = verifier.verifySignature(signature);
System.out.println("Signature verified: " + verified);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,47 @@
import java.security.KeyPair;
import java.security.Security;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.Ed448KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
import org.bouncycastle.crypto.signers.Ed448Signer;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Ed448SignAndVerify {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
// Generate a key pair
SecureRandom random = new SecureRandom();
Ed448KeyPairGenerator keyPairGenerator = new Ed448KeyPairGenerator();
keyPairGenerator.init(new Ed448KeyGenerationParameters(random));
AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();
Ed448PrivateKeyParameters privateKey = (Ed448PrivateKeyParameters) keyPair.getPrivate();
Ed448PublicKeyParameters publicKey = (Ed448PublicKeyParameters) keyPair.getPublic();
byte[] message = "Hello, Ed448 signature!".getBytes("UTF-8");
// Sign the message
Ed448Signer signer = new Ed448Signer("context".getBytes());
signer.init(true, privateKey); // true for signing
signer.update(message, 0, message.length);
byte[] signature = signer.generateSignature();
System.out.println("Signature generated!");
// Verify the signature
Ed448Signer verifier = new Ed448Signer("context".getBytes());
verifier.init(false, publicKey); // false for verification
verifier.update(message, 0, message.length);
boolean verified = verifier.verifySignature(signature);
System.out.println("Signature verified: " + verified);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,55 @@
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.pqc.crypto.lms.LMSKeyPairGenerator;
import org.bouncycastle.pqc.crypto.lms.LMSKeyGenerationParameters;
import org.bouncycastle.pqc.crypto.lms.LMSParameters;
import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters;
import org.bouncycastle.pqc.crypto.lms.LMSSigner;
import org.bouncycastle.pqc.crypto.lms.LMSigParameters;
import org.bouncycastle.pqc.crypto.lms.LMOtsParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
/**
* Example of the Leighton-Micali Signature (LMS) scheme using Bouncy Castle's
* low-level API.
*
*/
public class LMSSignAndVerify {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
// Set up LMS parameters
LMSParameters lmsParameters = new LMSParameters(
LMSigParameters.lms_sha256_n32_h10,
LMOtsParameters.sha256_n32_w8);
// Generate key pair
SecureRandom random = new SecureRandom();
LMSKeyPairGenerator keyPairGen = new LMSKeyPairGenerator();
keyPairGen.init(new LMSKeyGenerationParameters(lmsParameters, random));
AsymmetricCipherKeyPair keyPair = keyPairGen.generateKeyPair();
LMSPrivateKeyParameters privateKey = (LMSPrivateKeyParameters) keyPair.getPrivate();
LMSPublicKeyParameters publicKey = (LMSPublicKeyParameters) keyPair.getPublic();
byte[] message = "Hello, LMS signature!".getBytes("UTF-8");
// Sign the message
LMSSigner signer = new LMSSigner();
signer.init(true, privateKey); // true for signing
byte[] signature = signer.generateSignature(message);
// Verify the signature
LMSSigner verifier = new LMSSigner();
verifier.init(false, publicKey);
boolean verified = verifier.verifySignature(message, signature);
System.out.println("Signature verified: " + verified);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,98 @@
| ECDSASignAndVerify.java:57:16:57:49 | Key | Algorithm | ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve |
| ECDSASignAndVerify.java:57:16:57:49 | KeyGeneration | Algorithm | ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve |
| ECDSASignAndVerify.java:57:16:57:49 | KeyGeneration | Output | ECDSASignAndVerify.java:57:16:57:49 | Key |
| ECDSASignAndVerify.java:80:16:80:49 | Key | Algorithm | ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve |
| ECDSASignAndVerify.java:80:16:80:49 | KeyGeneration | Algorithm | ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve |
| ECDSASignAndVerify.java:80:16:80:49 | KeyGeneration | Output | ECDSASignAndVerify.java:80:16:80:49 | Key |
| ECDSASignAndVerify.java:103:16:103:49 | Key | Algorithm | ECDSASignAndVerify.java:103:16:103:49 | Key |
| ECDSASignAndVerify.java:103:16:103:49 | KeyGeneration | Algorithm | ECDSASignAndVerify.java:103:16:103:49 | KeyGeneration |
| ECDSASignAndVerify.java:103:16:103:49 | KeyGeneration | Output | ECDSASignAndVerify.java:103:16:103:49 | Key |
| ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm | Mode | ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm | Padding | ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:115:27:115:36 | Key | Source | ECDSASignAndVerify.java:57:16:57:49 | Key |
| ECDSASignAndVerify.java:115:27:115:36 | Key | Source | ECDSASignAndVerify.java:80:16:80:49 | Key |
| ECDSASignAndVerify.java:115:27:115:36 | Key | Source | ECDSASignAndVerify.java:103:16:103:49 | Key |
| ECDSASignAndVerify.java:116:44:116:76 | SignOperation | Algorithm | ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:116:44:116:76 | SignOperation | Input | ECDSASignAndVerify.java:116:69:116:75 | Message |
| ECDSASignAndVerify.java:116:44:116:76 | SignOperation | Key | ECDSASignAndVerify.java:115:27:115:36 | Key |
| ECDSASignAndVerify.java:116:44:116:76 | SignOperation | Output | ECDSASignAndVerify.java:116:44:116:76 | SignatureOutput |
| ECDSASignAndVerify.java:116:69:116:75 | Message | Source | ECDSASignAndVerify.java:31:30:31:54 | Constant |
| ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm | Mode | ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm | Padding | ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:120:30:120:38 | Key | Source | ECDSASignAndVerify.java:57:16:57:49 | Key |
| ECDSASignAndVerify.java:120:30:120:38 | Key | Source | ECDSASignAndVerify.java:80:16:80:49 | Key |
| ECDSASignAndVerify.java:120:30:120:38 | Key | Source | ECDSASignAndVerify.java:103:16:103:49 | Key |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation | Algorithm | ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation | Input | ECDSASignAndVerify.java:121:53:121:59 | Message |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation | Key | ECDSASignAndVerify.java:120:30:120:38 | Key |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation | Signature | ECDSASignAndVerify.java:121:62:121:73 | SignatureInput |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation | Signature | ECDSASignAndVerify.java:121:76:121:87 | SignatureInput |
| ECDSASignAndVerify.java:121:53:121:59 | Message | Source | ECDSASignAndVerify.java:121:53:121:59 | Message |
| ECDSASignAndVerify.java:121:62:121:73 | SignatureInput | Source | ECDSASignAndVerify.java:116:44:116:76 | SignatureOutput |
| ECDSASignAndVerify.java:121:76:121:87 | SignatureInput | Source | ECDSASignAndVerify.java:116:44:116:76 | SignatureOutput |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm | Mode | Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm | Padding | Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:21:47:21:80 | Key | Algorithm | Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:21:47:21:80 | KeyGeneration | Algorithm | Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:21:47:21:80 | KeyGeneration | Output | Ed448SignAndVerify.java:21:47:21:80 | Key |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm | Mode | Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm | Padding | Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:30:31:30:40 | Key | Source | Ed448SignAndVerify.java:21:47:21:80 | Key |
| Ed448SignAndVerify.java:31:27:31:33 | Message | Source | Ed448SignAndVerify.java:26:30:26:54 | Constant |
| Ed448SignAndVerify.java:32:32:32:57 | SignOperation | Algorithm | Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:32:32:32:57 | SignOperation | Input | Ed448SignAndVerify.java:31:27:31:33 | Message |
| Ed448SignAndVerify.java:32:32:32:57 | SignOperation | Key | Ed448SignAndVerify.java:30:31:30:40 | Key |
| Ed448SignAndVerify.java:32:32:32:57 | SignOperation | Output | Ed448SignAndVerify.java:32:32:32:57 | SignatureOutput |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm | Mode | Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm | Padding | Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:38:34:38:42 | Key | Source | Ed448SignAndVerify.java:21:47:21:80 | Key |
| Ed448SignAndVerify.java:39:29:39:35 | Message | Source | Ed448SignAndVerify.java:39:29:39:35 | Message |
| Ed448SignAndVerify.java:40:32:40:66 | VerifyOperation | Algorithm | Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:40:32:40:66 | VerifyOperation | Input | Ed448SignAndVerify.java:39:29:39:35 | Message |
| Ed448SignAndVerify.java:40:32:40:66 | VerifyOperation | Key | Ed448SignAndVerify.java:38:34:38:42 | Key |
| Ed448SignAndVerify.java:40:32:40:66 | VerifyOperation | Signature | Ed448SignAndVerify.java:40:57:40:65 | SignatureInput |
| Ed448SignAndVerify.java:40:57:40:65 | SignatureInput | Source | Ed448SignAndVerify.java:32:32:32:57 | SignatureOutput |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm | Mode | Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm | Padding | Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:21:47:21:80 | Key | Algorithm | Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:21:47:21:80 | KeyGeneration | Algorithm | Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:21:47:21:80 | KeyGeneration | Output | Ed25519SignAndVerify.java:21:47:21:80 | Key |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm | Mode | Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm | Padding | Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:30:31:30:40 | Key | Source | Ed25519SignAndVerify.java:21:47:21:80 | Key |
| Ed25519SignAndVerify.java:31:27:31:33 | Message | Source | Ed25519SignAndVerify.java:26:30:26:56 | Constant |
| Ed25519SignAndVerify.java:32:32:32:57 | SignOperation | Algorithm | Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:32:32:32:57 | SignOperation | Input | Ed25519SignAndVerify.java:31:27:31:33 | Message |
| Ed25519SignAndVerify.java:32:32:32:57 | SignOperation | Key | Ed25519SignAndVerify.java:30:31:30:40 | Key |
| Ed25519SignAndVerify.java:32:32:32:57 | SignOperation | Output | Ed25519SignAndVerify.java:32:32:32:57 | SignatureOutput |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm | Mode | Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm | Padding | Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:38:34:38:42 | Key | Source | Ed25519SignAndVerify.java:21:47:21:80 | Key |
| Ed25519SignAndVerify.java:39:29:39:35 | Message | Source | Ed25519SignAndVerify.java:39:29:39:35 | Message |
| Ed25519SignAndVerify.java:40:32:40:66 | VerifyOperation | Algorithm | Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:40:32:40:66 | VerifyOperation | Input | Ed25519SignAndVerify.java:39:29:39:35 | Message |
| Ed25519SignAndVerify.java:40:32:40:66 | VerifyOperation | Key | Ed25519SignAndVerify.java:38:34:38:42 | Key |
| Ed25519SignAndVerify.java:40:32:40:66 | VerifyOperation | Signature | Ed25519SignAndVerify.java:40:57:40:65 | SignatureInput |
| Ed25519SignAndVerify.java:40:57:40:65 | SignatureInput | Source | Ed25519SignAndVerify.java:32:32:32:57 | SignatureOutput |
| LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm | Mode | LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm | Padding | LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:33:47:33:74 | Key | Algorithm | LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:33:47:33:74 | KeyGeneration | Algorithm | LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:33:47:33:74 | KeyGeneration | Output | LMSSignAndVerify.java:33:47:33:74 | Key |
| LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm | Mode | LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm | Padding | LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:42:31:42:40 | Key | Source | LMSSignAndVerify.java:33:47:33:74 | Key |
| LMSSignAndVerify.java:43:32:43:64 | SignOperation | Algorithm | LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:43:32:43:64 | SignOperation | Input | LMSSignAndVerify.java:43:57:43:63 | Message |
| LMSSignAndVerify.java:43:32:43:64 | SignOperation | Key | LMSSignAndVerify.java:42:31:42:40 | Key |
| LMSSignAndVerify.java:43:32:43:64 | SignOperation | Output | LMSSignAndVerify.java:43:32:43:64 | SignatureOutput |
| LMSSignAndVerify.java:43:57:43:63 | Message | Source | LMSSignAndVerify.java:38:30:38:52 | Constant |
| LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm | Mode | LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm | Padding | LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:47:34:47:42 | Key | Source | LMSSignAndVerify.java:33:47:33:74 | Key |
| LMSSignAndVerify.java:48:32:48:75 | VerifyOperation | Algorithm | LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:48:32:48:75 | VerifyOperation | Input | LMSSignAndVerify.java:48:57:48:63 | Message |
| LMSSignAndVerify.java:48:32:48:75 | VerifyOperation | Key | LMSSignAndVerify.java:47:34:47:42 | Key |
| LMSSignAndVerify.java:48:32:48:75 | VerifyOperation | Signature | LMSSignAndVerify.java:48:66:48:74 | SignatureInput |
| LMSSignAndVerify.java:48:57:48:63 | Message | Source | LMSSignAndVerify.java:48:57:48:63 | Message |
| LMSSignAndVerify.java:48:66:48:74 | SignatureInput | Source | LMSSignAndVerify.java:43:32:43:64 | SignatureOutput |

View File

@@ -0,0 +1,5 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n, string key
select n, key, n.getChild(key)

View File

@@ -0,0 +1,74 @@
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | EllipticCurve | KeySize | 256 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | EllipticCurve | Name | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | EllipticCurve | ParsedName | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | EllipticCurve | RawName | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | EllipticCurve | KeySize | 256 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | EllipticCurve | Name | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | EllipticCurve | ParsedName | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | EllipticCurve | RawName | secp256r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | EllipticCurve | KeySize | 256 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | EllipticCurve | Name | secp256k1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | EllipticCurve | ParsedName | secp256k1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | EllipticCurve | RawName | secp256k1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | EllipticCurve | KeySize | 384 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | EllipticCurve | Name | secp384r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | EllipticCurve | ParsedName | secp384r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | EllipticCurve | RawName | secp384r1 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 |
| ECDSASignAndVerify.java:31:30:31:54 | Constant | Description | "Hello, ECDSA signature!" | ECDSASignAndVerify.java:31:30:31:54 | ECDSASignAndVerify.java:31:30:31:54 |
| ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve | KeySize | 256 | ECDSASignAndVerify.java:47:28:47:38 | ECDSASignAndVerify.java:47:28:47:38 |
| ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve | Name | secp256r1 | ECDSASignAndVerify.java:47:28:47:38 | ECDSASignAndVerify.java:47:28:47:38 |
| ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve | ParsedName | secp256r1 | ECDSASignAndVerify.java:47:28:47:38 | ECDSASignAndVerify.java:47:28:47:38 |
| ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve | RawName | secp256r1 | ECDSASignAndVerify.java:47:28:47:38 | ECDSASignAndVerify.java:47:28:47:38 |
| ECDSASignAndVerify.java:57:16:57:49 | Key | KeyType | Asymmetric | ECDSASignAndVerify.java:57:16:57:49 | ECDSASignAndVerify.java:57:16:57:49 |
| ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve | KeySize | 256 | ECDSASignAndVerify.java:65:28:65:38 | ECDSASignAndVerify.java:65:28:65:38 |
| ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve | Name | secp256k1 | ECDSASignAndVerify.java:65:28:65:38 | ECDSASignAndVerify.java:65:28:65:38 |
| ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve | ParsedName | secp256k1 | ECDSASignAndVerify.java:65:28:65:38 | ECDSASignAndVerify.java:65:28:65:38 |
| ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve | RawName | secp256k1 | ECDSASignAndVerify.java:65:28:65:38 | ECDSASignAndVerify.java:65:28:65:38 |
| ECDSASignAndVerify.java:80:16:80:49 | Key | KeyType | Asymmetric | ECDSASignAndVerify.java:80:16:80:49 | ECDSASignAndVerify.java:80:16:80:49 |
| ECDSASignAndVerify.java:89:28:89:38 | EllipticCurve | KeySize | 384 | ECDSASignAndVerify.java:89:28:89:38 | ECDSASignAndVerify.java:89:28:89:38 |
| ECDSASignAndVerify.java:89:28:89:38 | EllipticCurve | Name | secp384r1 | ECDSASignAndVerify.java:89:28:89:38 | ECDSASignAndVerify.java:89:28:89:38 |
| ECDSASignAndVerify.java:89:28:89:38 | EllipticCurve | ParsedName | secp384r1 | ECDSASignAndVerify.java:89:28:89:38 | ECDSASignAndVerify.java:89:28:89:38 |
| ECDSASignAndVerify.java:89:28:89:38 | EllipticCurve | RawName | secp384r1 | ECDSASignAndVerify.java:89:28:89:38 | ECDSASignAndVerify.java:89:28:89:38 |
| ECDSASignAndVerify.java:103:16:103:49 | Key | KeyType | Asymmetric | ECDSASignAndVerify.java:103:16:103:49 | ECDSASignAndVerify.java:103:16:103:49 |
| ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm | Name | ECDSA | ECDSASignAndVerify.java:114:30:114:46 | ECDSASignAndVerify.java:114:30:114:46 |
| ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm | RawName | ECDSA | ECDSASignAndVerify.java:114:30:114:46 | ECDSASignAndVerify.java:114:30:114:46 |
| ECDSASignAndVerify.java:115:27:115:36 | Key | KeyType | Unknown | ECDSASignAndVerify.java:115:27:115:36 | ECDSASignAndVerify.java:115:27:115:36 |
| ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm | Name | ECDSA | ECDSASignAndVerify.java:119:32:119:48 | ECDSASignAndVerify.java:119:32:119:48 |
| ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm | RawName | ECDSA | ECDSASignAndVerify.java:119:32:119:48 | ECDSASignAndVerify.java:119:32:119:48 |
| ECDSASignAndVerify.java:120:30:120:38 | Key | KeyType | Unknown | ECDSASignAndVerify.java:120:30:120:38 | ECDSASignAndVerify.java:120:30:120:38 |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm | KeySize | 448 | Ed448SignAndVerify.java:19:54:19:80 | Ed448SignAndVerify.java:19:54:19:80 |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm | Name | Ed448 | Ed448SignAndVerify.java:19:54:19:80 | Ed448SignAndVerify.java:19:54:19:80 |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm | RawName | Ed448 | Ed448SignAndVerify.java:19:54:19:80 | Ed448SignAndVerify.java:19:54:19:80 |
| Ed448SignAndVerify.java:21:47:21:80 | Key | KeyType | Asymmetric | Ed448SignAndVerify.java:21:47:21:80 | Ed448SignAndVerify.java:21:47:21:80 |
| Ed448SignAndVerify.java:26:30:26:54 | Constant | Description | "Hello, Ed448 signature!" | Ed448SignAndVerify.java:26:30:26:54 | Ed448SignAndVerify.java:26:30:26:54 |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm | KeySize | 448 | Ed448SignAndVerify.java:29:34:29:70 | Ed448SignAndVerify.java:29:34:29:70 |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm | Name | Ed448 | Ed448SignAndVerify.java:29:34:29:70 | Ed448SignAndVerify.java:29:34:29:70 |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm | RawName | Ed448 | Ed448SignAndVerify.java:29:34:29:70 | Ed448SignAndVerify.java:29:34:29:70 |
| Ed448SignAndVerify.java:30:31:30:40 | Key | KeyType | Unknown | Ed448SignAndVerify.java:30:31:30:40 | Ed448SignAndVerify.java:30:31:30:40 |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm | KeySize | 448 | Ed448SignAndVerify.java:37:36:37:72 | Ed448SignAndVerify.java:37:36:37:72 |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm | Name | Ed448 | Ed448SignAndVerify.java:37:36:37:72 | Ed448SignAndVerify.java:37:36:37:72 |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm | RawName | Ed448 | Ed448SignAndVerify.java:37:36:37:72 | Ed448SignAndVerify.java:37:36:37:72 |
| Ed448SignAndVerify.java:38:34:38:42 | Key | KeyType | Unknown | Ed448SignAndVerify.java:38:34:38:42 | Ed448SignAndVerify.java:38:34:38:42 |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm | KeySize | 256 | Ed25519SignAndVerify.java:19:56:19:84 | Ed25519SignAndVerify.java:19:56:19:84 |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm | Name | Ed25519 | Ed25519SignAndVerify.java:19:56:19:84 | Ed25519SignAndVerify.java:19:56:19:84 |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm | RawName | Ed25519 | Ed25519SignAndVerify.java:19:56:19:84 | Ed25519SignAndVerify.java:19:56:19:84 |
| Ed25519SignAndVerify.java:21:47:21:80 | Key | KeyType | Asymmetric | Ed25519SignAndVerify.java:21:47:21:80 | Ed25519SignAndVerify.java:21:47:21:80 |
| Ed25519SignAndVerify.java:26:30:26:56 | Constant | Description | "Hello, Ed25519 signature!" | Ed25519SignAndVerify.java:26:30:26:56 | Ed25519SignAndVerify.java:26:30:26:56 |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm | KeySize | 256 | Ed25519SignAndVerify.java:29:36:29:54 | Ed25519SignAndVerify.java:29:36:29:54 |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm | Name | Ed25519 | Ed25519SignAndVerify.java:29:36:29:54 | Ed25519SignAndVerify.java:29:36:29:54 |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm | RawName | Ed25519 | Ed25519SignAndVerify.java:29:36:29:54 | Ed25519SignAndVerify.java:29:36:29:54 |
| Ed25519SignAndVerify.java:30:31:30:40 | Key | KeyType | Unknown | Ed25519SignAndVerify.java:30:31:30:40 | Ed25519SignAndVerify.java:30:31:30:40 |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm | KeySize | 256 | Ed25519SignAndVerify.java:37:38:37:56 | Ed25519SignAndVerify.java:37:38:37:56 |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm | Name | Ed25519 | Ed25519SignAndVerify.java:37:38:37:56 | Ed25519SignAndVerify.java:37:38:37:56 |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm | RawName | Ed25519 | Ed25519SignAndVerify.java:37:38:37:56 | Ed25519SignAndVerify.java:37:38:37:56 |
| Ed25519SignAndVerify.java:38:34:38:42 | Key | KeyType | Unknown | Ed25519SignAndVerify.java:38:34:38:42 | Ed25519SignAndVerify.java:38:34:38:42 |
| LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm | Name | LMS | LMSSignAndVerify.java:31:46:31:70 | LMSSignAndVerify.java:31:46:31:70 |
| LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm | RawName | LMS | LMSSignAndVerify.java:31:46:31:70 | LMSSignAndVerify.java:31:46:31:70 |
| LMSSignAndVerify.java:33:47:33:74 | Key | KeyType | Asymmetric | LMSSignAndVerify.java:33:47:33:74 | LMSSignAndVerify.java:33:47:33:74 |
| LMSSignAndVerify.java:38:30:38:52 | Constant | Description | "Hello, LMS signature!" | LMSSignAndVerify.java:38:30:38:52 | LMSSignAndVerify.java:38:30:38:52 |
| LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm | Name | LMS | LMSSignAndVerify.java:41:32:41:46 | LMSSignAndVerify.java:41:32:41:46 |
| LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm | RawName | LMS | LMSSignAndVerify.java:41:32:41:46 | LMSSignAndVerify.java:41:32:41:46 |
| LMSSignAndVerify.java:42:31:42:40 | Key | KeyType | Unknown | LMSSignAndVerify.java:42:31:42:40 | LMSSignAndVerify.java:42:31:42:40 |
| LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm | Name | LMS | LMSSignAndVerify.java:46:34:46:48 | LMSSignAndVerify.java:46:34:46:48 |
| LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm | RawName | LMS | LMSSignAndVerify.java:46:34:46:48 | LMSSignAndVerify.java:46:34:46:48 |
| LMSSignAndVerify.java:47:34:47:42 | Key | KeyType | Unknown | LMSSignAndVerify.java:47:34:47:42 | LMSSignAndVerify.java:47:34:47:42 |

View File

@@ -0,0 +1,6 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n, string key, string value, Location location
where n.properties(key, value, location)
select n, key, value, location

View File

@@ -0,0 +1,67 @@
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/asn1/sec/SECNamedCurves.java:11:16:11:26 | EllipticCurve |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:31:11:41 | EllipticCurve |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:44:11:54 | EllipticCurve |
| ../../../../../stubs/bcprov-lts8on-2.73.7/org/bouncycastle/jce/ECNamedCurveTable.java:11:57:11:67 | EllipticCurve |
| ECDSASignAndVerify.java:31:30:31:54 | Constant |
| ECDSASignAndVerify.java:47:28:47:38 | EllipticCurve |
| ECDSASignAndVerify.java:57:16:57:49 | Key |
| ECDSASignAndVerify.java:57:16:57:49 | KeyGeneration |
| ECDSASignAndVerify.java:65:28:65:38 | EllipticCurve |
| ECDSASignAndVerify.java:80:16:80:49 | Key |
| ECDSASignAndVerify.java:80:16:80:49 | KeyGeneration |
| ECDSASignAndVerify.java:89:28:89:38 | EllipticCurve |
| ECDSASignAndVerify.java:103:16:103:49 | Key |
| ECDSASignAndVerify.java:103:16:103:49 | KeyGeneration |
| ECDSASignAndVerify.java:114:30:114:46 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:115:27:115:36 | Key |
| ECDSASignAndVerify.java:116:44:116:76 | SignOperation |
| ECDSASignAndVerify.java:116:44:116:76 | SignatureOutput |
| ECDSASignAndVerify.java:116:69:116:75 | Message |
| ECDSASignAndVerify.java:119:32:119:48 | KeyOperationAlgorithm |
| ECDSASignAndVerify.java:120:30:120:38 | Key |
| ECDSASignAndVerify.java:121:28:121:88 | VerifyOperation |
| ECDSASignAndVerify.java:121:53:121:59 | Message |
| ECDSASignAndVerify.java:121:62:121:73 | SignatureInput |
| ECDSASignAndVerify.java:121:76:121:87 | SignatureInput |
| Ed448SignAndVerify.java:19:54:19:80 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:21:47:21:80 | Key |
| Ed448SignAndVerify.java:21:47:21:80 | KeyGeneration |
| Ed448SignAndVerify.java:26:30:26:54 | Constant |
| Ed448SignAndVerify.java:29:34:29:70 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:30:31:30:40 | Key |
| Ed448SignAndVerify.java:31:27:31:33 | Message |
| Ed448SignAndVerify.java:32:32:32:57 | SignOperation |
| Ed448SignAndVerify.java:32:32:32:57 | SignatureOutput |
| Ed448SignAndVerify.java:37:36:37:72 | KeyOperationAlgorithm |
| Ed448SignAndVerify.java:38:34:38:42 | Key |
| Ed448SignAndVerify.java:39:29:39:35 | Message |
| Ed448SignAndVerify.java:40:32:40:66 | VerifyOperation |
| Ed448SignAndVerify.java:40:57:40:65 | SignatureInput |
| Ed25519SignAndVerify.java:19:56:19:84 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:21:47:21:80 | Key |
| Ed25519SignAndVerify.java:21:47:21:80 | KeyGeneration |
| Ed25519SignAndVerify.java:26:30:26:56 | Constant |
| Ed25519SignAndVerify.java:29:36:29:54 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:30:31:30:40 | Key |
| Ed25519SignAndVerify.java:31:27:31:33 | Message |
| Ed25519SignAndVerify.java:32:32:32:57 | SignOperation |
| Ed25519SignAndVerify.java:32:32:32:57 | SignatureOutput |
| Ed25519SignAndVerify.java:37:38:37:56 | KeyOperationAlgorithm |
| Ed25519SignAndVerify.java:38:34:38:42 | Key |
| Ed25519SignAndVerify.java:39:29:39:35 | Message |
| Ed25519SignAndVerify.java:40:32:40:66 | VerifyOperation |
| Ed25519SignAndVerify.java:40:57:40:65 | SignatureInput |
| LMSSignAndVerify.java:31:46:31:70 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:33:47:33:74 | Key |
| LMSSignAndVerify.java:33:47:33:74 | KeyGeneration |
| LMSSignAndVerify.java:38:30:38:52 | Constant |
| LMSSignAndVerify.java:41:32:41:46 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:42:31:42:40 | Key |
| LMSSignAndVerify.java:43:32:43:64 | SignOperation |
| LMSSignAndVerify.java:43:32:43:64 | SignatureOutput |
| LMSSignAndVerify.java:43:57:43:63 | Message |
| LMSSignAndVerify.java:46:34:46:48 | KeyOperationAlgorithm |
| LMSSignAndVerify.java:47:34:47:42 | Key |
| LMSSignAndVerify.java:48:32:48:75 | VerifyOperation |
| LMSSignAndVerify.java:48:57:48:63 | Message |
| LMSSignAndVerify.java:48:66:48:74 | SignatureInput |

View File

@@ -0,0 +1,5 @@
import java
import experimental.quantum.Language
from Crypto::NodeBase n
select n

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/bcprov-lts8on-2.73.7

View File

@@ -0,0 +1,3 @@
Copyright (c) 2000-2024 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,13 @@
package org.bouncycastle.asn1.sec;
import org.bouncycastle.asn1.x9.X9ECParameters;
public class SECNamedCurves {
public static X9ECParameters getByName(String name) {
return new X9ECParameters();
}
public static String getName(Object oid) {
return "secp256r1";
}
}

View File

@@ -0,0 +1,29 @@
package org.bouncycastle.asn1.x9;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
public class X9ECParameters {
public X9ECParameters() { }
public ECCurve getCurve() {
return new ECCurve();
}
public ECPoint getG() {
return new ECPoint();
}
public BigInteger getN() {
return BigInteger.ZERO;
}
public BigInteger getH() {
return BigInteger.ONE;
}
public byte[] getSeed() {
return new byte[0];
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.crypto;
public class AsymmetricCipherKeyPair {
private final Object privateKey;
private final Object publicKey;
public AsymmetricCipherKeyPair(Object publicKey, Object privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public Object getPrivate() {
return privateKey;
}
public Object getPublic() {
return publicKey;
}
}

View File

@@ -0,0 +1,17 @@
package org.bouncycastle.crypto.engines;
public class AESEngine {
public AESEngine() { }
public void init(boolean forEncryption, Object params) { }
public int getBlockSize() {
return 16; // AES block size is 16 bytes
}
public int processBlock(byte[] in, int inOff, byte[] out, int outOff) {
return getBlockSize();
}
public void reset() { }
}

View File

@@ -0,0 +1,16 @@
package org.bouncycastle.crypto.generators;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
public class ECKeyPairGenerator {
private ECKeyGenerationParameters parameters;
public void init(ECKeyGenerationParameters parameters) {
this.parameters = parameters;
}
public AsymmetricCipherKeyPair generateKeyPair() {
return new AsymmetricCipherKeyPair(null, null);
}
}

View File

@@ -0,0 +1,20 @@
package org.bouncycastle.crypto.generators;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
public class Ed25519KeyPairGenerator {
private Ed25519KeyGenerationParameters parameters;
public void init(Ed25519KeyGenerationParameters parameters) {
this.parameters = parameters;
}
public AsymmetricCipherKeyPair generateKeyPair() {
Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(parameters.getRandom());
Ed25519PublicKeyParameters publicKey = privateKey.generatePublicKey();
return new AsymmetricCipherKeyPair(publicKey, privateKey);
}
}

View File

@@ -0,0 +1,20 @@
package org.bouncycastle.crypto.generators;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
public class Ed448KeyPairGenerator {
private Ed448KeyGenerationParameters parameters;
public void init(Ed448KeyGenerationParameters parameters) {
this.parameters = parameters;
}
public AsymmetricCipherKeyPair generateKeyPair() {
Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters(parameters.getRandom());
Ed448PublicKeyParameters publicKey = privateKey.generatePublicKey();
return new AsymmetricCipherKeyPair(publicKey, privateKey);
}
}

View File

@@ -0,0 +1,21 @@
package org.bouncycastle.crypto.modes;
public class CBCBlockCipher {
private Object cipher;
public CBCBlockCipher(Object cipher) {
this.cipher = cipher;
}
public void init(boolean forEncryption, Object params) { }
public int getBlockSize() {
return 16; // AES block size
}
public int processBlock(byte[] in, int inOff, byte[] out, int outOff) {
return getBlockSize();
}
public void reset() { }
}

View File

@@ -0,0 +1,29 @@
package org.bouncycastle.crypto.modes;
public class GCMBlockCipher {
private Object engine;
public GCMBlockCipher(Object engine) {
this.engine = engine;
}
public void init(boolean forEncryption, Object params) { }
public int getOutputSize(int len) {
return len + 16; // Add space for authentication tag
}
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) {
return len;
}
public int doFinal(byte[] out, int outOff) {
return 16; // Return authentication tag size
}
public void reset() { }
public int getBlockSize() {
return 16;
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.crypto.paddings;
public class PKCS7Padding {
public PKCS7Padding() { }
public void init(Object random) { }
public String getPaddingName() {
return "PKCS7";
}
public int addPadding(byte[] in, int inOff) {
return 0; // Dummy implementation
}
public int padCount(byte[] in) {
return 0; // Dummy implementation
}
}

View File

@@ -0,0 +1,40 @@
package org.bouncycastle.crypto.paddings;
public class PaddedBufferedBlockCipher {
private Object cipher;
private Object padding;
public PaddedBufferedBlockCipher(Object cipher) {
this.cipher = cipher;
this.padding = new PKCS7Padding();
}
public PaddedBufferedBlockCipher(Object cipher, Object padding) {
this.cipher = cipher;
this.padding = padding;
}
public void init(boolean forEncryption, Object params) { }
public int getBlockSize() {
return 16;
}
public int getUpdateOutputSize(int len) {
return len + getBlockSize();
}
public int getOutputSize(int len) {
return len + getBlockSize();
}
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) {
return len;
}
public int doFinal(byte[] out, int outOff) {
return getBlockSize();
}
public void reset() { }
}

View File

@@ -0,0 +1,35 @@
package org.bouncycastle.crypto.params;
public class AEADParameters {
private final KeyParameter key;
private final int macSize;
private final byte[] nonce;
private final byte[] associatedText;
public AEADParameters(KeyParameter key, int macSize, byte[] nonce) {
this(key, macSize, nonce, null);
}
public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) {
this.key = key;
this.macSize = macSize;
this.nonce = nonce.clone();
this.associatedText = associatedText != null ? associatedText.clone() : null;
}
public KeyParameter getKey() {
return key;
}
public int getMacSize() {
return macSize;
}
public byte[] getNonce() {
return nonce.clone();
}
public byte[] getAssociatedText() {
return associatedText != null ? associatedText.clone() : null;
}
}

View File

@@ -0,0 +1,48 @@
package org.bouncycastle.crypto.params;
import org.bouncycastle.asn1.x9.X9ECParameters;
import java.math.BigInteger;
public class ECDomainParameters {
private final X9ECParameters parameters;
private final Object curve;
private final Object g;
private final BigInteger n;
private final BigInteger h;
public ECDomainParameters(X9ECParameters parameters) {
this.parameters = parameters;
this.curve = null;
this.g = null;
this.n = null;
this.h = null;
}
public ECDomainParameters(Object curve, Object g, BigInteger n, BigInteger h) {
this.parameters = null;
this.curve = curve;
this.g = g;
this.n = n;
this.h = h;
}
public X9ECParameters getParameters() {
return parameters;
}
public Object getCurve() {
return curve;
}
public Object getG() {
return g;
}
public BigInteger getN() {
return n;
}
public BigInteger getH() {
return h;
}
}

View File

@@ -0,0 +1,21 @@
package org.bouncycastle.crypto.params;
import java.security.SecureRandom;
public class ECKeyGenerationParameters {
private final ECDomainParameters domainParameters;
private final SecureRandom random;
public ECKeyGenerationParameters(ECDomainParameters domainParameters, SecureRandom random) {
this.domainParameters = domainParameters;
this.random = random;
}
public ECDomainParameters getDomainParameters() {
return domainParameters;
}
public SecureRandom getRandom() {
return random;
}
}

View File

@@ -0,0 +1,21 @@
package org.bouncycastle.crypto.params;
import java.math.BigInteger;
public class ECPrivateKeyParameters {
private final BigInteger d;
private final ECDomainParameters parameters;
public ECPrivateKeyParameters(BigInteger d, ECDomainParameters parameters) {
this.d = d;
this.parameters = parameters;
}
public BigInteger getD() {
return d;
}
public ECDomainParameters getParameters() {
return parameters;
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.crypto.params;
public class ECPublicKeyParameters {
private final Object q;
private final ECDomainParameters parameters;
public ECPublicKeyParameters(Object q, ECDomainParameters parameters) {
this.q = q;
this.parameters = parameters;
}
public Object getQ() {
return q;
}
public ECDomainParameters getParameters() {
return parameters;
}
}

View File

@@ -0,0 +1,15 @@
package org.bouncycastle.crypto.params;
import java.security.SecureRandom;
public class Ed25519KeyGenerationParameters {
private final SecureRandom random;
public Ed25519KeyGenerationParameters(SecureRandom random) {
this.random = random;
}
public SecureRandom getRandom() {
return random;
}
}

View File

@@ -0,0 +1,18 @@
package org.bouncycastle.crypto.params;
import java.security.SecureRandom;
public class Ed25519PrivateKeyParameters {
public Ed25519PrivateKeyParameters(SecureRandom random) { }
public Ed25519PrivateKeyParameters(byte[] privateKey) { }
public Ed25519PublicKeyParameters generatePublicKey() {
return new Ed25519PublicKeyParameters(new byte[32]);
}
public byte[] getEncoded() {
return new byte[32];
}
}

View File

@@ -0,0 +1,11 @@
package org.bouncycastle.crypto.params;
public class Ed25519PublicKeyParameters {
private byte[] publicKey = new byte[32];
public Ed25519PublicKeyParameters(byte[] publicKey) { }
public byte[] getEncoded() {
return publicKey;
}
}

View File

@@ -0,0 +1,15 @@
package org.bouncycastle.crypto.params;
import java.security.SecureRandom;
public class Ed448KeyGenerationParameters {
private final SecureRandom random;
public Ed448KeyGenerationParameters(SecureRandom random) {
this.random = random;
}
public SecureRandom getRandom() {
return random;
}
}

View File

@@ -0,0 +1,18 @@
package org.bouncycastle.crypto.params;
import java.security.SecureRandom;
public class Ed448PrivateKeyParameters {
public Ed448PrivateKeyParameters(SecureRandom random) { }
public Ed448PrivateKeyParameters(byte[] privateKey) { }
public Ed448PublicKeyParameters generatePublicKey() {
return new Ed448PublicKeyParameters(new byte[57]); // Ed448 public keys are 57 bytes
}
public byte[] getEncoded() {
return new byte[57]; // Ed448 private keys are also 57 bytes
}
}

View File

@@ -0,0 +1,11 @@
package org.bouncycastle.crypto.params;
public class Ed448PublicKeyParameters {
private byte[] publicKey = new byte[57]; // Ed448 public keys are 57 bytes
public Ed448PublicKeyParameters(byte[] publicKey) { }
public byte[] getEncoded() {
return publicKey;
}
}

View File

@@ -0,0 +1,13 @@
package org.bouncycastle.crypto.params;
public class KeyParameter {
private final byte[] key;
public KeyParameter(byte[] key) {
this.key = key.clone();
}
public byte[] getKey() {
return key.clone();
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.crypto.params;
public class ParametersWithIV {
private final Object parameters;
private final byte[] iv;
public ParametersWithIV(Object parameters, byte[] iv) {
this.parameters = parameters;
this.iv = iv.clone();
}
public Object getParameters() {
return parameters;
}
public byte[] getIV() {
return iv.clone();
}
}

View File

@@ -0,0 +1,23 @@
package org.bouncycastle.crypto.signers;
import java.math.BigInteger;
public class ECDSASigner {
private boolean forSigning;
private Object keyParameter;
public void init(boolean forSigning, Object keyParameter) {
this.forSigning = forSigning;
this.keyParameter = keyParameter;
}
public void update(byte[] message, int offset, int length) { }
public BigInteger[] generateSignature(byte[] message) {
return new BigInteger[] { BigInteger.ZERO, BigInteger.ZERO };
}
public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
return true;
}
}

View File

@@ -0,0 +1,18 @@
package org.bouncycastle.crypto.signers;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
public class Ed25519Signer {
public void init(boolean forSigning, Object keyParameter) { }
public void update(byte[] message, int offset, int length) { }
public byte[] generateSignature() {
return new byte[64];
}
public boolean verifySignature(byte[] signature) {
return true;
}
}

View File

@@ -0,0 +1,20 @@
package org.bouncycastle.crypto.signers;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
public class Ed448Signer {
public Ed448Signer(byte[] context) { }
public void init(boolean forSigning, Object keyParameter) { }
public void update(byte[] message, int offset, int length) { }
public byte[] generateSignature() {
return new byte[114];
}
public boolean verifySignature(byte[] signature) {
return true;
}
}

View File

@@ -0,0 +1,41 @@
package org.bouncycastle.jcajce.provider.asymmetric.ec;
import java.security.interfaces.ECPrivateKey;
import java.math.BigInteger;
public class BCECPrivateKey implements ECPrivateKey {
private final BigInteger d;
public BCECPrivateKey(BigInteger d) {
this.d = d;
}
public BigInteger getD() {
return d;
}
@Override
public String getAlgorithm() {
return "EC";
}
@Override
public String getFormat() {
return "PKCS#8";
}
@Override
public byte[] getEncoded() {
return new byte[0];
}
@Override
public java.security.spec.ECParameterSpec getParams() {
return null;
}
@Override
public BigInteger getS() {
return d;
}
}

View File

@@ -0,0 +1,37 @@
package org.bouncycastle.jcajce.provider.asymmetric.ec;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPoint;
public class BCECPublicKey implements ECPublicKey {
private final ECPoint w;
public BCECPublicKey(ECPoint w) {
this.w = w;
}
@Override
public String getAlgorithm() {
return "EC";
}
@Override
public String getFormat() {
return "X.509";
}
@Override
public byte[] getEncoded() {
return new byte[0];
}
@Override
public java.security.spec.ECParameterSpec getParams() {
return null;
}
@Override
public ECPoint getW() {
return w;
}
}

View File

@@ -0,0 +1,13 @@
package org.bouncycastle.jce;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
public class ECNamedCurveTable {
public static ECNamedCurveParameterSpec getParameterSpec(String name) {
return new ECNamedCurveParameterSpec(name, null, null, null, null);
}
public static String[] getNames() {
return new String[] { "secp256r1", "secp256k1", "secp384r1" };
}
}

View File

@@ -0,0 +1,9 @@
package org.bouncycastle.jce.provider;
import java.security.Provider;
public class BouncyCastleProvider extends Provider {
public BouncyCastleProvider() {
super("BC", 1.0, "Bouncy Castle Security Provider v2.73.7");
}
}

View File

@@ -0,0 +1,39 @@
package org.bouncycastle.jce.spec;
import java.math.BigInteger;
public class ECNamedCurveParameterSpec {
private final String name;
private final Object curve;
private final Object g;
private final BigInteger n;
private final BigInteger h;
public ECNamedCurveParameterSpec(String name, Object curve, Object g, BigInteger n, BigInteger h) {
this.name = name;
this.curve = curve;
this.g = g;
this.n = n;
this.h = h;
}
public String getName() {
return name;
}
public Object getCurve() {
return curve;
}
public Object getG() {
return g;
}
public BigInteger getN() {
return n;
}
public BigInteger getH() {
return h;
}
}

View File

@@ -0,0 +1,16 @@
package org.bouncycastle.jce.spec;
import java.security.spec.ECParameterSpec;
public class ECNamedCurveSpec extends ECParameterSpec {
private final String name;
public ECNamedCurveSpec(String name, Object curve, Object generator, Object order) {
super(null, null, null, 0);
this.name = name;
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
public class ECCurve {
public ECCurve() { }
public ECPoint createPoint(BigInteger x, BigInteger y) {
return new ECPoint();
}
public ECPoint getInfinity() {
return new ECPoint();
}
public int getFieldSize() {
return 256;
}
}

View File

@@ -0,0 +1,35 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
public class ECPoint {
public ECPoint() { }
public ECPoint add(ECPoint other) {
return new ECPoint();
}
public ECPoint multiply(BigInteger k) {
return new ECPoint();
}
public ECPoint negate() {
return new ECPoint();
}
public boolean isInfinity() {
return false;
}
public ECPoint normalize() {
return this;
}
public BigInteger getAffineXCoord() {
return BigInteger.ZERO;
}
public BigInteger getAffineYCoord() {
return BigInteger.ZERO;
}
}

View File

@@ -0,0 +1,10 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMOtsParameters {
public static final LMOtsParameters sha256_n32_w1 = new LMOtsParameters();
public static final LMOtsParameters sha256_n32_w2 = new LMOtsParameters();
public static final LMOtsParameters sha256_n32_w4 = new LMOtsParameters();
public static final LMOtsParameters sha256_n32_w8 = new LMOtsParameters();
private LMOtsParameters() { }
}

View File

@@ -0,0 +1,21 @@
package org.bouncycastle.pqc.crypto.lms;
import java.security.SecureRandom;
public class LMSKeyGenerationParameters {
private final LMSParameters lmsParameters;
private final SecureRandom random;
public LMSKeyGenerationParameters(LMSParameters lmsParameters, SecureRandom random) {
this.lmsParameters = lmsParameters;
this.random = random;
}
public LMSParameters getLMSParameters() {
return lmsParameters;
}
public SecureRandom getRandom() {
return random;
}
}

View File

@@ -0,0 +1,21 @@
package org.bouncycastle.pqc.crypto.lms;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
public class LMSKeyPairGenerator {
private LMSKeyGenerationParameters parameters;
public void init(LMSKeyGenerationParameters parameters) {
this.parameters = parameters;
}
public AsymmetricCipherKeyPair generateKeyPair() {
byte[] privateKeyData = new byte[32];
byte[] publicKeyData = new byte[32];
LMSPrivateKeyParameters privateKey = new LMSPrivateKeyParameters(privateKeyData);
LMSPublicKeyParameters publicKey = new LMSPublicKeyParameters(publicKeyData);
return new AsymmetricCipherKeyPair(publicKey, privateKey);
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMSParameters {
private final LMSigParameters lmSigParameters;
private final LMOtsParameters lmOtsParameters;
public LMSParameters(LMSigParameters lmSigParameters, LMOtsParameters lmOtsParameters) {
this.lmSigParameters = lmSigParameters;
this.lmOtsParameters = lmOtsParameters;
}
public LMSigParameters getLMSigParameters() {
return lmSigParameters;
}
public LMOtsParameters getLMOtsParameters() {
return lmOtsParameters;
}
}

View File

@@ -0,0 +1,13 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMSPrivateKeyParameters {
private final byte[] keyData;
public LMSPrivateKeyParameters(byte[] keyData) {
this.keyData = keyData.clone();
}
public byte[] getEncoded() {
return keyData.clone();
}
}

View File

@@ -0,0 +1,13 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMSPublicKeyParameters {
private final byte[] keyData;
public LMSPublicKeyParameters(byte[] keyData) {
this.keyData = keyData.clone();
}
public byte[] getEncoded() {
return keyData.clone();
}
}

View File

@@ -0,0 +1,19 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMSSigner {
private boolean forSigning;
private Object keyParameter;
public void init(boolean forSigning, Object keyParameter) {
this.forSigning = forSigning;
this.keyParameter = keyParameter;
}
public byte[] generateSignature(byte[] message) {
return new byte[64];
}
public boolean verifySignature(byte[] message, byte[] signature) {
return true;
}
}

View File

@@ -0,0 +1,10 @@
package org.bouncycastle.pqc.crypto.lms;
public class LMSigParameters {
public static final LMSigParameters lms_sha256_n32_h10 = new LMSigParameters();
public static final LMSigParameters lms_sha256_n32_h15 = new LMSigParameters();
public static final LMSigParameters lms_sha256_n32_h20 = new LMSigParameters();
public static final LMSigParameters lms_sha256_n32_h25 = new LMSigParameters();
private LMSigParameters() { }
}

View File

@@ -182,6 +182,13 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
*/
abstract class AlgorithmInstance extends KnownElement { }
abstract class EllipticCurveConsumingAlgorithmInstance extends AlgorithmInstance {
/**
* Gets the elliptic curve used by this algorithm.
*/
abstract AlgorithmValueConsumer getEllipticCurveConsumer();
}
/**
* An element that represents a generic source of data.
*
@@ -599,6 +606,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
ECDSA() or
Ed25519() or
Ed448() or
LMS() or
HSS() or
MLDSA() or
OtherSignatureAlgorithmType()
newtype TKEMAlgorithmType =
@@ -707,6 +717,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
or
type = TSignature(Ed448()) and name = "Ed448"
or
type = TSignature(LMS()) and name = "LMS"
or
type = TSignature(MLDSA()) and name = "MLDSA"
or
type = TSignature(OtherSignatureAlgorithmType()) and name = "UnknownSignature"
or
// Key Encapsulation Mechanisms
@@ -800,6 +814,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
*/
abstract class SignatureOperationInstance extends KeyOperationInstance {
/**
* Gets the consumer of the signature that is being verified in case of a
* verification operation.
* Gets the consumer of the signature that is being verified in case of a
* verification operation.
*/
@@ -881,6 +897,11 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
* Holds if this algorithm is expected to have a padding scheme specified.
*/
predicate shouldHavePaddingScheme() { any() }
/**
* Holds if this algorithm is expected to have an elliptic curve specified.
*/
predicate shouldHaveEllipticCurve() { any() }
}
newtype TBlockCipherModeOfOperationType =
@@ -1408,6 +1429,25 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
class AssetNode = NodeBase;
/**
* Holds if the given elliptic curve is directly consumed by another algorithm
* node.
*
* This predicate is used to filter out elliptic curve nodes in cases where
* the algorithm instance and the curve instance are represented by the same
* algorithm value consumer (e.g. in cases where both the algorithm and the
* curve are determined by the same instance).
*
* An alternative way to handle this would be to use separate instances to
* represent the elliptic curve and the algorithm.
*/
predicate isConsumedEllipticCurveNode(EllipticCurveNode node) {
exists(AlgorithmNode other |
other.asElement() instanceof EllipticCurveConsumingAlgorithmInstance and
other.asElement() = node.asElement()
)
}
/**
* A cryptographic operation, such as hashing or encryption.
*/
@@ -1433,7 +1473,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
AlgorithmNode getAKnownAlgorithm() {
result =
this.asElement().(OperationInstance).getAnAlgorithmValueConsumer().getAKnownSourceNode() and
this.isCandidateAlgorithmNode(result)
this.isCandidateAlgorithmNode(result) and
not isConsumedEllipticCurveNode(result)
}
override NodeBase getChild(string edgeName) {
@@ -1622,6 +1663,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
*/
private class KeyCreationCandidateAlgorithmNode extends TKeyCreationCandidateAlgorithm instanceof AlgorithmNode
{
LocatableElement asElement() { result = super.asElement() }
string toString() { result = super.getAlgorithmName() }
}
@@ -1664,7 +1707,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
KeyCreationCandidateAlgorithmNode getAKnownAlgorithm() {
result =
instance.(KeyCreationOperationInstance).getAnAlgorithmValueConsumer().getAKnownSourceNode()
instance.(KeyCreationOperationInstance).getAnAlgorithmValueConsumer().getAKnownSourceNode() and
not isConsumedEllipticCurveNode(result)
}
override NodeBase getChild(string edgeName) {
@@ -2363,6 +2407,26 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
result.asElement() = instance.asAlg().getPaddingAlgorithm()
}
/**
* Gets the elliptic curve used by this algorithm, if applicable.
*/
NodeBase getEllipticCurveOrGenericSource() {
result instanceof EllipticCurveNode and
result =
instance
.asAlg()
.(EllipticCurveConsumingAlgorithmInstance)
.getEllipticCurveConsumer()
.getAKnownSourceNode()
or
result =
instance
.asAlg()
.(EllipticCurveConsumingAlgorithmInstance)
.getEllipticCurveConsumer()
.getAGenericSourceNode()
}
override NodeBase getChild(string edgeName) {
result = super.getChild(edgeName)
or
@@ -2383,6 +2447,15 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
else result = this
) and
instance.asAlg().shouldHavePaddingScheme()
or
// [KNOWN_OR_UNKNOWN] - but only if not suppressed
edgeName = "Curve" and
(
if exists(this.getEllipticCurveOrGenericSource())
then result = this.getEllipticCurveOrGenericSource()
else result = this
) and
instance.asAlg() instanceof EllipticCurveConsumingAlgorithmInstance
}
override predicate properties(string key, string value, Location location) {