Skip to main content

KeyMaterialInternal

Struct KeyMaterialInternal 

Source
pub struct KeyMaterialInternal<const KEY_LEN: usize> { /* private fields */ }
Expand description

A wrapper for holding bytes-like key material (symmetric keys or seeds) which aims to apply a strict typing system to prevent many kinds of mis-use mistakes. The capacity of the internal buffer can be set at compile-time via the <KEY_LEN> param.

Implementations§

Source§

impl<const KEY_LEN: usize> KeyMaterialInternal<KEY_LEN>

Source

pub fn new() -> Self

Source

pub fn from_rng(rng: &mut impl RNG) -> Result<Self, KeyMaterialError>

Create a new instance of KeyMaterial containing random bytes from the provided random number generator.

Source

pub fn from_bytes(source: &[u8]) -> Result<Self, KeyMaterialError>

Constructor. Loads the provided data into a new KeyMaterial of type KeyType::BytesLowEntropy. It will detect if you give it all-zero source data and set the key type to KeyType::Zeroized instead.

Source

pub fn from_bytes_as_type( source: &[u8], key_type: KeyType, ) -> Result<Self, KeyMaterialError>

Constructor. 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. It will detect if you give it all-zero source data and set the key type to KeyType::Zeroized instead.

Will set the SecurityStrength automatically according to the following rules:

Source

pub fn from_key(other: &impl KeyMaterial) -> Result<Self, KeyMaterialError>

Copy constructor

Trait Implementations§

Source§

impl<const KEY_LEN: usize> Clone for KeyMaterialInternal<KEY_LEN>

Source§

fn clone(&self) -> KeyMaterialInternal<KEY_LEN>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const KEY_LEN: usize> Debug for KeyMaterialInternal<KEY_LEN>

Block accidental logging of the internal key material buffer.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const KEY_LEN: usize> Default for KeyMaterialInternal<KEY_LEN>

Source§

fn default() -> Self

Create a new empty (zeroized) instance.

Source§

impl<const KEY_LEN: usize> Display for KeyMaterialInternal<KEY_LEN>

Block accidental logging of the internal key material buffer.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const KEY_LEN: usize> Drop for KeyMaterialInternal<KEY_LEN>

Zeroize the key material on drop.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

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

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 KeyMaterial::allow_hazardous_operations is set: 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 core_interface::key_material::{KeyMaterial256, KeyType};
use core_interface::key_material::KeyMaterial;
use core_interface::errors::KeyMaterialError;

let key_bytes = [0u8; 16];
let mut key = KeyMaterial256::new();
let res = key.set_bytes_as_type(&key_bytes, KeyType::BytesLowEntropy);
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.
    key.allow_hazardous_operations();
    key.set_key_type(KeyType::BytesLowEntropy).unwrap(); // probably you should do something more elegant than .unwrap in your code ;)
    key.drop_hazardous_operations();
  },
  Err(_) => { /* figure out what else went wrong */ },
  Ok(_) => { /* good */ },
}

On the other hand, if KeyMaterial::allow_hazardous_operations is set 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 allow_hazardous_operations(&mut self)

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.

The purpose of the hazardous operations guard is not to prevent the user from accessing their data, but rather to make the developer think carefully about the operation they are about to perform, and to give static analysis tools an obvious marker that a given KeyMaterial variable warrants further inspection.

Source§

fn drop_hazardous_operations(&mut self)

Resets this instance to not be able to perform potentially hazardous operations.

Source§

fn convert_key_type( &mut self, new_key_type: KeyType, ) -> Result<(), KeyMaterialError>

Sets the key_type of this KeyMaterial object. Does not perform any operations on the actual key material, other than changing the key_type field. If allow_hazardous_operations is true, this method will allow conversion to any KeyType, otherwise checking is performed to ensure that the conversion is “safe”. This drops the allow_hazardous_operations flag, so if you need to do multiple hazardous operations on the same instance, then you’ll need to call .allow_hazardous_operations() each time.

Source§

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

Get a reference to the underlying key material bytes. Read more
Source§

fn mut_ref_to_bytes(&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. This requires KeyMaterial::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 KeyMaterial::drop_hazardous_operations.
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>

Source§

fn key_type(&self) -> KeyType

Source§

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

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. Read more
Source§

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

Requires KeyMaterial::allow_hazardous_operations to raise the security strength, but not to lower it. Throws KeyMaterialError::HazardousOperationNotPermitted on a request to raise the security level without KeyMaterial::allow_hazardous_operations set. Throws KeyMaterialError::InvalidLength on a request to set the security level higher than the current key length.
Source§

fn is_full_entropy(&self) -> bool

Source§

fn zeroize(&mut self)

Source§

fn truncate(&mut self, new_len: usize) -> Result<(), KeyMaterialError>

Is simply an alias to KeyMaterial::set_key_len, however, this does not require KeyMaterial::allow_hazardous_operations since truncation is a safe operation. If truncating below the current security strength, the security strength will be lowered accordingly.
Source§

fn concatenate( &mut self, other: &dyn KeyMaterial, ) -> Result<usize, KeyMaterialError>

Adds the other KeyMaterial into this one, assuming there is space. Does not require KeyMaterial::allow_hazardous_operations. Throws KeyMaterialError::InvalidLength if this object does not have enough space to add the other one. The resulting KeyType and security strength will be the lesser of the two keys. In other words, concatenating two 128-bit full entropy keys generated at a 128-bit DRBG security level will result in a 256-bit full entropy key still at the 128-bit DRBG security level. Concatenating a full entropy key with a low entropy key will result in a low entropy key. Read more
Source§

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

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

impl<const KEY_LEN: usize> PartialEq for KeyMaterialInternal<KEY_LEN>

Checks for equality of the key data (using a constant-time comparison), but does not check that the two keys have the same type. Therefore, for example, two keys loaded from the same bytes, one with type KeyType::BytesLowEntropy and the other with KeyType::MACKey will be considered equal.

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<const KEY_LEN: usize> Eq for KeyMaterialInternal<KEY_LEN>

Auto Trait Implementations§

§

impl<const KEY_LEN: usize> Freeze for KeyMaterialInternal<KEY_LEN>

§

impl<const KEY_LEN: usize> RefUnwindSafe for KeyMaterialInternal<KEY_LEN>

§

impl<const KEY_LEN: usize> Send for KeyMaterialInternal<KEY_LEN>

§

impl<const KEY_LEN: usize> Sync for KeyMaterialInternal<KEY_LEN>

§

impl<const KEY_LEN: usize> Unpin for KeyMaterialInternal<KEY_LEN>

§

impl<const KEY_LEN: usize> UnwindSafe for KeyMaterialInternal<KEY_LEN>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.