Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing inconsistent crypto consts #190

Merged
Show file tree
Hide file tree
Changes from all commits
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
75 changes: 65 additions & 10 deletions crate/kmip/src/crypto/elliptic_curves/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ pub fn create_approved_ecc_key_pair(
mod tests {
#[cfg(not(feature = "fips"))]
use openssl::pkey::{Id, PKey};
// Load FIPS provider module from OpenSSL.
#[cfg(feature = "fips")]
use openssl::provider::Provider;

#[cfg(feature = "fips")]
use super::{check_ecc_mask_against_flags, check_ecc_mask_algorithm_compliance};
Expand Down Expand Up @@ -495,7 +498,7 @@ mod tests {
fn test_ed25519_keypair_generation() {
#[cfg(feature = "fips")]
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();
Provider::load(None, "fips").unwrap();

let algorithm = Some(CryptographicAlgorithm::Ed25519);
let private_key_mask = Some(CryptographicUsageMask::Sign);
Expand Down Expand Up @@ -538,10 +541,6 @@ mod tests {
#[test]
#[cfg(not(feature = "fips"))]
fn test_x25519_conversions() {
#[cfg(feature = "fips")]
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

// Create a Key pair
// - the private key is a TransparentEcPrivateKey where the key value is the bytes of the scalar
// - the public key is a TransparentEcPublicKey where the key value is the bytes of the Montgomery point
Expand Down Expand Up @@ -643,7 +642,7 @@ mod tests {
fn test_approved_ecc_keypair_generation() {
#[cfg(feature = "fips")]
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();
Provider::load(None, "fips").unwrap();

// P-CURVES
keypair_generation(RecommendedCurve::P224);
Expand All @@ -655,10 +654,6 @@ mod tests {
#[test]
#[cfg(not(feature = "fips"))]
fn test_x448_conversions() {
#[cfg(feature = "fips")]
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

// Create a Key pair
// - the private key is a TransparentEcPrivateKey where the key value is the bytes of the scalar
// - the public key is a TransparentEcPublicKey where the key value is the bytes of the Montgomery point
Expand Down Expand Up @@ -712,6 +707,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_exact() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Sign
| CryptographicUsageMask::Verify
| CryptographicUsageMask::Encrypt
Expand All @@ -730,6 +728,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_correct() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Authenticate;

let flags = CryptographicUsageMask::Sign
Expand All @@ -746,6 +747,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_none() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let flags = CryptographicUsageMask::Unrestricted;

let res = check_ecc_mask_against_flags(None, flags);
Expand All @@ -756,6 +760,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_all() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = FIPS_PRIVATE_ECC_MASK_SIGN;

let flags = CryptographicUsageMask::Sign
Expand All @@ -780,6 +787,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_fips_sign() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Sign;
let res = check_ecc_mask_against_flags(Some(mask), FIPS_PRIVATE_ECC_MASK_SIGN);

Expand All @@ -794,6 +804,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_mask_flags_fips_dh() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::KeyAgreement;
let res = check_ecc_mask_against_flags(Some(mask), FIPS_PRIVATE_ECC_MASK_ECDH);

Expand Down Expand Up @@ -821,6 +834,9 @@ mod tests {
#[cfg(feature = "fips")]
/// This test should fail for unrestricted should not happen in FIPS mode.
fn test_mask_flags_unrestricted1() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Unrestricted;
let flags = CryptographicUsageMask::Unrestricted;

Expand All @@ -833,6 +849,9 @@ mod tests {
#[cfg(feature = "fips")]
/// This test should fail for unrestricted should not happen in FIPS mode.
fn test_mask_flags_unrestricted2() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Sign
| CryptographicUsageMask::Verify
| CryptographicUsageMask::Encrypt
Expand All @@ -848,6 +867,9 @@ mod tests {
#[cfg(feature = "fips")]
/// This test should fail for unrestricted should not happen in FIPS mode.
fn test_mask_flags_incorrect1() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Encrypt | CryptographicUsageMask::Decrypt;
let flags = CryptographicUsageMask::Encrypt;

Expand All @@ -860,6 +882,9 @@ mod tests {
#[cfg(feature = "fips")]
/// This test should fail for unrestricted should not happen in FIPS mode.
fn test_mask_flags_incorrect2() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::WrapKey;
let flags = CryptographicUsageMask::UnwrapKey;

Expand All @@ -872,6 +897,9 @@ mod tests {
#[cfg(feature = "fips")]
/// This test should fail for unrestricted should not happen in FIPS mode.
fn test_mask_flags_incorrect3() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let mask = CryptographicUsageMask::Sign
| CryptographicUsageMask::Verify
| CryptographicUsageMask::Encrypt
Expand All @@ -889,6 +917,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_check_ecc_algo_none() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let private_key_mask = CryptographicUsageMask::Sign;
let public_key_mask = CryptographicUsageMask::Verify;

Expand All @@ -906,6 +937,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_check_ecc_algo_contains() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let private_key_mask = CryptographicUsageMask::KeyAgreement;
let public_key_mask = CryptographicUsageMask::KeyAgreement;

Expand All @@ -928,6 +962,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_check_ecc_algo_not_contains() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let private_key_mask = CryptographicUsageMask::KeyAgreement;
let public_key_mask = CryptographicUsageMask::KeyAgreement;

Expand All @@ -946,6 +983,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_bad_mask() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let algorithm = CryptographicAlgorithm::EC;
let private_key_mask = CryptographicUsageMask::Decrypt;
let public_key_mask = CryptographicUsageMask::Encrypt;
Expand Down Expand Up @@ -1017,6 +1057,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_bad_algorithm() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let algorithm = CryptographicAlgorithm::Ed25519;
let private_key_mask = CryptographicUsageMask::Sign;
let public_key_mask = CryptographicUsageMask::Verify;
Expand Down Expand Up @@ -1062,6 +1105,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_incorrect_mask_and_algorithm_ecdh() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

// ECDH algorithm should not have Sign and Verify masks;
let algorithm = CryptographicAlgorithm::ECDH;
let private_key_mask = CryptographicUsageMask::Sign
Expand All @@ -1085,6 +1131,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_incorrect_mask_and_algorithm_ecdsa() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

// ECDSA algorithm should not have KeyAgreement mask;
let algorithm = CryptographicAlgorithm::ECDSA;
let private_key_mask = CryptographicUsageMask::Sign;
Expand All @@ -1104,6 +1153,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_incorrect_private_mask() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let algorithm = CryptographicAlgorithm::ECDSA;
let private_key_mask = CryptographicUsageMask::Sign | CryptographicUsageMask::Verify;
let public_key_mask = CryptographicUsageMask::Verify;
Expand All @@ -1122,6 +1174,9 @@ mod tests {
#[test]
#[cfg(feature = "fips")]
fn test_create_ecc_keys_incorrect_public_mask() {
// Load FIPS provider module from OpenSSL.
Provider::load(None, "fips").unwrap();

let algorithm = CryptographicAlgorithm::ECDSA;
let private_key_mask = CryptographicUsageMask::Sign;
let public_key_mask = CryptographicUsageMask::Sign;
Expand Down
15 changes: 9 additions & 6 deletions crate/kmip/src/crypto/password_derivation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ use crate::error::KmipError;
#[cfg(feature = "fips")]
use crate::kmip_bail;

/// Minimum random salt size in bytes to use when deriving keys.
const FIPS_MIN_SALT_SIZE: usize = 16;
Copy link
Contributor

@Manuthor Manuthor Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size in bytes and size in bits are a bit confusing. Does it make sense to uniformize them in the same unity ? Could we adopt a naming variable convention to make it clear that those constants are in bytes or in bits. Also, I see XXX_KLEN, XXX_HLEN, XXX_SIZE, XXX_SIZE_BITS and XXX_LENGTH. Should we use a unique suffix to those variables (_SIZE for example?)

#[cfg(feature = "fips")]
const FIPS_HLEN_BITS: usize = 512;
/// Output size in bits of the hash function used in PBKDF2.
const FIPS_HLEN: usize = 512;
#[cfg(feature = "fips")]
const FIPS_MIN_KLEN: usize = 14;
/// Minimum key length in bits to be derived in FIPS mode.
const FIPS_MIN_KLEN: usize = 112;
#[cfg(feature = "fips")]
/// Max key length authorized is (2^32 - 1) x hLen.
/// Max key length in bits authorized is (2^32 - 1) x hLen.
/// Source: NIST.FIPS.800-132 - Section 5.3.
const FIPS_MAX_KLEN: usize = ((1 << 32) - 1) * FIPS_HLEN_BITS;
const FIPS_MAX_KLEN: usize = ((1 << 32) - 1) * FIPS_HLEN;

#[cfg(feature = "fips")]
/// OWASP recommended parameter for SHA-512 chosen following NIST.FIPS.800-132
Expand All @@ -31,8 +34,8 @@ const FIPS_MIN_ITER: usize = 210_000;
pub fn derive_key_from_password<const LENGTH: usize>(
password: &[u8],
) -> Result<Secret<LENGTH>, KmipError> {
// Check requested key length is in the authorized bounds.
if LENGTH < FIPS_MIN_KLEN || LENGTH * 8 > FIPS_MAX_KLEN {
// Check requested key length converted in bits is in the authorized bounds.
if LENGTH * 8 < FIPS_MIN_KLEN || LENGTH * 8 > FIPS_MAX_KLEN {
kmip_bail!("Password derivation error: wrong output length argument, got {LENGTH}")
}

Expand Down
2 changes: 1 addition & 1 deletion crate/kmip/src/crypto/rsa/ckm_rsa_aes_key_wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn ckm_rsa_aes_key_unwrap(
let rsa_privkey = p_key.rsa()?;

#[cfg(feature = "fips")]
if rsa_privkey.size() < FIPS_MIN_RSA_MODULUS_LENGTH {
if p_key.bits() < FIPS_MIN_RSA_MODULUS_LENGTH {
kmip_bail!(
"CKM_RSA_OAEP decryption error: RSA key has insufficient size: expected >= {} bytes \
and got {} bytes",
Expand Down
8 changes: 4 additions & 4 deletions crate/kmip/src/crypto/rsa/ckm_rsa_pkcs_oaep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ fn init_ckm_rsa_pkcs_oaep_encryption_context(
) -> Result<(PkeyCtx<Public>, Vec<u8>), KmipError> {
let rsa_pub_key = pub_key.rsa()?;
#[cfg(feature = "fips")]
if pub_key.bits() < (FIPS_MIN_RSA_MODULUS_LENGTH * 8) {
if pub_key.bits() < FIPS_MIN_RSA_MODULUS_LENGTH {
kmip_bail!(
"CKM_RSA_OAEP encryption error: RSA key has insufficient size: expected >= {} bits \
and got {} bits",
(FIPS_MIN_RSA_MODULUS_LENGTH * 8),
FIPS_MIN_RSA_MODULUS_LENGTH,
pub_key.bits()
)
}
Expand Down Expand Up @@ -146,11 +146,11 @@ fn init_ckm_rsa_pkcs_oaep_decryption_context(
) -> Result<(PkeyCtx<Private>, Zeroizing<Vec<u8>>), KmipError> {
let rsa_priv_key = priv_key.rsa()?;
#[cfg(feature = "fips")]
if priv_key.bits() < (FIPS_MIN_RSA_MODULUS_LENGTH * 8) {
if priv_key.bits() < FIPS_MIN_RSA_MODULUS_LENGTH {
kmip_bail!(
"CKM_RSA_OAEP decryption error: RSA key has insufficient size: expected >= {} bits \
and got {} bits",
(FIPS_MIN_RSA_MODULUS_LENGTH * 8),
FIPS_MIN_RSA_MODULUS_LENGTH,
priv_key.bits()
)
}
Expand Down
3 changes: 2 additions & 1 deletion crate/kmip/src/crypto/rsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pub mod operation;
pub mod rsa_oaep_aes_gcm;

#[cfg(feature = "fips")]
pub const FIPS_MIN_RSA_MODULUS_LENGTH: u32 = 256;
/// FIPS minimum modulus length in bits.
pub const FIPS_MIN_RSA_MODULUS_LENGTH: u32 = 2048;

#[cfg(feature = "fips")]
/// RSA private key mask usage for FIPS mode: signing, auth and encryption.
Expand Down
16 changes: 14 additions & 2 deletions crate/kmip/src/crypto/rsa/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ pub fn create_rsa_key_pair(
public_key_mask: Option<CryptographicUsageMask>,
) -> Result<KeyPair, KmipError> {
#[cfg(feature = "fips")]
if key_size_in_bits < FIPS_MIN_RSA_MODULUS_LENGTH * 8 {
if key_size_in_bits < FIPS_MIN_RSA_MODULUS_LENGTH {
kmip_bail!(
"FIPS 140 mode requires a minimum key length of {} bits",
FIPS_MIN_RSA_MODULUS_LENGTH * 8
FIPS_MIN_RSA_MODULUS_LENGTH
)
}

Expand Down Expand Up @@ -230,6 +230,9 @@ pub fn create_rsa_key_pair(
#[test]
#[cfg(feature = "fips")]
fn test_create_rsa_incorrect_mask() {
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

let private_key_mask = Some(CryptographicUsageMask::Sign);
let public_key_mask = Some(CryptographicUsageMask::Sign | CryptographicUsageMask::Verify);

Expand Down Expand Up @@ -262,6 +265,9 @@ fn test_create_rsa_incorrect_mask() {
#[test]
#[cfg(feature = "fips")]
fn test_create_rsa_incorrect_mask_unrestricted() {
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

let private_key_mask = Some(CryptographicUsageMask::Unrestricted);
let public_key_mask = Some(CryptographicUsageMask::Verify);

Expand Down Expand Up @@ -294,6 +300,9 @@ fn test_create_rsa_incorrect_mask_unrestricted() {
#[test]
#[cfg(feature = "fips")]
fn test_create_rsa_fips_mask() {
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

let algorithm = Some(CryptographicAlgorithm::RSA);

let res = create_rsa_key_pair(
Expand All @@ -311,6 +320,9 @@ fn test_create_rsa_fips_mask() {
#[test]
#[cfg(feature = "fips")]
fn test_create_rsa_incorrect_algorithm() {
// Load FIPS provider module from OpenSSL.
openssl::provider::Provider::load(None, "fips").unwrap();

let private_key_mask = Some(CryptographicUsageMask::Sign);
let public_key_mask = Some(CryptographicUsageMask::Verify);

Expand Down
Loading
Loading