Add some basic documentation
This commit is contained in:
parent
0aac6402eb
commit
de9d4777aa
3 changed files with 108 additions and 0 deletions
71
src/ikm.rs
71
src/ikm.rs
|
@ -5,8 +5,17 @@ use std::time::{Duration, SystemTime};
|
|||
pub(crate) const IKM_BASE_STRUCT_SIZE: usize = 25;
|
||||
|
||||
pub(crate) type CounterId = u32;
|
||||
/// Abstract type representing the identifier of an [InputKeyMaterial].
|
||||
pub type IkmId = u32;
|
||||
|
||||
/// An input key material (IKM) is a secret random seed that is used to derive cryptographic keys.
|
||||
///
|
||||
/// In order to manage your IKMs, each one of them has an unique identifier. An IKM is also tight
|
||||
/// to a specific context in which it may be used. Keep in mind that an IKM is linked to a specific
|
||||
/// algorithm, as an expiration date and can be revoked.
|
||||
///
|
||||
/// This struct is exposed so you can display its informations when managing your IKMs using an
|
||||
/// [InputKeyMaterialList]. It it not meant to be used otherwise.
|
||||
#[derive(Debug)]
|
||||
pub struct InputKeyMaterial {
|
||||
pub id: IkmId,
|
||||
|
@ -71,6 +80,68 @@ impl InputKeyMaterial {
|
|||
}
|
||||
}
|
||||
|
||||
/// A list of [InputKeyMaterial] (IKM). This is where you should manage your secrets.
|
||||
///
|
||||
/// The way coffio works is quite simple: you generate a secret random seed (an input key material,
|
||||
/// IKM) that is used to derive cryptographic keys, which are used to encrypt your data. However,
|
||||
/// if your IKM or any derived key has leaked, or if you wishes to change the encryption algorithm,
|
||||
/// you need to generate an other IKM. This is why coffio uses a single opaque token capable of
|
||||
/// containing several IKMs, the [InputKeyMaterialList]. This way, the transition between two IKMs
|
||||
/// is smooth: you can use the new IKM to encrypt all new secrets and keep the revoked one to
|
||||
/// decrypt secrets it has already encrypted and you haven't re-encrypted using the new IKM yet.
|
||||
///
|
||||
/// This list is ordered. To encrypt new data, coffio will always use the last IKM that is not
|
||||
/// revoked and is within its validity period.
|
||||
///
|
||||
/// Encrypted data contains the [IkmId] of the IKM used to derive the key. To decrypt data, coffio
|
||||
/// will therefore search for this specific IKM in the [InputKeyMaterialList].
|
||||
///
|
||||
/// <div class="warning">
|
||||
/// Never remove an IKM from the list unless you are absolutely sure that all data encrypted using
|
||||
/// this IKM have been either deleted or re-encrypted using another IKM.
|
||||
/// </div>
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use coffio::{InputKeyMaterialList, Scheme};
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// // Create an empty IKM list.
|
||||
/// let mut ikml = InputKeyMaterialList::new();
|
||||
/// assert_eq!(ikml.len(), 0);
|
||||
///
|
||||
/// // Add an IKM to the list with the default settings.
|
||||
/// let _ = ikml.add_ikm();
|
||||
/// assert_eq!(ikml.len(), 1);
|
||||
///
|
||||
/// // Add an IKM to the list with custom settings.
|
||||
/// let _ = ikml.add_custom_ikm(
|
||||
/// Scheme::Aes128GcmWithSha256,
|
||||
/// Duration::from_secs(315_569_252),
|
||||
/// );
|
||||
/// assert_eq!(ikml.len(), 2);
|
||||
///
|
||||
/// // Retreive the id of the first IKM.
|
||||
/// let ikm_id = ikml[0].id.clone();
|
||||
///
|
||||
/// // Revoke the first IKM.
|
||||
/// ikml.revoke_ikm(ikm_id);
|
||||
/// assert_eq!(ikml.len(), 2);
|
||||
///
|
||||
/// // Delete the first IKM.
|
||||
/// ikml.delete_ikm(ikm_id);
|
||||
/// assert_eq!(ikml.len(), 1);
|
||||
///
|
||||
/// // Export the IKM list
|
||||
/// let exported_ikml = ikml.export()?;
|
||||
/// println!("My secret IKM list: {exported_ikml}");
|
||||
///
|
||||
/// // Import an IKM list
|
||||
/// let ikml2 = InputKeyMaterialList::import(&exported_ikml)?;
|
||||
/// assert_eq!(ikml2.len(), 1);
|
||||
/// # Ok::<(), coffio::Error>(())
|
||||
/// ```
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InputKeyMaterialList {
|
||||
pub(crate) ikm_lst: Vec<InputKeyMaterial>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![feature(doc_auto_cfg)]
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
mod canonicalization;
|
||||
#[cfg(feature = "encryption")]
|
||||
|
|
|
@ -23,9 +23,44 @@ pub(crate) type EncryptionFunction = dyn Fn(&[u8], &[u8], &[u8], &str) -> Result
|
|||
pub(crate) type GenNonceFunction = dyn Fn() -> Result<Vec<u8>>;
|
||||
pub(crate) type SchemeSerializeType = u32;
|
||||
|
||||
/// The cryptographic primitives used to encrypt the data.
|
||||
///
|
||||
/// Coffio does not impose an unique way to encrypt data. You can therefore choose between one of
|
||||
/// the supported scheme. Each scheme has advantages and drawbacks.
|
||||
///
|
||||
/// Before choosing a scheme, you should run the benchmark on the hardware where the encryption and
|
||||
/// decryption process will take place. Some scheme may have hardware optimizations that you want
|
||||
/// to take advantage of. Regarding the key length, the following website may help you choose one
|
||||
/// that suits your requirements: [https://www.keylength.com/](https://www.keylength.com/)
|
||||
///
|
||||
/// In the following scheme description, the following terms are used:
|
||||
/// - `Max data size` describes the maximal size of data that can safely be encrypted using a
|
||||
/// single key and nonce, which means you should never pass a `data` parameter to
|
||||
/// [encrypt][crate::CipherBox::encrypt] that has a higher size. Coffio will not enforce this
|
||||
/// limit, it is your responsibility to do so.
|
||||
/// - `Max invocations` describes the maximal number of times you can safely call
|
||||
/// [encrypt][crate::CipherBox::encrypt] with a single key, which means you should either rotate
|
||||
/// your IKM or use an appropriate key periodicity before reaching this number. Coffio will neither
|
||||
/// enforce this limit nor count the number of invocations, it is your responsibility to do so.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Scheme {
|
||||
/// `default`
|
||||
/// - Key derivation: BLAKE3 derive_key mode
|
||||
/// - Encryption: XChaCha20-Poly1305
|
||||
/// - Key size: 256 bits
|
||||
/// - Nonce size: 192 bits
|
||||
/// - Max data size: 256 GB
|
||||
/// - Max invocations: no limitation
|
||||
/// - Resources: [RFC 7539](https://datatracker.ietf.org/doc/html/rfc7539),
|
||||
/// [draft-irtf-cfrg-xchacha](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha)
|
||||
XChaCha20Poly1305WithBlake3 = 1,
|
||||
/// - Key derivation: HKDF-SHA256
|
||||
/// - Encryption: AES-GCM
|
||||
/// - Key size: 128 bits
|
||||
/// - Nonce size: 96 bits
|
||||
/// - Max data size: 64 GB
|
||||
/// - Max invocations: 2<sup>32</sup>
|
||||
/// - Resources: [NIST SP 800-38D](https://doi.org/10.6028/NIST.SP.800-38D)
|
||||
Aes128GcmWithSha256 = 2,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue