hpke_rs_crypto/
lib.rs

1#![doc = include_str!("../Readme.md")]
2#![no_std]
3
4extern crate alloc;
5#[cfg(feature = "std")]
6extern crate std;
7
8use alloc::string::String;
9use alloc::vec::Vec;
10
11use error::Error;
12use types::{AeadAlgorithm, KemAlgorithm};
13
14pub mod error;
15pub mod types;
16
17// re-export trait
18pub use rand_core::{CryptoRng, RngCore};
19
20/// The [`HpkeCrypto`] trait defines the necessary cryptographic functions used
21/// in the HPKE implementation.
22pub trait HpkeCrypto: core::fmt::Debug + Send + Sync {
23    /// The PRNG implementation returned in [`HpkeCrypto::prng()`].
24    type HpkePrng: RngCore + CryptoRng + HpkeTestRng;
25
26    /// The name of the implementation.
27    fn name() -> String;
28
29    /// Returns an error if the KDF algorithm is not supported by this crypto provider.
30    fn supports_kdf(alg: types::KdfAlgorithm) -> Result<(), Error>;
31
32    /// Returns an error if the KEM algorithm is not supported by this crypto provider.
33    fn supports_kem(alg: types::KemAlgorithm) -> Result<(), Error>;
34
35    /// Returns an error if the AEAD algorithm is not supported by this crypto provider.
36    fn supports_aead(alg: types::AeadAlgorithm) -> Result<(), Error>;
37
38    /// Get a stateful PRNG.
39    /// Note that this will create a new PRNG state.
40    fn prng() -> Self::HpkePrng;
41
42    /// Get the length of the output digest.
43    #[inline(always)]
44    fn kdf_digest_length(alg: types::KdfAlgorithm) -> usize {
45        match alg {
46            types::KdfAlgorithm::HkdfSha256 => 32,
47            types::KdfAlgorithm::HkdfSha384 => 48,
48            types::KdfAlgorithm::HkdfSha512 => 64,
49        }
50    }
51
52    /// KDF Extract
53    fn kdf_extract(alg: types::KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result<Vec<u8>, Error>;
54
55    /// KDF Expand
56    fn kdf_expand(
57        alg: types::KdfAlgorithm,
58        prk: &[u8],
59        info: &[u8],
60        output_size: usize,
61    ) -> Result<Vec<u8>, Error>;
62
63    /// Diffie-Hellman
64    fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result<Vec<u8>, Error>;
65
66    /// Diffie-Hellman with the base (generate public key for secret key `sk`).
67    fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result<Vec<u8>, Error>;
68
69    /// KEM key pair generation (encapsulation key, decapsulation key).
70    fn kem_key_gen(
71        alg: KemAlgorithm,
72        prng: &mut Self::HpkePrng,
73    ) -> Result<(Vec<u8>, Vec<u8>), Error>;
74
75    /// KEM key pair generation (encapsulation key, decapsulation key) based
76    /// on the `seed`.
77    fn kem_key_gen_derand(alg: KemAlgorithm, seed: &[u8]) -> Result<(Vec<u8>, Vec<u8>), Error>;
78
79    /// KEM encapsulation to `pk_r` (shared secret, ciphertext).
80    fn kem_encaps(
81        alg: KemAlgorithm,
82        pk_r: &[u8],
83        prng: &mut Self::HpkePrng,
84    ) -> Result<(Vec<u8>, Vec<u8>), Error>;
85
86    /// KEM decapsulation with `sk_r`.
87    /// Returns the shared secret.
88    fn kem_decaps(alg: KemAlgorithm, ct: &[u8], sk_r: &[u8]) -> Result<Vec<u8>, Error>;
89
90    /// Validate a secret key for its correctness.
91    fn dh_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result<Vec<u8>, Error>;
92
93    /// AEAD encrypt.
94    fn aead_seal(
95        alg: AeadAlgorithm,
96        key: &[u8],
97        nonce: &[u8],
98        aad: &[u8],
99        msg: &[u8],
100    ) -> Result<Vec<u8>, Error>;
101
102    /// AEAD decrypt.
103    fn aead_open(
104        alg: AeadAlgorithm,
105        key: &[u8],
106        nonce: &[u8],
107        aad: &[u8],
108        msg: &[u8],
109    ) -> Result<Vec<u8>, Error>;
110
111    /// Get key length for AEAD.
112    ///
113    /// Note that this function returns `0` for export only keys of unknown size.
114    fn aead_key_length(alg: AeadAlgorithm) -> usize {
115        match alg {
116            AeadAlgorithm::Aes128Gcm => 16,
117            AeadAlgorithm::Aes256Gcm => 32,
118            AeadAlgorithm::ChaCha20Poly1305 => 32,
119            AeadAlgorithm::HpkeExport => 0,
120        }
121    }
122
123    /// Get key length for AEAD.
124    ///
125    /// Note that this function returns `0` for export only nonces of unknown size.
126    fn aead_nonce_length(alg: AeadAlgorithm) -> usize {
127        match alg {
128            AeadAlgorithm::Aes128Gcm => 12,
129            AeadAlgorithm::Aes256Gcm => 12,
130            AeadAlgorithm::ChaCha20Poly1305 => 12,
131            AeadAlgorithm::HpkeExport => 0,
132        }
133    }
134
135    /// Get key length for AEAD.
136    ///
137    /// Note that this function returns `0` for export only tags of unknown size.
138    fn aead_tag_length(alg: AeadAlgorithm) -> usize {
139        match alg {
140            AeadAlgorithm::Aes128Gcm => 16,
141            AeadAlgorithm::Aes256Gcm => 16,
142            AeadAlgorithm::ChaCha20Poly1305 => 16,
143            AeadAlgorithm::HpkeExport => 0,
144        }
145    }
146}
147
148/// PRNG extension for testing that is supposed to return pre-configured bytes.
149pub trait HpkeTestRng {
150    // Error type to replace rand::Error (which is no longer available as of version 0.9)
151    type Error: core::fmt::Debug + core::fmt::Display;
152    /// Like [`TryRngCore::try_fill_bytes`] but the result is expected to be known.
153    fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error>;
154
155    /// Set the randomness state of this test PRNG.
156    fn seed(&mut self, seed: &[u8]);
157}