Skip to main content

embedded_cal/
empty.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// SPDX-FileCopyrightText: Inria-AIO, Cryspen, and Christian Amsüss
3
4//! Implementations of the various traits of embedded-cal that implemnt the empty set of
5//! algorithms.
6//!
7//! This is useful as a base type: Many layers work as extenders, and thus need a terminator type
8//! somewhere at the base of the composite type. In addition, it can be used to simplify code for
9//! hardware implementations.
10//!
11//! The types are ZST or uninhabited as suitable for the type.
12
13use super::*;
14
15/// An implementation of [`Cal`] that provides no single algorithm.
16///
17/// It implements all the individual traits, as well as the full `Cal` trait. The former is useful
18/// for hardware implementations that don't touch an area at all; the latter is useful in testing
19/// or when an extender is used standalone.
20pub struct EmptyCal;
21
22impl Cal for EmptyCal {
23    type DhProvider = Self;
24    type AeadProvider = Self;
25    type HashProvider = Self;
26    type HmacProvider = Self;
27
28    fn dh(&mut self) -> &mut Self::DhProvider {
29        self
30    }
31
32    fn aead(&mut self) -> &mut Self::AeadProvider {
33        self
34    }
35
36    fn hash(&mut self) -> &mut Self::HashProvider {
37        self
38    }
39
40    fn hmac(&mut self) -> &mut Self::HmacProvider {
41        self
42    }
43}
44
45// Those should all be shorter when <https://github.com/lake-rs/embedded-cal/issues/40> is
46// resolved; then again, the implementations that do make it short will live here. Until then, feel
47// free to copy those out into your Cal implementations.
48
49impl HashProvider for EmptyCal {
50    type Algorithm = NoAlgorithms;
51    type State = NoAlgorithms;
52    type Output = NoAlgorithms;
53
54    fn init(&mut self, algorithm: Self::Algorithm) -> Self::State {
55        match algorithm {}
56    }
57
58    fn update(&mut self, instance: &mut Self::State, _data: &[u8]) {
59        match *instance {}
60    }
61
62    fn finalize(&mut self, instance: Self::State) -> Self::Output {
63        match instance {}
64    }
65}
66
67impl HmacProvider for EmptyCal {
68    type Algorithm = NoAlgorithms;
69    type Key = NoAlgorithms;
70    type State = NoAlgorithms;
71    type Output = NoAlgorithms;
72
73    fn load_from_keydata(&mut self, algorithm: Self::Algorithm, _key: &[u8]) -> Self::Key {
74        match algorithm {}
75    }
76
77    fn init(&mut self, key: Self::Key) -> Self::State {
78        match key {}
79    }
80
81    fn update(&mut self, state: &mut Self::State, _data: &[u8]) {
82        match *state {}
83    }
84
85    fn finalize(&mut self, state: Self::State) -> Self::Output {
86        match state {}
87    }
88}
89
90impl AeadProvider for EmptyCal {
91    type Algorithm = NoAlgorithms;
92    type Key = NoAlgorithms;
93    type Tag = NoAlgorithms;
94
95    fn load_from_keydata(&mut self, alg: Self::Algorithm, _key: &[u8]) -> Self::Key {
96        match alg {}
97    }
98
99    fn encrypt_in_place(
100        &mut self,
101        key: &Self::Key,
102        _nonce: &[u8],
103        _message: &mut [u8],
104        _aad: impl AadGenerator,
105    ) -> Self::Tag {
106        match *key {}
107    }
108
109    fn decrypt_in_place(
110        &mut self,
111        key: &Self::Key,
112        _nonce: &[u8],
113        _message: &mut [u8],
114        _tag: &[u8],
115        _aad: impl AadGenerator,
116    ) -> Result<(), DecryptionFailed> {
117        match *key {}
118    }
119}
120
121impl DhProvider for EmptyCal {
122    type Algorithm = NoAlgorithms;
123    type VisibleSecretKey = NoAlgorithms;
124    type SecretKey = NoAlgorithms;
125    type PublicKey = NoAlgorithms;
126    type SharedSecret = NoAlgorithms;
127
128    fn generate_visible(&mut self, alg: Self::Algorithm) -> Self::VisibleSecretKey {
129        match alg {}
130    }
131
132    fn shared_secret(
133        &mut self,
134        private: &Self::SecretKey,
135        _public: &Self::PublicKey,
136    ) -> Result<Self::SharedSecret, IncompatibleKeys> {
137        match *private {}
138    }
139
140    fn public_key(&mut self, private: &Self::SecretKey) -> Self::PublicKey {
141        match *private {}
142    }
143
144    #[allow(unreachable_code, reason = "needed to satisfy RPIT")]
145    fn raw_secret_bytes<'s>(
146        &mut self,
147        secret: &'s Self::SharedSecret,
148    ) -> impl AsRef<[u8]> + use<'s> {
149        match *secret {};
150        &[]
151    }
152
153    #[allow(unreachable_code, reason = "needed to satisfy RPIT")]
154    fn export_secretkey_bytes<'s>(
155        &mut self,
156        secretkey: &'s Self::VisibleSecretKey,
157    ) -> impl AsRef<[u8]> + use<'s> {
158        match *secretkey {};
159        &[]
160    }
161
162    fn import_secretkey_bytes(
163        &mut self,
164        alg: Self::Algorithm,
165        _secret: &[u8],
166    ) -> Result<Self::VisibleSecretKey, crate::ImportError> {
167        match alg {}
168    }
169
170    #[allow(unreachable_code, reason = "needed to satisfy RPIT")]
171    fn export_publickey_bytes<'p>(
172        &mut self,
173        public: &'p Self::PublicKey,
174    ) -> impl AsRef<[u8]> + use<'p> {
175        match *public {};
176        &[]
177    }
178    fn import_publickey_bytes(
179        &mut self,
180        alg: Self::Algorithm,
181        _data: &[u8],
182    ) -> Result<Self::PublicKey, crate::ImportError> {
183        match alg {}
184    }
185}
186
187impl plumbing::Plumbing for EmptyCal {}
188
189impl plumbing::hash::Hash for EmptyCal {}
190
191impl plumbing::hash::Sha2Short for EmptyCal {
192    const SUPPORTED: bool = false;
193    const SEND_PADDING: bool = false;
194    const FIRST_CHUNK_SIZE: usize = 0;
195    const UPDATE_MULTICHUNK: bool = false;
196
197    type State = NoAlgorithms;
198
199    fn init(&mut self, _variant: plumbing::hash::Sha2ShortVariant) -> Self::State {
200        panic!("user disregarded SUPPORTED=false")
201    }
202
203    fn update(&mut self, instance: &mut Self::State, _data: &[u8]) {
204        match *instance {}
205    }
206
207    fn finalize(&mut self, instance: Self::State, _last_chunk: &[u8], _target: &mut [u8]) {
208        match instance {}
209    }
210}
211
212impl plumbing::ec::Ec for EmptyCal {
213    const MAX_SCALAR_LENGTH: usize = 0;
214
215    type PrimitivesP256 = Self;
216    type PrimitivesX25519 = Self;
217    type PrimitivesX448 = Self;
218
219    fn p256(&mut self) -> &mut Self::PrimitivesP256 {
220        self
221    }
222    fn x25519(&mut self) -> &mut Self::PrimitivesX25519 {
223        self
224    }
225    fn x448(&mut self) -> &mut Self::PrimitivesX448 {
226        self
227    }
228}
229
230impl<C: plumbing::ec::Curve> plumbing::ec::EcPrimitives<C> for EmptyCal {
231    const HAS_MULTIPLY_SCALAR_POINT: bool = false;
232
233    type Scalar = NoAlgorithms;
234    type Point = NoAlgorithms;
235
236    fn multiply_scalar_point(&mut self, a: &Self::Scalar, _b: &Self::Point) -> Self::Point {
237        match *a {}
238    }
239
240    fn point(&mut self, x: Self::Scalar, _y: Self::Scalar) -> Self::Point {
241        match x {}
242    }
243
244    fn import_scalar_bytes(&mut self, _scalar: &[u8]) -> Result<Self::Scalar, crate::ImportError> {
245        Err(crate::ImportError)
246    }
247
248    fn export_scalar_bytes<'s>(
249        &mut self,
250        _scalar: &'s Self::Scalar,
251    ) -> impl AsRef<[u8]> + use<'s, C> {
252        // Actually never returns because it can not be entered due to *scalar being uninhabited,
253        // but we'll have to give a type nonetheless.
254        &[]
255    }
256
257    fn x_coord(&mut self, point: &Self::Point) -> Self::Scalar {
258        match *point {}
259    }
260
261    fn y_coord(&mut self, point: &Self::Point) -> Self::Scalar {
262        match *point {}
263    }
264}
265
266/// Type which an implementation of [`Cal`] can use when it implements no algorithm for a
267/// particular provider.
268///
269/// This type is uninhabited and can stand in for all of the `Algorithm` associated types as well
270/// as state and result types.
271#[derive(Clone, PartialEq, Eq, Debug)]
272pub enum NoAlgorithms {}
273
274impl AeadAlgorithm for NoAlgorithms {
275    fn key_length(&self) -> usize {
276        match *self {}
277    }
278
279    fn tag_length(&self) -> usize {
280        match *self {}
281    }
282
283    fn nonce_length(&self) -> usize {
284        match *self {}
285    }
286}
287
288impl HashAlgorithm for NoAlgorithms {
289    fn len(&self) -> usize {
290        match *self {}
291    }
292}
293
294impl HmacAlgorithm for NoAlgorithms {
295    const MAX_LEN: usize = 0;
296
297    type MaxLenBuf = [u8; 0];
298
299    fn len(&self) -> usize {
300        match *self {}
301    }
302}
303
304impl AsRef<[u8]> for NoAlgorithms {
305    fn as_ref(&self) -> &[u8] {
306        match *self {}
307    }
308}
309
310impl DhAlgorithm for NoAlgorithms {
311    fn output_length(&self) -> usize {
312        match *self {}
313    }
314}