Skip to main content

bouncycastle_core/
traits.rs

1//! Provides simplified abstracted APIs over classes of cryptographic primitives, such as Hash, KDF, etc.
2
3use crate::errors::*;
4use crate::key_material::KeyMaterialTrait;
5use core::fmt::{Debug, Display};
6use core::marker::Sized;
7
8// Imports needed for docs
9#[allow(unused_imports)]
10use crate::key_material::KeyMaterial;
11#[allow(unused_imports)]
12use crate::key_material::KeyType;
13// end of imports needed for docs
14
15/// Metadata about a cryptographic algorithm.
16pub trait Algorithm {
17    /// String name for the algorithm, used consistently across the library.
18    const ALG_NAME: &'static str;
19    /// Maximum security strength supported by the algorithm.
20    /// In other words, this algorithm can produce outputs up to this security strength,
21    /// but may produce outputs with lower security strength, for example, if asked to truncate.
22    const MAX_SECURITY_STRENGTH: SecurityStrength;
23}
24
25/// Some algorithms have an assigned OID.
26pub trait AlgorithmOID {
27    /// The OID in component form -- each u32 is one OID component.
28    const OID: &'static [u32];
29    /// The OID in its DER-encoded form.
30    const OID_DER: &'static [u8];
31}
32
33// todo -- split all the SymmetricCipher traits into Encryptor and Decryptor
34/// The basic one-shot encrypt and decrypt that all types of symmetric ciphers must implement.
35/// These are meant to be simple, easy to use, secure, and fool-proof APIs, but they may result in
36/// ciphertexts that are incompatible with other implementations as ciphers in more complex modes, such
37/// as AEADs or stream ciphers may need to stick extra data either at the beginning or end of the ciphertext.
38/// See the documentation of the underlying implementation for more details.
39pub trait SymmetricCipher<const KEY_LEN: usize, const INIT_DATA_LEN: usize>: Algorithm {
40    #[cfg(feature = "std")]
41    /// A one-shot API to encrypt some plaintext with the given key.
42    /// This function returns the ciphertext as a `Vec<u8>`, and therefore is only available when compiling with std.
43    /// Returns a tuple containing the initialization data and the ciphertext.
44    /// This is not available if building for no_std.
45    fn encrypt(
46        key: &KeyMaterial<KEY_LEN>,
47        plaintext: &[u8],
48    ) -> Result<([u8; INIT_DATA_LEN], Vec<u8>), SymmetricCipherError>;
49    /// A one-shot API to encrypt some plaintext with the given key.
50    /// This function takes a reference to the output buffer for the ciphertext, and is therefore available in no_std.
51    /// See the documentation for the underlying implementation for details on providing a ciphertext buffer of sufficient size;
52    /// typically the ciphertext is the same length as the plaintext, but some ciphers may have an expansion factor or require
53    /// extra space for a nonce or tag.
54    /// Returns a tuple containing the initialization data and the number of bytes written to the ciphertext buffer.
55    fn encrypt_out(
56        key: &KeyMaterial<KEY_LEN>,
57        plaintext: &[u8],
58        ciphertext: &mut [u8],
59    ) -> Result<([u8; INIT_DATA_LEN], usize), SymmetricCipherError>;
60    #[cfg(feature = "std")]
61    /// A one-shot API to decrypt some ciphertext with the given key.
62    /// This function returns the ciphertext as a `Vec<u8>`, and therefore is only available when compiling with std.
63    /// This is not available if building for no_std.
64    fn decrypt(
65        key: &KeyMaterial<KEY_LEN>,
66        init_data: [u8; INIT_DATA_LEN],
67        ciphertext: &[u8],
68    ) -> Result<Vec<u8>, SymmetricCipherError>;
69    /// A one-shot API to decrypt some ciphertext with the given key.
70    /// This function takes a reference to the output buffer for the plaintext, and is therefore available in no_std.
71    /// See the documentation for the underlying implementation for details on providing a plaintext buffer of sufficient size;
72    /// typically the ciphertext is the same length as the plaintext, but some ciphers may have an expansion factor or require
73    /// extra space for a nonce or tag.
74    /// Returns a tuple containing the initialization data and the number of bytes written to the plaintext buffer.
75    fn decrypt_out(
76        key: &KeyMaterial<KEY_LEN>,
77        init_data: [u8; INIT_DATA_LEN],
78        ciphertext: &[u8],
79        plaintext: &mut [u8],
80    ) -> Result<usize, SymmetricCipherError>;
81}
82
83/// The basic functions of a block cipher.
84/// This trait allows for a block cipher to generate initialization data, such as an Initialization Vector (IV) or Counter (CTR)
85/// which is not technically part of the ciphertext, but must be transmitted along with the ciphertext in order for the
86/// recipient to perform successful decryption. The length of the initialization data is specified by the implementing struct
87/// via the `INIT_DATA_LEN` constant.
88/// In order for these one-shot APIs to be usable securely in all contexts, the init data will be generated
89/// securely by the block cipher implementation and returned along with the ciphertext, and there is no API for the
90/// user to provide the init data. If you require this functionality, see the documentation for the underlying implementation.
91pub trait BlockCipher<const KEY_LEN: usize, const INIT_DATA_LEN: usize, const BLOCK_LEN: usize>:
92    SymmetricCipher<KEY_LEN, INIT_DATA_LEN> + Sized
93{
94    /// Constructor that begins a flow of the streaming API for encrypting one block at a time.
95    /// Allows for the implementation to return init data such as an IV which is generated prior to encrypting the first block.
96    fn do_encrypt_init(
97        key: &KeyMaterial<KEY_LEN>,
98    ) -> Result<(Self, [u8; INIT_DATA_LEN]), SymmetricCipherError>;
99    /// Encrypts a single block of plaintext.
100    fn do_encrypt_block(
101        &mut self,
102        plaintext: &[u8; BLOCK_LEN],
103    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
104    /// Encrypts a single block of plaintext and writes the ciphertext to the provided buffer.
105    fn do_encrypt_block_out(
106        &mut self,
107        plaintext: &[u8; BLOCK_LEN],
108        ciphertext: &mut [u8; BLOCK_LEN],
109    ) -> Result<usize, SymmetricCipherError>;
110    /// Encrypts the final block of plaintext.
111    fn do_encrypt_final(
112        &mut self,
113        plaintext: &[u8; BLOCK_LEN],
114    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
115    /// Encrypts the final block of plaintext and writes the ciphertext to the provided buffer.
116    fn do_encrypt_final_out(
117        &mut self,
118        plaintext: &[u8; BLOCK_LEN],
119        ciphertext: &mut [u8; BLOCK_LEN],
120    ) -> Result<usize, SymmetricCipherError>;
121    /// Constructor that begins a flow of the streaming API for decryption one block at a time.
122    fn do_decrypt_init(
123        key: &KeyMaterial<KEY_LEN>,
124        init_data: &[u8; INIT_DATA_LEN],
125    ) -> Result<Self, SymmetricCipherError>;
126    /// Decrypts a single block of ciphertext.
127    fn do_decrypt_block(
128        &mut self,
129        ciphertext: &[u8; BLOCK_LEN],
130    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
131    /// Decrypts a single block of ciphertext and writes the plaintext to the provided buffer.
132    fn do_decrypt_block_out(
133        &mut self,
134        ciphertext: &[u8; BLOCK_LEN],
135        plaintext: &mut [u8; BLOCK_LEN],
136    ) -> Result<usize, SymmetricCipherError>;
137    /// Decrypts the final block of ciphertext.
138    /// This is the decryption counterpart to [`BlockCipher::do_encrypt_final`] and is where an
139    /// implementation validates and strips any padding (or otherwise finalizes the flow).
140    fn do_decrypt_final(
141        &mut self,
142        ciphertext: &[u8; BLOCK_LEN],
143    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
144    /// Decrypts the final block of ciphertext and writes the plaintext to the provided buffer.
145    fn do_decrypt_final_out(
146        &mut self,
147        ciphertext: &[u8; BLOCK_LEN],
148        plaintext: &mut [u8; BLOCK_LEN],
149    ) -> Result<usize, SymmetricCipherError>;
150}
151
152/// The basic functions of an Authenticated Encryption with Addititional Data cipher.
153pub trait AEADCipher<const KEY_LEN: usize, const NONCE_LEN: usize, const TAG_LEN: usize>:
154    SymmetricCipher<KEY_LEN, NONCE_LEN> + Sized
155{
156    #[cfg(feature = "std")]
157    /// A one-shot API to encrypt some plaintext with the given key.
158    /// A distinguishing feature of AEAD ciphers is the ability to provide additional authenticated data (AAD)
159    /// that is not encrypted but is protected by the authentication tag; ie it can be sent along with the ciphertext
160    /// and any tampering with it will result in the decryption operation failing the tag check.
161    /// This function returns the ciphertext as a `Vec<u8>`, and therefore is only available when compiling with std.
162    /// Returns a tuple containing a generated nonce, the ciphertext and the tag.
163    fn aead_encrypt(
164        key: &KeyMaterial<KEY_LEN>,
165        aad: &[u8],
166        plaintext: &[u8],
167    ) -> Result<([u8; NONCE_LEN], Vec<u8>, [u8; TAG_LEN]), SymmetricCipherError>;
168    /// A one-shot API to encrypt some plaintext with the given key.
169    /// A distinguishing feature of AEAD ciphers is the ability to provide additional authenticated data (AAD)
170    /// that is not encrypted but is protected by the authentication tag; ie it can be sent along with the ciphertext
171    /// and any tampering with it will result in the decryption operation failing the tag check.
172    /// Returns a tuple containing the randomly-generated nonce, number of bytes written to the ciphertext buffer, and the tag.
173    /// If you need a deterministic mode where you feed in the nonce, use the streaming API of [`BlockCipher`]
174    /// or [`StreamCipher`] as appropriate and feed the nonce into the IV field.
175    fn aead_encrypt_out(
176        key: &KeyMaterial<KEY_LEN>,
177        aad: &[u8],
178        plaintext: &[u8],
179        ciphertext: &mut [u8],
180    ) -> Result<([u8; NONCE_LEN], usize, [u8; TAG_LEN]), SymmetricCipherError>;
181    /// All AEAD ciphers will also be either a [`BlockCipher`] or a [`StreamCipher`], and so will already
182    /// have a streaming API.
183    /// This allows you to finish either style of streaming API flow with AEAD specific do_final()
184    /// that computes and returns the authentication tag.
185    fn do_aead_encrypt_final(self) -> Result<[u8; TAG_LEN], SymmetricCipherError>;
186    #[cfg(feature = "std")]
187    /// A one-shot API to decrypt some ciphertext with the given key.
188    /// This function returns the ciphertext as a `Vec<u8>`, and therefore is only available when compiling with std.
189    fn aead_decrypt(
190        key: &KeyMaterial<KEY_LEN>,
191        nonce: &[u8; NONCE_LEN],
192        aad: &[u8],
193        ciphertext: &[u8],
194        tag: &[u8; TAG_LEN],
195    ) -> Result<Vec<u8>, SymmetricCipherError>;
196    /// A one-shot API to decrypt some ciphertext with the given key.
197    /// This function takes a reference to the output buffer for the plaintext, and is therefore available in no_std.
198    /// See the documentation for the underlying implementation for details on providing a plaintext buffer of sufficient size;
199    /// typically the ciphertext is the same length as the plaintext, but some ciphers may have an expansion factor or require
200    /// extra space for a nonce or tag.
201    /// Returns the number of bytes written to the plaintext buffer.
202    fn aead_decrypt_out(
203        key: &KeyMaterial<KEY_LEN>,
204        nonce: &[u8; NONCE_LEN],
205        aad: &[u8],
206        ciphertext: &[u8],
207        tag: &[u8; TAG_LEN],
208        plaintext: &mut [u8],
209    ) -> Result<usize, SymmetricCipherError>;
210    /// All AEAD ciphers will also be either a [`BlockCipher`] or a [`StreamCipher`], and so will already
211    /// have a streaming API.
212    /// This allows you to finish either style of streaming API flow with AEAD specific do_final()
213    /// that computes and returns the authentication tag.
214    fn do_aead_decrypt_final(self, tag: &[u8; TAG_LEN]) -> Result<(), SymmetricCipherError>;
215}
216
217/// The basic functions of a stream cipher, which differ from those of a block cipher only in that
218/// a stream cipher is assumed to have no underlying block size tied to the implementation, and so the caller gets to specify
219/// the block size for the streaming APIs.
220pub trait StreamCipher<const KEY_LEN: usize, const INIT_DATA_LEN: usize>:
221    SymmetricCipher<KEY_LEN, INIT_DATA_LEN> + Sized
222{
223    /// Constructor that begins a flow of the streaming API for encrypting one block at a time.
224    /// Allows for the implementation to return init data such as an IV which is generated prior to encrypting the first block.
225    fn do_stream_encrypt_init(
226        key: &KeyMaterial<KEY_LEN>,
227    ) -> Result<(Self, [u8; INIT_DATA_LEN]), SymmetricCipherError>;
228    /// Encrypts a single block of plaintext.
229    fn do_stream_encrypt_block<const BLOCK_LEN: usize>(
230        &mut self,
231        plaintext: &[u8; BLOCK_LEN],
232    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
233    /// Encrypts a single block of plaintext and writes the ciphertext to the provided buffer.
234    fn do_stream_encrypt_block_out<const BLOCK_LEN: usize>(
235        &mut self,
236        plaintext: &[u8; BLOCK_LEN],
237        ciphertext: &mut [u8; BLOCK_LEN],
238    ) -> Result<usize, SymmetricCipherError>;
239    /// Encrypts the final block of plaintext.
240    fn do_stream_encrypt_final<const BLOCK_LEN: usize>(
241        &mut self,
242        plaintext: &[u8; BLOCK_LEN],
243    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
244    /// Encrypts the final block of plaintext and writes the ciphertext to the provided buffer.
245    fn do_stream_encrypt_final_out<const BLOCK_LEN: usize>(
246        &mut self,
247        plaintext: &[u8; BLOCK_LEN],
248        ciphertext: &mut [u8; BLOCK_LEN],
249    ) -> Result<usize, SymmetricCipherError>;
250    /// Constructor that begins a flow of the streaming API for decryption one block at a time.
251    fn do_stream_decrypt_init(
252        key: &KeyMaterial<KEY_LEN>,
253        init_data: &[u8; INIT_DATA_LEN],
254    ) -> Result<Self, SymmetricCipherError>;
255    /// Decrypts a single block of ciphertext.
256    fn do_stream_decrypt_block<const BLOCK_LEN: usize>(
257        &mut self,
258        ciphertext: &[u8; BLOCK_LEN],
259    ) -> Result<[u8; BLOCK_LEN], SymmetricCipherError>;
260    /// Decrypts a single block of ciphertext and writes the plaintext to the provided buffer.
261    fn do_stream_decrypt_block_out<const BLOCK_LEN: usize>(
262        &mut self,
263        ciphertext: &[u8; BLOCK_LEN],
264        plaintext: &mut [u8; BLOCK_LEN],
265    ) -> Result<usize, SymmetricCipherError>;
266}
267
268/// A hash function is a cryptographic primitive that takes an input of any length and produces a fixed-size output.
269/// Formally: `H: {0,1}^* -> {0,1}^n`.
270/// A cryptographic hash function will typically satisfy several security properties, including:
271/// * Collision resistance: finding two inputs that yield the same output is computationally difficult.
272/// * Preimage resistance: from a given output, finding an input that generates it is computationally difficult.
273/// * Second preimage resistance: given an input, finding another input that yields the same output is computationally difficult.
274pub trait Hash: Algorithm + Default {
275    /// The size of the internal block in bits -- needed by functions such as HMAC to compute security parameters.
276    fn block_bitlen(&self) -> usize;
277
278    /// The size of the output in bytes.
279    fn output_len(&self) -> usize;
280
281    /// A static one-shot API that hashes the provided data.
282    /// `data` can be of any length, including zero bytes.
283    fn hash(self, data: &[u8]) -> Vec<u8>;
284
285    /// A static one-shot API that hashes the provided data into the provided output slice.
286    /// `data` can be of any length, including zero bytes.
287    /// The entire output buffer is zeroized before the hash output is written.
288    /// The return value is the number of bytes written.
289    fn hash_out(self, data: &[u8], output: &mut [u8]) -> usize;
290
291    /// Provide a chunk of data to be absorbed into the hashes.
292    /// `data` can be of any length, including zero bytes.
293    /// do_update() is intended to be used as part of a streaming interface, and so may by called multiple times.
294    fn do_update(&mut self, data: &[u8]);
295
296    /// Finish absorbing input and produce the hashes output.
297    /// Consumes self, so this must be the final call to this object.
298    fn do_final(self) -> Vec<u8>;
299
300    /// Finish absorbing input and produce the hashes output.
301    /// Consumes self, so this must be the final call to this object.
302    ///
303    /// If the provided buffer is smaller than the hash's output length, the output will be truncated.
304    /// If the provided buffer is larger than the hash's output length, the output  will be placed in
305    /// the first [`Hash::output_len`] bytes.
306    /// The entire output buffer is zeroized before the hash output is written, so any bytes past
307    /// [`Hash::output_len`] will be 0.
308    ///
309    /// The return value is the number of bytes written.
310    fn do_final_out(self, output: &mut [u8]) -> usize;
311
312    /// The same as [`Hash::do_final`], but allows for supplying a partial byte as the last input.
313    /// Assumes that the input is in the least significant bits (big endian).
314    fn do_final_partial_bits(
315        self,
316        partial_byte: u8,
317        num_partial_bits: usize,
318    ) -> Result<Vec<u8>, HashError>;
319
320    /// The same as [`Hash::do_final_out`], but allows for supplying a partial byte as the last input.
321    /// Assumes that the input is in the least significant bits (big endian).
322    /// will be placed in the first [`Hash::output_len`] bytes.
323    /// The entire output buffer is zeroized before the hash output is written.
324    /// The return value is the number of bytes written.
325    fn do_final_partial_bits_out(
326        self,
327        partial_byte: u8,
328        num_partial_bits: usize,
329        output: &mut [u8],
330    ) -> Result<usize, HashError>;
331
332    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
333    fn max_security_strength(&self) -> SecurityStrength;
334}
335
336/// Standard parameters for a hash function.
337pub trait HashAlgParams: Algorithm {
338    /// The fixed output length of the hash function.
339    const OUTPUT_LEN: usize;
340    /// The internal block length of the hash function, which is often used as a meta-parameter for
341    /// determining the security strength of the hash function since this limits the internal
342    /// collision resistance of the hash function.
343    const BLOCK_LEN: usize;
344}
345
346/// A Key Derivation Function (KDF) is a function that takes in one or more input key and some unstructured
347/// additional input, and uses them to produces a derived key.
348pub trait KDF: Default {
349    /// Implementations of this function are capable of deriving an output key from an input key,
350    /// assuming that they have been properly initialized.
351    ///
352    /// # Entropy Conversion rules
353    /// Implementations SHOULD act on a KeyMaterial of any [`KeyType`] and will generally
354    /// return a KeyMaterial of the same type
355    ///
356    /// ex.:
357    ///
358    ///   * [`KeyType::Unknown`] -> [`KeyType::Unknown`])
359    ///   * [`KeyType::CryptographicRandom`] -> [`KeyType::CryptographicRandom`])
360    ///   * [`KeyType::SymmetricCipherKey`] -> [`KeyType::SymmetricCipherKey`])
361    ///
362    /// If provided with an input key, even if it is [`KeyType::CryptographicRandom`], but that
363    /// contains less key material than the internal block size of the KDF, then the KDF
364    /// will not be considered properly seeded, and the output [`KeyMaterial`] will be set to
365    /// [`KeyType::Unknown`] -- for example, seeding SHA3-256 with a [`KeyMaterial`] containing
366    /// only 128 bits of key material.
367    ///
368    /// An implementation can, and in most cases SHOULD, return a [`HashError`] if provided
369    /// with a [`KeyMaterial`] of type [`KeyType::Zeroized`].
370    ///
371    /// # Additional Input
372    /// The `additional_input` parameter is used in deriving the key, but is not credited with any entropy,
373    /// and therefore does not affect the type of the output [`KeyMaterial`].
374    /// This corresponds directly to `FixedInfo` as defined in NIST SP 800-56C.
375    /// The `additional_input` parameter can be empty by passing in `&[0u8; 0]`.
376    ///
377    /// Output length: this function will create a KeyMaterial populated with the default output length
378    /// of the underlying hash primitive.
379    fn derive_key(
380        self,
381        key: &impl KeyMaterialTrait,
382        additional_input: &[u8],
383    ) -> Result<Box<dyn KeyMaterialTrait>, KDFError>;
384
385    /// Same as [`KDF::derive_key`], but fills the provided output [`KeyMaterial`].
386    ///
387    /// Output length: this function will behave differently depending on the underlying hash primitive;
388    /// some, such as SHA2 or SHA3 will produce a fixed-length output, while others, such as SHAKE or HKDF,
389    /// will fill the provided KeyMaterial to capacity and require you to truncate it afterward
390    /// using [`KeyMaterialTrait::set_key_len`].
391    fn derive_key_out(
392        self,
393        key: &impl KeyMaterialTrait,
394        additional_input: &[u8],
395        output_key: &mut impl KeyMaterialTrait,
396    ) -> Result<usize, KDFError>;
397
398    /// Meant to be used for hybrid key establishment schemes or other spit-key scenarios where multiple
399    /// keys need to be combined into a single key of the same length.
400    ///
401    /// This function can also be used to mix a KeyMaterial of low entropy with one of full entropy to
402    /// produce a new full entropy key. For the purposes of determining whether enough input key material
403    /// was provided, the lengths of all full-entropy input keys are added together.
404    ///
405    /// Implementations that are not safe to be used as a split-key PRF MAY still implement this function
406    /// and return a result, but SHOULD set the entropy level of the returned key appropriately; for example
407    /// a KDF that is only full-entropy when keyed in the first input SHOULD return a full entropy key
408    /// only if the first input is full entropy.
409    ///
410    /// Implementations can, and in most cases SHOULD, return a [`KeyMaterial`] of the same type as the
411    /// strongest key, and SHOULD throw a [`HashError`] if all input keys are zeroized.
412    /// For example output a [`KeyType::CryptographicRandom`] key whenever any one of
413    /// the input keys is a [`KeyType::CryptographicRandom`] key.
414    /// As another example, combining a [`KeyType::Unknown`] key with a [`KeyType::MACKey`] key
415    /// should return a [`KeyType::MACKey`].
416    ///
417    /// Output length: this function will create a KeyMaterial populated with the default output length
418    /// of the underlying hash primitive.
419    fn derive_key_from_multiple(
420        self,
421        keys: &[&impl KeyMaterialTrait],
422        additional_input: &[u8],
423    ) -> Result<Box<dyn KeyMaterialTrait>, KDFError>;
424
425    /// Same as [`KDF::derive_key`], but fills the provided output [`KeyMaterial`].
426    ///
427    /// Output length: this function will behave differently depending on the underlying hash primitive;
428    /// some, such as SHA2 or SHA3 will produce a fixed-length output, while others, such as SHAKE or HKDF,
429    /// will fill the provided KeyMaterial to capacity and require you to truncate it afterward
430    /// by using [`KeyMaterialTrait::set_key_len`].
431    fn derive_key_from_multiple_out(
432        self,
433        keys: &[&impl KeyMaterialTrait],
434        additional_input: &[u8],
435        output_key: &mut impl KeyMaterialTrait,
436    ) -> Result<usize, KDFError>;
437
438    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
439    fn max_security_strength(&self) -> SecurityStrength;
440}
441
442/// A Key Encapsulation Mechanism (KEM) is defined as a set of three operations:
443/// key generation, encapsulation, and decapsulation.
444///
445/// This trait represents the encapsulation operation performed by the holder of the public key.
446/// Decapsulation operations are performed by the corresponding [`KEMDecapsulator`] trait, and key
447/// generation is provided as an inherent associated function directly on the algorithm struct.
448/// There are several reasons for this split: first is architectural; some complex algorithms may
449/// benefit from having the encapsulation and decapsulation implementations split into separate modules.
450/// Second is for compliance: sometimes a policy soft-deprecates an algorithm so that new ciphertexts
451/// can no longer be created, but existing ciphertexts can still be decapsulated. Splitting the traits
452/// makes this policy easier to enforce.
453///
454/// The arrays used to encode public keys, ciphertexts, and shared secrets are statically-sized
455/// because this allows us to safely remove runtime checks for array lengths, which overall reduces
456/// the fallibility of the library. This design choice could make this trait complicated to apply
457/// to a KEM algorithm that does not have fixed sizes for the encodings of these objects.
458pub trait KEMEncapsulator<
459    PK: KEMPublicKey<PK_LEN>,
460    const PK_LEN: usize,
461    const CT_LEN: usize,
462    const SS_LEN: usize,
463>: Sized
464{
465    /// Performs an encapsulation against the given public key.
466    /// Sources randomness from the library's default OS-backed RNG.
467    /// Returns the ciphertext and derived shared secret.
468    fn encaps(pk: &PK) -> Result<(KeyMaterial<SS_LEN>, [u8; CT_LEN]), KEMError>;
469    /// Performs an encapsulation against the given public key.
470    /// Sources randomness from the provided RNG.
471    /// Returns the ciphertext and derived shared secret.
472    fn encaps_rng(
473        pk: &PK,
474        rng: &mut dyn RNG,
475    ) -> Result<(KeyMaterial<SS_LEN>, [u8; CT_LEN]), KEMError>;
476}
477
478/// A Key Encapsulation Mechanism (KEM) is defined as a set of three operations:
479/// key generation, encapsulation, and decapsulation.
480///
481/// This trait represents the decapsulation operation performed by the holder of the private key.
482/// Encapsulation operations are performed by the corresponding [`KEMEncapsulator`] trait, and key
483/// generation is provided as an inherent associated function directly on the algorithm struct.
484/// There are several reasons for this split: first is architectural; some complex algorithms may
485/// benefit from having the encapsulation and decapsulation implementations split into separate modules.
486/// Second is for compliance: sometimes a policy soft-deprecates an algorithm so that new ciphertexts
487/// can no longer be created, but existing ciphertexts can still be decapsulated. Splitting the traits
488/// makes this policy easier to enforce.
489///
490/// The arrays used to encode private keys, ciphertexts, and shared secrets are statically-sized
491/// because this allows us to safely remove runtime checks for array lengths, which overall reduces
492/// the fallibility of the library. This design choice could make this trait complicated to apply
493/// to a KEM algorithm that does not have fixed sizes for the encodings of these objects.
494pub trait KEMDecapsulator<
495    SK: KEMPrivateKey<SK_LEN>,
496    const SK_LEN: usize,
497    const CT_LEN: usize,
498    const SS_LEN: usize,
499>: Sized
500{
501    /// Performs a decapsulation of the given ciphertext.
502    /// Returns the derived shared secret.
503    fn decaps(sk: &SK, ct: &[u8]) -> Result<KeyMaterial<SS_LEN>, KEMError>;
504}
505
506// todo: could the public and private key types impl Into<T: AsRef<[u8]>> and From<T: AsRef<[u8]>>
507// todo: that automatically call the encode and from_bytes() ?
508
509/// A public key for a KEM algorithm, often denoted "pk".
510pub trait KEMPublicKey<const PK_LEN: usize>:
511    PartialEq + Eq + Clone + Debug + Display + Sized
512{
513    /// Write it out to bytes in its standard encoding.
514    fn encode(&self) -> [u8; PK_LEN];
515    /// Write it out to bytes in its standard encoding.
516    /// The entire output buffer is zeroized before the encoding is written.
517    fn encode_out(&self, out: &mut [u8; PK_LEN]) -> usize;
518    /// Read it in from bytes in its standard encoding.
519    fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError>;
520}
521
522/// A private key for a KEM algorithm, often denoted "sk" (for "secret key").
523pub trait KEMPrivateKey<const SK_LEN: usize>: PartialEq + Eq + Clone + Sized {
524    /// Write it out to bytes in its standard encoding.
525    fn encode(&self) -> [u8; SK_LEN];
526    /// Write it out to bytes in its standard encoding.
527    /// The entire output buffer is zeroized before the encoding is written.
528    fn encode_out(&self, out: &mut [u8; SK_LEN]) -> usize;
529    /// Read it in from bytes in its standard encoding.
530    fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError>;
531}
532
533/// A Message Authentication Code algorithm is a keyed hash function that behaves somewhat like a symmetric signature function.
534/// A MAC algorithm takes in a key and some data, and produces a MAC (message authentication code) that
535/// can be used to verify the integrity of data.
536///
537/// This trait provides one-shot functions [`MAC::mac`], [`MAC::mac_out`], and [`MAC::verify`].
538/// It also provides streaming functions [`MAC::do_update`], [`MAC::do_final`], [`MAC::do_final_out`],
539/// and [`MAC::do_verify_final`].
540/// The workflow is that a MAC object is initialized with a key with [`MAC::new`] -- or [`MAC::new_allow_weak_key`] if you
541/// need to disable the library's safety mechanism to prevent the use of weak keys -- then data is
542/// processed into one or more calls to [`MAC::do_update`],
543/// after that the object can either create a MAC with [`MAC::do_final`] or [`MAC::do_final_out`] (which are final functions, and so consume the object),
544/// or the object can be used to verify a MAC.
545///
546/// For varifying an existing MAC, it is functionally equivalent to use the provided [`MAC::verify`] and [`MAC::do_verify_final`]
547/// function or to compute a new MAC and compare it to the existing MAC, however the provided verification functions
548/// use constant-time comparison to avoid cryptographic timing attacks whereby an attacker could learn
549/// the bytes of the MAC value under some conditions. Therefore, it is highly recommended to use the provided verification functions.
550///
551/// Note that the MAC key is not represented in this trait because it is provided to the MAC algorithm
552/// as part of its new functions.
553///
554/// MACs do not implement Default because they do not have a sensible no-args constructor.
555pub trait MAC: Sized {
556    /// Create a new MAC instance with the given key.
557    ///
558    /// This is a common constructor whether creating or verifying a MAC value.
559    ///
560    /// Key / Salt is optional, which is indicated by providing an uninitialized KeyMaterial object of length zero,
561    /// the capacity is irrelevant, so KeyMateriol256::new() or KeyMaterial_internal::<0>::new() would both count as an absent salt.
562    ///
563    /// # Note about the security strength of the provided key:
564    /// If you initialize the MAC with a key that is tagged at a lower [`SecurityStrength`] than the
565    /// underlying hash function then [`MAC::new`] will fail with the following error:
566    /// ```text
567    /// MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")
568    /// ```
569    /// There are situations in which it is completely reasonable and secure to provide low-entropy
570    /// (and sometimes all-zero) keys / salts; for these cases we have provided [`MAC::new_allow_weak_key`].
571    fn new(key: &impl KeyMaterialTrait) -> Result<Self, MACError>;
572
573    /// Create a new HMAC instance with the given key.
574    ///
575    /// This constructor completely ignores the [`SecurityStrength`] tag on the input key and will "just work".
576    /// This should be used if you really do need to use a weak key, such as an all-zero salt,
577    /// but use of this constructor is discouraged and you should really be asking yourself why you need it;
578    /// in most cases it indicates that your key is not long enough to support the security level of this
579    /// HMAC instance, or the key was derived using algorithms at a lower security level, etc.
580    fn new_allow_weak_key(key: &impl KeyMaterialTrait) -> Result<Self, MACError>;
581
582    /// The size of the output in bytes.
583    fn output_len(&self) -> usize;
584
585    /// One-shot API that computes a MAC for the provided data.
586    /// `data` can be of any length, including zero bytes.
587    ///
588    /// Note about the security strength of the provided key:
589    /// If the provided key is tagged at a lower [`SecurityStrength`] than the instantiated MAC algorithm,
590    /// this will fail with an error:
591    /// ```text
592    /// MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")
593    /// ```
594    fn mac(self, data: &[u8]) -> Vec<u8>;
595
596    /// One-shot API that computes a MAC for the provided data and writes it into the provided output slice.
597    /// `data` can be of any length, including zero bytes.
598    ///
599    /// Depending on the underlying MAC implementation, NIST may require that the library enforce
600    /// a minimum length on the mac output value. See documentation for the underlying implementation
601    /// to see conditions under which it throws [`MACError::InvalidLength`].
602    ///
603    /// The entire output buffer is zeroized before the MAC value is written.
604    fn mac_out(self, data: &[u8], out: &mut [u8]) -> Result<usize, MACError>;
605
606    /// One-shot API that verifies a MAC for the provided data.
607    /// `data` can be of any length, including zero bytes.
608    ///
609    /// Internally, this will re-compute the MAC value and then compare it to the provided mac value
610    /// using constant-time comparison. It is highly encouraged to use this utility function instead of
611    /// comparing mac values for equality yourself.
612    ///
613    /// Returns a bool to indicate successful verification of the provided mac value.
614    /// The provided mac value must be an exact match, including length; for example a mac value
615    /// which has been truncated, or which contains extra bytes at the end is considered to not be a match
616    /// and will return false.
617    fn verify(self, data: &[u8], mac: &[u8]) -> bool;
618
619    /// Provide a chunk of data to be absorbed into the MAC.
620    /// `data` can be of any length, including zero bytes.
621    /// do_update() is intended to be used as part of a streaming interface, and so may by called multiple times.
622    fn do_update(&mut self, data: &[u8]);
623
624    /// Finish absorbing input and produce the MAC value.
625    fn do_final(self) -> Vec<u8>;
626
627    /// Depending on the underlying MAC implementation, NIST may require that the library enforce
628    /// a minimum length on the mac output value. See documentation for the underlying implementation
629    /// to see conditions under which it throws [`MACError::InvalidLength`].
630    ///
631    /// The entire output buffer is zeroized before the MAC value is written.
632    fn do_final_out(self, out: &mut [u8]) -> Result<usize, MACError>;
633
634    /// Internally, this will re-compute the MAC value and then compare it to the provided mac value
635    /// using constant-time comparison. It is highly encouraged to use this utility function instead of
636    /// comparing mac values for equality yourself.
637    ///
638    /// Returns a bool to indicate successful verification of the provided mac value.
639    /// The provided mac value must be an exact match, including length; for example a mac value
640    /// which has been truncated, or which contains extra bytes at the end is considered to not be a match
641    /// and will return false.
642    fn do_verify_final(self, mac: &[u8]) -> bool;
643
644    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
645    fn max_security_strength(&self) -> SecurityStrength;
646}
647
648/// A general indicator used across the library for marking the security level of a cryptographic primitive,
649/// and for tracking the security level of the algorithms that interacted with a given piece of data.
650/// For example, if a KDF at the 128-bit security strength is used to produce a 512-bit key, that key
651/// will also be tagged as having a 128-bit security strength.
652///
653/// Some functions across the library may reject or behave differently based on the security strength
654/// of the inputs they are given. For example a `keygen_from_seed()` may reject a seed taged at a lower
655/// security strength than the one required by the algorithm, or it may proceed, but lower its own
656/// advertised security strength accordingly -- each cryptographic primitive may have additional detail.
657// Dev note: The explicit `#[repr(u8)]` discriminants are the stable on-the-wire encoding used by
658// `SerializableState` implementations (see the corresponding `TryFrom<u8>` impl below).
659// If additional strength levels are added in the future, they can be placed into the enum in
660// any order, but should use currently unassigned values (unless you're doing this on a MAJOR or MINOR
661// release as a breaking change).
662#[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)]
663#[repr(u8)]
664pub enum SecurityStrength {
665    ///
666    None = 0,
667    ///
668    _112bit = 1,
669    ///
670    _128bit = 2,
671    ///
672    _192bit = 3,
673    ///
674    _256bit = 4,
675}
676
677impl TryFrom<u8> for SecurityStrength {
678    type Error = SuspendableError;
679
680    /// Inverse of `self as u8`; rejects unrecognized discriminants with [`SuspendableError::InvalidData`].
681    fn try_from(value: u8) -> Result<Self, Self::Error> {
682        Ok(match value {
683            0 => Self::None,
684            1 => Self::_112bit,
685            2 => Self::_128bit,
686            3 => Self::_192bit,
687            4 => Self::_256bit,
688            _ => return Err(SuspendableError::InvalidData),
689        })
690    }
691}
692
693impl SecurityStrength {
694    /// Rounds down to the closest supported security strength.
695    /// For example, 120-bits is rounded down to 112-bit.
696    pub fn from_bits(bits: usize) -> Self {
697        if bits < 112 {
698            Self::None
699        } else if bits < 128 {
700            Self::_112bit
701        } else if bits < 192 {
702            Self::_128bit
703        } else if bits < 256 {
704            Self::_192bit
705        } else {
706            Self::_256bit
707        }
708    }
709
710    /// Rounds down to the closest supported security strength.
711    /// For example, 15 bytes (120-bits) is rounded down to 112-bit.
712    pub fn from_bytes(bytes: usize) -> Self {
713        Self::from_bits(bytes * 8)
714    }
715
716    /// Outputs the security strength in bits for easier computation.
717    pub fn as_int(&self) -> u32 {
718        match self {
719            Self::None => 0,
720            Self::_112bit => 112,
721            Self::_128bit => 128,
722            Self::_192bit => 192,
723            Self::_256bit => 256,
724        }
725    }
726}
727
728/// An interface for random number generation.
729/// This interface is meant to be simpler and more ergonomic than the interfaces provided by the
730/// `rng` crate, but that one should
731/// be used by applications that intend to submit to FIPS certification as it more closely aligns with the
732/// requirements of SP 800-90A.
733/// Note: this interface produces bytes. If you want a [`KeyMaterialTrait`], then use [`KeyMaterial::from_rng`].
734///
735/// Implementors are expected to also implement [`Default`] (default-construction should produce a
736/// securely OS-seeded instance), but this is intentionally *not* a supertrait bound: requiring
737/// `Default` would make `RNG` not dyn-compatible, and `&mut dyn RNG` is needed so RNG instances
738/// can be handed around as trait objects.
739pub trait RNG {
740    // TODO: add back once we figure out streaming interaction with entropy sources.
741    // fn add_seed_bytes(&mut self, additional_seed: &[u8]) -> Result<(), RNGError>;
742
743    /// Provide additional key material to be mixed in to the existing RNG instance.
744    /// The exact behaviour will be implementation-specific, but this is intended for injecting
745    /// additional entropy, not as the primary method of seeding the RNG.
746    fn add_seed_keymaterial(
747        &mut self,
748        additional_seed: &dyn KeyMaterialTrait,
749    ) -> Result<(), RNGError>;
750    /// Returns the next random 32-bit integer.
751    fn next_int(&mut self) -> Result<u32, RNGError>;
752
753    /// Returns the number of requested bytes.
754    fn next_bytes(&mut self, len: usize) -> Result<Vec<u8>, RNGError>;
755
756    /// Returns the number of bytes written.
757    /// The entire output buffer is zeroized before the random bytes are written.
758    fn next_bytes_out(&mut self, out: &mut [u8]) -> Result<usize, RNGError>;
759
760    /// Fill the provided [`KeyMaterial`] with random bytes.
761    fn fill_keymaterial_out(&mut self, out: &mut dyn KeyMaterialTrait) -> Result<usize, RNGError>;
762
763    /// Returns the Security Strength of this RNG.
764    // todo: we should do a refactor to make [Algorithm] be a `security_strength()` function instead of constant,
765    //      then have `RNG: Algorithm`, then delete this function.
766    fn security_strength(&self) -> SecurityStrength;
767}
768
769/// Allows a stateful object to suspend its operation by serializing its state into a byte array
770///so that it can be resumed later, potentially from a different host.
771///
772/// This is intended for situations where an object is being used through its streaming API
773/// (do_update, do_final) and the operation wants to be paused to a cache, for example while waiting
774/// for network IO.
775///
776/// This is not intended as a mechanism to clone the state of an object since in most cases `.clone()`
777/// will be more straightforward.
778///
779/// The serialized state MAY contain short-term sensitive values such as nonces or IVs,
780/// but it MUST NOT include a serialized private key.
781/// Keyed algorithms MUST instead impl
782/// [`SuspendableKeyed`] which requires the key to be supplied independently at the time of deserialization.
783pub trait Suspendable<const SERIALIZED_STATE_LEN: usize>: Sized {
784    /// Suspend operation by serializing out the state of the object.
785    ///
786    /// Note that this consumes `self` to prevent accidentally continuing to use the object after serialization.
787    /// If you want to do this intentionally, then you will need to clone the object before serializing it.
788    ///
789    /// The serialized state MUST include a prefix indicating the version of the library that serialized it.
790    fn suspend(self) -> [u8; SERIALIZED_STATE_LEN];
791
792    /// Resume operation from a serialized state.
793    ///
794    /// Deserializers SHOULD check the version and reject serialized states from incompatible versions
795    /// (including rejecting serializations from a future version of the library).
796    /// For example, if a given object made a breaking change to its serialization in version 1.2.3, then its
797    /// deserializer should reject serialized states from that version or older.
798    fn from_suspended(state: [u8; SERIALIZED_STATE_LEN]) -> Result<Self, SuspendableError>;
799}
800
801/// Similar to [`Suspendable`] in that it allows a stateful object to suspend its operation by
802/// serializing its state into a byte array so that it can be resumed later, potentially from a different host.
803///
804/// The difference is that this trait is for keyed algorithms -- MACs, symmetric ciphers, signatures, etc --
805/// which require a private key in order to resume successfully.
806/// For security reasons, the private key is not included in the serialized state
807/// and must be provided separately as part of the deserialization process.
808pub trait SuspendableKeyed<const SERIALIZED_STATE_LEN: usize>: Sized {
809    /// The type of key that must be re-supplied to resume this object.
810    type Key: ?Sized;
811
812    /// Suspend operation by serializing out the state of the object.
813    ///
814    /// Note that this consumes `self` to prevent accidentally continuing to use the object after serialization.
815    /// If you want to do this intentionally, then you will need to clone the object before serializing it.
816    ///
817    /// The serialized state MUST include a prefix indicating the version of the library that serialized it.
818    fn suspend(self) -> [u8; SERIALIZED_STATE_LEN];
819
820    /// Resume operation from a serialized state and the key.
821    ///
822    /// Deserializers SHOULD check the version and reject serialized states from incompatible versions
823    /// (including rejecting serializations from a future version of the library).
824    /// For example, if a given object made a breaking change to its serialization in version 1.2.3, then its
825    /// deserializer should reject serialized states from that version or older.
826    fn from_suspended(
827        state: [u8; SERIALIZED_STATE_LEN],
828        key: &Self::Key,
829    ) -> Result<Self, SuspendableError>;
830}
831
832/// Pre-Hashed Signer is an extension to [`Signer`] that adds functionality specific to signature
833/// primatives that can operate on a pre-hashed message instead of the full message.
834pub trait PHSigner<
835    PK: SignaturePublicKey<PK_LEN>,
836    SK: SignaturePrivateKey<SK_LEN>,
837    const PK_LEN: usize,
838    const SK_LEN: usize,
839    const SIG_LEN: usize,
840    const PH_LEN: usize,
841>: Signer<SK, SK_LEN, SIG_LEN>
842{
843    /// Produce a signature for the provided pre-hashed message and context.
844    ///
845    /// `ctx` accepts a zero-length byte array.
846    ///
847    /// A note about the `ctx` context parameter:
848    /// This is a newer addition to cryptographic signature primitives. It allows for binding the
849    /// signature to some external property of the application so that a signature will fail to validate
850    /// if removed from its intended context.
851    /// This is particularly useful at preventing content confusion attacks between data formats that
852    /// have very similar data structures, for example S/MIME emails, signed PDFs, and signed executables
853    /// that all use the Cryptographic Message Syntax (CMS) data format, or multiple data objects that
854    /// all use the JWS data format.
855    /// To be properly effective, the ctx value must not be under the control of the attacker, which generally
856    /// means that it needs to be a value that is never transmitted over the wire, but rather is something
857    /// known to the application by context.
858    /// For example, "email" vs "pdf" would be a good choice since the application should know what it is
859    /// attempting to sign or verify.
860    /// The `ctx` param can also be used to bind the signed content to a transaction ID or a username,
861    /// but care should be taken to ensure that an attacker attempting a
862    /// content confusion attack not also cause the signed / verifier to use an incorrect transaction ID or username.
863    ///
864    /// Not all signature primitives will support a context value, so you may need to consult the
865    /// documentation for the underlying primitive for how it handles a ctx in that case, for example, it
866    /// might throw an error, ignore the provided ctx value, or append the ctx to the msg in a non-standard way.
867    fn sign_ph(
868        sk: &SK,
869        ph: &[u8; PH_LEN],
870        ctx: Option<&[u8]>,
871    ) -> Result<[u8; SIG_LEN], SignatureError>;
872    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
873    /// The entire output buffer is zeroized before the signature is written.
874    fn sign_ph_out(
875        sk: &SK,
876        ph: &[u8; PH_LEN],
877        ctx: Option<&[u8]>,
878        output: &mut [u8; SIG_LEN],
879    ) -> Result<usize, SignatureError>;
880}
881
882/// Pre-Hashed Signature Verifier is an extension to [`SignatureVerifier`] that adds functionality specific to signature
883/// primatives that can operate on a pre-hashed message instead of the full message.
884pub trait PHSignatureVerifier<
885    PK: SignaturePublicKey<PK_LEN>,
886    const PK_LEN: usize,
887    const SIG_LEN: usize,
888    const PH_LEN: usize,
889>: SignatureVerifier<PK, PK_LEN, SIG_LEN>
890{
891    /// On success, returns Ok(())
892    /// On failure, returns Err([`SignatureError::SignatureVerificationFailed`]); may also return other types of [`SignatureError`] as appropriate (such as for invalid-length inputs).
893    fn verify_ph(
894        pk: &PK,
895        ph: &[u8; PH_LEN],
896        ctx: Option<&[u8]>,
897        sig: &[u8],
898    ) -> Result<(), SignatureError>;
899}
900
901// todo: could the public and private key types impl Into<T: AsRef<[u8]>> and From<T: AsRef<[u8]>>
902// todo: that automatically call the encode and from_bytes() ?
903
904/// A public key for a signature algorithm, often denoted "pk".
905pub trait SignaturePublicKey<const PK_LEN: usize>:
906    PartialEq + Eq + Clone + Debug + Display + Sized
907{
908    /// Write it out to bytes in its standard encoding.
909    fn encode(&self) -> [u8; PK_LEN];
910    /// Write it out to bytes in its standard encoding.
911    /// The entire output buffer is zeroized before the encoding is written.
912    fn encode_out(&self, out: &mut [u8; PK_LEN]) -> usize;
913    /// Read it in from bytes in its standard encoding.
914    fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError>;
915}
916
917/// A private key for a signature algorithm, often denoted "sk" (for "secret key").
918pub trait SignaturePrivateKey<const SK_LEN: usize>: PartialEq + Eq + Clone + Sized {
919    /// Write it out to bytes in its standard encoding.
920    fn encode(&self) -> [u8; SK_LEN];
921    /// Write it out to bytes in its standard encoding.
922    /// The entire output buffer is zeroized before the encoding is written.
923    fn encode_out(&self, out: &mut [u8; SK_LEN]) -> usize;
924    /// Read it in from bytes in its standard encoding.
925    fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError>;
926}
927
928/// A digital signature algorithm is defined as a set of three operations:
929/// key generation, signing, and verification.
930///
931/// This trait represents the operations performed by the holder of the signing private key:
932/// which include signing and key generation. Verification operations are performed by the corresponding
933/// [`SignatureVerifier`] trait.
934/// There are several reasons for this split: first is architectural; some complex algorithms may
935/// benefit from having the signature generation and verification implementations split into separate modules.
936/// Second is for compliance: sometimes a policy soft-deprecates an algorithm so that new signatures
937/// can no longer be created, but existing signatures can still be verified. Splitting the traits
938/// makes this policy easier to enforce.
939///
940/// This high-level trait defines the operations over a generic signature algorithm that is assumed
941/// to source all its randomness from bouncycastle's default os-backed RNG.
942/// The underlying signature primitives will expose APIs that allow for specifying a specific RNG
943/// or deterministic seed values.
944///
945/// The arrays used to encode public keys, private keys, and signature values are statically-sized
946/// because this allows us to safely remove runtime checks for array lengths, which overall reduces
947/// the fallibility of the library. This design choice could make this trait complicated to apply
948/// to a signature algorithm that do not have fixed sizes for the encodings of these objects.
949pub trait Signer<SK: SignaturePrivateKey<SK_LEN>, const SK_LEN: usize, const SIG_LEN: usize>:
950    Sized
951{
952    /// Produce a signature for the provided message and context.
953    /// Both the `msg` and `ctx` accept zero-length byte arrays.
954    ///
955    /// A note about the `ctx` context parameter:
956    /// This is a newer addition to cryptographic signature primitives. It allows for binding the
957    /// signature to some external property of the application so that a signature will fail to validate
958    /// if removed from its intended context.
959    /// This is particularly useful at preventing content confusion attacks between data formats that
960    /// have very similar data structures, for example S/MIME emails, signed PDFs, and signed executables
961    /// that all use the Cryptographic Message Syntax (CMS) data format, or multiple data objects that
962    /// all use the JWS data format.
963    /// To be properly effective, the ctx value must not be under the control of the attacker, which generally
964    /// means that it needs to be a value that is never transmitted over the wire, but rather is something
965    /// known to the application by context.
966    /// For example, "email" vs "pdf" would be a good choice since the application should know what it is
967    /// attempting to sign or verify.
968    /// The `ctx` param can also be used to bind the signed content to a transaction ID or a username,
969    /// but care should be taken to ensure that an attacker attempting a
970    /// content confusion attack not also cause the signed / verifier to use an incorrect transaction ID or username.
971    ///
972    /// Not all signature primitives will support a context value, so you may need to consult the
973    /// documentation for the underlying primitive for how it handles a ctx in that case, for example, it
974    /// might throw an error, ignore the provided ctx value, or append the ctx to the msg in a non-standard way.
975    fn sign(sk: &SK, msg: &[u8], ctx: Option<&[u8]>) -> Result<[u8; SIG_LEN], SignatureError>;
976
977    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
978    /// The entire output buffer is zeroized before the signature is written.
979    fn sign_out(
980        sk: &SK,
981        msg: &[u8],
982        ctx: Option<&[u8]>,
983        output: &mut [u8; SIG_LEN],
984    ) -> Result<usize, SignatureError>;
985
986    /* streaming signing API */
987    /// Initialize a signer for streaming mode with the provided private key.
988    fn sign_init(sk: &SK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>;
989
990    // todo: make this a AsRef<[u8]> ?
991    /// Update the signer with the next chunk of data.
992    /// This can be called multiple times.
993    fn sign_update(&mut self, msg_chunk: &[u8]);
994
995    /// Complete the signing operation. Consumes self.
996    fn sign_final(self) -> Result<[u8; SIG_LEN], SignatureError>;
997
998    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
999    /// The entire output buffer is zeroized before the signature is written.
1000    fn sign_final_out(self, output: &mut [u8; SIG_LEN]) -> Result<usize, SignatureError>;
1001}
1002
1003/// A digital signature algorithm is defined as a set of three operations:
1004/// key generation, signing, and verification.
1005///
1006/// This trait represents the verification operations performed by the holder of the verification public key.
1007/// Keygen and signing operations are performed by the corresponding [`Signer`] trait.
1008/// There are several reasons for this split: first is architectural; some complex algorithms may
1009/// benefit from having the signature generation and verification implementations split into separate modules.
1010/// Second is for compliance: sometimes a policy soft-deprecates an algorithm so that new signatures
1011/// can no longer be created, but existing signatures can still be verified. Splitting the traits
1012/// makes this policy easier to enforce.
1013///
1014/// Here we statically-size the arrays used to encode public keys, private keys, and signature values
1015/// because this allows us to safely remove runtime checks for array lengths, which overall reduces
1016/// the fallibility of the library. This design choice could make this trait complicated to apply
1017/// to a signature algorithm that do not have fixed sizes for the encodings of these objects.
1018pub trait SignatureVerifier<
1019    PK: SignaturePublicKey<PK_LEN>,
1020    const PK_LEN: usize,
1021    const SIG_LEN: usize,
1022>: Sized
1023{
1024    /// On success, returns Ok(())
1025    /// On failure, returns Err([`SignatureError::SignatureVerificationFailed`]); may also return other types of [`SignatureError`] as appropriate (such as for invalid-length inputs).
1026    fn verify(pk: &PK, msg: &[u8], ctx: Option<&[u8]>, sig: &[u8]) -> Result<(), SignatureError>;
1027
1028    /// streaming verification API
1029    fn verify_init(pk: &PK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>;
1030
1031    // todo: make this a AsRef<[u8]> ?
1032    /// Update the verifier with the next chunk of data.
1033    /// This can be called multiple times.
1034    fn verify_update(&mut self, msg_chunk: &[u8]);
1035
1036    /// On success, returns Ok(())
1037    /// On failure, returns Err([`SignatureError::SignatureVerificationFailed`]); may also return other types of [`SignatureError`] as appropriate (such as for invalid-length inputs).
1038    fn verify_final(self, sig: &[u8]) -> Result<(), SignatureError>;
1039}
1040
1041/// Extensible Output Functions (XOFs) are similar to hash functions, except that they can produce output of arbitrary length.
1042/// The naming used for the functions of this trait are borrowed from the SHA3-style sponge constructions that split XOF operation
1043/// into two phases: an absorb phase in which an arbitrary amount of input is provided to the XOF,
1044/// and then a squeeze phase in which an arbitrary amount of output is extracted.
1045/// Once squeezing begins, no more input can be absorbed.
1046///
1047/// XOFs are _similar to_ hash functions, but are not hash functions for one technical but important reason:
1048/// since the amount of output to produce is not provided to the XOF in advance, it cannot be used to
1049/// diversify the XOF output streams.
1050/// In other words, the overlapping parts of their outputs will be the same!
1051/// For example, consider two XOFs that absorb the same input data, one that is squeezed to produce 32 bytes,
1052/// and the other to produce 1 kb; both outputs will be identical in their first 32 bytes.
1053/// This could lead to loss of security in a number of ways, for example distinguishing attacks where
1054/// it is sufficient for the attacker to know that two values came from the same input, even if the
1055/// attacker cannot learn what that input was. This is attack is often sufficient, for example,
1056/// to break anonymity-preserving technology.
1057/// Applications that require the arbitrary-length output of an XOF, but also care about these
1058/// distinguishing attacks should consider adding a cryptographic salt to diversify the inputs.
1059pub trait XOF: Default {
1060    /// A static one-shot API that digests the input data and produces `result_len` bytes of output.
1061    fn hash_xof(self, data: &[u8], result_len: usize) -> Vec<u8>;
1062
1063    /// A static one-shot API that digests the input data and produces `result_len` bytes of output.
1064    /// Fills the provided output slice.
1065    /// The entire output buffer is zeroized before the output is written.
1066    fn hash_xof_out(self, data: &[u8], output: &mut [u8]) -> usize;
1067
1068    /// Absorb some amount of input.
1069    fn absorb(&mut self, data: &[u8]) -> Result<(), HashError>;
1070
1071    /// Switches to squeezing.
1072    fn absorb_last_partial_byte(
1073        &mut self,
1074        partial_byte: u8,
1075        num_partial_bits: usize,
1076    ) -> Result<(), HashError>;
1077
1078    /// Can be called multiple times.
1079    fn squeeze(&mut self, num_bytes: usize) -> Vec<u8>;
1080
1081    /// Can be called multiple times.
1082    /// Fills the provided output slice.
1083    /// The entire output buffer is zeroized before the output is written.
1084    fn squeeze_out(&mut self, output: &mut [u8]) -> usize;
1085
1086    /// Squeezes a partial byte from the XOF.
1087    /// Output will be in the top `num_bits` bits of the returned u8 (ie Big Endian).
1088    /// This is a final call and consumes self.
1089    fn squeeze_partial_byte_final(self, num_bits: usize) -> Result<u8, HashError>;
1090
1091    /// The same as [`XOF::squeeze_partial_byte_final`], but writes into the provided output byte.
1092    /// The output byte is zeroized before the result is written.
1093    fn squeeze_partial_byte_final_out(
1094        self,
1095        num_bits: usize,
1096        output: &mut u8,
1097    ) -> Result<(), HashError>;
1098
1099    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
1100    // todo: we should do a refactor to make [Algorithm] be a `security_strength()` function instead of constant,
1101    //      then have `RNG: Algorithm`, then delete this function.
1102    fn max_security_strength(&self) -> SecurityStrength;
1103}