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