Skip to content
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
7 changes: 6 additions & 1 deletion .github/workflows/openjdk-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ jobs:
dnf --assumeyes --disable-repo=fedora-cisco-openh264 \
install git cargo clang-devel openssl-devel zlib-devel sed \
sqlite-devel openssl opensc unzip wget \
java-${{ env.openjdk_feature }}-openjdk-devel
java-${{ env.openjdk_feature }}-openjdk-devel \
'perl(FindBin)' 'perl(lib)' 'perl(File::Compare)' \
'perl(File::Copy)' 'perl(bigint)' 'perl(Time::HiRes)' \
'perl(IPC::Cmd)' 'perl(Pod::Html)' 'perl(Digest::SHA)' \
'perl(Module::Load::Conditional)' 'perl(File::Temp)' \
'perl(Test::Harness)' 'perl(Test::More)' 'perl(Math::BigInt)'

# Kryoptic build steps; try to keep in sync with relevant build.yml steps.
- name: Checkout Repository
Expand Down
26 changes: 25 additions & 1 deletion src/fips/indicators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ struct FipsMechanism {
/// Struct that holds FIPS properties for keys and mechanisms
struct FipsChecks {
keys: [FipsKeyType; 17],
mechs: [FipsMechanism; 91],
mechs: [FipsMechanism; 93],
}

/// A constant instantiation of FIPS properties with a list
Expand Down Expand Up @@ -552,6 +552,19 @@ const FIPS_CHECKS: FipsChecks = FipsChecks {
restrictions: [restrict!(CKK_EC), restrict!()],
genflags: 0,
},
/* EDDSA */
FipsMechanism {
mechanism: CKM_EC_EDWARDS_KEY_PAIR_GEN,
operations: CKF_GENERATE_KEY_PAIR,
restrictions: [restrict!(CKK_EC_EDWARDS), restrict!()],
genflags: CKF_SIGN | CKF_VERIFY,
},
FipsMechanism {
mechanism: CKM_EDDSA,
operations: CKF_SIGN | CKF_VERIFY,
restrictions: [restrict!(CKK_EC_EDWARDS), restrict!()],
genflags: 0,
},
/* AES */
FipsMechanism {
mechanism: CKM_AES_KEY_GEN,
Expand Down Expand Up @@ -1315,6 +1328,17 @@ pub fn is_key_approved(key: &Object, op: CK_FLAGS) -> bool {
check_key(key, op, None, None)
}

/// Adds validation flag to the object, if it is not yet present
/// and if the object passes validation rules.
pub fn add_missing_validation_flag(key: &mut Object) {
if let Ok(_) = key.get_attr_as_ulong(CKA_OBJECT_VALIDATION_FLAGS) {
return;
}
if is_key_approved(key, CK_UNAVAILABLE_INFORMATION) {
add_fips_flag(key);
}
}

/// Helper to check if an operation is approved
///
/// Applies key checks as well as mechanism checks according to the
Expand Down
12 changes: 12 additions & 0 deletions src/storage/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use std::fmt::Debug;

use crate::attribute::{Attribute, CkAttrs};
use crate::error::Result;
#[cfg(feature = "fips")]
use crate::fips::indicators::add_missing_validation_flag;
use crate::object::Object;
use crate::pkcs11::*;
use crate::storage::aci::{StorageACI, StorageAuthInfo};
Expand Down Expand Up @@ -297,6 +299,13 @@ impl Storage for StdStorageFormat {
* some attributes or not */
attrs.add_missing_ulong(CKA_SENSITIVE, &dnm);
attrs.add_missing_ulong(CKA_EXTRACTABLE, &dnm);
#[cfg(feature = "fips")]
{
/* We need these to be able to derive object validation flag */
attrs.add_missing_ulong(CKA_EC_PARAMS, &dnm);
attrs.add_missing_ulong(CKA_VALUE_LEN, &dnm);
attrs.add_missing_ulong(CKA_MODULUS, &dnm);
}
}

let mut obj = self.store.fetch_by_uid(&uid, attrs.as_slice())?;
Expand All @@ -315,6 +324,9 @@ impl Storage for StdStorageFormat {
}
}

#[cfg(feature = "fips")]
add_missing_validation_flag(&mut obj);

obj.set_handle(handle);
Ok(obj)
}
Expand Down
23 changes: 12 additions & 11 deletions src/storage/nssdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use std::sync::{Arc, Mutex, MutexGuard};
use crate::attribute::{AttrType, Attribute, CkAttrs};
use crate::defaults;
use crate::error::{Error, Result};
#[cfg(feature = "fips")]
use crate::fips::indicators::add_missing_validation_flag;
use crate::misc::{copy_sized_string, zeromem};
use crate::object::Object;
use crate::pkcs11::*;
Expand Down Expand Up @@ -957,6 +959,13 @@ impl Storage for NSSStorage {
let _ = attrs.remove_ulong(a.type_);
}
}
#[cfg(feature = "fips")]
{
/* We need these to be able to derive object validation flag */
attrs.add_missing_ulong(CKA_EC_PARAMS, &dnm);
attrs.add_missing_ulong(CKA_VALUE_LEN, &dnm);
attrs.add_missing_ulong(CKA_MODULUS, &dnm);
}
}
let mut obj =
self.fetch_by_nssid(&table, nssobjid, attrs.as_slice())?;
Expand Down Expand Up @@ -1000,22 +1009,14 @@ impl Storage for NSSStorage {
match attributes.iter().position(|r| r.type_ == a) {
Some(_) => {
factory.set_attribute_default(a, &mut obj)?;
#[cfg(feature = "fips")]
if a == CKA_OBJECT_VALIDATION_FLAGS {
/* All keys stored in the database are considered
* FIPS approved, on the assumption you can't import
* or create non-approved keys in the first place
*/
obj.set_attr(Attribute::from_ulong(
CKA_OBJECT_VALIDATION_FLAGS,
crate::fips::indicators::KRF_FIPS,
))?;
}
}
None => (),
}
}

#[cfg(feature = "fips")]
add_missing_validation_flag(&mut obj);

obj.set_handle(handle);
Ok(obj)
}
Expand Down
12 changes: 12 additions & 0 deletions src/tests/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ fn test_aes_operations() {
(CKA_UNWRAP, true),
],
));
assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, handle, 1), true);

{
/* AES ECB */
Expand Down Expand Up @@ -690,6 +692,7 @@ fn test_aes_operations() {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
assert_eq!(check_object_validation(session, key_handle, 1), true);

let ciphertext = hex::decode("4154c0be71072945d8156f5f046d198d")
.expect("Failed to decode ciphertext");
Expand Down Expand Up @@ -718,6 +721,8 @@ fn test_aes_operations() {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
assert_eq!(check_object_validation(session, key_handle, 1), true);

let iv = hex::decode("1dbbeb2f19abb448af849796244a19d7")
.expect("Failed to decode IV");
let plaintext = hex::decode(
Expand Down Expand Up @@ -759,6 +764,8 @@ fn test_aes_operations() {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
assert_eq!(check_object_validation(session, key_handle, 1), true);

let (iv, aad, tag, ct, plaintext) = get_gcm_test_data();

let param = CK_GCM_PARAMS {
Expand Down Expand Up @@ -795,6 +802,8 @@ fn test_aes_operations() {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
assert_eq!(check_object_validation(session, key_handle, 1), true);

let iv = hex::decode("0007bdfd5cbd60278dcc091200000001")
.expect("failed to decode iv");
let plaintext = hex::decode(
Expand Down Expand Up @@ -911,6 +920,7 @@ fn test_aes_operations() {
&mut wp_handle2,
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_object_validation(session, wp_handle2, 1), true);

let mut value = [0u8; AES_BLOCK_SIZE];
let mut extract_template = make_ptrs_template(&[(
Expand Down Expand Up @@ -1033,6 +1043,7 @@ fn test_aes_operations() {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
assert_eq!(check_object_validation(session, key_handle, 1), true);
let (iv, aad, tag, ct, plaintext) = get_gcm_test_data();

let ret = fn_message_decrypt_init(session, &mut mechanism, key_handle);
Expand Down Expand Up @@ -1272,6 +1283,7 @@ fn test_aes_macs() {
&[],
&[(CKA_SIGN, true), (CKA_VERIFY, true),],
));
assert_eq!(check_object_validation(session, handle, 1), true);

#[cfg(not(feature = "fips"))]
{
Expand Down
13 changes: 13 additions & 0 deletions src/tests/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,15 @@ fn test_ec_keys() {
(CKA_EXTRACTABLE, true),
],
));
assert_eq!(check_validation(session, t.fips_indicator), true);
assert_eq!(
check_object_validation(session, pubkey, t.fips_indicator),
true
);
assert_eq!(
check_object_validation(session, prikey, t.fips_indicator),
true
);

if t.op_flags.1 == CKA_SIGN {
let sig = ret_or_panic!(sig_gen(
Expand Down Expand Up @@ -526,6 +535,10 @@ fn test_ec_keys() {
assert_eq!(ret, CKR_OK);

assert_eq!(check_validation(session, t.fips_indicator), true);
assert_eq!(
check_object_validation(session, prikey2, t.fips_indicator),
true
);

if t.op_flags.1 == CKA_SIGN {
/* Test the unwrapped key can be used */
Expand Down
4 changes: 4 additions & 0 deletions src/tests/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ fn test_rsa_operations() {
));

assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, hpri, 1), true);
assert_eq!(check_object_validation(session, hpub, 1), true);

let label = "Public Key test 1";
let mut template = make_ptrs_template(&[(
Expand Down Expand Up @@ -583,6 +585,8 @@ fn test_rsa_mechs() {
));

assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, pubkey, 1), true);
assert_eq!(check_object_validation(session, prikey, 1), true);

/* Classic PKCS 1.5 */
for mech in [
Expand Down
9 changes: 9 additions & 0 deletions src/tests/simplekdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fn test_concatenate_kdf() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 0), true);
assert_eq!(check_object_validation(session, dk_handle, 0), true);

let exp_value = hex::decode("0123456789abcdef").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -96,6 +97,7 @@ fn test_concatenate_kdf() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 0), true);
assert_eq!(check_object_validation(session, dk_handle, 0), true);

let exp_value = hex::decode("0123456789abcdef").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -125,6 +127,7 @@ fn test_concatenate_kdf() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 0), true);
assert_eq!(check_object_validation(session, dk_handle, 0), true);

let exp_value = hex::decode("89abcdef01234567").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -154,6 +157,7 @@ fn test_concatenate_kdf() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 0), true);
assert_eq!(check_object_validation(session, dk_handle, 0), true);

let exp_value = hex::decode("88888888").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -229,6 +233,7 @@ fn test_concatenate_kdf_fips() {
let value = ret_or_panic!(extract_key_value(session, dk_handle));
assert_eq!(value, exp_value);
assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, dk_handle, 1), true);

// Concatenate base and data
let data = hex::decode("0e0f").unwrap();
Expand All @@ -254,6 +259,7 @@ fn test_concatenate_kdf_fips() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, dk_handle, 1), true);

let exp_value = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -283,6 +289,7 @@ fn test_concatenate_kdf_fips() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, dk_handle, 1), true);

let exp_value = hex::decode("0e0f000102030405060708090a0b0c0d").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -312,6 +319,7 @@ fn test_concatenate_kdf_fips() {
);
assert_eq!(ret, CKR_OK);
assert_eq!(check_validation(session, 1), true);
assert_eq!(check_object_validation(session, dk_handle, 1), true);

let exp_value = hex::decode("00112233445566778899aabbccdd").unwrap();
let value = ret_or_panic!(extract_key_value(session, dk_handle));
Expand Down Expand Up @@ -361,6 +369,7 @@ fn test_concatenate_kdf_fips() {
let value = ret_or_panic!(extract_key_value(session, dk_handle));
assert_eq!(value, exp_value);
assert_eq!(check_validation(session, 0), true);
assert_eq!(check_object_validation(session, dk_handle, 0), true);

testtokn.finalize();
}
Loading
Loading