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