Skip to content
Closed
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
4 changes: 2 additions & 2 deletions INTRODUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ While the `KeyMaterial` is fundamentally just a buffer of bytes, it tracks many

The `KeyMaterial` object is used consistently across the library and any functions that manipulate a key material object will properly update the metadata to track any changes made to the key's entropy or security strength. For example, a `KeyMaterial512{ key_type: MACKey, security_strength: _256bit}` will have its security strength downgraded to 128 bit if you pass it through a SHA256-based KDF, indicating that it is no longer sufficient to generate a full-strength AES256 or ML-DSA-87.

Of course, there will always be things developers need to do that the library did not provide a utility function for, for example, you may actually need an all-zero MACKey in order to implement certain standardized MAC algorithms. To the end, the library will allow you to, for example, force a key type to any full-entropy key type and security strength, or even get a direct immutable or mutable reference to the underlying buffer via `.ref_to_bytes()` and `mut_ref_to_bytes()`, but only with use of the `allow_hazardous_operations` flag:
Of course, there will always be things developers need to do that the library did not provide a utility function for, for example, you may actually need an all-zero MACKey in order to implement certain standardized MAC algorithms. To the end, the library will allow you to, for example, force a key type to any full-entropy key type and security strength, or even get a direct immutable or mutable reference to the underlying buffer via `.ref_to_bytes()` and `ref_to_bytes_mut()`, but only with use of the `allow_hazardous_operations` flag:

```rust
key.allow_hazardous_operations();
Expand Down Expand Up @@ -202,4 +202,4 @@ As this is an alpha release, we're eagerly looking for feedback from the communi
You can reach us at <some email address>

Sincerely,
Mike Ounsworth (lead maintainer of BC-Rust), on behalf of the Legion of the Bouncy Castle and the entire Bouncy Castle community
Mike Ounsworth (lead maintainer of BC-Rust), on behalf of the Legion of the Bouncy Castle and the entire Bouncy Castle community
8 changes: 4 additions & 4 deletions crypto/core/src/key_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub trait KeyMaterialTrait {
/// This requires [KeyMaterialTrait::allow_hazardous_operations] to be set.
/// When writing directly to the buffer, you are responsible for setting the key_len and key_type afterwards,
/// and you should [KeyMaterialTrait::drop_hazardous_operations].
fn mut_ref_to_bytes(&mut self) -> Result<&mut [u8], KeyMaterialError>;
fn ref_to_bytes_mut(&mut self) -> Result<&mut [u8], KeyMaterialError>;

/// The size of the internal buffer; ie the largest key that this instance can hold.
/// Equivalent to the <KEY_LEN> constant param this object was created with.
Expand Down Expand Up @@ -151,7 +151,7 @@ pub trait KeyMaterialTrait {

/// Sets this instance to be able to perform potentially hazardous operations such as
/// casting a KeyMaterial of type RawUnknownEntropy or RawLowEntropy into RawFullEntropy or SymmetricCipherKey,
/// or manually setting the key bytes via [KeyMaterialTrait::mut_ref_to_bytes], which then requires you to be responsible
/// or manually setting the key bytes via [KeyMaterialTrait::ref_to_bytes_mut], which then requires you to be responsible
/// for setting the key_len and key_type afterwards.
///
/// The purpose of the hazardous operations guard is not to prevent the user from accessing their data,
Expand Down Expand Up @@ -254,7 +254,7 @@ impl<const KEY_LEN: usize> KeyMaterial<KEY_LEN> {
let mut key = Self::new();
key.allow_hazardous_operations();

rng.next_bytes_out(&mut key.mut_ref_to_bytes().unwrap())
rng.next_bytes_out(&mut key.ref_to_bytes_mut().unwrap())
.map_err(|_| KeyMaterialError::GenericError("RNG failed."))?;

key.key_len = KEY_LEN;
Expand Down Expand Up @@ -354,7 +354,7 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
&self.buf[..self.key_len]
}

fn mut_ref_to_bytes(&mut self) -> Result<&mut [u8], KeyMaterialError> {
fn ref_to_bytes_mut(&mut self) -> Result<&mut [u8], KeyMaterialError> {
if !self.allow_hazardous_operations {
return Err(KeyMaterialError::HazardousOperationNotPermitted);
}
Expand Down
14 changes: 7 additions & 7 deletions crypto/core/tests/key_material_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mod test_key_material {
assert_eq!(key.capacity(), 32);
assert_eq!(key.ref_to_bytes(), &[1u8; 16]); // note: this is also testing that even though the internal buffer is larger than 16 bytes, it slices it down to length.

match key.mut_ref_to_bytes() {
match key.ref_to_bytes_mut() {
Ok(_) => {
panic!("getting a mut ref should require setting hazardous operations.")
}
Expand All @@ -85,12 +85,12 @@ mod test_key_material {
}
}
key.allow_hazardous_operations();
assert_eq!(key.mut_ref_to_bytes().unwrap().len(), 32);
assert_eq!(key.mut_ref_to_bytes().unwrap()[..16], [1u8; 16]);
assert_eq!(key.mut_ref_to_bytes().unwrap()[16..], [0u8; 16]);
assert_eq!(key.ref_to_bytes_mut().unwrap().len(), 32);
assert_eq!(key.ref_to_bytes_mut().unwrap()[..16], [1u8; 16]);
assert_eq!(key.ref_to_bytes_mut().unwrap()[16..], [0u8; 16]);

// and I can set them
key.mut_ref_to_bytes().unwrap().copy_from_slice(&[2u8; 32]);
key.ref_to_bytes_mut().unwrap().copy_from_slice(&[2u8; 32]);
key.set_key_len(32).unwrap();
assert_eq!(key.ref_to_bytes(), &[2u8; 32]);
assert_eq!(key.key_len(), 32);
Expand Down Expand Up @@ -179,7 +179,7 @@ mod test_key_material {
// 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));
assert!(key.ref_to_bytes_mut().unwrap().iter().any(|&b| b != 0));
key.drop_hazardous_operations();

key.zeroize();
Expand All @@ -192,7 +192,7 @@ mod test_key_material {
// actually overwritten with zeros.
// Note: key_len is now 0, so ref_to_bytes() returns an empty slice.
key.allow_hazardous_operations();
let full_buf = key.mut_ref_to_bytes().unwrap();
let full_buf = key.ref_to_bytes_mut().unwrap();
assert_eq!(full_buf.len(), capacity);
assert!(full_buf.iter().all(|&b| b == 0));
key.drop_hazardous_operations();
Expand Down
6 changes: 3 additions & 3 deletions crypto/hkdf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
let mut bytes_written: usize = 0;

okm.allow_hazardous_operations();
let out: &mut [u8] = okm.mut_ref_to_bytes()?;
let out: &mut [u8] = okm.ref_to_bytes_mut()?;
// Could potentially speed this up by unrolling T(0) and T(1)

// We're gonna have to kludge the prk key type to MACKey to make HMAC happy, but we'll set it back to the original value afterwards.
Expand Down Expand Up @@ -568,9 +568,9 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {

let output_key_type = self.entropy.get_output_key_type(); // need to do this above self.hmac.do_final_out, which will consume self.

okm.allow_hazardous_operations(); // doing it here to get mut_ref_to_bytes
okm.allow_hazardous_operations(); // doing it here to get ref_to_bytes_mut
let bytes_written =
self.hmac.unwrap().do_final_out(&mut okm.mut_ref_to_bytes().unwrap())?;
self.hmac.unwrap().do_final_out(&mut okm.ref_to_bytes_mut().unwrap())?;
okm.set_key_len(bytes_written)?;
okm.set_key_type(output_key_type)?;
if output_key_type <= KeyType::BytesLowEntropy {
Expand Down
6 changes: 3 additions & 3 deletions crypto/rng/src/hash_drbg80090a.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ impl<H: HashDRBG80090AParams> HashDRBG80090A<H> {
seed.set_key_type(KeyType::Seed).unwrap();
match H::HASH {
SupportedHash::SHA256 => {
getrandom::fill(&mut seed.mut_ref_to_bytes().unwrap()[..32]).unwrap();
getrandom::fill(&mut seed.ref_to_bytes_mut().unwrap()[..32]).unwrap();
seed.set_key_len(32).unwrap();
seed.set_security_strength(SecurityStrength::_128bit).unwrap();
}
SupportedHash::SHA512 => {
getrandom::fill(&mut seed.mut_ref_to_bytes().unwrap()).unwrap();
getrandom::fill(&mut seed.ref_to_bytes_mut().unwrap()).unwrap();
seed.set_key_len(64).unwrap();
seed.set_security_strength(SecurityStrength::_256bit).unwrap();
}
Expand Down Expand Up @@ -463,7 +463,7 @@ impl<H: HashDRBG80090AParams> Sp80090ADrbg for HashDRBG80090A<H> {
out: &mut impl KeyMaterialTrait,
) -> Result<usize, RNGError> {
out.allow_hazardous_operations();
let bytes_written = self.generate_out(additional_input, out.mut_ref_to_bytes().unwrap())?;
let bytes_written = self.generate_out(additional_input, out.ref_to_bytes_mut().unwrap())?;

out.set_key_len(bytes_written)?;
out.set_key_type(KeyType::BytesFullEntropy)?;
Expand Down
2 changes: 1 addition & 1 deletion crypto/sha3/src/sha3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<PARAMS: SHA3Params> SHA3<PARAMS> {
let mut key_type = self.kdf_key_type.clone();
let output_security_strength = self.kdf_security_strength.clone();
output_key.allow_hazardous_operations();
let bytes_written = self.do_final_out(output_key.mut_ref_to_bytes()?);
let bytes_written = self.do_final_out(output_key.ref_to_bytes_mut()?);
output_key.set_key_len(bytes_written)?;

// since we've done some computation, the result will not actually be zeroized, even if all input key material was zeroized.
Expand Down
2 changes: 1 addition & 1 deletion crypto/sha3/src/shake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl<PARAMS: SHAKEParams> SHAKE<PARAMS> {
output_key.allow_hazardous_operations();
let bytes_written = self.squeeze_out(
output_key
.mut_ref_to_bytes()
.ref_to_bytes_mut()
.expect("We just set .allow_hazardous_operations(), so this should be fine."),
);
output_key.set_key_len(bytes_written)?;
Expand Down
Loading