Visitar URL original
Crypto: Support additional JCA algorithms/modes, add PQC demo queries by nicolaswill · Pull Request #21354 · github/codeql · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Support additional JCA algorithms and tests
Extend the experimental JCA model to recognize additional symmetric ciphers and padding/mode types (ARIA, Camellia, Twofish, SEED, Salsa20, LRW, PKCS1Padding, PSS) and fix DES/DESEDE classification ordering. Add test coverage with AdditionalSymmetricAlgorithms.java and expand existing tests: EllipticCurve1 (Ed448 and NIST P-256/P-384/P-521 key generation) and SymmetricModesTest (3DES ECB, DES CFB/OFB). Update standardization logic and test expectations (node_edges, node_properties, nodes) to reflect the new algorithm mappings.
  • Loading branch information
nicolaswill committed Feb 22, 2026
commit e0ff863b85a61beeb40f9ad62acded90ddfed28e
35 changes: 30 additions & 5 deletions java/ql/lib/experimental/quantum/JCA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ module JCAModel {
predicate cipher_names(string algo) {
algo.toUpperCase()
.matches([
"AES", "AESWrap", "AESWrapPad", "ARCFOUR", "Blowfish", "ChaCha20", "ChaCha20-Poly1305",
"DES", "DESede", "DESedeWrap", "ECIES", "PBEWith%", "RC2", "RC4", "RC5", "RSA",
"Skipjack", "Idea"
"AES", "AESWrap", "AESWrapPad", "ARCFOUR", "ARIA", "Blowfish", "Camellia",
"ChaCha20", "ChaCha20-Poly1305", "DES", "DESede", "DESedeWrap", "ECIES",
"PBEWith%", "RC2", "RC4", "RC5", "RSA", "Salsa20", "SEED", "Skipjack", "Idea",
"Twofish"
].toUpperCase())
}

Expand Down Expand Up @@ -189,6 +190,8 @@ module JCAModel {
type = KeyOpAlg::PCBC() and name = "PCBC"
or
type = KeyOpAlg::KWP() and name = "KWP"
or
type = KeyOpAlg::LRW() and name = "LRW"
}

bindingset[name]
Expand All @@ -197,13 +200,31 @@ module JCAModel {
upper.matches("AES%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
or
// NOTE: there is DES and DESede
upper.matches("DES%") and
// NOTE: DESede (TripleDES) must be matched before DES% to avoid misclassification
upper.matches("DESEDE%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
or
not upper.matches("DESEDE%") and upper.matches("DES%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DES())
or
upper = "TRIPLEDES" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
or
upper = "ARIA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::ARIA())
or
upper = "CAMELLIA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::CAMELLIA())
or
upper = "TWOFISH" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TWOFISH())
or
upper = "SEED" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::SEED())
or
upper = "SALSA20" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::SALSA20())
or
upper = "IDEA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::IDEA())
or
Expand Down Expand Up @@ -363,6 +384,10 @@ module JCAModel {
type instanceof KeyOpAlg::PKCS7 and name = ["PKCS5Padding", "PKCS7Padding"] // TODO: misnomer in the JCA?
or
type instanceof KeyOpAlg::OAEP and name.matches("OAEP%") // TODO: handle OAEPWith%
or
type instanceof KeyOpAlg::PKCS1_V1_5 and name = "PKCS1Padding"
or
type instanceof KeyOpAlg::PSS and name = "PSS"
}

override KeyOpAlg::PaddingSchemeType getPaddingType() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.example.crypto.algorithms;

import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

/**
* Demonstrates symmetric encryption using cipher algorithms beyond the
* standard JCA defaults, typically available through BouncyCastle.
*
* Algorithms covered: Twofish, ARIA, Camellia, Salsa20, SEED, Blowfish.
*/
public class AdditionalSymmetricAlgorithms {

/**
* Twofish in CBC mode with PKCS5 padding.
*/
public byte[] twofishEncrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("Twofish");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("Twofish/CBC/PKCS5Padding");
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}

/**
* ARIA in CBC mode with PKCS5 padding.
*/
public byte[] ariaEncrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("ARIA");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("ARIA/CBC/PKCS5Padding");
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}

/**
* Camellia in CBC mode with no padding.
*/
public byte[] camelliaEncrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("Camellia");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("Camellia/CBC/NoPadding");
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}

/**
* Salsa20 stream cipher.
*/
public byte[] salsa20Encrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("Salsa20");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("Salsa20");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(plaintext);
}

/**
* SEED in CBC mode with PKCS5 padding.
*/
public byte[] seedEncrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("SEED");
keyGen.init(128);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("SEED/CBC/PKCS5Padding");
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}

/**
* Blowfish in CBC mode with PKCS5 padding.
*/
public byte[] blowfishEncrypt(byte[] plaintext) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(128);
SecretKey key = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
byte[] iv = new byte[8];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,41 @@ public KeyPair generateESKeyPair() throws Exception {
return kpg.generateKeyPair();
}

/**
* Generates an Ed448 key pair (for signatures).
*/
public KeyPair generateEd448KeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed448");
return kpg.generateKeyPair();
}

/**
* Generates a key pair using the NIST P-256 alias for secp256r1.
*/
public KeyPair generateNISTP256KeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(new java.security.spec.ECGenParameterSpec("P-256"));
return kpg.generateKeyPair();
}

/**
* Generates a key pair using the NIST P-384 alias for secp384r1.
*/
public KeyPair generateNISTP384KeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(new java.security.spec.ECGenParameterSpec("P-384"));
return kpg.generateKeyPair();
}

/**
* Generates a key pair using the NIST P-521 alias for secp521r1.
*/
public KeyPair generateNISTP521KeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(new java.security.spec.ECGenParameterSpec("P-521"));
return kpg.generateKeyPair();
}

/**
* Generates a key pair for an "Other" elliptic curve type.
* This serves as a fallback example (using secp256r1).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,38 @@ public SecretKey generateAESKey() throws Exception {
kg.init(256, new SecureRandom());
return kg.generateKey();
}

// ---------------------------
// DESede and DES Mode Variants
// ---------------------------
/**
* DESede (TripleDES) in ECB mode.
*/
public byte[] tripleDesEcbEncrypt(SecretKey key, byte[] plaintext) throws Exception {
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(plaintext);
}

/**
* DES in CFB mode.
*/
public byte[] desCfbEncrypt(SecretKey key, byte[] plaintext) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CFB/NoPadding");
byte[] iv = new byte[8];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}

/**
* DES in OFB mode.
*/
public byte[] desOfbEncrypt(SecretKey key, byte[] plaintext) throws Exception {
Cipher cipher = Cipher.getInstance("DES/OFB/NoPadding");
byte[] iv = new byte[8];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(plaintext);
}
}
Loading