kernel/hil/public_key_crypto/
keys.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Key interface for Public/Private key encryption
6
7use crate::hil::entropy;
8use crate::ErrorCode;
9
10/// Upcall from the `PubPrivKeyGenerate` trait.
11pub trait PubPrivKeyGenerateClient<'a> {
12    /// The `generate()` command has been completed.
13    fn generation_complete(
14        &'a self,
15        result: Result<(), (ErrorCode, &'static mut [u8], &'static mut [u8])>,
16    );
17}
18
19/// An internal representation of a asymetric Public key.
20///
21/// This trait is useful for managing keys internally in Tock.
22///
23/// PubKey is designed for fixed length keys. That is an implementation should
24/// support only a single key length, for example RSA 2048.
25/// Note that we don't use const generics here though. That is because even
26/// within a single key length implementation, there can be different length
27/// inputs, for examples compressed or uncompressed keys.
28pub trait PubKey {
29    /// Import an existing public key.
30    ///
31    /// The reference to the `public_key` is stored internally and can be
32    /// retrieved with the `pub_key()` function.
33    /// The `public_key` can be either a mutable static or an immutable static,
34    /// depending on where the key is stored (flash or memory).
35    ///
36    /// The possible ErrorCodes are:
37    ///     - `BUSY`: A key is already imported or in the process of being
38    ///               generated.
39    ///     - `INVAL`: An invalid key was supplied.
40    ///     - `SIZE`: An invalid key size was supplied.
41    fn import_public_key(
42        &self,
43        public_key: &'static [u8],
44    ) -> Result<(), (ErrorCode, &'static [u8])>;
45
46    /// Return the public key supplied by `import_public_key()` or
47    /// `generate()`.
48    ///
49    /// On success the return value is `Ok(())` with the buffer that was
50    /// originally passed in to hold the key.
51    ///
52    /// On failure the possible ErrorCodes are:
53    ///     - `NODEVICE`: The key does not exist
54    fn pub_key(&self) -> Result<&'static [u8], ErrorCode>;
55
56    /// Report the length of the public key in bytes, as returned from `pub_key()`.
57    /// A value of 0 indicates that the key does not exist.
58    fn len(&self) -> usize;
59}
60
61/// An internal representation of a asymetric Public key.
62///
63/// This trait is useful for managing keys internally in Tock.
64///
65/// PubKey is designed for fixed length keys. That is an implementation should
66/// support only a single key length, for example RSA 2048.
67/// Note that we don't use const generics here though. That is because even
68/// within a single key length implementation, there can be different length
69/// inputs, for examples compressed or uncompressed keys.
70pub trait PubKeyMut {
71    /// Import an existing public key.
72    ///
73    /// The reference to the `public_key` is stored internally and can be
74    /// retrieved with the `pub_key()` function.
75    /// The `public_key` can be either a mutable static or an immutable static,
76    /// depending on where the key is stored (flash or memory).
77    ///
78    /// The possible ErrorCodes are:
79    ///     - `BUSY`: A key is already imported or in the process of being
80    ///                  generated.
81    ///     - `INVAL`: An invalid key was supplied.
82    ///     - `SIZE`: An invalid key size was supplied.
83    fn import_public_key(
84        &self,
85        public_key: &'static mut [u8],
86    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
87
88    /// Return the public key supplied by `import_public_key()` or
89    /// `generate()`.
90    ///
91    /// On success the return value is `Ok(())` with the buffer that was
92    /// originally passed in to hold the key.
93    ///
94    /// On failure the possible ErrorCodes are:
95    ///     - `NODEVICE`: The key does not exist
96    fn pub_key(&self) -> Result<&'static mut [u8], ErrorCode>;
97
98    /// Report the length of the public key in bytes, as returned from `pub_key()`.
99    /// A value of 0 indicates that the key does not exist.
100    fn len(&self) -> usize;
101}
102
103/// An internal representation of a asymetric Public and Private key.
104///
105/// This trait is useful for managing keys internally in Tock.
106///
107/// PubPrivKey is designed for fixed length keys. That is an implementation
108/// should support only a single key length, for example RSA 2048.
109/// Note that we don't use const generics here though. That is because even
110/// within a single key length implementation, there can be different length
111/// inputs, for examples compressed or uncompressed keys.
112pub trait PubPrivKey: PubKey {
113    /// Import an existing private key.
114    ///
115    /// The reference to the `private_key` is stored internally and can be
116    /// retrieved with the `priv_key()` function.
117    /// The `private_key` can be either a mutable static or an immutable static,
118    /// depending on where the key is stored (flash or memory).
119    ///
120    /// The possible ErrorCodes are:
121    ///     - `BUSY`: A key is already imported or in the process of being
122    ///               generated.
123    ///     - `INVAL`: An invalid key was supplied.
124    ///     - `SIZE`: An invalid key size was supplied.
125    fn import_private_key(
126        &self,
127        private_key: &'static [u8],
128    ) -> Result<(), (ErrorCode, &'static [u8])>;
129
130    /// Return the private key supplied by `import_private_key()` or
131    /// `generate()`.
132    ///
133    /// On success the return value is `Ok(())` with the buffer that was
134    /// originally passed in to hold the key.
135    ///
136    /// On failure the possible ErrorCodes are:
137    ///     - `NODEVICE`: The key does not exist
138    fn priv_key(&self) -> Result<&'static [u8], ErrorCode>;
139
140    /// Report the length of the private key in bytes, as returned from `priv_key()`.
141    /// A value of 0 indicates that the key does not exist.
142    fn len(&self) -> usize;
143}
144
145/// An internal representation of a asymetric Public and Private key.
146///
147/// This trait is useful for managing keys internally in Tock.
148///
149/// PubPrivKey is designed for fixed length keys. That is an implementation
150/// should support only a single key length, for example RSA 2048.
151/// Note that we don't use const generics here though. That is because even
152/// within a single key length implementation, there can be different length
153/// inputs, for examples compressed or uncompressed keys.
154pub trait PubPrivKeyMut: PubKeyMut {
155    /// Import an existing private key.
156    ///
157    /// The reference to the `private_key` is stored internally and can be
158    /// retrieved with the `priv_key()` function.
159    /// The `private_key` can be either a mutable static or an immutable static,
160    /// depending on where the key is stored (flash or memory).
161    ///
162    /// The possible ErrorCodes are:
163    ///     - `BUSY`: A key is already imported or in the process of being
164    ///                  generated.
165    ///     - `INVAL`: An invalid key was supplied.
166    ///     - `SIZE`: An invalid key size was supplied.
167    fn import_private_key(
168        &self,
169        private_key: &'static mut [u8],
170    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
171
172    /// Return the private key supplied by `import_private_key()` or
173    /// `generate()`.
174    ///
175    /// On success the return value is `Ok(())` with the buffer that was
176    /// originally passed in to hold the key.
177    ///
178    /// On failure the possible ErrorCodes are:
179    ///     - `NODEVICE`: The key does not exist
180    fn priv_key(&self) -> Result<&'static mut [u8], ErrorCode>;
181
182    /// Report the length of the private key in bytes, as returned from `priv_key()`.
183    /// A value of 0 indicates that the key does not exist.
184    fn len(&self) -> usize;
185}
186
187/// An internal representation of generating asymetric Public/Private key
188/// pairs.
189///
190/// This trait is useful for managing keys internally in Tock.
191pub trait PubPrivKeyGenerate<'a>: PubPrivKey {
192    /// Set the client. This client will be called when the `generate()`
193    /// function is complete. If using an existing key this doesn't need to be
194    /// used.
195    fn set_client(&'a self, client: &'a dyn PubPrivKeyGenerateClient<'a>);
196
197    /// This generates a new private/public key pair. The length will be
198    /// hard coded by the implementation, for example RSA 2048 will create a
199    /// 2048 bit key.
200    /// This will call the `generation_complete()` on completion. They keys
201    /// cannot be used and will return `None` until the upcall has been called.
202    ///
203    /// The keys generated by `generate()` will depend on the implementation.
204    ///
205    /// The original key buffers can be retrieve usind the `pub_key()` and
206    /// `priv_key()` functions.
207    ///
208    /// The possible ErrorCodes are:
209    ///     - `BUSY`: A key is already imported or in the process of being
210    ///               generated.
211    ///     - `OFF`: The underlying `trng` is powered down.
212    ///     - `SIZE`: An invalid buffer size was supplied.
213    fn generate(
214        &'a self,
215        trng: &'a dyn entropy::Entropy32,
216        public_key_buffer: &'static mut [u8],
217        private_key_buffer: &'static mut [u8],
218    ) -> Result<(), (ErrorCode, &'static mut [u8], &'static mut [u8])>;
219}
220
221pub trait RsaKey: PubKey {
222    /// Run the specified closure over the modulus, if it exists
223    /// The modulus is returned MSB (big endian)
224    /// Returns `Some()` if the key exists and the closure was called,
225    /// otherwise returns `None`.
226    fn map_modulus(&self, closure: &dyn Fn(&[u8])) -> Option<()>;
227
228    /// The the modulus if it exists.
229    /// The modulus is returned MSB (big endian)
230    /// Returns `Some()` if the key exists otherwise returns `None`.
231    /// The modulus can be returned by calling `import_public_key()` with
232    /// the output of this function.
233    fn take_modulus(&self) -> Option<&'static [u8]>;
234
235    /// Returns the public exponent of the key pair if it exists
236    fn public_exponent(&self) -> Option<u32>;
237}
238
239pub trait RsaPrivKey: PubPrivKey + RsaKey {
240    /// Returns the specified closure over the private exponent, if it exists
241    /// The exponent is returned MSB (big endian)
242    /// Returns `Some()` if the key exists and the closure was called,
243    /// otherwise returns `None`.
244    fn map_exponent(&self, closure: &dyn Fn(&[u8])) -> Option<()>;
245
246    /// The the private exponent if it exists.
247    /// The exponent is returned MSB (big endian)
248    /// Returns `Some()` if the key exists otherwise returns `None`.
249    /// The exponent can be returned by calling `import_private_key()` with
250    /// the output of this function.
251    fn take_exponent(&self) -> Option<&'static [u8]>;
252}
253
254pub trait RsaKeyMut: PubKeyMut {
255    /// Run the specified closure over the modulus, if it exists
256    /// The modulus is returned MSB (big endian)
257    /// Returns `Some()` if the key exists and the closure was called,
258    /// otherwise returns `None`.
259    fn map_modulus(&self, closure: &dyn Fn(&mut [u8])) -> Option<()>;
260
261    /// The the modulus if it exists.
262    /// The modulus is returned MSB (big endian)
263    /// Returns `Some()` if the key exists otherwise returns `None`.
264    /// The modulus can be returned by calling `import_public_key()` with
265    /// the output of this function.
266    fn take_modulus(&self) -> Option<&'static mut [u8]>;
267
268    /// Returns the public exponent of the key pair if it exists
269    fn public_exponent(&self) -> Option<u32>;
270}
271
272pub trait RsaPrivKeyMut: PubPrivKeyMut + RsaKeyMut {
273    /// Returns the specified closure over the private exponent, if it exists
274    /// The exponent is returned MSB (big endian)
275    /// Returns `Some()` if the key exists and the closure was called,
276    /// otherwise returns `None`.
277    fn map_exponent(&self, closure: &dyn Fn(&mut [u8])) -> Option<()>;
278
279    /// The the private exponent if it exists.
280    /// The exponent is returned MSB (big endian)
281    /// Returns `Some()` if the key exists otherwise returns `None`.
282    /// The exponent can be returned by calling `import_private_key()` with
283    /// the output of this function.
284    fn take_exponent(&self) -> Option<&'static mut [u8]>;
285}