Skip to main content

KeyMaterialTrait

Trait KeyMaterialTrait 

Source
pub trait KeyMaterialTrait: KeyMaterialInternalTrait {
Show 14 methods // Required methods fn set_bytes_as_type( &mut self, source: &[u8], key_type: KeyType, ) -> Result<(), KeyMaterialError>; fn ref_to_bytes(&self) -> &[u8] ; fn ref_to_bytes_mut(&mut self) -> Result<&mut [u8], KeyMaterialError>; fn capacity(&self) -> usize; fn key_len(&self) -> usize; fn set_key_len(&mut self, key_len: usize) -> Result<(), KeyMaterialError>; fn key_type(&self) -> KeyType; fn set_key_type( &mut self, key_type: KeyType, ) -> Result<(), KeyMaterialError>; fn security_strength(&self) -> SecurityStrength; fn set_security_strength( &mut self, strength: SecurityStrength, ) -> Result<(), KeyMaterialError>; fn is_full_entropy(&self) -> bool; fn zeroize(&mut self); fn equals(&self, other: &dyn KeyMaterialTrait) -> bool; fn truncate(self, into: &mut dyn KeyMaterialTrait);
}
Expand description

A helper class used across the bc-rust.test library to hold bytes-like key material. See KeyMaterial for for details, such as constructors.

Required Methods§

Source

fn set_bytes_as_type( &mut self, source: &[u8], key_type: KeyType, ) -> Result<(), KeyMaterialError>

Loads the provided data into a new KeyMaterial of the specified type. This is discouraged unless the caller knows the provenance of the data, such as loading it from a cryptographic private key file.

This behaves differently on all-zero input key depending on whether it is run within a do_hazardous_operations closure: if not set, then it will succeed, setting the key type to KeyType::Zeroized and also return a KeyMaterialError::ActingOnZeroizedKey to indicate that you may want to perform error-handling, which could be manually setting the key type if you intend to allow zero keys, or do some other error-handling, like figure out why your RNG is broken. Note that even if a KeyMaterialError::ActingOnZeroizedKey is returned, the object is still populated and usable. For example, you could catch it like this:

use bouncycastle_core::key_material::{KeyMaterial256, KeyType, KeyMaterialTrait, do_hazardous_operations};
use bouncycastle_core::key_material::KeyMaterial;
use bouncycastle_core::errors::KeyMaterialError;

let key_bytes = [0u8; 16];
let mut key = KeyMaterial256::new();
let res = key.set_bytes_as_type(&key_bytes, KeyType::Unknown);
match res {
  Err(KeyMaterialError::ActingOnZeroizedKey) => {
    // Either figure out why your passed an all-zero key,
    // or set the key type manually, if that's what you intended.
    do_hazardous_operations(&mut key, |key| {
        key.set_key_type(KeyType::Unknown)
    }).unwrap(); // probably you should do something more elegant than .unwrap in your code ;)
  },
  Err(_) => { /* figure out what else went wrong */ },
  Ok(_) => { /* good */ },
}

On the other hand, if run inside a do_hazardous_operations closure then it will just do what you asked without complaining.

Since this zeroizes and resets the key material, this is considered a dangerous conversion.

Will set the SecurityStrength automatically according to the following rules:

Source

fn ref_to_bytes(&self) -> &[u8]

Get a reference to the underlying key material bytes.

By reading the key bytes out of the KeyMaterialTrait object, you lose the protections that it offers, however, this does not require do_hazardous_operations in the name of API ergonomics: setting do_hazardous_operations requires a mutable reference and reading the bytes is not an operation that should require mutability.

Source

fn ref_to_bytes_mut(&mut self) -> Result<&mut [u8], KeyMaterialError>

Get a mutable reference to the underlying key material bytes so that you can read or write to the underlying bytes without needing to create a temporary buffer, especially useful in cases where the required size of that buffer may be tricky to figure out at compile-time.

§🚨 Hazardous Operation🚨

This function needs to be run within a do_hazardous_operations closure.

When writing directly to the buffer, you are responsible for setting the key_len and key_type afterward.

Source

fn capacity(&self) -> usize

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.

Source

fn key_len(&self) -> usize

Length of the key material in bytes.

Source

fn set_key_len(&mut self, key_len: usize) -> Result<(), KeyMaterialError>

Sets the internal key length without changing the capacity of the KeyMaterial. Primarily intended for truncation if you are provided with a key that is larger than you need, or to extend the length of an undersized KeyMaterial.

If truncating, it will automatically downgrade the SecurityStrength accordingly.

§🚨 Hazardous Operation 🚨

Using this function to extend the length of a key is always hazardous and needs to be run within a do_hazardous_operations closure since this can result in a key containing a large number of zeroes, or containing key material from a previous key held in the same buffer. When extending the length, you take responsibility for the security implications.

Truncation (that is, reducing the length) is always safe and does not require a do_hazardous_operations closure.

Source

fn key_type(&self) -> KeyType

Returns the KeyType of this KeyMaterial object.

Source

fn set_key_type(&mut self, key_type: KeyType) -> Result<(), KeyMaterialError>

Sets (or safely converts) the KeyType of this KeyMaterial object. Does not perform any operations on the actual key material, other than changing the key_type field.

§🚨 Hazardous Operation 🚨

Inside a do_hazardous_operations closure this will set the key to any KeyType. Outside such a closure, only “safe” conversions are permitted: a KeyType::CryptographicRandom key may be converted to any type, and any type may be converted to itself (a no-op). A hazardous conversion attempted outside a do_hazardous_operations closure returns KeyMaterialError::HazardousOperationNotPermitted, and converting a KeyType::Zeroized key returns KeyMaterialError::ActingOnZeroizedKey.

Source

fn security_strength(&self) -> SecurityStrength

Security Strength, as used here, aligns with NIST SP 800-90A guidance for random number generation, specifically section 8.4.

The idea is to be able to track for cryptographic seeds and bytes-like key objects across the entire library, the instatiated security level of the RNG that generated it, and whether it was handled by any intermediate objects, such as Key Derivation Functions, that have a smaller internal security level and therefore result in downgrading the security level of the key material.

Note that while security strength is closely related to entropy, it is a property of the algorithms that touched the key material and not of the key material data itself, and therefore it is tracked independantly from key length and entropy level / key type.

Source

fn set_security_strength( &mut self, strength: SecurityStrength, ) -> Result<(), KeyMaterialError>

Set the SecurityStrength of the KeyMaterial.

§🚨 Hazardous Operation🚨

This function needs to be run within a do_hazardous_operations closure to raise the security strength, but not to lower it.

Outside of a do_hazardous_operations closure it will throw a KeyMaterialError::HazardousOperationNotPermitted on a request to raise the security level, and throw a KeyMaterialError::InvalidLength on a request to set the security level higher than the current key length. Inside a do_hazardous_operations it will do what you asked without complaining.

Source

fn is_full_entropy(&self) -> bool

Whether or not the KeyMaterial is one of the full entropy key types.

Source

fn zeroize(&mut self)

Securely resets the contents to all zeroes. Note that KeyMaterial will automatically zeroize itself when dropped, so it is not necessary to call this method simply because the object is going out of scope, but it provided in case you want to zeroize it early, or before re-using the same instance of KeyMaterial to hold a different key, potentially of a different length.

Source

fn equals(&self, other: &dyn KeyMaterialTrait) -> bool

Perform a constant-time comparison between the two key material buffers, ignoring differences in capacity, KeyType, SecurityStrength, etc.

Source

fn truncate(self, into: &mut dyn KeyMaterialTrait)

Truncate this key material into the provided destination. Not an error to provide a destination which is larger than the source. Consumes self, use clone() if you intend to make a copy.

Implementors§

Source§

impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN>