blob: bf20ac9968c05d1dad68b2cc811fadec81e19515 [file] [log] [blame]
David Drysdale747e5932023-10-17 14:43:43 +01001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
David Drysdale9f27bc92022-06-10 15:53:32 +010015//! Traits representing abstractions of cryptographic functionality.
David Drysdale9f27bc92022-06-10 15:53:32 +010016use super::*;
David Drysdaleccc2d1b2023-05-04 12:22:01 +010017use crate::{crypto::ec::Key, der_err, explicit, keyblob, vec_try, Error};
David Drysdale0b3938d2022-09-28 16:49:16 +010018use alloc::{boxed::Box, vec::Vec};
Hasini Gunasinghec939a9b2022-11-17 02:45:22 +000019use der::Decode;
David Drysdale0986c772022-11-03 08:12:53 +000020use kmr_wire::{keymint, keymint::Digest, KeySizeInBits, RsaExponent};
David Drysdale9f27bc92022-06-10 15:53:32 +010021use log::{error, warn};
22
23/// Combined collection of trait implementations that must be provided.
David Drysdale90a8c832023-05-11 14:38:42 +010024pub struct Implementation {
David Drysdale9f27bc92022-06-10 15:53:32 +010025 /// Random number generator.
David Drysdale90a8c832023-05-11 14:38:42 +010026 pub rng: Box<dyn Rng>,
David Drysdale9f27bc92022-06-10 15:53:32 +010027
David Drysdaleed33ed12022-08-23 10:01:39 +010028 /// A local clock, if available. If not available, KeyMint will require timestamp tokens to
29 /// be provided by an external `ISecureClock` (with which it shares a common key).
David Drysdale90a8c832023-05-11 14:38:42 +010030 pub clock: Option<Box<dyn MonotonicClock>>,
David Drysdale9f27bc92022-06-10 15:53:32 +010031
32 /// A constant-time equality implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010033 pub compare: Box<dyn ConstTimeEq>,
David Drysdale9f27bc92022-06-10 15:53:32 +010034
35 /// AES implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010036 pub aes: Box<dyn Aes>,
David Drysdale9f27bc92022-06-10 15:53:32 +010037
38 /// DES implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010039 pub des: Box<dyn Des>,
David Drysdale9f27bc92022-06-10 15:53:32 +010040
41 /// HMAC implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010042 pub hmac: Box<dyn Hmac>,
David Drysdale9f27bc92022-06-10 15:53:32 +010043
44 /// RSA implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010045 pub rsa: Box<dyn Rsa>,
David Drysdale9f27bc92022-06-10 15:53:32 +010046
47 /// EC implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010048 pub ec: Box<dyn Ec>,
David Drysdale9f27bc92022-06-10 15:53:32 +010049
David Drysdaleed33ed12022-08-23 10:01:39 +010050 /// CKDF implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010051 pub ckdf: Box<dyn Ckdf>,
David Drysdaleed33ed12022-08-23 10:01:39 +010052
53 /// HKDF implementation.
David Drysdale90a8c832023-05-11 14:38:42 +010054 pub hkdf: Box<dyn Hkdf>,
David Drysdale83390142023-10-13 07:16:43 +010055
56 /// SHA-256 implementation.
57 pub sha256: Box<dyn Sha256>,
David Drysdale9f27bc92022-06-10 15:53:32 +010058}
59
60/// Abstraction of a random number generator that is cryptographically secure
61/// and which accepts additional entropy to be mixed in.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +000062pub trait Rng: Send {
David Drysdale9f27bc92022-06-10 15:53:32 +010063 /// Add entropy to the generator's pool.
64 fn add_entropy(&mut self, data: &[u8]);
65 /// Generate random data.
66 fn fill_bytes(&mut self, dest: &mut [u8]);
67 /// Return a random `u64` value.
68 fn next_u64(&mut self) -> u64 {
69 let mut buf = [0u8; 8];
70 self.fill_bytes(&mut buf);
71 u64::from_le_bytes(buf)
72 }
73}
74
75/// Abstraction of constant-time comparisons, for use in cryptographic contexts where timing attacks
76/// need to be avoided.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +000077pub trait ConstTimeEq: Send {
David Drysdale9f27bc92022-06-10 15:53:32 +010078 /// Indicate whether arguments are the same.
79 fn eq(&self, left: &[u8], right: &[u8]) -> bool;
80 /// Indicate whether arguments are the different.
81 fn ne(&self, left: &[u8], right: &[u8]) -> bool {
82 !self.eq(left, right)
83 }
84}
85
86/// Abstraction of a monotonic clock.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +000087pub trait MonotonicClock: Send {
David Drysdale9f27bc92022-06-10 15:53:32 +010088 /// Return the current time in milliseconds since some arbitrary point in time. Time must be
89 /// monotonically increasing, and "current time" must not repeat until the Android device
90 /// reboots, or until at least 50 million years have elapsed. Time must also continue to
91 /// advance while the device is suspended (which may not be the case with e.g. Linux's
92 /// `clock_gettime(CLOCK_MONOTONIC)`).
93 fn now(&self) -> MillisecondsSinceEpoch;
94}
95
96/// Abstraction of AES functionality.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +000097pub trait Aes: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +010098 /// Generate an AES key. The default implementation fills with random data. Key generation
99 /// parameters are passed in for reference, to allow for implementations that might have
100 /// parameter-specific behaviour.
David Drysdale9f27bc92022-06-10 15:53:32 +0100101 fn generate_key(
102 &self,
103 rng: &mut dyn Rng,
104 variant: aes::Variant,
David Drysdale0b3938d2022-09-28 16:49:16 +0100105 _params: &[keymint::KeyParam],
106 ) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100107 Ok(match variant {
108 aes::Variant::Aes128 => {
109 let mut key = [0; 16];
110 rng.fill_bytes(&mut key[..]);
David Drysdale0b3938d2022-09-28 16:49:16 +0100111 KeyMaterial::Aes(aes::Key::Aes128(key).into())
David Drysdale9f27bc92022-06-10 15:53:32 +0100112 }
113 aes::Variant::Aes192 => {
114 let mut key = [0; 24];
115 rng.fill_bytes(&mut key[..]);
David Drysdale0b3938d2022-09-28 16:49:16 +0100116 KeyMaterial::Aes(aes::Key::Aes192(key).into())
David Drysdale9f27bc92022-06-10 15:53:32 +0100117 }
118 aes::Variant::Aes256 => {
119 let mut key = [0; 32];
120 rng.fill_bytes(&mut key[..]);
David Drysdale0b3938d2022-09-28 16:49:16 +0100121 KeyMaterial::Aes(aes::Key::Aes256(key).into())
David Drysdale9f27bc92022-06-10 15:53:32 +0100122 }
123 })
124 }
125
David Drysdale0b3938d2022-09-28 16:49:16 +0100126 /// Import an AES key, also returning the key size in bits. Key import parameters are passed in
127 /// for reference, to allow for implementations that might have parameter-specific behaviour.
128 fn import_key(
129 &self,
130 data: &[u8],
131 _params: &[keymint::KeyParam],
132 ) -> Result<(KeyMaterial, KeySizeInBits), Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100133 let aes_key = aes::Key::new_from(data)?;
134 let key_size = aes_key.size();
David Drysdale0b3938d2022-09-28 16:49:16 +0100135 Ok((KeyMaterial::Aes(aes_key.into()), key_size))
David Drysdale9f27bc92022-06-10 15:53:32 +0100136 }
137
David Drysdalefc718252022-06-10 16:06:24 +0100138 /// Create an AES operation. For block mode operations with no padding
139 /// ([`aes::CipherMode::EcbNoPadding`] and [`aes::CipherMode::CbcNoPadding`]) the operation
David Drysdale244b3842024-07-15 12:34:20 +0100140 /// implementation should reject (with `ErrorCode::InvalidInputLength`) input data that does
David Drysdalefc718252022-06-10 16:06:24 +0100141 /// not end up being a multiple of the block size.
David Drysdale9f27bc92022-06-10 15:53:32 +0100142 fn begin(
143 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100144 key: OpaqueOr<aes::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100145 mode: aes::CipherMode,
146 dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100147 ) -> Result<Box<dyn EmittingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100148
149 /// Create an AES-GCM operation.
150 fn begin_aead(
151 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100152 key: OpaqueOr<aes::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100153 mode: aes::GcmMode,
154 dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100155 ) -> Result<Box<dyn AadOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100156}
157
158/// Abstraction of 3-DES functionality.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000159pub trait Des: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +0100160 /// Generate a triple DES key. Key generation parameters are passed in for reference, to allow
161 /// for implementations that might have parameter-specific behaviour.
162 fn generate_key(
163 &self,
164 rng: &mut dyn Rng,
165 _params: &[keymint::KeyParam],
166 ) -> Result<KeyMaterial, Error> {
167 let mut key = vec_try![0; 24]?;
David Drysdaleed33ed12022-08-23 10:01:39 +0100168 // Note: parity bits must be ignored.
David Drysdale9f27bc92022-06-10 15:53:32 +0100169 rng.fill_bytes(&mut key[..]);
David Drysdale0b3938d2022-09-28 16:49:16 +0100170 Ok(KeyMaterial::TripleDes(des::Key::new(key)?.into()))
David Drysdale9f27bc92022-06-10 15:53:32 +0100171 }
172
David Drysdale0b3938d2022-09-28 16:49:16 +0100173 /// Import a triple DES key. Key import parameters are passed in for reference, to allow for
174 /// implementations that might have parameter-specific behaviour.
175 fn import_key(&self, data: &[u8], _params: &[keymint::KeyParam]) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100176 let des_key = des::Key::new_from(data)?;
David Drysdale0b3938d2022-09-28 16:49:16 +0100177 Ok(KeyMaterial::TripleDes(des_key.into()))
David Drysdale9f27bc92022-06-10 15:53:32 +0100178 }
179
David Drysdalefc718252022-06-10 16:06:24 +0100180 /// Create a DES operation. For block mode operations with no padding
181 /// ([`des::Mode::EcbNoPadding`] and [`des::Mode::CbcNoPadding`]) the operation implementation
David Drysdale244b3842024-07-15 12:34:20 +0100182 /// should reject (with `ErrorCode::InvalidInputLength`) input data that does not end up being
David Drysdalefc718252022-06-10 16:06:24 +0100183 /// a multiple of the block size.
David Drysdale9f27bc92022-06-10 15:53:32 +0100184 fn begin(
185 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100186 key: OpaqueOr<des::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100187 mode: des::Mode,
188 dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100189 ) -> Result<Box<dyn EmittingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100190}
191
192/// Abstraction of HMAC functionality.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000193pub trait Hmac: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +0100194 /// Generate an HMAC key. Key generation parameters are passed in for reference, to allow for
195 /// implementations that might have parameter-specific behaviour.
David Drysdale9f27bc92022-06-10 15:53:32 +0100196 fn generate_key(
197 &self,
198 rng: &mut dyn Rng,
199 key_size: KeySizeInBits,
David Drysdale0b3938d2022-09-28 16:49:16 +0100200 _params: &[keymint::KeyParam],
201 ) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100202 hmac::valid_hal_size(key_size)?;
203
David Drysdale0b3938d2022-09-28 16:49:16 +0100204 let key_len = (key_size.0 / 8) as usize;
205 let mut key = vec_try![0; key_len]?;
David Drysdale9f27bc92022-06-10 15:53:32 +0100206 rng.fill_bytes(&mut key);
David Drysdale0b3938d2022-09-28 16:49:16 +0100207 Ok(KeyMaterial::Hmac(hmac::Key::new(key).into()))
David Drysdale9f27bc92022-06-10 15:53:32 +0100208 }
209
David Drysdale0b3938d2022-09-28 16:49:16 +0100210 /// Import an HMAC key, also returning the key size in bits. Key import parameters are passed in
211 /// for reference, to allow for implementations that might have parameter-specific behaviour.
212 fn import_key(
213 &self,
214 data: &[u8],
215 _params: &[keymint::KeyParam],
216 ) -> Result<(KeyMaterial, KeySizeInBits), Error> {
217 let hmac_key = hmac::Key::new_from(data)?;
David Drysdale9f27bc92022-06-10 15:53:32 +0100218 let key_size = hmac_key.size();
219 hmac::valid_hal_size(key_size)?;
David Drysdale0b3938d2022-09-28 16:49:16 +0100220 Ok((KeyMaterial::Hmac(hmac_key.into()), key_size))
David Drysdale9f27bc92022-06-10 15:53:32 +0100221 }
222
223 /// Create an HMAC operation. Implementations can assume that:
224 /// - `key` will have length in range `8..=64` bytes.
225 /// - `digest` will not be [`Digest::None`]
David Drysdaleed33ed12022-08-23 10:01:39 +0100226 fn begin(
227 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100228 key: OpaqueOr<hmac::Key>,
David Drysdaleed33ed12022-08-23 10:01:39 +0100229 digest: Digest,
230 ) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100231}
232
233/// Abstraction of AES-CMAC functionality. (Note that this is not exposed in the KeyMint HAL API
234/// directly, but is required for the CKDF operations involved in `ISharedSecret` negotiation.)
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000235pub trait AesCmac: Send {
David Drysdale9f27bc92022-06-10 15:53:32 +0100236 /// Create an AES-CMAC operation. Implementations can assume that `key` will have length
237 /// of either 16 (AES-128) or 32 (AES-256).
David Drysdale0b3938d2022-09-28 16:49:16 +0100238 fn begin(&self, key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100239}
240
241/// Abstraction of RSA functionality.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000242pub trait Rsa: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +0100243 /// Generate an RSA key. Key generation parameters are passed in for reference, to allow for
244 /// implementations that might have parameter-specific behaviour.
David Drysdale9f27bc92022-06-10 15:53:32 +0100245 fn generate_key(
246 &self,
247 rng: &mut dyn Rng,
248 key_size: KeySizeInBits,
David Drysdale0b3938d2022-09-28 16:49:16 +0100249 pub_exponent: RsaExponent,
250 params: &[keymint::KeyParam],
251 ) -> Result<KeyMaterial, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100252
253 /// Import an RSA key in PKCS#8 format, also returning the key size in bits and public exponent.
David Drysdale0b3938d2022-09-28 16:49:16 +0100254 /// Key import parameters are passed in for reference, to allow for implementations that might
255 /// have parameter-specific behaviour.
David Drysdale9f27bc92022-06-10 15:53:32 +0100256 fn import_pkcs8_key(
257 &self,
258 data: &[u8],
David Drysdale0b3938d2022-09-28 16:49:16 +0100259 _params: &[keymint::KeyParam],
260 ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error> {
David Drysdale0986c772022-11-03 08:12:53 +0000261 rsa::import_pkcs8_key(data)
David Drysdale0b3938d2022-09-28 16:49:16 +0100262 }
David Drysdale9f27bc92022-06-10 15:53:32 +0100263
Hasini Gunasinghed8518eb2022-11-16 23:50:22 +0000264 /// Return the public key data corresponds to the provided private `key`,
265 /// as an ASN.1 DER-encoded `SEQUENCE` as per RFC 3279 section 2.3.1:
266 /// ```asn1
267 /// RSAPublicKey ::= SEQUENCE {
268 /// modulus INTEGER, -- n
269 /// publicExponent INTEGER } -- e
270 /// ```
271 /// which is the `subjectPublicKey` to be included in `SubjectPublicKeyInfo`.
272 fn subject_public_key(&self, key: &OpaqueOr<rsa::Key>) -> Result<Vec<u8>, Error> {
273 // The default implementation only handles the `Explicit<rsa::Key>` variant.
274 let rsa_key = explicit!(key)?;
275 rsa_key.subject_public_key()
276 }
277
David Drysdale9f27bc92022-06-10 15:53:32 +0100278 /// Create an RSA decryption operation.
279 fn begin_decrypt(
280 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100281 key: OpaqueOr<rsa::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100282 mode: rsa::DecryptionMode,
David Drysdaleed33ed12022-08-23 10:01:39 +0100283 ) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100284
David Drysdalefc718252022-06-10 16:06:24 +0100285 /// Create an RSA signing operation. For [`rsa::SignMode::Pkcs1_1_5Padding(Digest::None)`] the
David Drysdale244b3842024-07-15 12:34:20 +0100286 /// implementation should reject (with `ErrorCode::InvalidInputLength`) accumulated input that
David Drysdale0b3938d2022-09-28 16:49:16 +0100287 /// is larger than the size of the RSA key less overhead
David Drysdalefc718252022-06-10 16:06:24 +0100288 /// ([`rsa::PKCS1_UNDIGESTED_SIGNATURE_PADDING_OVERHEAD`]).
David Drysdale9f27bc92022-06-10 15:53:32 +0100289 fn begin_sign(
290 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100291 key: OpaqueOr<rsa::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100292 mode: rsa::SignMode,
David Drysdaleed33ed12022-08-23 10:01:39 +0100293 ) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100294}
295
296/// Abstraction of EC functionality.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000297pub trait Ec: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +0100298 /// Generate an EC key for a NIST curve. Key generation parameters are passed in for reference,
299 /// to allow for implementations that might have parameter-specific behaviour.
David Drysdale9f27bc92022-06-10 15:53:32 +0100300 fn generate_nist_key(
301 &self,
302 rng: &mut dyn Rng,
303 curve: ec::NistCurve,
David Drysdale0b3938d2022-09-28 16:49:16 +0100304 params: &[keymint::KeyParam],
305 ) -> Result<KeyMaterial, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100306
David Drysdale0b3938d2022-09-28 16:49:16 +0100307 /// Generate an Ed25519 key. Key generation parameters are passed in for reference, to allow
308 /// for implementations that might have parameter-specific behaviour.
309 fn generate_ed25519_key(
310 &self,
311 rng: &mut dyn Rng,
312 params: &[keymint::KeyParam],
313 ) -> Result<KeyMaterial, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100314
David Drysdale0b3938d2022-09-28 16:49:16 +0100315 /// Generate an X25519 key. Key generation parameters are passed in for reference, to allow for
316 /// implementations that might have parameter-specific behaviour.
317 fn generate_x25519_key(
318 &self,
319 rng: &mut dyn Rng,
320 params: &[keymint::KeyParam],
321 ) -> Result<KeyMaterial, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100322
David Drysdale0b3938d2022-09-28 16:49:16 +0100323 /// Import an EC key in PKCS#8 format. Key import parameters are passed in for reference, to
324 /// allow for implementations that might have parameter-specific behaviour.
325 fn import_pkcs8_key(
326 &self,
327 data: &[u8],
David Drysdale0986c772022-11-03 08:12:53 +0000328 _params: &[keymint::KeyParam],
David Drysdale0b3938d2022-09-28 16:49:16 +0100329 ) -> Result<KeyMaterial, Error> {
David Drysdale0986c772022-11-03 08:12:53 +0000330 ec::import_pkcs8_key(data)
David Drysdale0b3938d2022-09-28 16:49:16 +0100331 }
David Drysdale9f27bc92022-06-10 15:53:32 +0100332
David Drysdale0b3938d2022-09-28 16:49:16 +0100333 /// Import a 32-byte raw Ed25519 key. Key import parameters are passed in for reference, to
334 /// allow for implementations that might have parameter-specific behaviour.
335 fn import_raw_ed25519_key(
336 &self,
337 data: &[u8],
338 _params: &[keymint::KeyParam],
339 ) -> Result<KeyMaterial, Error> {
David Drysdale0986c772022-11-03 08:12:53 +0000340 ec::import_raw_ed25519_key(data)
David Drysdale9f27bc92022-06-10 15:53:32 +0100341 }
342
David Drysdale0b3938d2022-09-28 16:49:16 +0100343 /// Import a 32-byte raw X25519 key. Key import parameters are passed in for reference, to
344 /// allow for implementations that might have parameter-specific behaviour.
345 fn import_raw_x25519_key(
346 &self,
347 data: &[u8],
348 _params: &[keymint::KeyParam],
349 ) -> Result<KeyMaterial, Error> {
David Drysdale0986c772022-11-03 08:12:53 +0000350 ec::import_raw_x25519_key(data)
David Drysdaleed33ed12022-08-23 10:01:39 +0100351 }
352
Hasini Gunasinghec939a9b2022-11-17 02:45:22 +0000353 /// Return the public key data that corresponds to the provided private `key`.
354 /// If `CurveType` of the key is `CurveType::Nist`, return the public key data
355 /// as a SEC-1 encoded uncompressed point as described in RFC 5480 section 2.1.
356 /// I.e. 0x04: uncompressed, followed by x || y coordinates.
357 ///
358 /// For other two curve types, return the raw public key data.
359 fn subject_public_key(&self, key: &OpaqueOr<ec::Key>) -> Result<Vec<u8>, Error> {
360 // The default implementation only handles the `Explicit<ec::Key>` variant.
361 let ec_key = explicit!(key)?;
362 match ec_key {
363 Key::P224(nist_key)
364 | Key::P256(nist_key)
365 | Key::P384(nist_key)
366 | Key::P521(nist_key) => {
David Drysdaleccc2d1b2023-05-04 12:22:01 +0100367 let ec_pvt_key = sec1::EcPrivateKey::from_der(nist_key.0.as_slice())
368 .map_err(|e| der_err!(e, "failed to parse DER NIST EC PrivateKey"))?;
Hasini Gunasinghec939a9b2022-11-17 02:45:22 +0000369 match ec_pvt_key.public_key {
370 Some(pub_key) => Ok(pub_key.to_vec()),
371 None => {
372 // Key structure doesn't include optional public key, so regenerate it.
373 let nist_curve: ec::NistCurve = ec_key.curve().try_into()?;
374 Ok(self.nist_public_key(nist_key, nist_curve)?)
375 }
376 }
377 }
378 Key::Ed25519(ed25519_key) => self.ed25519_public_key(ed25519_key),
379 Key::X25519(x25519_key) => self.x25519_public_key(x25519_key),
380 }
381 }
382
David Drysdaleed33ed12022-08-23 10:01:39 +0100383 /// Return the public key data that corresponds to the provided private `key`, as a SEC-1
David Drysdale0b3938d2022-09-28 16:49:16 +0100384 /// encoded uncompressed point.
David Drysdaleed33ed12022-08-23 10:01:39 +0100385 fn nist_public_key(&self, key: &ec::NistKey, curve: ec::NistCurve) -> Result<Vec<u8>, Error>;
386
387 /// Return the raw public key data that corresponds to the provided private `key`.
388 fn ed25519_public_key(&self, key: &ec::Ed25519Key) -> Result<Vec<u8>, Error>;
389
390 /// Return the raw public key data that corresponds to the provided private `key`.
391 fn x25519_public_key(&self, key: &ec::X25519Key) -> Result<Vec<u8>, Error>;
392
David Drysdale0b3938d2022-09-28 16:49:16 +0100393 /// Create an EC key agreement operation.
394 /// The accumulated input for the operation is expected to be the peer's
395 /// public key, provided as an ASN.1 DER-encoded `SubjectPublicKeyInfo`.
396 fn begin_agree(&self, key: OpaqueOr<ec::Key>) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100397
David Drysdalefc718252022-06-10 16:06:24 +0100398 /// Create an EC signing operation. For Ed25519 signing operations, the implementation should
David Drysdale244b3842024-07-15 12:34:20 +0100399 /// reject (with `ErrorCode::InvalidInputLength`) accumulated data that is larger than
David Drysdalefc718252022-06-10 16:06:24 +0100400 /// [`ec::MAX_ED25519_MSG_SIZE`].
David Drysdaleed33ed12022-08-23 10:01:39 +0100401 fn begin_sign(
402 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100403 key: OpaqueOr<ec::Key>,
David Drysdaleed33ed12022-08-23 10:01:39 +0100404 digest: Digest,
405 ) -> Result<Box<dyn AccumulatingOperation>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100406}
407
David Drysdaleed33ed12022-08-23 10:01:39 +0100408/// Abstraction of an in-progress operation that emits data as it progresses.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000409pub trait EmittingOperation: Send {
David Drysdaleed33ed12022-08-23 10:01:39 +0100410 /// Update operation with data.
411 fn update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error>;
David Drysdale9f27bc92022-06-10 15:53:32 +0100412
David Drysdaleed33ed12022-08-23 10:01:39 +0100413 /// Complete operation, consuming `self`.
David Drysdale9f27bc92022-06-10 15:53:32 +0100414 fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>;
415}
416
David Drysdaleed33ed12022-08-23 10:01:39 +0100417/// Abstraction of an in-progress operation that has authenticated associated data.
418pub trait AadOperation: EmittingOperation {
419 /// Update additional data. Implementations can assume that all calls to `update_aad()`
420 /// will occur before any calls to `update()` or `finish()`.
421 fn update_aad(&mut self, aad: &[u8]) -> Result<(), Error>;
422}
423
424/// Abstraction of an in-progress operation that only emits data when it completes.
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000425pub trait AccumulatingOperation: Send {
David Drysdale0b3938d2022-09-28 16:49:16 +0100426 /// Maximum size of accumulated input.
427 fn max_input_size(&self) -> Option<usize> {
428 None
429 }
430
David Drysdaleed33ed12022-08-23 10:01:39 +0100431 /// Update operation with data.
David Drysdale9f27bc92022-06-10 15:53:32 +0100432 fn update(&mut self, data: &[u8]) -> Result<(), Error>;
433
David Drysdaleed33ed12022-08-23 10:01:39 +0100434 /// Complete operation, consuming `self`.
David Drysdale9f27bc92022-06-10 15:53:32 +0100435 fn finish(self: Box<Self>) -> Result<Vec<u8>, Error>;
436}
437
David Drysdaleed33ed12022-08-23 10:01:39 +0100438/// Abstraction of HKDF key derivation with HMAC-SHA256.
439///
440/// A default implementation of this trait is available (in `crypto.rs`) for any type that
441/// implements [`Hmac`].
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000442pub trait Hkdf: Send {
David Drysdale63e6ad62023-05-05 17:41:08 +0100443 /// Perform combined HKDF using the input key material in `ikm`.
Orlando Arbildo97ee0582023-01-13 17:05:26 +0000444 fn hkdf(&self, salt: &[u8], ikm: &[u8], info: &[u8], out_len: usize) -> Result<Vec<u8>, Error> {
445 let prk = self.extract(salt, ikm)?;
446 self.expand(&prk, info, out_len)
447 }
448
David Drysdale63e6ad62023-05-05 17:41:08 +0100449 /// Perform the HKDF-Extract step on the input key material in `ikm`, using optional `salt`.
Orlando Arbildo97ee0582023-01-13 17:05:26 +0000450 fn extract(&self, salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>;
451
David Drysdale63e6ad62023-05-05 17:41:08 +0100452 /// Perform the HKDF-Expand step using the pseudo-random key in `prk`.
Orlando Arbildo97ee0582023-01-13 17:05:26 +0000453 fn expand(
454 &self,
455 prk: &OpaqueOr<hmac::Key>,
456 info: &[u8],
457 out_len: usize,
458 ) -> Result<Vec<u8>, Error>;
David Drysdaleed33ed12022-08-23 10:01:39 +0100459}
460
461/// Abstraction of CKDF key derivation with AES-CMAC KDF from NIST SP 800-108 in counter mode (see
462/// section 5.1).
463///
464/// Aa default implementation of this trait is available (in `crypto.rs`) for any type that
465/// implements [`AesCmac`].
Orlando Arbildo0eb2d942023-09-14 23:16:12 +0000466pub trait Ckdf: Send {
David Drysdale63e6ad62023-05-05 17:41:08 +0100467 /// Perform CKDF using the key material in `key`.
David Drysdaleed33ed12022-08-23 10:01:39 +0100468 fn ckdf(
469 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100470 key: &OpaqueOr<aes::Key>,
David Drysdaleed33ed12022-08-23 10:01:39 +0100471 label: &[u8],
472 chunks: &[&[u8]],
473 out_len: usize,
474 ) -> Result<Vec<u8>, Error>;
475}
476
David Drysdale83390142023-10-13 07:16:43 +0100477/// Abstraction for SHA-256 hashing.
478pub trait Sha256: Send {
479 /// Generate the SHA-256 input of `data`.
480 fn hash(&self, data: &[u8]) -> Result<[u8; 32], Error>;
481}
482
David Drysdale9f27bc92022-06-10 15:53:32 +0100483////////////////////////////////////////////////////////////
David Drysdaleced326a2022-10-31 07:24:24 +0000484// No-op implementations of traits. These implementations are
485// only intended for convenience during the process of porting
486// the KeyMint code to a new environment.
David Drysdale9f27bc92022-06-10 15:53:32 +0100487
David Drysdaleed33ed12022-08-23 10:01:39 +0100488/// Macro to emit an error log indicating that an unimplemented function
489/// has been invoked (and where it is).
Hasini Gunasinghe567751d2022-11-01 06:19:00 +0000490#[macro_export]
David Drysdale9f27bc92022-06-10 15:53:32 +0100491macro_rules! log_unimpl {
492 () => {
David Drysdaleced326a2022-10-31 07:24:24 +0000493 error!("{}:{}: Unimplemented placeholder KeyMint trait method invoked!", file!(), line!(),);
David Drysdale9f27bc92022-06-10 15:53:32 +0100494 };
495}
David Drysdaleed33ed12022-08-23 10:01:39 +0100496
497/// Mark a method as unimplemented (log error, return `ErrorCode::Unimplemented`)
Hasini Gunasinghe567751d2022-11-01 06:19:00 +0000498#[macro_export]
David Drysdale9f27bc92022-06-10 15:53:32 +0100499macro_rules! unimpl {
500 () => {
501 log_unimpl!();
502 return Err(Error::Hal(
David Drysdale0b3938d2022-09-28 16:49:16 +0100503 kmr_wire::keymint::ErrorCode::Unimplemented,
David Drysdaleced326a2022-10-31 07:24:24 +0000504 alloc::format!("{}:{}: method unimplemented", file!(), line!()),
David Drysdale9f27bc92022-06-10 15:53:32 +0100505 ));
506 };
507}
508
David Drysdale63e6ad62023-05-05 17:41:08 +0100509/// Stub implementation of [`Rng`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100510pub struct NoOpRng;
511impl Rng for NoOpRng {
512 fn add_entropy(&mut self, _data: &[u8]) {
513 log_unimpl!();
514 }
515 fn fill_bytes(&mut self, _dest: &mut [u8]) {
516 log_unimpl!();
517 }
518}
519
David Drysdale63e6ad62023-05-05 17:41:08 +0100520/// Stub implementation of [`ConstTimeEq`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100521#[derive(Clone)]
522pub struct InsecureEq;
523impl ConstTimeEq for InsecureEq {
524 fn eq(&self, left: &[u8], right: &[u8]) -> bool {
525 warn!("Insecure comparison operation performed");
526 left == right
527 }
528}
529
David Drysdale63e6ad62023-05-05 17:41:08 +0100530/// Stub implementation of [`MonotonicClock`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100531pub struct NoOpClock;
532impl MonotonicClock for NoOpClock {
533 fn now(&self) -> MillisecondsSinceEpoch {
534 log_unimpl!();
535 MillisecondsSinceEpoch(0)
536 }
537}
538
David Drysdale63e6ad62023-05-05 17:41:08 +0100539/// Stub implementation of [`Aes`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100540pub struct NoOpAes;
541impl Aes for NoOpAes {
542 fn begin(
543 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100544 _key: OpaqueOr<aes::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100545 _mode: aes::CipherMode,
546 _dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100547 ) -> Result<Box<dyn EmittingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100548 unimpl!();
549 }
550 fn begin_aead(
551 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100552 _key: OpaqueOr<aes::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100553 _mode: aes::GcmMode,
554 _dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100555 ) -> Result<Box<dyn AadOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100556 unimpl!();
557 }
558}
559
David Drysdale63e6ad62023-05-05 17:41:08 +0100560/// Stub implementation of [`Des`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100561pub struct NoOpDes;
562impl Des for NoOpDes {
563 fn begin(
564 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100565 _key: OpaqueOr<des::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100566 _mode: des::Mode,
567 _dir: SymmetricOperation,
David Drysdaleed33ed12022-08-23 10:01:39 +0100568 ) -> Result<Box<dyn EmittingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100569 unimpl!();
570 }
571}
572
David Drysdale63e6ad62023-05-05 17:41:08 +0100573/// Stub implementation of [`Hmac`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100574pub struct NoOpHmac;
575impl Hmac for NoOpHmac {
David Drysdaleed33ed12022-08-23 10:01:39 +0100576 fn begin(
577 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100578 _key: OpaqueOr<hmac::Key>,
David Drysdaleed33ed12022-08-23 10:01:39 +0100579 _digest: Digest,
580 ) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100581 unimpl!();
582 }
583}
584
David Drysdale244b3842024-07-15 12:34:20 +0100585/// Stub implementation of [`AesCmac`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100586pub struct NoOpAesCmac;
587impl AesCmac for NoOpAesCmac {
David Drysdale0b3938d2022-09-28 16:49:16 +0100588 fn begin(&self, _key: OpaqueOr<aes::Key>) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100589 unimpl!();
590 }
591}
592
David Drysdale63e6ad62023-05-05 17:41:08 +0100593/// Stub implementation of [`Rsa`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100594pub struct NoOpRsa;
595impl Rsa for NoOpRsa {
596 fn generate_key(
597 &self,
598 _rng: &mut dyn Rng,
599 _key_size: KeySizeInBits,
David Drysdale0b3938d2022-09-28 16:49:16 +0100600 _pub_exponent: RsaExponent,
601 _params: &[keymint::KeyParam],
602 ) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100603 unimpl!();
604 }
605
David Drysdale9f27bc92022-06-10 15:53:32 +0100606 fn begin_decrypt(
607 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100608 _key: OpaqueOr<rsa::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100609 _mode: rsa::DecryptionMode,
David Drysdaleed33ed12022-08-23 10:01:39 +0100610 ) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100611 unimpl!();
612 }
613
614 fn begin_sign(
615 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100616 _key: OpaqueOr<rsa::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100617 _mode: rsa::SignMode,
David Drysdaleed33ed12022-08-23 10:01:39 +0100618 ) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100619 unimpl!();
620 }
621}
622
David Drysdale63e6ad62023-05-05 17:41:08 +0100623/// Stub implementation of [`Ec`].
David Drysdale9f27bc92022-06-10 15:53:32 +0100624pub struct NoOpEc;
625impl Ec for NoOpEc {
626 fn generate_nist_key(
627 &self,
628 _rng: &mut dyn Rng,
629 _curve: ec::NistCurve,
David Drysdale0b3938d2022-09-28 16:49:16 +0100630 _params: &[keymint::KeyParam],
631 ) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100632 unimpl!();
633 }
634
David Drysdale0b3938d2022-09-28 16:49:16 +0100635 fn generate_ed25519_key(
David Drysdale9f27bc92022-06-10 15:53:32 +0100636 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100637 _rng: &mut dyn Rng,
638 _params: &[keymint::KeyParam],
639 ) -> Result<KeyMaterial, Error> {
640 unimpl!();
641 }
642
643 fn generate_x25519_key(
644 &self,
645 _rng: &mut dyn Rng,
646 _params: &[keymint::KeyParam],
647 ) -> Result<KeyMaterial, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100648 unimpl!();
649 }
650
David Drysdaleed33ed12022-08-23 10:01:39 +0100651 fn nist_public_key(&self, _key: &ec::NistKey, _curve: ec::NistCurve) -> Result<Vec<u8>, Error> {
652 unimpl!();
653 }
654
655 fn ed25519_public_key(&self, _key: &ec::Ed25519Key) -> Result<Vec<u8>, Error> {
656 unimpl!();
657 }
658
659 fn x25519_public_key(&self, _key: &ec::X25519Key) -> Result<Vec<u8>, Error> {
660 unimpl!();
661 }
662
David Drysdale0b3938d2022-09-28 16:49:16 +0100663 fn begin_agree(
664 &self,
665 _key: OpaqueOr<ec::Key>,
666 ) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100667 unimpl!();
668 }
669
670 fn begin_sign(
671 &self,
David Drysdale0b3938d2022-09-28 16:49:16 +0100672 _key: OpaqueOr<ec::Key>,
David Drysdale9f27bc92022-06-10 15:53:32 +0100673 _digest: Digest,
David Drysdaleed33ed12022-08-23 10:01:39 +0100674 ) -> Result<Box<dyn AccumulatingOperation>, Error> {
David Drysdale9f27bc92022-06-10 15:53:32 +0100675 unimpl!();
676 }
677}
David Drysdale0cf92d22022-06-10 15:56:42 +0100678
David Drysdale63e6ad62023-05-05 17:41:08 +0100679/// Stub implementation of [`keyblob::SecureDeletionSecretManager`].
David Drysdale0cf92d22022-06-10 15:56:42 +0100680pub struct NoOpSdsManager;
681impl keyblob::SecureDeletionSecretManager for NoOpSdsManager {
David Drysdale0b3938d2022-09-28 16:49:16 +0100682 fn get_or_create_factory_reset_secret(
683 &mut self,
684 _rng: &mut dyn Rng,
685 ) -> Result<keyblob::SecureDeletionData, Error> {
686 unimpl!();
687 }
688
689 fn get_factory_reset_secret(&self) -> Result<keyblob::SecureDeletionData, Error> {
690 unimpl!();
691 }
692
David Drysdale0cf92d22022-06-10 15:56:42 +0100693 fn new_secret(
694 &mut self,
695 _rng: &mut dyn Rng,
David Drysdale92d887b2022-11-30 12:14:01 +0000696 _purpose: keyblob::SlotPurpose,
David Drysdale0cf92d22022-06-10 15:56:42 +0100697 ) -> Result<(keyblob::SecureDeletionSlot, keyblob::SecureDeletionData), Error> {
698 unimpl!();
699 }
700
701 fn get_secret(
702 &self,
703 _slot: keyblob::SecureDeletionSlot,
704 ) -> Result<keyblob::SecureDeletionData, Error> {
705 unimpl!();
706 }
707 fn delete_secret(&mut self, _slot: keyblob::SecureDeletionSlot) -> Result<(), Error> {
708 unimpl!();
709 }
710
711 fn delete_all(&mut self) {
712 log_unimpl!();
713 }
714}