aranya_crypto/ciphersuite/mod.rs
1//! - `AEAD`: Authenticated Encryption with Additional
2//! Authenticated Data. See [AEAD] and [RFC 5116].
3//! - `Digital signature`: See [Signature].
4//! - `encapsulate`: To encrypt cryptographic key material,
5//! typically for use with an asymmetric algorithm. See [KEM].
6//! - `HPKE`: Hybrid Public Key Encryption. See [HPKE].
7//! - `KDF`: A Key Derivation Function. See [KDF].
8//! - `KEM`: A Key Encapsulation Mechanism. See [KEM].
9//! - `seal`: Synonymous with "encrypt."
10//! - `open`: Synonymous with "decrypt."
11//!
12//! [AEAD]: https://en.wikipedia.org/wiki/Authenticated_encryption
13//! [HPKE]: https://www.rfc-editor.org/rfc/rfc9180.html
14//! [KDF]: https://en.wikipedia.org/wiki/Key_derivation_function
15//! [KEM]: https://en.wikipedia.org/wiki/Key_encapsulation_mechanism
16//! [RFC 5116]: https://www.rfc-editor.org/rfc/rfc5116
17//! [Signature]: https://en.wikipedia.org/wiki/Digital_signature
18
19mod ext;
20
21use spideroak_crypto::{
22 hash,
23 hpke::{HpkeAead, HpkeKdf, HpkeKem},
24 mac,
25 oid::Identified,
26 signer,
27 typenum::U32,
28};
29
30pub(crate) use crate::ciphersuite::ext::CipherSuiteExt;
31pub use crate::ciphersuite::ext::Oids;
32
33/// A marker trait for AEADs.
34pub trait Aead: HpkeAead + Identified {}
35
36impl<A: HpkeAead + Identified> Aead for A {}
37
38/// A marker trait for cryptographic hash functions.
39pub trait Hash: hash::Hash + Identified {}
40
41impl<H: hash::Hash + Identified> Hash for H {}
42
43/// A marker trait for key derivation functions.
44pub trait Kdf: HpkeKdf + Identified {}
45
46impl<K: HpkeKdf + Identified> Kdf for K {}
47
48/// A marker trait for key encapsulation mechanisms.
49pub trait Kem: HpkeKem + Identified {}
50
51impl<K: HpkeKem + Identified> Kem for K {}
52
53/// A marker trait for messaged authentication codes.
54pub trait Mac: mac::Mac + Identified {}
55
56impl<M: mac::Mac + Identified> Mac for M {}
57
58/// A marker trait for digital signatures.
59pub trait Signer: signer::Signer + Identified {}
60
61impl<S: signer::Signer + Identified> Signer for S {}
62
63/// The cryptographic primitives used by the cryptography engine.
64///
65/// # Warning
66///
67/// It is incredibly important to fully read the documentation
68/// for every single primitive as some primitives have very
69/// particular requirements. For example, implementations of
70/// [`Signer`] must reject non-canonical signatures. For ECDSA,
71/// this might mean rejecting `-s mod N`.
72///
73/// While the requirements were designed to help ensure safe
74/// defaults regardless of algorithm, it is still possible to
75/// choose algorithms (or implementations) that severely
76/// compromise the security of the engine. As such, we very
77/// highly recommend that only cryptographers or experienced
78/// cryptography engineers implement their own cipher suites.
79///
80/// Additionally, please test your implementation using the
81/// `test_util` module.
82pub trait CipherSuite {
83 /// OIDS contains the OIDs from the algorithms in the cipher
84 /// suite.
85 const OIDS: Oids<Self> = Oids::new();
86
87 /// See [`Aead`] for more information.
88 type Aead: Aead;
89 /// See [`Hash`] for more information.
90 type Hash: Hash<DigestSize = U32>;
91 /// See [`Kdf`] for more information.
92 type Kdf: Kdf;
93 /// See [`Kem`] for more information.
94 type Kem: Kem;
95 /// See [`Mac`] for more information.
96 type Mac: Mac;
97 /// See [`Signer`] for more information.
98 type Signer: Signer;
99}
100
101#[cfg(test)]
102mod tests {
103 #[cfg(feature = "bearssl")]
104 mod bearssl {
105 use spideroak_crypto::oid::consts::{DHKEM_P256_HKDF_SHA256, DHKEM_P521_HKDF_SHA512};
106
107 use crate::{
108 bearssl::{
109 self, Aes256Gcm, HkdfSha256, HkdfSha384, HkdfSha512, HmacSha512, P256, P384, P521,
110 Sha256,
111 },
112 kem_with_oid,
113 test_util::{TestCs, test_ciphersuite},
114 };
115
116 kem_with_oid! {
117 /// DHKEM(P256, HKDF-SHA256).
118 #[derive(Debug)]
119 struct DhKemP256HkdfSha256(bearssl::DhKemP256HkdfSha256) => DHKEM_P256_HKDF_SHA256
120 }
121
122 kem_with_oid! {
123 /// DHKEM(P521, HKDF-SHA512).
124 #[derive(Debug)]
125 struct DhKemP521HkdfSha512(bearssl::DhKemP521HkdfSha512) => DHKEM_P521_HKDF_SHA512
126 }
127
128 test_ciphersuite!(p256, TestCs<
129 Aes256Gcm,
130 Sha256,
131 HkdfSha256,
132 DhKemP256HkdfSha256,
133 HmacSha512,
134 P256,
135 >);
136 test_ciphersuite!(p384, TestCs<
137 Aes256Gcm,
138 Sha256,
139 HkdfSha384,
140 DhKemP256HkdfSha256, // DhKemP384HkdfSha384 does not exist
141 HmacSha512,
142 P384,
143 >);
144 test_ciphersuite!(p521, TestCs<
145 Aes256Gcm,
146 Sha256,
147 HkdfSha512,
148 DhKemP521HkdfSha512,
149 HmacSha512,
150 P521,
151 >);
152 }
153
154 mod rust {
155 use spideroak_crypto::{
156 oid::consts::DHKEM_P256_HKDF_SHA256,
157 rust::{self, Aes256Gcm, HkdfSha256, HkdfSha384, HmacSha512, P256, P384, Sha256},
158 };
159
160 use crate::{
161 kem_with_oid,
162 test_util::{TestCs, test_ciphersuite},
163 };
164
165 kem_with_oid! {
166 /// DHKEM(P256, HKDF-SHA256).
167 #[derive(Debug)]
168 struct DhKemP256HkdfSha256(rust::DhKemP256HkdfSha256) => DHKEM_P256_HKDF_SHA256
169 }
170
171 test_ciphersuite!(p256, TestCs<
172 Aes256Gcm,
173 Sha256,
174 HkdfSha256,
175 DhKemP256HkdfSha256,
176 HmacSha512,
177 P256,
178 >);
179 test_ciphersuite!(p384, TestCs<
180 Aes256Gcm,
181 Sha256,
182 HkdfSha384,
183 DhKemP256HkdfSha256, // DhKemP384HkdfSha384 does not exist
184 HmacSha512,
185 P384,
186 >);
187 }
188}