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 15 //! Traits representing abstractions of cryptographic functionality. 16 use super::*; 17 use crate::{crypto::ec::Key, der_err, explicit, keyblob, vec_try, Error}; 18 use alloc::{boxed::Box, vec::Vec}; 19 use der::Decode; 20 use kmr_wire::{keymint, keymint::Digest, KeySizeInBits, RsaExponent}; 21 use log::{error, warn}; 22 23 /// Combined collection of trait implementations that must be provided. 24 pub struct Implementation { 25 /// Random number generator. 26 pub rng: Box<dyn Rng>, 27 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). 30 pub clock: Option<Box<dyn MonotonicClock>>, 31 32 /// A constant-time equality implementation. 33 pub compare: Box<dyn ConstTimeEq>, 34 35 /// AES implementation. 36 pub aes: Box<dyn Aes>, 37 38 /// DES implementation. 39 pub des: Box<dyn Des>, 40 41 /// HMAC implementation. 42 pub hmac: Box<dyn Hmac>, 43 44 /// RSA implementation. 45 pub rsa: Box<dyn Rsa>, 46 47 /// EC implementation. 48 pub ec: Box<dyn Ec>, 49 50 /// CKDF implementation. 51 pub ckdf: Box<dyn Ckdf>, 52 53 /// HKDF implementation. 54 pub hkdf: Box<dyn Hkdf>, 55 56 /// SHA-256 implementation. 57 pub sha256: Box<dyn Sha256>, 58 } 59 60 /// Abstraction of a random number generator that is cryptographically secure 61 /// and which accepts additional entropy to be mixed in. 62 pub trait Rng: Send { 63 /// Add entropy to the generator's pool. add_entropy(&mut self, data: &[u8])64 fn add_entropy(&mut self, data: &[u8]); 65 /// Generate random data. fill_bytes(&mut self, dest: &mut [u8])66 fn fill_bytes(&mut self, dest: &mut [u8]); 67 /// Return a random `u64` value. next_u64(&mut self) -> u6468 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. 77 pub trait ConstTimeEq: Send { 78 /// Indicate whether arguments are the same. eq(&self, left: &[u8], right: &[u8]) -> bool79 fn eq(&self, left: &[u8], right: &[u8]) -> bool; 80 /// Indicate whether arguments are the different. ne(&self, left: &[u8], right: &[u8]) -> bool81 fn ne(&self, left: &[u8], right: &[u8]) -> bool { 82 !self.eq(left, right) 83 } 84 } 85 86 /// Abstraction of a monotonic clock. 87 pub trait MonotonicClock: Send { 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)`). now(&self) -> MillisecondsSinceEpoch93 fn now(&self) -> MillisecondsSinceEpoch; 94 } 95 96 /// Abstraction of AES functionality. 97 pub trait Aes: Send { 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. generate_key( &self, rng: &mut dyn Rng, variant: aes::Variant, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>101 fn generate_key( 102 &self, 103 rng: &mut dyn Rng, 104 variant: aes::Variant, 105 _params: &[keymint::KeyParam], 106 ) -> Result<KeyMaterial, Error> { 107 Ok(match variant { 108 aes::Variant::Aes128 => { 109 let mut key = [0; 16]; 110 rng.fill_bytes(&mut key[..]); 111 KeyMaterial::Aes(aes::Key::Aes128(key).into()) 112 } 113 aes::Variant::Aes192 => { 114 let mut key = [0; 24]; 115 rng.fill_bytes(&mut key[..]); 116 KeyMaterial::Aes(aes::Key::Aes192(key).into()) 117 } 118 aes::Variant::Aes256 => { 119 let mut key = [0; 32]; 120 rng.fill_bytes(&mut key[..]); 121 KeyMaterial::Aes(aes::Key::Aes256(key).into()) 122 } 123 }) 124 } 125 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. import_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<(KeyMaterial, KeySizeInBits), Error>128 fn import_key( 129 &self, 130 data: &[u8], 131 _params: &[keymint::KeyParam], 132 ) -> Result<(KeyMaterial, KeySizeInBits), Error> { 133 let aes_key = aes::Key::new_from(data)?; 134 let key_size = aes_key.size(); 135 Ok((KeyMaterial::Aes(aes_key.into()), key_size)) 136 } 137 138 /// Create an AES operation. For block mode operations with no padding 139 /// ([`aes::CipherMode::EcbNoPadding`] and [`aes::CipherMode::CbcNoPadding`]) the operation 140 /// implementation should reject (with `ErrorCode::InvalidInputLength`) input data that does 141 /// not end up being a multiple of the block size. begin( &self, key: OpaqueOr<aes::Key>, mode: aes::CipherMode, dir: SymmetricOperation, ) -> Result<Box<dyn EmittingOperation>, Error>142 fn begin( 143 &self, 144 key: OpaqueOr<aes::Key>, 145 mode: aes::CipherMode, 146 dir: SymmetricOperation, 147 ) -> Result<Box<dyn EmittingOperation>, Error>; 148 149 /// Create an AES-GCM operation. begin_aead( &self, key: OpaqueOr<aes::Key>, mode: aes::GcmMode, dir: SymmetricOperation, ) -> Result<Box<dyn AadOperation>, Error>150 fn begin_aead( 151 &self, 152 key: OpaqueOr<aes::Key>, 153 mode: aes::GcmMode, 154 dir: SymmetricOperation, 155 ) -> Result<Box<dyn AadOperation>, Error>; 156 } 157 158 /// Abstraction of 3-DES functionality. 159 pub trait Des: Send { 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. generate_key( &self, rng: &mut dyn Rng, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>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]?; 168 // Note: parity bits must be ignored. 169 rng.fill_bytes(&mut key[..]); 170 Ok(KeyMaterial::TripleDes(des::Key::new(key)?.into())) 171 } 172 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. import_key(&self, data: &[u8], _params: &[keymint::KeyParam]) -> Result<KeyMaterial, Error>175 fn import_key(&self, data: &[u8], _params: &[keymint::KeyParam]) -> Result<KeyMaterial, Error> { 176 let des_key = des::Key::new_from(data)?; 177 Ok(KeyMaterial::TripleDes(des_key.into())) 178 } 179 180 /// Create a DES operation. For block mode operations with no padding 181 /// ([`des::Mode::EcbNoPadding`] and [`des::Mode::CbcNoPadding`]) the operation implementation 182 /// should reject (with `ErrorCode::InvalidInputLength`) input data that does not end up being 183 /// a multiple of the block size. begin( &self, key: OpaqueOr<des::Key>, mode: des::Mode, dir: SymmetricOperation, ) -> Result<Box<dyn EmittingOperation>, Error>184 fn begin( 185 &self, 186 key: OpaqueOr<des::Key>, 187 mode: des::Mode, 188 dir: SymmetricOperation, 189 ) -> Result<Box<dyn EmittingOperation>, Error>; 190 } 191 192 /// Abstraction of HMAC functionality. 193 pub trait Hmac: Send { 194 /// Generate an HMAC key. Key generation parameters are passed in for reference, to allow for 195 /// implementations that might have parameter-specific behaviour. generate_key( &self, rng: &mut dyn Rng, key_size: KeySizeInBits, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>196 fn generate_key( 197 &self, 198 rng: &mut dyn Rng, 199 key_size: KeySizeInBits, 200 _params: &[keymint::KeyParam], 201 ) -> Result<KeyMaterial, Error> { 202 hmac::valid_hal_size(key_size)?; 203 204 let key_len = (key_size.0 / 8) as usize; 205 let mut key = vec_try![0; key_len]?; 206 rng.fill_bytes(&mut key); 207 Ok(KeyMaterial::Hmac(hmac::Key::new(key).into())) 208 } 209 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. import_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<(KeyMaterial, KeySizeInBits), Error>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)?; 218 let key_size = hmac_key.size(); 219 hmac::valid_hal_size(key_size)?; 220 Ok((KeyMaterial::Hmac(hmac_key.into()), key_size)) 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`] begin( &self, key: OpaqueOr<hmac::Key>, digest: Digest, ) -> Result<Box<dyn AccumulatingOperation>, Error>226 fn begin( 227 &self, 228 key: OpaqueOr<hmac::Key>, 229 digest: Digest, 230 ) -> Result<Box<dyn AccumulatingOperation>, Error>; 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.) 235 pub trait AesCmac: Send { 236 /// Create an AES-CMAC operation. Implementations can assume that `key` will have length 237 /// of either 16 (AES-128) or 32 (AES-256). begin(&self, key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>238 fn begin(&self, key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>; 239 } 240 241 /// Abstraction of RSA functionality. 242 pub trait Rsa: Send { 243 /// Generate an RSA key. Key generation parameters are passed in for reference, to allow for 244 /// implementations that might have parameter-specific behaviour. generate_key( &self, rng: &mut dyn Rng, key_size: KeySizeInBits, pub_exponent: RsaExponent, params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>245 fn generate_key( 246 &self, 247 rng: &mut dyn Rng, 248 key_size: KeySizeInBits, 249 pub_exponent: RsaExponent, 250 params: &[keymint::KeyParam], 251 ) -> Result<KeyMaterial, Error>; 252 253 /// Import an RSA key in PKCS#8 format, also returning the key size in bits and public exponent. 254 /// Key import parameters are passed in for reference, to allow for implementations that might 255 /// have parameter-specific behaviour. import_pkcs8_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error>256 fn import_pkcs8_key( 257 &self, 258 data: &[u8], 259 _params: &[keymint::KeyParam], 260 ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error> { 261 rsa::import_pkcs8_key(data) 262 } 263 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`. subject_public_key(&self, key: &OpaqueOr<rsa::Key>) -> Result<Vec<u8>, Error>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 278 /// Create an RSA decryption operation. begin_decrypt( &self, key: OpaqueOr<rsa::Key>, mode: rsa::DecryptionMode, ) -> Result<Box<dyn AccumulatingOperation>, Error>279 fn begin_decrypt( 280 &self, 281 key: OpaqueOr<rsa::Key>, 282 mode: rsa::DecryptionMode, 283 ) -> Result<Box<dyn AccumulatingOperation>, Error>; 284 285 /// Create an RSA signing operation. For [`rsa::SignMode::Pkcs1_1_5Padding(Digest::None)`] the 286 /// implementation should reject (with `ErrorCode::InvalidInputLength`) accumulated input that 287 /// is larger than the size of the RSA key less overhead 288 /// ([`rsa::PKCS1_UNDIGESTED_SIGNATURE_PADDING_OVERHEAD`]). begin_sign( &self, key: OpaqueOr<rsa::Key>, mode: rsa::SignMode, ) -> Result<Box<dyn AccumulatingOperation>, Error>289 fn begin_sign( 290 &self, 291 key: OpaqueOr<rsa::Key>, 292 mode: rsa::SignMode, 293 ) -> Result<Box<dyn AccumulatingOperation>, Error>; 294 } 295 296 /// Abstraction of EC functionality. 297 pub trait Ec: Send { 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. generate_nist_key( &self, rng: &mut dyn Rng, curve: ec::NistCurve, params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>300 fn generate_nist_key( 301 &self, 302 rng: &mut dyn Rng, 303 curve: ec::NistCurve, 304 params: &[keymint::KeyParam], 305 ) -> Result<KeyMaterial, Error>; 306 307 /// Generate an Ed25519 key. Key generation parameters are passed in for reference, to allow 308 /// for implementations that might have parameter-specific behaviour. generate_ed25519_key( &self, rng: &mut dyn Rng, params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>309 fn generate_ed25519_key( 310 &self, 311 rng: &mut dyn Rng, 312 params: &[keymint::KeyParam], 313 ) -> Result<KeyMaterial, Error>; 314 315 /// Generate an X25519 key. Key generation parameters are passed in for reference, to allow for 316 /// implementations that might have parameter-specific behaviour. generate_x25519_key( &self, rng: &mut dyn Rng, params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>317 fn generate_x25519_key( 318 &self, 319 rng: &mut dyn Rng, 320 params: &[keymint::KeyParam], 321 ) -> Result<KeyMaterial, Error>; 322 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. import_pkcs8_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>325 fn import_pkcs8_key( 326 &self, 327 data: &[u8], 328 _params: &[keymint::KeyParam], 329 ) -> Result<KeyMaterial, Error> { 330 ec::import_pkcs8_key(data) 331 } 332 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. import_raw_ed25519_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>335 fn import_raw_ed25519_key( 336 &self, 337 data: &[u8], 338 _params: &[keymint::KeyParam], 339 ) -> Result<KeyMaterial, Error> { 340 ec::import_raw_ed25519_key(data) 341 } 342 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. import_raw_x25519_key( &self, data: &[u8], _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>345 fn import_raw_x25519_key( 346 &self, 347 data: &[u8], 348 _params: &[keymint::KeyParam], 349 ) -> Result<KeyMaterial, Error> { 350 ec::import_raw_x25519_key(data) 351 } 352 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. subject_public_key(&self, key: &OpaqueOr<ec::Key>) -> Result<Vec<u8>, Error>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) => { 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"))?; 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 383 /// Return the public key data that corresponds to the provided private `key`, as a SEC-1 384 /// encoded uncompressed point. nist_public_key(&self, key: &ec::NistKey, curve: ec::NistCurve) -> Result<Vec<u8>, Error>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`. ed25519_public_key(&self, key: &ec::Ed25519Key) -> Result<Vec<u8>, Error>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`. x25519_public_key(&self, key: &ec::X25519Key) -> Result<Vec<u8>, Error>391 fn x25519_public_key(&self, key: &ec::X25519Key) -> Result<Vec<u8>, Error>; 392 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`. begin_agree(&self, key: OpaqueOr<ec::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>396 fn begin_agree(&self, key: OpaqueOr<ec::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>; 397 398 /// Create an EC signing operation. For Ed25519 signing operations, the implementation should 399 /// reject (with `ErrorCode::InvalidInputLength`) accumulated data that is larger than 400 /// [`ec::MAX_ED25519_MSG_SIZE`]. begin_sign( &self, key: OpaqueOr<ec::Key>, digest: Digest, ) -> Result<Box<dyn AccumulatingOperation>, Error>401 fn begin_sign( 402 &self, 403 key: OpaqueOr<ec::Key>, 404 digest: Digest, 405 ) -> Result<Box<dyn AccumulatingOperation>, Error>; 406 } 407 408 /// Abstraction of an in-progress operation that emits data as it progresses. 409 pub trait EmittingOperation: Send { 410 /// Update operation with data. update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error>411 fn update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error>; 412 413 /// Complete operation, consuming `self`. finish(self: Box<Self>) -> Result<Vec<u8>, Error>414 fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>; 415 } 416 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()`. update_aad(&mut self, aad: &[u8]) -> Result<(), Error>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. 425 pub trait AccumulatingOperation: Send { 426 /// Maximum size of accumulated input. max_input_size(&self) -> Option<usize>427 fn max_input_size(&self) -> Option<usize> { 428 None 429 } 430 431 /// Update operation with data. update(&mut self, data: &[u8]) -> Result<(), Error>432 fn update(&mut self, data: &[u8]) -> Result<(), Error>; 433 434 /// Complete operation, consuming `self`. finish(self: Box<Self>) -> Result<Vec<u8>, Error>435 fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>; 436 } 437 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`]. 442 pub trait Hkdf: Send { 443 /// Perform combined HKDF using the input key material in `ikm`. hkdf(&self, salt: &[u8], ikm: &[u8], info: &[u8], out_len: usize) -> Result<Vec<u8>, Error>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 449 /// Perform the HKDF-Extract step on the input key material in `ikm`, using optional `salt`. extract(&self, salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>450 fn extract(&self, salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>; 451 452 /// Perform the HKDF-Expand step using the pseudo-random key in `prk`. expand( &self, prk: &OpaqueOr<hmac::Key>, info: &[u8], out_len: usize, ) -> Result<Vec<u8>, Error>453 fn expand( 454 &self, 455 prk: &OpaqueOr<hmac::Key>, 456 info: &[u8], 457 out_len: usize, 458 ) -> Result<Vec<u8>, Error>; 459 460 /// Perform combined HKDF using the input key material in `ikm`, emitting output in the form of 461 /// an AES key. hkdf_aes( &self, salt: &[u8], ikm: &[u8], info: &[u8], variant: aes::Variant, ) -> Result<OpaqueOr<aes::Key>, Error>462 fn hkdf_aes( 463 &self, 464 salt: &[u8], 465 ikm: &[u8], 466 info: &[u8], 467 variant: aes::Variant, 468 ) -> Result<OpaqueOr<aes::Key>, Error> { 469 // Default implementation generates explicit key material and converts to an [`aes::Key`]. 470 let data = self.hkdf(salt, ikm, info, variant.key_size())?; 471 let explicit_key = aes::Key::new(data)?; 472 Ok(explicit_key.into()) 473 } 474 475 /// Perform the HKDF-Expand step using the pseudo-random key in `prk`, emitting output in the 476 /// form of an AES key. expand_aes( &self, prk: &OpaqueOr<hmac::Key>, info: &[u8], variant: aes::Variant, ) -> Result<OpaqueOr<aes::Key>, Error>477 fn expand_aes( 478 &self, 479 prk: &OpaqueOr<hmac::Key>, 480 info: &[u8], 481 variant: aes::Variant, 482 ) -> Result<OpaqueOr<aes::Key>, Error> { 483 // Default implementation generates explicit key material and converts to an [`aes::Key`]. 484 let data = self.expand(prk, info, variant.key_size())?; 485 let explicit_key = aes::Key::new(data)?; 486 Ok(explicit_key.into()) 487 } 488 } 489 490 /// Abstraction of CKDF key derivation with AES-CMAC KDF from NIST SP 800-108 in counter mode (see 491 /// section 5.1). 492 /// 493 /// Aa default implementation of this trait is available (in `crypto.rs`) for any type that 494 /// implements [`AesCmac`]. 495 pub trait Ckdf: Send { 496 /// Perform CKDF using the key material in `key`. ckdf( &self, key: &OpaqueOr<aes::Key>, label: &[u8], chunks: &[&[u8]], out_len: usize, ) -> Result<Vec<u8>, Error>497 fn ckdf( 498 &self, 499 key: &OpaqueOr<aes::Key>, 500 label: &[u8], 501 chunks: &[&[u8]], 502 out_len: usize, 503 ) -> Result<Vec<u8>, Error>; 504 } 505 506 /// Abstraction for SHA-256 hashing. 507 pub trait Sha256: Send { 508 /// Generate the SHA-256 input of `data`. hash(&self, data: &[u8]) -> Result<[u8; 32], Error>509 fn hash(&self, data: &[u8]) -> Result<[u8; 32], Error>; 510 } 511 512 //////////////////////////////////////////////////////////// 513 // No-op implementations of traits. These implementations are 514 // only intended for convenience during the process of porting 515 // the KeyMint code to a new environment. 516 517 /// Macro to emit an error log indicating that an unimplemented function 518 /// has been invoked (and where it is). 519 #[macro_export] 520 macro_rules! log_unimpl { 521 () => { 522 error!("{}:{}: Unimplemented placeholder KeyMint trait method invoked!", file!(), line!(),); 523 }; 524 } 525 526 /// Mark a method as unimplemented (log error, return `ErrorCode::Unimplemented`) 527 #[macro_export] 528 macro_rules! unimpl { 529 () => { 530 log_unimpl!(); 531 return Err(Error::Hal( 532 kmr_wire::keymint::ErrorCode::Unimplemented, 533 alloc::format!("{}:{}: method unimplemented", file!(), line!()), 534 )); 535 }; 536 } 537 538 /// Stub implementation of [`Rng`]. 539 pub struct NoOpRng; 540 impl Rng for NoOpRng { add_entropy(&mut self, _data: &[u8])541 fn add_entropy(&mut self, _data: &[u8]) { 542 log_unimpl!(); 543 } fill_bytes(&mut self, _dest: &mut [u8])544 fn fill_bytes(&mut self, _dest: &mut [u8]) { 545 log_unimpl!(); 546 } 547 } 548 549 /// Stub implementation of [`ConstTimeEq`]. 550 #[derive(Clone)] 551 pub struct InsecureEq; 552 impl ConstTimeEq for InsecureEq { eq(&self, left: &[u8], right: &[u8]) -> bool553 fn eq(&self, left: &[u8], right: &[u8]) -> bool { 554 warn!("Insecure comparison operation performed"); 555 left == right 556 } 557 } 558 559 /// Stub implementation of [`MonotonicClock`]. 560 pub struct NoOpClock; 561 impl MonotonicClock for NoOpClock { now(&self) -> MillisecondsSinceEpoch562 fn now(&self) -> MillisecondsSinceEpoch { 563 log_unimpl!(); 564 MillisecondsSinceEpoch(0) 565 } 566 } 567 568 /// Stub implementation of [`Aes`]. 569 pub struct NoOpAes; 570 impl Aes for NoOpAes { begin( &self, _key: OpaqueOr<aes::Key>, _mode: aes::CipherMode, _dir: SymmetricOperation, ) -> Result<Box<dyn EmittingOperation>, Error>571 fn begin( 572 &self, 573 _key: OpaqueOr<aes::Key>, 574 _mode: aes::CipherMode, 575 _dir: SymmetricOperation, 576 ) -> Result<Box<dyn EmittingOperation>, Error> { 577 unimpl!(); 578 } begin_aead( &self, _key: OpaqueOr<aes::Key>, _mode: aes::GcmMode, _dir: SymmetricOperation, ) -> Result<Box<dyn AadOperation>, Error>579 fn begin_aead( 580 &self, 581 _key: OpaqueOr<aes::Key>, 582 _mode: aes::GcmMode, 583 _dir: SymmetricOperation, 584 ) -> Result<Box<dyn AadOperation>, Error> { 585 unimpl!(); 586 } 587 } 588 589 /// Stub implementation of [`Des`]. 590 pub struct NoOpDes; 591 impl Des for NoOpDes { begin( &self, _key: OpaqueOr<des::Key>, _mode: des::Mode, _dir: SymmetricOperation, ) -> Result<Box<dyn EmittingOperation>, Error>592 fn begin( 593 &self, 594 _key: OpaqueOr<des::Key>, 595 _mode: des::Mode, 596 _dir: SymmetricOperation, 597 ) -> Result<Box<dyn EmittingOperation>, Error> { 598 unimpl!(); 599 } 600 } 601 602 /// Stub implementation of [`Hmac`]. 603 pub struct NoOpHmac; 604 impl Hmac for NoOpHmac { begin( &self, _key: OpaqueOr<hmac::Key>, _digest: Digest, ) -> Result<Box<dyn AccumulatingOperation>, Error>605 fn begin( 606 &self, 607 _key: OpaqueOr<hmac::Key>, 608 _digest: Digest, 609 ) -> Result<Box<dyn AccumulatingOperation>, Error> { 610 unimpl!(); 611 } 612 } 613 614 /// Stub implementation of [`AesCmac`]. 615 pub struct NoOpAesCmac; 616 impl AesCmac for NoOpAesCmac { begin(&self, _key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>617 fn begin(&self, _key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error> { 618 unimpl!(); 619 } 620 } 621 622 /// Stub implementation of [`Rsa`]. 623 pub struct NoOpRsa; 624 impl Rsa for NoOpRsa { generate_key( &self, _rng: &mut dyn Rng, _key_size: KeySizeInBits, _pub_exponent: RsaExponent, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>625 fn generate_key( 626 &self, 627 _rng: &mut dyn Rng, 628 _key_size: KeySizeInBits, 629 _pub_exponent: RsaExponent, 630 _params: &[keymint::KeyParam], 631 ) -> Result<KeyMaterial, Error> { 632 unimpl!(); 633 } 634 begin_decrypt( &self, _key: OpaqueOr<rsa::Key>, _mode: rsa::DecryptionMode, ) -> Result<Box<dyn AccumulatingOperation>, Error>635 fn begin_decrypt( 636 &self, 637 _key: OpaqueOr<rsa::Key>, 638 _mode: rsa::DecryptionMode, 639 ) -> Result<Box<dyn AccumulatingOperation>, Error> { 640 unimpl!(); 641 } 642 begin_sign( &self, _key: OpaqueOr<rsa::Key>, _mode: rsa::SignMode, ) -> Result<Box<dyn AccumulatingOperation>, Error>643 fn begin_sign( 644 &self, 645 _key: OpaqueOr<rsa::Key>, 646 _mode: rsa::SignMode, 647 ) -> Result<Box<dyn AccumulatingOperation>, Error> { 648 unimpl!(); 649 } 650 } 651 652 /// Stub implementation of [`Ec`]. 653 pub struct NoOpEc; 654 impl Ec for NoOpEc { generate_nist_key( &self, _rng: &mut dyn Rng, _curve: ec::NistCurve, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>655 fn generate_nist_key( 656 &self, 657 _rng: &mut dyn Rng, 658 _curve: ec::NistCurve, 659 _params: &[keymint::KeyParam], 660 ) -> Result<KeyMaterial, Error> { 661 unimpl!(); 662 } 663 generate_ed25519_key( &self, _rng: &mut dyn Rng, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>664 fn generate_ed25519_key( 665 &self, 666 _rng: &mut dyn Rng, 667 _params: &[keymint::KeyParam], 668 ) -> Result<KeyMaterial, Error> { 669 unimpl!(); 670 } 671 generate_x25519_key( &self, _rng: &mut dyn Rng, _params: &[keymint::KeyParam], ) -> Result<KeyMaterial, Error>672 fn generate_x25519_key( 673 &self, 674 _rng: &mut dyn Rng, 675 _params: &[keymint::KeyParam], 676 ) -> Result<KeyMaterial, Error> { 677 unimpl!(); 678 } 679 nist_public_key(&self, _key: &ec::NistKey, _curve: ec::NistCurve) -> Result<Vec<u8>, Error>680 fn nist_public_key(&self, _key: &ec::NistKey, _curve: ec::NistCurve) -> Result<Vec<u8>, Error> { 681 unimpl!(); 682 } 683 ed25519_public_key(&self, _key: &ec::Ed25519Key) -> Result<Vec<u8>, Error>684 fn ed25519_public_key(&self, _key: &ec::Ed25519Key) -> Result<Vec<u8>, Error> { 685 unimpl!(); 686 } 687 x25519_public_key(&self, _key: &ec::X25519Key) -> Result<Vec<u8>, Error>688 fn x25519_public_key(&self, _key: &ec::X25519Key) -> Result<Vec<u8>, Error> { 689 unimpl!(); 690 } 691 begin_agree( &self, _key: OpaqueOr<ec::Key>, ) -> Result<Box<dyn AccumulatingOperation>, Error>692 fn begin_agree( 693 &self, 694 _key: OpaqueOr<ec::Key>, 695 ) -> Result<Box<dyn AccumulatingOperation>, Error> { 696 unimpl!(); 697 } 698 begin_sign( &self, _key: OpaqueOr<ec::Key>, _digest: Digest, ) -> Result<Box<dyn AccumulatingOperation>, Error>699 fn begin_sign( 700 &self, 701 _key: OpaqueOr<ec::Key>, 702 _digest: Digest, 703 ) -> Result<Box<dyn AccumulatingOperation>, Error> { 704 unimpl!(); 705 } 706 } 707 708 /// Stub implementation of [`keyblob::SecureDeletionSecretManager`]. 709 pub struct NoOpSdsManager; 710 impl keyblob::SecureDeletionSecretManager for NoOpSdsManager { get_or_create_factory_reset_secret( &mut self, _rng: &mut dyn Rng, ) -> Result<keyblob::SecureDeletionData, Error>711 fn get_or_create_factory_reset_secret( 712 &mut self, 713 _rng: &mut dyn Rng, 714 ) -> Result<keyblob::SecureDeletionData, Error> { 715 unimpl!(); 716 } 717 get_factory_reset_secret(&self) -> Result<keyblob::SecureDeletionData, Error>718 fn get_factory_reset_secret(&self) -> Result<keyblob::SecureDeletionData, Error> { 719 unimpl!(); 720 } 721 new_secret( &mut self, _rng: &mut dyn Rng, _purpose: keyblob::SlotPurpose, ) -> Result<(keyblob::SecureDeletionSlot, keyblob::SecureDeletionData), Error>722 fn new_secret( 723 &mut self, 724 _rng: &mut dyn Rng, 725 _purpose: keyblob::SlotPurpose, 726 ) -> Result<(keyblob::SecureDeletionSlot, keyblob::SecureDeletionData), Error> { 727 unimpl!(); 728 } 729 get_secret( &self, _slot: keyblob::SecureDeletionSlot, ) -> Result<keyblob::SecureDeletionData, Error>730 fn get_secret( 731 &self, 732 _slot: keyblob::SecureDeletionSlot, 733 ) -> Result<keyblob::SecureDeletionData, Error> { 734 unimpl!(); 735 } delete_secret(&mut self, _slot: keyblob::SecureDeletionSlot) -> Result<(), Error>736 fn delete_secret(&mut self, _slot: keyblob::SecureDeletionSlot) -> Result<(), Error> { 737 unimpl!(); 738 } 739 delete_all(&mut self)740 fn delete_all(&mut self) { 741 log_unimpl!(); 742 } 743 } 744