Skip to content
Closed
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
93 changes: 75 additions & 18 deletions crypto/core/tests/key_material_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ mod test_key_material {
key.allow_hazardous_operations();
key.set_bytes_as_type(&key_bytes, KeyType::BytesLowEntropy).unwrap();
assert_eq!(key.key_type(), KeyType::BytesLowEntropy);

key.drop_hazardous_operations();
// nothing else requires setting hazardous operations.
}

Expand Down Expand Up @@ -94,6 +94,7 @@ mod test_key_material {
key.set_key_len(32).unwrap();
assert_eq!(key.ref_to_bytes(), &[2u8; 32]);
assert_eq!(key.key_len(), 32);
key.drop_hazardous_operations();
}

#[test]
Expand Down Expand Up @@ -173,15 +174,28 @@ mod test_key_material {
#[test]
fn zeroize() {
let mut key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
let capacity = key.capacity();

// Sanity check: the backing buffer actually holds non-zero key material before it is wiped.
// Without this, the post-zeroize assertion below could pass vacuously.
key.allow_hazardous_operations();
assert!(key.mut_ref_to_bytes().unwrap().iter().any(|&b| b != 0));
key.drop_hazardous_operations();

key.zeroize();
let key_len = key.key_len();
assert_eq!(key_len, 0);
assert_eq!(key.key_type(), KeyType::Zeroized);

// zeroize() must wipe the entire backing buffer.
// Full capacity must be inspected to confirm the previously-set bytes were
// actually overwritten with zeros.
// Note: key_len is now 0, so ref_to_bytes() returns an empty slice.
key.allow_hazardous_operations();
let mut buf = vec![0u8; key_len];
buf.copy_from_slice(key.ref_to_bytes());
assert!(buf.iter().all(|&b| b == 0));
let full_buf = key.mut_ref_to_bytes().unwrap();
assert_eq!(full_buf.len(), capacity);
assert!(full_buf.iter().all(|&b| b == 0));
key.drop_hazardous_operations();
}

#[test]
Expand Down Expand Up @@ -263,8 +277,8 @@ mod test_key_material {
key.convert_key_type(KeyType::BytesFullEntropy).unwrap();
assert_eq!(key.key_type(), KeyType::BytesFullEntropy);
assert!(key.is_full_entropy());

key.drop_hazardous_operations();

match key.convert_key_type(KeyType::SymmetricCipherKey) {
Ok(()) => { /* good */ }
_ => panic!("Expected Ok(())"),
Expand All @@ -277,6 +291,7 @@ mod test_key_material {
let mut key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
key.allow_hazardous_operations();
key.convert_key_type(KeyType::BytesFullEntropy).unwrap();
key.drop_hazardous_operations();
match key.convert_key_type(KeyType::Seed) {
Ok(()) => { /* good */ }
_ => panic!("Expected Ok(())"),
Expand Down Expand Up @@ -406,18 +421,22 @@ mod test_key_material {
key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
key.allow_hazardous_operations();
key.convert_key_type(KeyType::BytesFullEntropy).unwrap();
key.drop_hazardous_operations();

key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
key.allow_hazardous_operations();
key.convert_key_type(KeyType::MACKey).unwrap();
key.drop_hazardous_operations();

key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
key.allow_hazardous_operations();
key.convert_key_type(KeyType::SymmetricCipherKey).unwrap();
key.drop_hazardous_operations();

key = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
key.allow_hazardous_operations();
key.convert_key_type(KeyType::Seed).unwrap();
key.drop_hazardous_operations();
}

#[test]
Expand Down Expand Up @@ -493,6 +512,7 @@ mod test_key_material {
// should work if you allow hazardous conversions.
key.allow_hazardous_operations();
key.convert_key_type(KeyType::SymmetricCipherKey).unwrap();
key.drop_hazardous_operations();
}

#[test]
Expand Down Expand Up @@ -570,6 +590,7 @@ mod test_key_material {
// now it should work
key.set_security_strength(SecurityStrength::_128bit).unwrap();
assert_eq!(key.security_strength(), SecurityStrength::_128bit);
key.drop_hazardous_operations();

// BytesLowEntropy keys cannot have a security strength other than None.
// success
Expand All @@ -583,12 +604,14 @@ mod test_key_material {
Err(KeyMaterialError::SecurityStrength(_)) => { /* good */ }
_ => panic!("Expected KeyMaterialError::SecurityStrength"),
}
key.drop_hazardous_operations();

// Zeroized keys cannot have a security strength other than None.
// success
let mut key = KeyMaterial256::new();
key.allow_hazardous_operations();
key.set_key_len(32).unwrap(); // still zeroized
key.drop_hazardous_operations();
assert_eq!(key.key_type(), KeyType::Zeroized);
// setting to ::None should work .. even without setting .allow_hazardous_operations()
key.set_security_strength(SecurityStrength::None).unwrap();
Expand All @@ -598,6 +621,7 @@ mod test_key_material {
Err(KeyMaterialError::SecurityStrength(_)) => { /* good */ }
_ => panic!("Expected KeyMaterialError::SecurityStrength"),
}
key.drop_hazardous_operations();
}

#[test]
Expand Down Expand Up @@ -678,22 +702,55 @@ mod test_key_material {

#[test]
fn eq() {
// On instances of the same exact type (size).
let key1 = KeyMaterial256::from_bytes(
b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
)
.unwrap();
let key2 = KeyMaterial256::from_bytes(
b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
)
.unwrap();
// For context:
// DUMMY_KEY: &[u8; 64] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\
// \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\
// \x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\
// \x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F";

// Same bytes, full capacity. Should be equal.
let key1 = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
let key2 = KeyMaterial256::from_bytes(&DUMMY_KEY[..32]).unwrap();
assert_eq!(key1, key2);

let key3 = KeyMaterial256::from_bytes(
b"\x0F\x0E\x0D\x0C\x0B\x0A\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00",
)
.unwrap();
// Same length, different content. Should NOT be equal.
let key3 = KeyMaterial256::from_bytes(&[0xFFu8; 32]).unwrap();
assert_ne!(key1, key3);

// Different length, overlapping prefix. Should NOT be equal.
let key_short = KeyMaterial256::from_bytes(&DUMMY_KEY[..16]).unwrap();
assert_ne!(key1, key_short);

// PartialEq ignores key_type: same bytes, different KeyType. Should be equal.
let key_low =
KeyMaterial256::from_bytes_as_type(&DUMMY_KEY[..32], KeyType::BytesLowEntropy).unwrap();
let key_mac =
KeyMaterial256::from_bytes_as_type(&DUMMY_KEY[..32], KeyType::MACKey).unwrap();
assert_eq!(key_low, key_mac);

// PartialEq ignores security_strength: same bytes, different strength. Should be equal.
let key_strong =
KeyMaterial256::from_bytes_as_type(&DUMMY_KEY[..32], KeyType::BytesFullEntropy)
.unwrap();
let mut key_weak =
KeyMaterial256::from_bytes_as_type(&DUMMY_KEY[..32], KeyType::BytesFullEntropy)
.unwrap();
key_weak.set_security_strength(SecurityStrength::_128bit).unwrap();
assert_ne!(key_strong.security_strength(), key_weak.security_strength()); // strengths differ
assert_eq!(key_strong, key_weak); // but keys are still equal

// Partially-filled buffers with identical content. Should be equal.
let key_half1 = KeyMaterial256::from_bytes(&DUMMY_KEY[..16]).unwrap();
let key_half2 = KeyMaterial256::from_bytes(&DUMMY_KEY[..16]).unwrap();
assert_eq!(key_half1, key_half2);

// Verify with a second size (KeyMaterial512) to cover the generic impl.
let key512_a = KeyMaterial512::from_bytes(&DUMMY_KEY[..64]).unwrap();
let key512_b = KeyMaterial512::from_bytes(&DUMMY_KEY[..64]).unwrap();
assert_eq!(key512_a, key512_b);

let key512_c = KeyMaterial512::from_bytes(&[0xFFu8; 64]).unwrap();
assert_ne!(key512_a, key512_c);
}

#[test]
Expand Down
Loading