xref: /aosp_15_r20/system/keymint/common/src/crypto/traits.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
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