aranya_crypto_core/test_util/
mod.rs1#![allow(clippy::arithmetic_side_effects)]
7#![allow(clippy::panic)]
8#![cfg(any(test, feature = "test_util"))]
9#![cfg_attr(docsrs, doc(cfg(feature = "test_util")))]
10#![forbid(unsafe_code)]
11
12pub mod aead;
13pub mod hash;
14pub mod hpke;
15pub mod kdf;
16pub mod mac;
17pub mod signer;
18pub mod vectors;
19
20use core::{
21 fmt::{self, Debug},
22 marker::PhantomData,
23};
24
25pub use aead::test_aead;
26pub use hash::test_hash;
27pub use hpke::test_hpke;
28pub use kdf::test_kdf;
29pub use mac::test_mac;
30pub use signer::test_signer;
31use subtle::{Choice, ConstantTimeEq};
32use zeroize::ZeroizeOnDrop;
33
34use crate::{
35 aead::{Aead, AeadId, Lifetime, OpenError, SealError},
36 csprng::Csprng,
37 import::{ExportError, Import, ImportError},
38 kdf::{Kdf, KdfError, KdfId, Prk},
39 keys::{PublicKey, SecretKey, SecretKeyBytes},
40 mac::{Mac, MacId},
41 signer::{Signature, Signer, SignerError, SignerId, SigningKey, VerifyingKey},
42};
43
44#[macro_export]
45#[doc(hidden)]
46macro_rules! __apply {
47 ($callback:ident, $($tt:tt),* $(,)?) => {
48 $(
49 $callback!($tt);
50 )*
51 };
52}
53pub use __apply;
54
55#[macro_export]
57macro_rules! assert_ct_eq {
58 ($lhs:expr, $rhs:expr) => {
59 assert!(bool::from(::subtle::ConstantTimeEq::ct_eq(&$lhs, &$rhs)))
60 };
61 ($lhs:expr, $rhs:expr, ) => {
62 $crate::assert_ct_eq!($lhs, $rhs)
63 };
64 ($lhs:expr, $rhs:expr, $($args:tt)+) => {
65 assert!(bool::from(::subtle::ConstantTimeEq::ct_eq(&$lhs, &$rhs)), $($args)+)
66 };
67}
68pub(super) use assert_ct_eq;
69
70#[macro_export]
72macro_rules! assert_ct_ne {
73 ($lhs:expr, $rhs:expr) => {
74 assert!(bool::from(::subtle::ConstantTimeEq::ct_ne(&$lhs, &$rhs)))
75 };
76 ($lhs:expr, $rhs:expr, ) => {
77 $crate::assert_ct_ne!($lhs, $rhs)
78 };
79 ($lhs:expr, $rhs:expr, $($args:tt)+) => {
80 assert!(bool::from(::subtle::ConstantTimeEq::ct_ne(&$lhs, &$rhs)), $($args)+)
81 };
82}
83pub(super) use assert_ct_ne;
84
85macro_rules! assert_all_zero {
87 ($data:expr) => {
88 let data: &[u8] = &$data.as_ref();
89 for c in data {
90 assert_eq!(*c, 0, "Default must return all zeros");
91 }
92 };
93}
94pub(super) use assert_all_zero;
95
96#[macro_export]
98#[doc(hidden)]
99macro_rules! __doctest_os_hardware_rand {
100 () => {
101 #[cfg(feature = "trng")]
102 #[no_mangle]
103 extern "C" fn OS_hardware_rand() -> u32 {
104 use rand::RngCore;
105 rand::rngs::OsRng.next_u32()
106 }
107 };
108}
109
110pub struct AeadWithDefaults<T>(T);
112
113impl<T: Aead> Aead for AeadWithDefaults<T> {
114 const ID: AeadId = T::ID;
115
116 const LIFETIME: Lifetime = T::LIFETIME;
117
118 type KeySize = T::KeySize;
119 const KEY_SIZE: usize = T::KEY_SIZE;
120
121 type NonceSize = T::NonceSize;
122 const NONCE_SIZE: usize = T::NONCE_SIZE;
123
124 type Overhead = T::Overhead;
125 const OVERHEAD: usize = T::OVERHEAD;
126
127 const MAX_PLAINTEXT_SIZE: u64 = T::MAX_PLAINTEXT_SIZE;
128 const MAX_ADDITIONAL_DATA_SIZE: u64 = T::MAX_ADDITIONAL_DATA_SIZE;
129 const MAX_CIPHERTEXT_SIZE: u64 = T::MAX_CIPHERTEXT_SIZE;
130
131 type Key = T::Key;
132
133 fn new(key: &Self::Key) -> Self {
134 Self(T::new(key))
135 }
136
137 fn seal_in_place(
138 &self,
139 nonce: &[u8],
140 data: &mut [u8],
141 tag: &mut [u8],
142 additional_data: &[u8],
143 ) -> Result<(), SealError> {
144 self.0.seal_in_place(nonce, data, tag, additional_data)
145 }
146
147 fn open_in_place(
148 &self,
149 nonce: &[u8],
150 data: &mut [u8],
151 tag: &[u8],
152 additional_data: &[u8],
153 ) -> Result<(), OpenError> {
154 self.0.open_in_place(nonce, data, tag, additional_data)
155 }
156}
157
158pub struct KdfWithDefaults<T>(PhantomData<T>);
160
161impl<T: Kdf> Kdf for KdfWithDefaults<T> {
162 const ID: KdfId = T::ID;
163
164 type MaxOutput = T::MaxOutput;
165
166 type PrkSize = T::PrkSize;
167
168 fn extract_multi<I>(ikm: I, salt: &[u8]) -> Prk<Self::PrkSize>
169 where
170 I: IntoIterator,
171 I::Item: AsRef<[u8]>,
172 {
173 T::extract_multi(ikm, salt)
174 }
175
176 fn expand_multi<I>(out: &mut [u8], prk: &Prk<Self::PrkSize>, info: I) -> Result<(), KdfError>
177 where
178 I: IntoIterator,
179 I::Item: AsRef<[u8]>,
180 I::IntoIter: Clone,
181 {
182 T::expand_multi(out, prk, info)
183 }
184}
185
186#[derive(Clone)]
188pub struct MacWithDefaults<T>(T);
189
190impl<T: Mac> Mac for MacWithDefaults<T> {
191 const ID: MacId = T::ID;
192
193 type Tag = T::Tag;
194 type TagSize = T::TagSize;
195
196 type Key = T::Key;
197 type KeySize = T::KeySize;
198
199 fn new(key: &Self::Key) -> Self {
200 Self(T::new(key))
201 }
202
203 fn update(&mut self, data: &[u8]) {
204 self.0.update(data)
205 }
206
207 fn tag(self) -> Self::Tag {
208 self.0.tag()
209 }
210}
211
212pub struct SignerWithDefaults<T: ?Sized>(T);
214
215impl<T: Signer + ?Sized> Signer for SignerWithDefaults<T> {
216 const ID: SignerId = T::ID;
217
218 type SigningKey = SigningKeyWithDefaults<T>;
219 type VerifyingKey = VerifyingKeyWithDefaults<T>;
220 type Signature = SignatureWithDefaults<T>;
221}
222
223pub struct SigningKeyWithDefaults<T: Signer + ?Sized>(T::SigningKey);
225
226impl<T: Signer + ?Sized> SigningKey<SignerWithDefaults<T>> for SigningKeyWithDefaults<T> {
227 fn sign(&self, msg: &[u8]) -> Result<SignatureWithDefaults<T>, SignerError> {
228 Ok(SignatureWithDefaults(self.0.sign(msg)?))
229 }
230
231 fn public(&self) -> Result<VerifyingKeyWithDefaults<T>, crate::signer::PkError> {
232 Ok(VerifyingKeyWithDefaults(self.0.public()?))
233 }
234}
235
236impl<T: Signer + ?Sized> SecretKey for SigningKeyWithDefaults<T> {
237 type Size = <T::SigningKey as SecretKey>::Size;
238
239 fn new<R: Csprng>(rng: &mut R) -> Self {
240 Self(T::SigningKey::new(rng))
241 }
242
243 fn try_export_secret(&self) -> Result<SecretKeyBytes<Self::Size>, ExportError> {
244 self.0.try_export_secret()
245 }
246}
247
248impl<T: Signer + ?Sized> ConstantTimeEq for SigningKeyWithDefaults<T> {
249 fn ct_eq(&self, other: &Self) -> Choice {
250 ConstantTimeEq::ct_eq(&self.0, &other.0)
251 }
252}
253
254impl<'a, T: Signer + ?Sized> Import<&'a [u8]> for SigningKeyWithDefaults<T> {
255 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
256 Ok(Self(T::SigningKey::import(data)?))
257 }
258}
259
260impl<T: Signer + ?Sized> Clone for SigningKeyWithDefaults<T> {
261 fn clone(&self) -> Self {
262 Self(self.0.clone())
263 }
264}
265
266impl<T: Signer + ?Sized> ZeroizeOnDrop for SigningKeyWithDefaults<T> {}
267
268pub struct VerifyingKeyWithDefaults<T: Signer + ?Sized>(T::VerifyingKey);
270
271impl<T: Signer + ?Sized> VerifyingKey<SignerWithDefaults<T>> for VerifyingKeyWithDefaults<T> {
272 fn verify(&self, msg: &[u8], sig: &SignatureWithDefaults<T>) -> Result<(), SignerError> {
273 self.0.verify(msg, &sig.0)
274 }
275}
276
277impl<T: Signer + ?Sized> PublicKey for VerifyingKeyWithDefaults<T> {
278 type Data = <T::VerifyingKey as PublicKey>::Data;
279
280 fn export(&self) -> Self::Data {
281 self.0.export()
282 }
283}
284
285impl<'a, T: Signer + ?Sized> Import<&'a [u8]> for VerifyingKeyWithDefaults<T> {
286 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
287 Ok(Self(T::VerifyingKey::import(data)?))
288 }
289}
290
291impl<T: Signer + ?Sized> Clone for VerifyingKeyWithDefaults<T> {
292 fn clone(&self) -> Self {
293 Self(self.0.clone())
294 }
295}
296
297impl<T: Signer + ?Sized> Debug for VerifyingKeyWithDefaults<T> {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 Debug::fmt(&self.0, f)
300 }
301}
302
303impl<T: Signer + ?Sized> Eq for VerifyingKeyWithDefaults<T> {}
304impl<T: Signer + ?Sized> PartialEq for VerifyingKeyWithDefaults<T> {
305 fn eq(&self, other: &Self) -> bool {
306 PartialEq::eq(&self.0, &other.0)
307 }
308}
309
310pub struct SignatureWithDefaults<T: Signer + ?Sized>(T::Signature);
312
313impl<T: Signer + ?Sized> Signature<SignerWithDefaults<T>> for SignatureWithDefaults<T> {
314 type Data = <T::Signature as Signature<T>>::Data;
315
316 fn export(&self) -> Self::Data {
317 self.0.export()
318 }
319}
320
321impl<T: Signer + ?Sized> Clone for SignatureWithDefaults<T> {
322 fn clone(&self) -> Self {
323 Self(self.0.clone())
324 }
325}
326
327impl<T: Signer + ?Sized> Debug for SignatureWithDefaults<T> {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 Debug::fmt(&self.0, f)
330 }
331}
332
333impl<'a, T: Signer + ?Sized> Import<&'a [u8]> for SignatureWithDefaults<T> {
334 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
335 Ok(Self(T::Signature::import(data)?))
336 }
337}