use crate::config::config::AlgorithmConfig;
use crate::pkcs11_abi::constants::*;
use crate::pkcs11_abi::types::{CK_MECHANISM_TYPE, CK_RV};
pub fn is_sign_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_SHA256_RSA_PKCS
| CKM_SHA384_RSA_PKCS
| CKM_SHA512_RSA_PKCS
| CKM_RSA_PKCS_PSS
| CKM_SHA256_RSA_PKCS_PSS
| CKM_SHA384_RSA_PKCS_PSS
| CKM_SHA512_RSA_PKCS_PSS
| CKM_ECDSA
| CKM_ECDSA_SHA256
| CKM_ECDSA_SHA384
| CKM_ECDSA_SHA512
| CKM_EDDSA
| CKM_ML_DSA
| CKM_ML_DSA_44
| CKM_ML_DSA_65
| CKM_ML_DSA_87
| CKM_SLH_DSA
| CKM_SLH_DSA_SHA2_128S
| CKM_SLH_DSA_SHA2_256S
| CKM_HYBRID_ML_DSA_ECDSA
)
}
pub fn is_encrypt_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_AES_GCM | CKM_AES_CBC | CKM_AES_CBC_PAD | CKM_AES_CTR | CKM_RSA_PKCS_OAEP
)
}
pub fn is_keygen_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(mechanism, CKM_AES_KEY_GEN)
}
pub fn is_keypair_gen_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_RSA_PKCS_KEY_PAIR_GEN
| CKM_EC_KEY_PAIR_GEN
| CKM_EC_EDWARDS_KEY_PAIR_GEN
| CKM_EDDSA
| CKM_ML_KEM_KEY_PAIR_GEN
| CKM_ML_DSA_KEY_PAIR_GEN
| CKM_SLH_DSA_KEY_PAIR_GEN
| CKM_ML_KEM_512
| CKM_ML_KEM_768
| CKM_ML_KEM_1024
| CKM_ML_DSA_44
| CKM_ML_DSA_65
| CKM_ML_DSA_87
| CKM_SLH_DSA_SHA2_128S
| CKM_SLH_DSA_SHA2_256S
)
}
pub fn is_kem_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(mechanism, CKM_ML_KEM_512 | CKM_ML_KEM_768 | CKM_ML_KEM_1024)
}
pub fn is_digest_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_SHA_1
| CKM_SHA256
| CKM_SHA384
| CKM_SHA512
| CKM_SHA3_256
| CKM_SHA3_384
| CKM_SHA3_512
)
}
pub fn is_wrap_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(mechanism, CKM_AES_KEY_WRAP | CKM_AES_KEY_WRAP_KWP)
}
pub fn is_derive_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(mechanism, CKM_ECDH1_DERIVE | CKM_ECDH1_COFACTOR_DERIVE)
}
pub fn supported_mechanisms() -> Vec<CK_MECHANISM_TYPE> {
vec![
CKM_RSA_PKCS_KEY_PAIR_GEN,
CKM_SHA256_RSA_PKCS,
CKM_SHA384_RSA_PKCS,
CKM_SHA512_RSA_PKCS,
CKM_RSA_PKCS_PSS,
CKM_SHA256_RSA_PKCS_PSS,
CKM_SHA384_RSA_PKCS_PSS,
CKM_SHA512_RSA_PKCS_PSS,
CKM_RSA_PKCS_OAEP,
CKM_EC_KEY_PAIR_GEN,
CKM_ECDSA,
CKM_ECDSA_SHA256,
CKM_ECDSA_SHA384,
CKM_ECDSA_SHA512,
CKM_ECDH1_DERIVE,
CKM_ECDH1_COFACTOR_DERIVE,
CKM_EC_EDWARDS_KEY_PAIR_GEN,
CKM_EDDSA,
CKM_AES_KEY_GEN,
CKM_AES_GCM,
CKM_AES_CBC,
CKM_AES_CBC_PAD,
CKM_AES_CTR,
CKM_AES_KEY_WRAP,
CKM_AES_KEY_WRAP_KWP,
CKM_SHA_1,
CKM_SHA256,
CKM_SHA384,
CKM_SHA512,
CKM_SHA3_256,
CKM_SHA3_384,
CKM_SHA3_512,
CKM_ML_KEM_KEY_PAIR_GEN,
CKM_ML_DSA_KEY_PAIR_GEN,
CKM_ML_DSA,
CKM_SLH_DSA_KEY_PAIR_GEN,
CKM_SLH_DSA,
CKM_ML_KEM_512,
CKM_ML_KEM_768,
CKM_ML_KEM_1024,
CKM_ML_DSA_44,
CKM_ML_DSA_65,
CKM_ML_DSA_87,
CKM_SLH_DSA_SHA2_128S,
CKM_SLH_DSA_SHA2_256S,
CKM_HYBRID_ML_DSA_ECDSA,
]
}
pub fn is_fips_approved(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_RSA_PKCS_KEY_PAIR_GEN
| CKM_RSA_PKCS
| CKM_SHA256_RSA_PKCS
| CKM_SHA384_RSA_PKCS
| CKM_SHA512_RSA_PKCS
| CKM_RSA_PKCS_PSS
| CKM_SHA256_RSA_PKCS_PSS
| CKM_SHA384_RSA_PKCS_PSS
| CKM_SHA512_RSA_PKCS_PSS
| CKM_RSA_PKCS_OAEP
| CKM_EC_KEY_PAIR_GEN
| CKM_ECDSA
| CKM_ECDSA_SHA256
| CKM_ECDSA_SHA384
| CKM_ECDSA_SHA512
| CKM_ECDH1_DERIVE
| CKM_ECDH1_COFACTOR_DERIVE
| CKM_AES_KEY_GEN
| CKM_AES_GCM
| CKM_AES_CBC
| CKM_AES_CBC_PAD
| CKM_AES_CTR
| CKM_AES_KEY_WRAP
| CKM_AES_KEY_WRAP_KWP
| CKM_SHA256
| CKM_SHA384
| CKM_SHA512
| CKM_SHA3_256
| CKM_SHA3_384
| CKM_SHA3_512
)
}
fn is_pqc_mechanism(mechanism: CK_MECHANISM_TYPE) -> bool {
matches!(
mechanism,
CKM_ML_KEM_KEY_PAIR_GEN
| CKM_ML_DSA_KEY_PAIR_GEN
| CKM_ML_DSA
| CKM_SLH_DSA_KEY_PAIR_GEN
| CKM_SLH_DSA
| CKM_ML_KEM_512
| CKM_ML_KEM_768
| CKM_ML_KEM_1024
| CKM_ML_DSA_44
| CKM_ML_DSA_65
| CKM_ML_DSA_87
| CKM_SLH_DSA_SHA2_128S
| CKM_SLH_DSA_SHA2_256S
| CKM_HYBRID_ML_DSA_ECDSA
)
}
pub fn validate_mechanism_for_policy(
mechanism: CK_MECHANISM_TYPE,
config: &AlgorithmConfig,
is_signing_context: bool,
) -> Result<(), CK_RV> {
if config.fips_approved_only && !is_fips_approved(mechanism) {
tracing::warn!(
"FIPS approved mode: blocking non-approved mechanism 0x{:08X}",
mechanism
);
return Err(CKR_MECHANISM_INVALID);
}
if !config.enable_pqc && is_pqc_mechanism(mechanism) {
tracing::warn!("PQC disabled: blocking PQC mechanism 0x{:08X}", mechanism);
return Err(CKR_MECHANISM_INVALID);
}
if mechanism == CKM_SHA_1 {
if config.fips_approved_only {
tracing::warn!("FIPS mode: blocking SHA-1 (CKM_SHA_1) — deprecated per SP 800-131A");
return Err(CKR_MECHANISM_INVALID);
}
if !config.allow_sha1_signing && is_signing_context {
tracing::warn!("SHA-1 signing disabled: blocking CKM_SHA_1 in signing context");
return Err(CKR_MECHANISM_INVALID);
}
}
Ok(())
}
pub fn supported_mechanisms_filtered(config: &AlgorithmConfig) -> Vec<CK_MECHANISM_TYPE> {
supported_mechanisms()
.into_iter()
.filter(|&mech| {
if config.fips_approved_only && !is_fips_approved(mech) {
return false;
}
if config.fips_approved_only && mech == CKM_SHA_1 {
return false;
}
if !config.enable_pqc && is_pqc_mechanism(mech) {
return false;
}
true
})
.collect()
}