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}