David Drysdale | 747e593 | 2023-10-17 14:43:43 +0100 | [diff] [blame] | 1 | // Copyright 2022, The Android Open Source Project |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 15 | //! Traits representing abstractions of cryptographic functionality. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 16 | use super::*; |
David Drysdale | ccc2d1b | 2023-05-04 12:22:01 +0100 | [diff] [blame] | 17 | use crate::{crypto::ec::Key, der_err, explicit, keyblob, vec_try, Error}; |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 18 | use alloc::{boxed::Box, vec::Vec}; |
Hasini Gunasinghe | c939a9b | 2022-11-17 02:45:22 +0000 | [diff] [blame] | 19 | use der::Decode; |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 20 | use kmr_wire::{keymint, keymint::Digest, KeySizeInBits, RsaExponent}; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 21 | use log::{error, warn}; |
| 22 | |
| 23 | /// Combined collection of trait implementations that must be provided. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 24 | pub struct Implementation { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 25 | /// Random number generator. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 26 | pub rng: Box<dyn Rng>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 27 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 28 | /// A local clock, if available. If not available, KeyMint will require timestamp tokens to |
| 29 | /// be provided by an external `ISecureClock` (with which it shares a common key). |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 30 | pub clock: Option<Box<dyn MonotonicClock>>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 31 | |
| 32 | /// A constant-time equality implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 33 | pub compare: Box<dyn ConstTimeEq>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 34 | |
| 35 | /// AES implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 36 | pub aes: Box<dyn Aes>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 37 | |
| 38 | /// DES implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 39 | pub des: Box<dyn Des>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 40 | |
| 41 | /// HMAC implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 42 | pub hmac: Box<dyn Hmac>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 43 | |
| 44 | /// RSA implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 45 | pub rsa: Box<dyn Rsa>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 46 | |
| 47 | /// EC implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 48 | pub ec: Box<dyn Ec>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 49 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 50 | /// CKDF implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 51 | pub ckdf: Box<dyn Ckdf>, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 52 | |
| 53 | /// HKDF implementation. |
David Drysdale | 90a8c83 | 2023-05-11 14:38:42 +0100 | [diff] [blame] | 54 | pub hkdf: Box<dyn Hkdf>, |
David Drysdale | 8339014 | 2023-10-13 07:16:43 +0100 | [diff] [blame] | 55 | |
| 56 | /// SHA-256 implementation. |
| 57 | pub sha256: Box<dyn Sha256>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | /// Abstraction of a random number generator that is cryptographically secure |
| 61 | /// and which accepts additional entropy to be mixed in. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 62 | pub trait Rng: Send { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 63 | /// Add entropy to the generator's pool. |
| 64 | fn add_entropy(&mut self, data: &[u8]); |
| 65 | /// Generate random data. |
| 66 | fn fill_bytes(&mut self, dest: &mut [u8]); |
| 67 | /// Return a random `u64` value. |
| 68 | fn next_u64(&mut self) -> u64 { |
| 69 | let mut buf = [0u8; 8]; |
| 70 | self.fill_bytes(&mut buf); |
| 71 | u64::from_le_bytes(buf) |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | /// Abstraction of constant-time comparisons, for use in cryptographic contexts where timing attacks |
| 76 | /// need to be avoided. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 77 | pub trait ConstTimeEq: Send { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 78 | /// Indicate whether arguments are the same. |
| 79 | fn eq(&self, left: &[u8], right: &[u8]) -> bool; |
| 80 | /// Indicate whether arguments are the different. |
| 81 | fn ne(&self, left: &[u8], right: &[u8]) -> bool { |
| 82 | !self.eq(left, right) |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | /// Abstraction of a monotonic clock. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 87 | pub trait MonotonicClock: Send { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 88 | /// Return the current time in milliseconds since some arbitrary point in time. Time must be |
| 89 | /// monotonically increasing, and "current time" must not repeat until the Android device |
| 90 | /// reboots, or until at least 50 million years have elapsed. Time must also continue to |
| 91 | /// advance while the device is suspended (which may not be the case with e.g. Linux's |
| 92 | /// `clock_gettime(CLOCK_MONOTONIC)`). |
| 93 | fn now(&self) -> MillisecondsSinceEpoch; |
| 94 | } |
| 95 | |
| 96 | /// Abstraction of AES functionality. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 97 | pub trait Aes: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 98 | /// Generate an AES key. The default implementation fills with random data. Key generation |
| 99 | /// parameters are passed in for reference, to allow for implementations that might have |
| 100 | /// parameter-specific behaviour. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 101 | fn generate_key( |
| 102 | &self, |
| 103 | rng: &mut dyn Rng, |
| 104 | variant: aes::Variant, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 105 | _params: &[keymint::KeyParam], |
| 106 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 107 | Ok(match variant { |
| 108 | aes::Variant::Aes128 => { |
| 109 | let mut key = [0; 16]; |
| 110 | rng.fill_bytes(&mut key[..]); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 111 | KeyMaterial::Aes(aes::Key::Aes128(key).into()) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 112 | } |
| 113 | aes::Variant::Aes192 => { |
| 114 | let mut key = [0; 24]; |
| 115 | rng.fill_bytes(&mut key[..]); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 116 | KeyMaterial::Aes(aes::Key::Aes192(key).into()) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 117 | } |
| 118 | aes::Variant::Aes256 => { |
| 119 | let mut key = [0; 32]; |
| 120 | rng.fill_bytes(&mut key[..]); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 121 | KeyMaterial::Aes(aes::Key::Aes256(key).into()) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 122 | } |
| 123 | }) |
| 124 | } |
| 125 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 126 | /// Import an AES key, also returning the key size in bits. Key import parameters are passed in |
| 127 | /// for reference, to allow for implementations that might have parameter-specific behaviour. |
| 128 | fn import_key( |
| 129 | &self, |
| 130 | data: &[u8], |
| 131 | _params: &[keymint::KeyParam], |
| 132 | ) -> Result<(KeyMaterial, KeySizeInBits), Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 133 | let aes_key = aes::Key::new_from(data)?; |
| 134 | let key_size = aes_key.size(); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 135 | Ok((KeyMaterial::Aes(aes_key.into()), key_size)) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 136 | } |
| 137 | |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 138 | /// Create an AES operation. For block mode operations with no padding |
| 139 | /// ([`aes::CipherMode::EcbNoPadding`] and [`aes::CipherMode::CbcNoPadding`]) the operation |
David Drysdale | 244b384 | 2024-07-15 12:34:20 +0100 | [diff] [blame] | 140 | /// implementation should reject (with `ErrorCode::InvalidInputLength`) input data that does |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 141 | /// not end up being a multiple of the block size. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 142 | fn begin( |
| 143 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 144 | key: OpaqueOr<aes::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 145 | mode: aes::CipherMode, |
| 146 | dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 147 | ) -> Result<Box<dyn EmittingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 148 | |
| 149 | /// Create an AES-GCM operation. |
| 150 | fn begin_aead( |
| 151 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 152 | key: OpaqueOr<aes::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 153 | mode: aes::GcmMode, |
| 154 | dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 155 | ) -> Result<Box<dyn AadOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 156 | } |
| 157 | |
| 158 | /// Abstraction of 3-DES functionality. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 159 | pub trait Des: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 160 | /// Generate a triple DES key. Key generation parameters are passed in for reference, to allow |
| 161 | /// for implementations that might have parameter-specific behaviour. |
| 162 | fn generate_key( |
| 163 | &self, |
| 164 | rng: &mut dyn Rng, |
| 165 | _params: &[keymint::KeyParam], |
| 166 | ) -> Result<KeyMaterial, Error> { |
| 167 | let mut key = vec_try![0; 24]?; |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 168 | // Note: parity bits must be ignored. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 169 | rng.fill_bytes(&mut key[..]); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 170 | Ok(KeyMaterial::TripleDes(des::Key::new(key)?.into())) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 171 | } |
| 172 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 173 | /// Import a triple DES key. Key import parameters are passed in for reference, to allow for |
| 174 | /// implementations that might have parameter-specific behaviour. |
| 175 | fn import_key(&self, data: &[u8], _params: &[keymint::KeyParam]) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 176 | let des_key = des::Key::new_from(data)?; |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 177 | Ok(KeyMaterial::TripleDes(des_key.into())) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 178 | } |
| 179 | |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 180 | /// Create a DES operation. For block mode operations with no padding |
| 181 | /// ([`des::Mode::EcbNoPadding`] and [`des::Mode::CbcNoPadding`]) the operation implementation |
David Drysdale | 244b384 | 2024-07-15 12:34:20 +0100 | [diff] [blame] | 182 | /// should reject (with `ErrorCode::InvalidInputLength`) input data that does not end up being |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 183 | /// a multiple of the block size. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 184 | fn begin( |
| 185 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 186 | key: OpaqueOr<des::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 187 | mode: des::Mode, |
| 188 | dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 189 | ) -> Result<Box<dyn EmittingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | /// Abstraction of HMAC functionality. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 193 | pub trait Hmac: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 194 | /// Generate an HMAC key. Key generation parameters are passed in for reference, to allow for |
| 195 | /// implementations that might have parameter-specific behaviour. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 196 | fn generate_key( |
| 197 | &self, |
| 198 | rng: &mut dyn Rng, |
| 199 | key_size: KeySizeInBits, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 200 | _params: &[keymint::KeyParam], |
| 201 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 202 | hmac::valid_hal_size(key_size)?; |
| 203 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 204 | let key_len = (key_size.0 / 8) as usize; |
| 205 | let mut key = vec_try![0; key_len]?; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 206 | rng.fill_bytes(&mut key); |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 207 | Ok(KeyMaterial::Hmac(hmac::Key::new(key).into())) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 208 | } |
| 209 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 210 | /// Import an HMAC key, also returning the key size in bits. Key import parameters are passed in |
| 211 | /// for reference, to allow for implementations that might have parameter-specific behaviour. |
| 212 | fn import_key( |
| 213 | &self, |
| 214 | data: &[u8], |
| 215 | _params: &[keymint::KeyParam], |
| 216 | ) -> Result<(KeyMaterial, KeySizeInBits), Error> { |
| 217 | let hmac_key = hmac::Key::new_from(data)?; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 218 | let key_size = hmac_key.size(); |
| 219 | hmac::valid_hal_size(key_size)?; |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 220 | Ok((KeyMaterial::Hmac(hmac_key.into()), key_size)) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | /// Create an HMAC operation. Implementations can assume that: |
| 224 | /// - `key` will have length in range `8..=64` bytes. |
| 225 | /// - `digest` will not be [`Digest::None`] |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 226 | fn begin( |
| 227 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 228 | key: OpaqueOr<hmac::Key>, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 229 | digest: Digest, |
| 230 | ) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | /// Abstraction of AES-CMAC functionality. (Note that this is not exposed in the KeyMint HAL API |
| 234 | /// directly, but is required for the CKDF operations involved in `ISharedSecret` negotiation.) |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 235 | pub trait AesCmac: Send { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 236 | /// Create an AES-CMAC operation. Implementations can assume that `key` will have length |
| 237 | /// of either 16 (AES-128) or 32 (AES-256). |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 238 | fn begin(&self, key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 239 | } |
| 240 | |
| 241 | /// Abstraction of RSA functionality. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 242 | pub trait Rsa: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 243 | /// Generate an RSA key. Key generation parameters are passed in for reference, to allow for |
| 244 | /// implementations that might have parameter-specific behaviour. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 245 | fn generate_key( |
| 246 | &self, |
| 247 | rng: &mut dyn Rng, |
| 248 | key_size: KeySizeInBits, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 249 | pub_exponent: RsaExponent, |
| 250 | params: &[keymint::KeyParam], |
| 251 | ) -> Result<KeyMaterial, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 252 | |
| 253 | /// Import an RSA key in PKCS#8 format, also returning the key size in bits and public exponent. |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 254 | /// Key import parameters are passed in for reference, to allow for implementations that might |
| 255 | /// have parameter-specific behaviour. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 256 | fn import_pkcs8_key( |
| 257 | &self, |
| 258 | data: &[u8], |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 259 | _params: &[keymint::KeyParam], |
| 260 | ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error> { |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 261 | rsa::import_pkcs8_key(data) |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 262 | } |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 263 | |
Hasini Gunasinghe | d8518eb | 2022-11-16 23:50:22 +0000 | [diff] [blame] | 264 | /// Return the public key data corresponds to the provided private `key`, |
| 265 | /// as an ASN.1 DER-encoded `SEQUENCE` as per RFC 3279 section 2.3.1: |
| 266 | /// ```asn1 |
| 267 | /// RSAPublicKey ::= SEQUENCE { |
| 268 | /// modulus INTEGER, -- n |
| 269 | /// publicExponent INTEGER } -- e |
| 270 | /// ``` |
| 271 | /// which is the `subjectPublicKey` to be included in `SubjectPublicKeyInfo`. |
| 272 | fn subject_public_key(&self, key: &OpaqueOr<rsa::Key>) -> Result<Vec<u8>, Error> { |
| 273 | // The default implementation only handles the `Explicit<rsa::Key>` variant. |
| 274 | let rsa_key = explicit!(key)?; |
| 275 | rsa_key.subject_public_key() |
| 276 | } |
| 277 | |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 278 | /// Create an RSA decryption operation. |
| 279 | fn begin_decrypt( |
| 280 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 281 | key: OpaqueOr<rsa::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 282 | mode: rsa::DecryptionMode, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 283 | ) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 284 | |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 285 | /// Create an RSA signing operation. For [`rsa::SignMode::Pkcs1_1_5Padding(Digest::None)`] the |
David Drysdale | 244b384 | 2024-07-15 12:34:20 +0100 | [diff] [blame] | 286 | /// implementation should reject (with `ErrorCode::InvalidInputLength`) accumulated input that |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 287 | /// is larger than the size of the RSA key less overhead |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 288 | /// ([`rsa::PKCS1_UNDIGESTED_SIGNATURE_PADDING_OVERHEAD`]). |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 289 | fn begin_sign( |
| 290 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 291 | key: OpaqueOr<rsa::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 292 | mode: rsa::SignMode, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 293 | ) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 294 | } |
| 295 | |
| 296 | /// Abstraction of EC functionality. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 297 | pub trait Ec: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 298 | /// Generate an EC key for a NIST curve. Key generation parameters are passed in for reference, |
| 299 | /// to allow for implementations that might have parameter-specific behaviour. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 300 | fn generate_nist_key( |
| 301 | &self, |
| 302 | rng: &mut dyn Rng, |
| 303 | curve: ec::NistCurve, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 304 | params: &[keymint::KeyParam], |
| 305 | ) -> Result<KeyMaterial, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 306 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 307 | /// Generate an Ed25519 key. Key generation parameters are passed in for reference, to allow |
| 308 | /// for implementations that might have parameter-specific behaviour. |
| 309 | fn generate_ed25519_key( |
| 310 | &self, |
| 311 | rng: &mut dyn Rng, |
| 312 | params: &[keymint::KeyParam], |
| 313 | ) -> Result<KeyMaterial, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 314 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 315 | /// Generate an X25519 key. Key generation parameters are passed in for reference, to allow for |
| 316 | /// implementations that might have parameter-specific behaviour. |
| 317 | fn generate_x25519_key( |
| 318 | &self, |
| 319 | rng: &mut dyn Rng, |
| 320 | params: &[keymint::KeyParam], |
| 321 | ) -> Result<KeyMaterial, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 322 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 323 | /// Import an EC key in PKCS#8 format. Key import parameters are passed in for reference, to |
| 324 | /// allow for implementations that might have parameter-specific behaviour. |
| 325 | fn import_pkcs8_key( |
| 326 | &self, |
| 327 | data: &[u8], |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 328 | _params: &[keymint::KeyParam], |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 329 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 330 | ec::import_pkcs8_key(data) |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 331 | } |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 332 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 333 | /// Import a 32-byte raw Ed25519 key. Key import parameters are passed in for reference, to |
| 334 | /// allow for implementations that might have parameter-specific behaviour. |
| 335 | fn import_raw_ed25519_key( |
| 336 | &self, |
| 337 | data: &[u8], |
| 338 | _params: &[keymint::KeyParam], |
| 339 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 340 | ec::import_raw_ed25519_key(data) |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 341 | } |
| 342 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 343 | /// Import a 32-byte raw X25519 key. Key import parameters are passed in for reference, to |
| 344 | /// allow for implementations that might have parameter-specific behaviour. |
| 345 | fn import_raw_x25519_key( |
| 346 | &self, |
| 347 | data: &[u8], |
| 348 | _params: &[keymint::KeyParam], |
| 349 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 0986c77 | 2022-11-03 08:12:53 +0000 | [diff] [blame] | 350 | ec::import_raw_x25519_key(data) |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 351 | } |
| 352 | |
Hasini Gunasinghe | c939a9b | 2022-11-17 02:45:22 +0000 | [diff] [blame] | 353 | /// Return the public key data that corresponds to the provided private `key`. |
| 354 | /// If `CurveType` of the key is `CurveType::Nist`, return the public key data |
| 355 | /// as a SEC-1 encoded uncompressed point as described in RFC 5480 section 2.1. |
| 356 | /// I.e. 0x04: uncompressed, followed by x || y coordinates. |
| 357 | /// |
| 358 | /// For other two curve types, return the raw public key data. |
| 359 | fn subject_public_key(&self, key: &OpaqueOr<ec::Key>) -> Result<Vec<u8>, Error> { |
| 360 | // The default implementation only handles the `Explicit<ec::Key>` variant. |
| 361 | let ec_key = explicit!(key)?; |
| 362 | match ec_key { |
| 363 | Key::P224(nist_key) |
| 364 | | Key::P256(nist_key) |
| 365 | | Key::P384(nist_key) |
| 366 | | Key::P521(nist_key) => { |
David Drysdale | ccc2d1b | 2023-05-04 12:22:01 +0100 | [diff] [blame] | 367 | let ec_pvt_key = sec1::EcPrivateKey::from_der(nist_key.0.as_slice()) |
| 368 | .map_err(|e| der_err!(e, "failed to parse DER NIST EC PrivateKey"))?; |
Hasini Gunasinghe | c939a9b | 2022-11-17 02:45:22 +0000 | [diff] [blame] | 369 | match ec_pvt_key.public_key { |
| 370 | Some(pub_key) => Ok(pub_key.to_vec()), |
| 371 | None => { |
| 372 | // Key structure doesn't include optional public key, so regenerate it. |
| 373 | let nist_curve: ec::NistCurve = ec_key.curve().try_into()?; |
| 374 | Ok(self.nist_public_key(nist_key, nist_curve)?) |
| 375 | } |
| 376 | } |
| 377 | } |
| 378 | Key::Ed25519(ed25519_key) => self.ed25519_public_key(ed25519_key), |
| 379 | Key::X25519(x25519_key) => self.x25519_public_key(x25519_key), |
| 380 | } |
| 381 | } |
| 382 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 383 | /// Return the public key data that corresponds to the provided private `key`, as a SEC-1 |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 384 | /// encoded uncompressed point. |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 385 | fn nist_public_key(&self, key: &ec::NistKey, curve: ec::NistCurve) -> Result<Vec<u8>, Error>; |
| 386 | |
| 387 | /// Return the raw public key data that corresponds to the provided private `key`. |
| 388 | fn ed25519_public_key(&self, key: &ec::Ed25519Key) -> Result<Vec<u8>, Error>; |
| 389 | |
| 390 | /// Return the raw public key data that corresponds to the provided private `key`. |
| 391 | fn x25519_public_key(&self, key: &ec::X25519Key) -> Result<Vec<u8>, Error>; |
| 392 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 393 | /// Create an EC key agreement operation. |
| 394 | /// The accumulated input for the operation is expected to be the peer's |
| 395 | /// public key, provided as an ASN.1 DER-encoded `SubjectPublicKeyInfo`. |
| 396 | fn begin_agree(&self, key: OpaqueOr<ec::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 397 | |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 398 | /// Create an EC signing operation. For Ed25519 signing operations, the implementation should |
David Drysdale | 244b384 | 2024-07-15 12:34:20 +0100 | [diff] [blame] | 399 | /// reject (with `ErrorCode::InvalidInputLength`) accumulated data that is larger than |
David Drysdale | fc71825 | 2022-06-10 16:06:24 +0100 | [diff] [blame] | 400 | /// [`ec::MAX_ED25519_MSG_SIZE`]. |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 401 | fn begin_sign( |
| 402 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 403 | key: OpaqueOr<ec::Key>, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 404 | digest: Digest, |
| 405 | ) -> Result<Box<dyn AccumulatingOperation>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 406 | } |
| 407 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 408 | /// Abstraction of an in-progress operation that emits data as it progresses. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 409 | pub trait EmittingOperation: Send { |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 410 | /// Update operation with data. |
| 411 | fn update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error>; |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 412 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 413 | /// Complete operation, consuming `self`. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 414 | fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>; |
| 415 | } |
| 416 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 417 | /// Abstraction of an in-progress operation that has authenticated associated data. |
| 418 | pub trait AadOperation: EmittingOperation { |
| 419 | /// Update additional data. Implementations can assume that all calls to `update_aad()` |
| 420 | /// will occur before any calls to `update()` or `finish()`. |
| 421 | fn update_aad(&mut self, aad: &[u8]) -> Result<(), Error>; |
| 422 | } |
| 423 | |
| 424 | /// Abstraction of an in-progress operation that only emits data when it completes. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 425 | pub trait AccumulatingOperation: Send { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 426 | /// Maximum size of accumulated input. |
| 427 | fn max_input_size(&self) -> Option<usize> { |
| 428 | None |
| 429 | } |
| 430 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 431 | /// Update operation with data. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 432 | fn update(&mut self, data: &[u8]) -> Result<(), Error>; |
| 433 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 434 | /// Complete operation, consuming `self`. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 435 | fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>; |
| 436 | } |
| 437 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 438 | /// Abstraction of HKDF key derivation with HMAC-SHA256. |
| 439 | /// |
| 440 | /// A default implementation of this trait is available (in `crypto.rs`) for any type that |
| 441 | /// implements [`Hmac`]. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 442 | pub trait Hkdf: Send { |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 443 | /// Perform combined HKDF using the input key material in `ikm`. |
Orlando Arbildo | 97ee058 | 2023-01-13 17:05:26 +0000 | [diff] [blame] | 444 | fn hkdf(&self, salt: &[u8], ikm: &[u8], info: &[u8], out_len: usize) -> Result<Vec<u8>, Error> { |
| 445 | let prk = self.extract(salt, ikm)?; |
| 446 | self.expand(&prk, info, out_len) |
| 447 | } |
| 448 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 449 | /// Perform the HKDF-Extract step on the input key material in `ikm`, using optional `salt`. |
Orlando Arbildo | 97ee058 | 2023-01-13 17:05:26 +0000 | [diff] [blame] | 450 | fn extract(&self, salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>; |
| 451 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 452 | /// Perform the HKDF-Expand step using the pseudo-random key in `prk`. |
Orlando Arbildo | 97ee058 | 2023-01-13 17:05:26 +0000 | [diff] [blame] | 453 | fn expand( |
| 454 | &self, |
| 455 | prk: &OpaqueOr<hmac::Key>, |
| 456 | info: &[u8], |
| 457 | out_len: usize, |
| 458 | ) -> Result<Vec<u8>, Error>; |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 459 | } |
| 460 | |
| 461 | /// Abstraction of CKDF key derivation with AES-CMAC KDF from NIST SP 800-108 in counter mode (see |
| 462 | /// section 5.1). |
| 463 | /// |
| 464 | /// Aa default implementation of this trait is available (in `crypto.rs`) for any type that |
| 465 | /// implements [`AesCmac`]. |
Orlando Arbildo | 0eb2d94 | 2023-09-14 23:16:12 +0000 | [diff] [blame] | 466 | pub trait Ckdf: Send { |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 467 | /// Perform CKDF using the key material in `key`. |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 468 | fn ckdf( |
| 469 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 470 | key: &OpaqueOr<aes::Key>, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 471 | label: &[u8], |
| 472 | chunks: &[&[u8]], |
| 473 | out_len: usize, |
| 474 | ) -> Result<Vec<u8>, Error>; |
| 475 | } |
| 476 | |
David Drysdale | 8339014 | 2023-10-13 07:16:43 +0100 | [diff] [blame] | 477 | /// Abstraction for SHA-256 hashing. |
| 478 | pub trait Sha256: Send { |
| 479 | /// Generate the SHA-256 input of `data`. |
| 480 | fn hash(&self, data: &[u8]) -> Result<[u8; 32], Error>; |
| 481 | } |
| 482 | |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 483 | //////////////////////////////////////////////////////////// |
David Drysdale | ced326a | 2022-10-31 07:24:24 +0000 | [diff] [blame] | 484 | // No-op implementations of traits. These implementations are |
| 485 | // only intended for convenience during the process of porting |
| 486 | // the KeyMint code to a new environment. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 487 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 488 | /// Macro to emit an error log indicating that an unimplemented function |
| 489 | /// has been invoked (and where it is). |
Hasini Gunasinghe | 567751d | 2022-11-01 06:19:00 +0000 | [diff] [blame] | 490 | #[macro_export] |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 491 | macro_rules! log_unimpl { |
| 492 | () => { |
David Drysdale | ced326a | 2022-10-31 07:24:24 +0000 | [diff] [blame] | 493 | error!("{}:{}: Unimplemented placeholder KeyMint trait method invoked!", file!(), line!(),); |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 494 | }; |
| 495 | } |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 496 | |
| 497 | /// Mark a method as unimplemented (log error, return `ErrorCode::Unimplemented`) |
Hasini Gunasinghe | 567751d | 2022-11-01 06:19:00 +0000 | [diff] [blame] | 498 | #[macro_export] |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 499 | macro_rules! unimpl { |
| 500 | () => { |
| 501 | log_unimpl!(); |
| 502 | return Err(Error::Hal( |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 503 | kmr_wire::keymint::ErrorCode::Unimplemented, |
David Drysdale | ced326a | 2022-10-31 07:24:24 +0000 | [diff] [blame] | 504 | alloc::format!("{}:{}: method unimplemented", file!(), line!()), |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 505 | )); |
| 506 | }; |
| 507 | } |
| 508 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 509 | /// Stub implementation of [`Rng`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 510 | pub struct NoOpRng; |
| 511 | impl Rng for NoOpRng { |
| 512 | fn add_entropy(&mut self, _data: &[u8]) { |
| 513 | log_unimpl!(); |
| 514 | } |
| 515 | fn fill_bytes(&mut self, _dest: &mut [u8]) { |
| 516 | log_unimpl!(); |
| 517 | } |
| 518 | } |
| 519 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 520 | /// Stub implementation of [`ConstTimeEq`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 521 | #[derive(Clone)] |
| 522 | pub struct InsecureEq; |
| 523 | impl ConstTimeEq for InsecureEq { |
| 524 | fn eq(&self, left: &[u8], right: &[u8]) -> bool { |
| 525 | warn!("Insecure comparison operation performed"); |
| 526 | left == right |
| 527 | } |
| 528 | } |
| 529 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 530 | /// Stub implementation of [`MonotonicClock`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 531 | pub struct NoOpClock; |
| 532 | impl MonotonicClock for NoOpClock { |
| 533 | fn now(&self) -> MillisecondsSinceEpoch { |
| 534 | log_unimpl!(); |
| 535 | MillisecondsSinceEpoch(0) |
| 536 | } |
| 537 | } |
| 538 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 539 | /// Stub implementation of [`Aes`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 540 | pub struct NoOpAes; |
| 541 | impl Aes for NoOpAes { |
| 542 | fn begin( |
| 543 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 544 | _key: OpaqueOr<aes::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 545 | _mode: aes::CipherMode, |
| 546 | _dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 547 | ) -> Result<Box<dyn EmittingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 548 | unimpl!(); |
| 549 | } |
| 550 | fn begin_aead( |
| 551 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 552 | _key: OpaqueOr<aes::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 553 | _mode: aes::GcmMode, |
| 554 | _dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 555 | ) -> Result<Box<dyn AadOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 556 | unimpl!(); |
| 557 | } |
| 558 | } |
| 559 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 560 | /// Stub implementation of [`Des`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 561 | pub struct NoOpDes; |
| 562 | impl Des for NoOpDes { |
| 563 | fn begin( |
| 564 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 565 | _key: OpaqueOr<des::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 566 | _mode: des::Mode, |
| 567 | _dir: SymmetricOperation, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 568 | ) -> Result<Box<dyn EmittingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 569 | unimpl!(); |
| 570 | } |
| 571 | } |
| 572 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 573 | /// Stub implementation of [`Hmac`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 574 | pub struct NoOpHmac; |
| 575 | impl Hmac for NoOpHmac { |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 576 | fn begin( |
| 577 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 578 | _key: OpaqueOr<hmac::Key>, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 579 | _digest: Digest, |
| 580 | ) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 581 | unimpl!(); |
| 582 | } |
| 583 | } |
| 584 | |
David Drysdale | 244b384 | 2024-07-15 12:34:20 +0100 | [diff] [blame] | 585 | /// Stub implementation of [`AesCmac`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 586 | pub struct NoOpAesCmac; |
| 587 | impl AesCmac for NoOpAesCmac { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 588 | fn begin(&self, _key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 589 | unimpl!(); |
| 590 | } |
| 591 | } |
| 592 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 593 | /// Stub implementation of [`Rsa`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 594 | pub struct NoOpRsa; |
| 595 | impl Rsa for NoOpRsa { |
| 596 | fn generate_key( |
| 597 | &self, |
| 598 | _rng: &mut dyn Rng, |
| 599 | _key_size: KeySizeInBits, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 600 | _pub_exponent: RsaExponent, |
| 601 | _params: &[keymint::KeyParam], |
| 602 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 603 | unimpl!(); |
| 604 | } |
| 605 | |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 606 | fn begin_decrypt( |
| 607 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 608 | _key: OpaqueOr<rsa::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 609 | _mode: rsa::DecryptionMode, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 610 | ) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 611 | unimpl!(); |
| 612 | } |
| 613 | |
| 614 | fn begin_sign( |
| 615 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 616 | _key: OpaqueOr<rsa::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 617 | _mode: rsa::SignMode, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 618 | ) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 619 | unimpl!(); |
| 620 | } |
| 621 | } |
| 622 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 623 | /// Stub implementation of [`Ec`]. |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 624 | pub struct NoOpEc; |
| 625 | impl Ec for NoOpEc { |
| 626 | fn generate_nist_key( |
| 627 | &self, |
| 628 | _rng: &mut dyn Rng, |
| 629 | _curve: ec::NistCurve, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 630 | _params: &[keymint::KeyParam], |
| 631 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 632 | unimpl!(); |
| 633 | } |
| 634 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 635 | fn generate_ed25519_key( |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 636 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 637 | _rng: &mut dyn Rng, |
| 638 | _params: &[keymint::KeyParam], |
| 639 | ) -> Result<KeyMaterial, Error> { |
| 640 | unimpl!(); |
| 641 | } |
| 642 | |
| 643 | fn generate_x25519_key( |
| 644 | &self, |
| 645 | _rng: &mut dyn Rng, |
| 646 | _params: &[keymint::KeyParam], |
| 647 | ) -> Result<KeyMaterial, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 648 | unimpl!(); |
| 649 | } |
| 650 | |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 651 | fn nist_public_key(&self, _key: &ec::NistKey, _curve: ec::NistCurve) -> Result<Vec<u8>, Error> { |
| 652 | unimpl!(); |
| 653 | } |
| 654 | |
| 655 | fn ed25519_public_key(&self, _key: &ec::Ed25519Key) -> Result<Vec<u8>, Error> { |
| 656 | unimpl!(); |
| 657 | } |
| 658 | |
| 659 | fn x25519_public_key(&self, _key: &ec::X25519Key) -> Result<Vec<u8>, Error> { |
| 660 | unimpl!(); |
| 661 | } |
| 662 | |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 663 | fn begin_agree( |
| 664 | &self, |
| 665 | _key: OpaqueOr<ec::Key>, |
| 666 | ) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 667 | unimpl!(); |
| 668 | } |
| 669 | |
| 670 | fn begin_sign( |
| 671 | &self, |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 672 | _key: OpaqueOr<ec::Key>, |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 673 | _digest: Digest, |
David Drysdale | ed33ed1 | 2022-08-23 10:01:39 +0100 | [diff] [blame] | 674 | ) -> Result<Box<dyn AccumulatingOperation>, Error> { |
David Drysdale | 9f27bc9 | 2022-06-10 15:53:32 +0100 | [diff] [blame] | 675 | unimpl!(); |
| 676 | } |
| 677 | } |
David Drysdale | 0cf92d2 | 2022-06-10 15:56:42 +0100 | [diff] [blame] | 678 | |
David Drysdale | 63e6ad6 | 2023-05-05 17:41:08 +0100 | [diff] [blame] | 679 | /// Stub implementation of [`keyblob::SecureDeletionSecretManager`]. |
David Drysdale | 0cf92d2 | 2022-06-10 15:56:42 +0100 | [diff] [blame] | 680 | pub struct NoOpSdsManager; |
| 681 | impl keyblob::SecureDeletionSecretManager for NoOpSdsManager { |
David Drysdale | 0b3938d | 2022-09-28 16:49:16 +0100 | [diff] [blame] | 682 | fn get_or_create_factory_reset_secret( |
| 683 | &mut self, |
| 684 | _rng: &mut dyn Rng, |
| 685 | ) -> Result<keyblob::SecureDeletionData, Error> { |
| 686 | unimpl!(); |
| 687 | } |
| 688 | |
| 689 | fn get_factory_reset_secret(&self) -> Result<keyblob::SecureDeletionData, Error> { |
| 690 | unimpl!(); |
| 691 | } |
| 692 | |
David Drysdale | 0cf92d2 | 2022-06-10 15:56:42 +0100 | [diff] [blame] | 693 | fn new_secret( |
| 694 | &mut self, |
| 695 | _rng: &mut dyn Rng, |
David Drysdale | 92d887b | 2022-11-30 12:14:01 +0000 | [diff] [blame] | 696 | _purpose: keyblob::SlotPurpose, |
David Drysdale | 0cf92d2 | 2022-06-10 15:56:42 +0100 | [diff] [blame] | 697 | ) -> Result<(keyblob::SecureDeletionSlot, keyblob::SecureDeletionData), Error> { |
| 698 | unimpl!(); |
| 699 | } |
| 700 | |
| 701 | fn get_secret( |
| 702 | &self, |
| 703 | _slot: keyblob::SecureDeletionSlot, |
| 704 | ) -> Result<keyblob::SecureDeletionData, Error> { |
| 705 | unimpl!(); |
| 706 | } |
| 707 | fn delete_secret(&mut self, _slot: keyblob::SecureDeletionSlot) -> Result<(), Error> { |
| 708 | unimpl!(); |
| 709 | } |
| 710 | |
| 711 | fn delete_all(&mut self) { |
| 712 | log_unimpl!(); |
| 713 | } |
| 714 | } |