• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Code for dealing with HAL-defined types, especially conversions to/from internal types.
2 //!
3 //! The internal code for KeyMint uses its own type definitions, not the HAL-defined autogenerated
4 //! types, for two reasons:
5 //!
6 //! - The auto-generated types impose a dependency on Binder which is not appropriate for
7 //!   code being built for a secure environment.
8 //! - The auto-generated types are not idiomatic Rust, and have reduced type safety.
9 //!
10 //! This module includes code to convert between HAL types (re-used under `kmr_hal::hal`) and
11 //! internal types (under `kmr_wire`), via the [`Fromm`] / [`TryFromm`], [`Innto`] and
12 //! [`TryInnto`] traits (which are deliberately misspelled to avoid a clash with standard
13 //! traits -- see below).
14 //!
15 //! - Going from wire=>HAL is an infallible conversion, as the wire types are stricter.
16 //! - Going from HAL=>wire is often a fallible conversion, as there may be "enum" values
17 //!   that are not in range.
18 //!
19 //! This module (and `kmr_wire`) must be kept in sync with the Android KeyMint HAL definition.
20 
21 #![allow(non_snake_case)]
22 
23 use crate::binder;
24 use keymint::{KeyParameterValue::KeyParameterValue, Tag::Tag, TagType::TagType};
25 use kmr_wire as wire;
26 use kmr_wire::{keymint::DateTime, keymint::KeyParam, KeySizeInBits, RsaExponent};
27 use log::{error, warn};
28 use std::convert::TryFrom;
29 use std::ffi::CString;
30 
31 pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint;
32 pub use android_hardware_security_rkp::aidl::android::hardware::security::keymint as rkp;
33 pub use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock;
34 pub use android_hardware_security_sharedsecret::aidl::android::hardware::security::sharedsecret;
35 
36 #[cfg(test)]
37 mod tests;
38 
39 /// Emit a failure for a failed type conversion.
40 #[inline]
failed_conversion(_err: kmr_wire::ValueNotRecognized) -> binder::Status41 pub fn failed_conversion(_err: kmr_wire::ValueNotRecognized) -> binder::Status {
42     binder::Status::new_service_specific_error(
43         keymint::ErrorCode::ErrorCode::INVALID_ARGUMENT.0,
44         Some(&CString::new("conversion from HAL type to internal type failed").unwrap()),
45     )
46 }
47 
48 /// Determine the tag type for a tag, based on the top 4 bits of the tag number.
tag_type(tag: Tag) -> TagType49 pub fn tag_type(tag: Tag) -> TagType {
50     match ((tag.0 as u32) & 0xf0000000u32) as i32 {
51         x if x == TagType::ENUM.0 => TagType::ENUM,
52         x if x == TagType::ENUM_REP.0 => TagType::ENUM_REP,
53         x if x == TagType::UINT.0 => TagType::UINT,
54         x if x == TagType::UINT_REP.0 => TagType::UINT_REP,
55         x if x == TagType::ULONG.0 => TagType::ULONG,
56         x if x == TagType::DATE.0 => TagType::DATE,
57         x if x == TagType::BOOL.0 => TagType::BOOL,
58         x if x == TagType::BIGNUM.0 => TagType::BIGNUM,
59         x if x == TagType::BYTES.0 => TagType::BYTES,
60         x if x == TagType::ULONG_REP.0 => TagType::ULONG_REP,
61         _ => TagType::INVALID,
62     }
63 }
64 
65 // Neither the `kmr_wire` types nor the `hal` types are local to this crate, which means that Rust's
66 // orphan rule means we cannot implement the standard conversion traits.  So instead define our own
67 // equivalent conversion traits that are local, and for which we're allowed to provide
68 // implementations.  Give them an odd name to avoid confusion with the standard traits.
69 
70 /// Local equivalent of `From` trait, with a different name to avoid clashes.
71 pub trait Fromm<T>: Sized {
fromm(val: T) -> Self72     fn fromm(val: T) -> Self;
73 }
74 /// Local equivalent of `TryFrom` trait, with a different name to avoid clashes.
75 pub trait TryFromm<T>: Sized {
76     type Error;
try_fromm(val: T) -> Result<Self, Self::Error>77     fn try_fromm(val: T) -> Result<Self, Self::Error>;
78 }
79 /// Local equivalent of `Into` trait, with a different name to avoid clashes.
80 pub trait Innto<T> {
innto(self) -> T81     fn innto(self) -> T;
82 }
83 /// Local equivalent of `TryInto` trait, with a different name to avoid clashes.
84 pub trait TryInnto<T> {
85     type Error;
try_innto(self) -> Result<T, Self::Error>86     fn try_innto(self) -> Result<T, Self::Error>;
87 }
88 /// Blanket implementation of `Innto` from `Fromm`
89 impl<T, U> Innto<U> for T
90 where
91     U: Fromm<T>,
92 {
innto(self) -> U93     fn innto(self) -> U {
94         U::fromm(self)
95     }
96 }
97 /// Blanket implementation of `TryInnto` from `TryFromm`
98 impl<T, U> TryInnto<U> for T
99 where
100     U: TryFromm<T>,
101 {
102     type Error = U::Error;
try_innto(self) -> Result<U, Self::Error>103     fn try_innto(self) -> Result<U, Self::Error> {
104         U::try_fromm(self)
105     }
106 }
107 /// Blanket implementation of `Fromm<Vec<T>>` from `Fromm<T>`
108 impl<T, U> Fromm<Vec<T>> for Vec<U>
109 where
110     U: Fromm<T>,
111 {
fromm(val: Vec<T>) -> Vec<U>112     fn fromm(val: Vec<T>) -> Vec<U> {
113         val.into_iter().map(|t| <U>::fromm(t)).collect()
114     }
115 }
116 
117 // Conversions from `kmr_wire` types into the equivalent types in the auto-generated HAL code. These
118 // conversions are infallible, because the range of the `wire` types is strictly contained within
119 // the HAL types.
120 
121 impl Fromm<wire::sharedsecret::SharedSecretParameters>
122     for sharedsecret::SharedSecretParameters::SharedSecretParameters
123 {
fromm(val: wire::sharedsecret::SharedSecretParameters) -> Self124     fn fromm(val: wire::sharedsecret::SharedSecretParameters) -> Self {
125         Self { seed: val.seed, nonce: val.nonce }
126     }
127 }
128 impl Fromm<wire::secureclock::Timestamp> for secureclock::Timestamp::Timestamp {
fromm(val: wire::secureclock::Timestamp) -> Self129     fn fromm(val: wire::secureclock::Timestamp) -> Self {
130         Self { milliSeconds: val.milliseconds }
131     }
132 }
133 impl Fromm<wire::secureclock::TimeStampToken> for secureclock::TimeStampToken::TimeStampToken {
fromm(val: wire::secureclock::TimeStampToken) -> Self134     fn fromm(val: wire::secureclock::TimeStampToken) -> Self {
135         Self { challenge: val.challenge, timestamp: val.timestamp.innto(), mac: val.mac }
136     }
137 }
138 impl Fromm<wire::keymint::Certificate> for keymint::Certificate::Certificate {
fromm(val: wire::keymint::Certificate) -> Self139     fn fromm(val: wire::keymint::Certificate) -> Self {
140         Self { encodedCertificate: val.encoded_certificate }
141     }
142 }
143 impl Fromm<wire::rpc::DeviceInfo> for rkp::DeviceInfo::DeviceInfo {
fromm(val: wire::rpc::DeviceInfo) -> Self144     fn fromm(val: wire::rpc::DeviceInfo) -> Self {
145         Self { deviceInfo: val.device_info }
146     }
147 }
148 impl Fromm<wire::keymint::HardwareAuthToken> for keymint::HardwareAuthToken::HardwareAuthToken {
fromm(val: wire::keymint::HardwareAuthToken) -> Self149     fn fromm(val: wire::keymint::HardwareAuthToken) -> Self {
150         Self {
151             challenge: val.challenge,
152             userId: val.user_id,
153             authenticatorId: val.authenticator_id,
154             authenticatorType: val.authenticator_type.innto(),
155             timestamp: val.timestamp.innto(),
156             mac: val.mac,
157         }
158     }
159 }
160 impl Fromm<wire::keymint::KeyCharacteristics> for keymint::KeyCharacteristics::KeyCharacteristics {
fromm(val: wire::keymint::KeyCharacteristics) -> Self161     fn fromm(val: wire::keymint::KeyCharacteristics) -> Self {
162         Self {
163             securityLevel: val.security_level.innto(),
164             authorizations: val.authorizations.innto(),
165         }
166     }
167 }
168 impl Fromm<wire::keymint::KeyCreationResult> for keymint::KeyCreationResult::KeyCreationResult {
fromm(val: wire::keymint::KeyCreationResult) -> Self169     fn fromm(val: wire::keymint::KeyCreationResult) -> Self {
170         Self {
171             keyBlob: val.key_blob,
172             keyCharacteristics: val.key_characteristics.innto(),
173             certificateChain: val.certificate_chain.innto(),
174         }
175     }
176 }
177 impl Fromm<wire::keymint::KeyMintHardwareInfo>
178     for keymint::KeyMintHardwareInfo::KeyMintHardwareInfo
179 {
fromm(val: wire::keymint::KeyMintHardwareInfo) -> Self180     fn fromm(val: wire::keymint::KeyMintHardwareInfo) -> Self {
181         Self {
182             versionNumber: val.version_number,
183             securityLevel: val.security_level.innto(),
184             keyMintName: val.key_mint_name,
185             keyMintAuthorName: val.key_mint_author_name,
186             timestampTokenRequired: val.timestamp_token_required,
187         }
188     }
189 }
190 impl Fromm<wire::rpc::MacedPublicKey> for rkp::MacedPublicKey::MacedPublicKey {
fromm(val: wire::rpc::MacedPublicKey) -> Self191     fn fromm(val: wire::rpc::MacedPublicKey) -> Self {
192         Self { macedKey: val.maced_key }
193     }
194 }
195 impl Fromm<wire::rpc::ProtectedData> for rkp::ProtectedData::ProtectedData {
fromm(val: wire::rpc::ProtectedData) -> Self196     fn fromm(val: wire::rpc::ProtectedData) -> Self {
197         Self { protectedData: val.protected_data }
198     }
199 }
200 impl Fromm<wire::rpc::HardwareInfo> for rkp::RpcHardwareInfo::RpcHardwareInfo {
fromm(val: wire::rpc::HardwareInfo) -> Self201     fn fromm(val: wire::rpc::HardwareInfo) -> Self {
202         Self {
203             versionNumber: val.version_number,
204             rpcAuthorName: val.rpc_author_name,
205             supportedEekCurve: val.supported_eek_curve as i32,
206             uniqueId: val.unique_id,
207             supportedNumKeysInCsr: val.supported_num_keys_in_csr,
208         }
209     }
210 }
211 
212 impl Fromm<wire::keymint::KeyParam> for keymint::KeyParameter::KeyParameter {
fromm(val: wire::keymint::KeyParam) -> Self213     fn fromm(val: wire::keymint::KeyParam) -> Self {
214         let (tag, value) = match val {
215             // Enum-holding variants.
216             KeyParam::Purpose(v) => (Tag::PURPOSE, KeyParameterValue::KeyPurpose(v.innto())),
217             KeyParam::Algorithm(v) => (Tag::ALGORITHM, KeyParameterValue::Algorithm(v.innto())),
218             KeyParam::BlockMode(v) => (Tag::BLOCK_MODE, KeyParameterValue::BlockMode(v.innto())),
219             KeyParam::Digest(v) => (Tag::DIGEST, KeyParameterValue::Digest(v.innto())),
220             KeyParam::Padding(v) => (Tag::PADDING, KeyParameterValue::PaddingMode(v.innto())),
221             KeyParam::EcCurve(v) => (Tag::EC_CURVE, KeyParameterValue::EcCurve(v.innto())),
222             KeyParam::RsaOaepMgfDigest(v) => {
223                 (Tag::RSA_OAEP_MGF_DIGEST, KeyParameterValue::Digest(v.innto()))
224             }
225             KeyParam::Origin(v) => (Tag::ORIGIN, KeyParameterValue::Origin(v.innto())),
226 
227             // `u32`-holding variants.
228             KeyParam::KeySize(v) => (Tag::KEY_SIZE, KeyParameterValue::Integer(v.0 as i32)),
229             KeyParam::MinMacLength(v) => {
230                 (Tag::MIN_MAC_LENGTH, KeyParameterValue::Integer(v as i32))
231             }
232             KeyParam::MaxUsesPerBoot(v) => {
233                 (Tag::MAX_USES_PER_BOOT, KeyParameterValue::Integer(v as i32))
234             }
235             KeyParam::UsageCountLimit(v) => {
236                 (Tag::USAGE_COUNT_LIMIT, KeyParameterValue::Integer(v as i32))
237             }
238             KeyParam::UserId(v) => (Tag::USER_ID, KeyParameterValue::Integer(v as i32)),
239             KeyParam::UserAuthType(v) => {
240                 // Special case: auth type is a bitmask, so the Rust types use `u32` but the HAL
241                 // type has an "enum".
242                 (
243                     Tag::USER_AUTH_TYPE,
244                     KeyParameterValue::HardwareAuthenticatorType(
245                         keymint::HardwareAuthenticatorType::HardwareAuthenticatorType(v as i32),
246                     ),
247                 )
248             }
249             KeyParam::AuthTimeout(v) => (Tag::AUTH_TIMEOUT, KeyParameterValue::Integer(v as i32)),
250             KeyParam::OsVersion(v) => (Tag::OS_VERSION, KeyParameterValue::Integer(v as i32)),
251             KeyParam::OsPatchlevel(v) => (Tag::OS_PATCHLEVEL, KeyParameterValue::Integer(v as i32)),
252             KeyParam::VendorPatchlevel(v) => {
253                 (Tag::VENDOR_PATCHLEVEL, KeyParameterValue::Integer(v as i32))
254             }
255             KeyParam::BootPatchlevel(v) => {
256                 (Tag::BOOT_PATCHLEVEL, KeyParameterValue::Integer(v as i32))
257             }
258             KeyParam::MacLength(v) => (Tag::MAC_LENGTH, KeyParameterValue::Integer(v as i32)),
259             KeyParam::MaxBootLevel(v) => {
260                 (Tag::MAX_BOOT_LEVEL, KeyParameterValue::Integer(v as i32))
261             }
262 
263             // `u64`-holding variants.
264             KeyParam::RsaPublicExponent(v) => {
265                 (Tag::RSA_PUBLIC_EXPONENT, KeyParameterValue::LongInteger(v.0 as i64))
266             }
267             KeyParam::UserSecureId(v) => {
268                 (Tag::USER_SECURE_ID, KeyParameterValue::LongInteger(v as i64))
269             }
270 
271             // `true`-holding variants.
272             KeyParam::CallerNonce => (Tag::CALLER_NONCE, KeyParameterValue::BoolValue(true)),
273             KeyParam::IncludeUniqueId => {
274                 (Tag::INCLUDE_UNIQUE_ID, KeyParameterValue::BoolValue(true))
275             }
276             KeyParam::BootloaderOnly => (Tag::BOOTLOADER_ONLY, KeyParameterValue::BoolValue(true)),
277             KeyParam::RollbackResistance => {
278                 (Tag::ROLLBACK_RESISTANCE, KeyParameterValue::BoolValue(true))
279             }
280             KeyParam::EarlyBootOnly => (Tag::EARLY_BOOT_ONLY, KeyParameterValue::BoolValue(true)),
281             KeyParam::AllowWhileOnBody => {
282                 (Tag::ALLOW_WHILE_ON_BODY, KeyParameterValue::BoolValue(true))
283             }
284             KeyParam::NoAuthRequired => (Tag::NO_AUTH_REQUIRED, KeyParameterValue::BoolValue(true)),
285             KeyParam::TrustedUserPresenceRequired => {
286                 (Tag::TRUSTED_USER_PRESENCE_REQUIRED, KeyParameterValue::BoolValue(true))
287             }
288             KeyParam::TrustedConfirmationRequired => {
289                 (Tag::TRUSTED_CONFIRMATION_REQUIRED, KeyParameterValue::BoolValue(true))
290             }
291             KeyParam::UnlockedDeviceRequired => {
292                 (Tag::UNLOCKED_DEVICE_REQUIRED, KeyParameterValue::BoolValue(true))
293             }
294             KeyParam::DeviceUniqueAttestation => {
295                 (Tag::DEVICE_UNIQUE_ATTESTATION, KeyParameterValue::BoolValue(true))
296             }
297             KeyParam::StorageKey => (Tag::STORAGE_KEY, KeyParameterValue::BoolValue(true)),
298             KeyParam::ResetSinceIdRotation => {
299                 (Tag::RESET_SINCE_ID_ROTATION, KeyParameterValue::BoolValue(true))
300             }
301 
302             // `DateTime`-holding variants.
303             KeyParam::ActiveDatetime(v) => {
304                 (Tag::ACTIVE_DATETIME, KeyParameterValue::DateTime(v.ms_since_epoch))
305             }
306             KeyParam::OriginationExpireDatetime(v) => {
307                 (Tag::ORIGINATION_EXPIRE_DATETIME, KeyParameterValue::DateTime(v.ms_since_epoch))
308             }
309             KeyParam::UsageExpireDatetime(v) => {
310                 (Tag::USAGE_EXPIRE_DATETIME, KeyParameterValue::DateTime(v.ms_since_epoch))
311             }
312             KeyParam::CreationDatetime(v) => {
313                 (Tag::CREATION_DATETIME, KeyParameterValue::DateTime(v.ms_since_epoch))
314             }
315             KeyParam::CertificateNotBefore(v) => {
316                 (Tag::CERTIFICATE_NOT_BEFORE, KeyParameterValue::DateTime(v.ms_since_epoch))
317             }
318             KeyParam::CertificateNotAfter(v) => {
319                 (Tag::CERTIFICATE_NOT_AFTER, KeyParameterValue::DateTime(v.ms_since_epoch))
320             }
321 
322             // `Vec<u8>`-holding variants.
323             KeyParam::ApplicationId(v) => (Tag::APPLICATION_ID, KeyParameterValue::Blob(v)),
324             KeyParam::ApplicationData(v) => (Tag::APPLICATION_DATA, KeyParameterValue::Blob(v)),
325             KeyParam::AttestationChallenge(v) => {
326                 (Tag::ATTESTATION_CHALLENGE, KeyParameterValue::Blob(v))
327             }
328             KeyParam::AttestationApplicationId(v) => {
329                 (Tag::ATTESTATION_APPLICATION_ID, KeyParameterValue::Blob(v))
330             }
331             KeyParam::AttestationIdBrand(v) => {
332                 (Tag::ATTESTATION_ID_BRAND, KeyParameterValue::Blob(v))
333             }
334             KeyParam::AttestationIdDevice(v) => {
335                 (Tag::ATTESTATION_ID_DEVICE, KeyParameterValue::Blob(v))
336             }
337             KeyParam::AttestationIdProduct(v) => {
338                 (Tag::ATTESTATION_ID_PRODUCT, KeyParameterValue::Blob(v))
339             }
340             KeyParam::AttestationIdSerial(v) => {
341                 (Tag::ATTESTATION_ID_SERIAL, KeyParameterValue::Blob(v))
342             }
343             KeyParam::AttestationIdImei(v) => {
344                 (Tag::ATTESTATION_ID_IMEI, KeyParameterValue::Blob(v))
345             }
346             KeyParam::AttestationIdSecondImei(v) => {
347                 (Tag::ATTESTATION_ID_SECOND_IMEI, KeyParameterValue::Blob(v))
348             }
349             KeyParam::AttestationIdMeid(v) => {
350                 (Tag::ATTESTATION_ID_MEID, KeyParameterValue::Blob(v))
351             }
352             KeyParam::AttestationIdManufacturer(v) => {
353                 (Tag::ATTESTATION_ID_MANUFACTURER, KeyParameterValue::Blob(v))
354             }
355             KeyParam::AttestationIdModel(v) => {
356                 (Tag::ATTESTATION_ID_MODEL, KeyParameterValue::Blob(v))
357             }
358             KeyParam::Nonce(v) => (Tag::NONCE, KeyParameterValue::Blob(v)),
359             KeyParam::RootOfTrust(v) => (Tag::ROOT_OF_TRUST, KeyParameterValue::Blob(v)),
360             KeyParam::CertificateSerial(v) => (Tag::CERTIFICATE_SERIAL, KeyParameterValue::Blob(v)),
361             KeyParam::CertificateSubject(v) => {
362                 (Tag::CERTIFICATE_SUBJECT, KeyParameterValue::Blob(v))
363             }
364         };
365         Self { tag, value }
366     }
367 }
368 
369 // Conversions from auto-generated HAL types into the equivalent types from `kmr_wire`.  These
370 // conversions are generally fallible, because the "enum" types generated for the HAL are actually
371 // `i32` values, which may contain invalid values.
372 
373 impl Fromm<secureclock::TimeStampToken::TimeStampToken> for wire::secureclock::TimeStampToken {
fromm(val: secureclock::TimeStampToken::TimeStampToken) -> Self374     fn fromm(val: secureclock::TimeStampToken::TimeStampToken) -> Self {
375         Self { challenge: val.challenge, timestamp: val.timestamp.innto(), mac: val.mac }
376     }
377 }
378 impl Fromm<secureclock::Timestamp::Timestamp> for wire::secureclock::Timestamp {
fromm(val: secureclock::Timestamp::Timestamp) -> Self379     fn fromm(val: secureclock::Timestamp::Timestamp) -> Self {
380         Self { milliseconds: val.milliSeconds }
381     }
382 }
383 impl Fromm<sharedsecret::SharedSecretParameters::SharedSecretParameters>
384     for wire::sharedsecret::SharedSecretParameters
385 {
fromm(val: sharedsecret::SharedSecretParameters::SharedSecretParameters) -> Self386     fn fromm(val: sharedsecret::SharedSecretParameters::SharedSecretParameters) -> Self {
387         Self { seed: val.seed, nonce: val.nonce }
388     }
389 }
390 impl TryFromm<keymint::AttestationKey::AttestationKey> for wire::keymint::AttestationKey {
391     type Error = wire::ValueNotRecognized;
try_fromm(val: keymint::AttestationKey::AttestationKey) -> Result<Self, Self::Error>392     fn try_fromm(val: keymint::AttestationKey::AttestationKey) -> Result<Self, Self::Error> {
393         Ok(Self {
394             key_blob: val.keyBlob,
395             attest_key_params: val
396                 .attestKeyParams // Vec<KeyParameter>
397                 .into_iter() // Iter<KeyParameter>
398                 .filter_map(|p| (&p).try_innto().transpose())
399                 .collect::<Result<Vec<KeyParam>, _>>()?,
400             issuer_subject_name: val.issuerSubjectName,
401         })
402     }
403 }
404 impl TryFromm<keymint::HardwareAuthToken::HardwareAuthToken> for wire::keymint::HardwareAuthToken {
405     type Error = wire::ValueNotRecognized;
try_fromm(val: keymint::HardwareAuthToken::HardwareAuthToken) -> Result<Self, Self::Error>406     fn try_fromm(val: keymint::HardwareAuthToken::HardwareAuthToken) -> Result<Self, Self::Error> {
407         Ok(Self {
408             challenge: val.challenge,
409             user_id: val.userId,
410             authenticator_id: val.authenticatorId,
411             authenticator_type: val.authenticatorType.try_innto()?,
412             timestamp: val.timestamp.innto(),
413             mac: val.mac,
414         })
415     }
416 }
417 impl Fromm<rkp::MacedPublicKey::MacedPublicKey> for wire::rpc::MacedPublicKey {
fromm(val: rkp::MacedPublicKey::MacedPublicKey) -> Self418     fn fromm(val: rkp::MacedPublicKey::MacedPublicKey) -> Self {
419         Self { maced_key: val.macedKey }
420     }
421 }
422 impl Fromm<&rkp::MacedPublicKey::MacedPublicKey> for wire::rpc::MacedPublicKey {
fromm(val: &rkp::MacedPublicKey::MacedPublicKey) -> Self423     fn fromm(val: &rkp::MacedPublicKey::MacedPublicKey) -> Self {
424         Self { maced_key: val.macedKey.to_vec() }
425     }
426 }
427 
428 macro_rules! value_of {
429     {
430         $val:expr, $variant:ident
431     } => {
432         if let keymint::KeyParameterValue::KeyParameterValue::$variant(v) = $val.value {
433             Ok(v)
434         } else {
435             error!("failed to convert parameter '{}' with value {:?}", stringify!($val), $val);
436             Err(wire::ValueNotRecognized)
437         }
438     }
439 }
440 
441 macro_rules! check_bool {
442     {
443         $val:expr
444     } => {
445         if let keymint::KeyParameterValue::KeyParameterValue::BoolValue(true) = $val.value {
446             Ok(())
447         } else {
448             Err(wire::ValueNotRecognized)
449         }
450     }
451 }
452 
453 macro_rules! clone_blob {
454     {
455         $val:expr
456     } => {
457         if let keymint::KeyParameterValue::KeyParameterValue::Blob(b) = &$val.value {
458             Ok(b.clone())
459         } else {
460             Err(wire::ValueNotRecognized)
461         }
462     }
463 }
464 
465 /// Converting a HAL `KeyParameter` to a wire `KeyParam` may fail (producing an `Err`) but may also
466 /// silently drop unknown tags (producing `Ok(None)`)
467 impl TryFromm<&keymint::KeyParameter::KeyParameter> for Option<KeyParam> {
468     type Error = wire::ValueNotRecognized;
try_fromm(val: &keymint::KeyParameter::KeyParameter) -> Result<Self, Self::Error>469     fn try_fromm(val: &keymint::KeyParameter::KeyParameter) -> Result<Self, Self::Error> {
470         Ok(match val.tag {
471             // Enum-holding variants.
472             keymint::Tag::Tag::PURPOSE => {
473                 Some(KeyParam::Purpose(value_of!(val, KeyPurpose)?.try_innto()?))
474             }
475             keymint::Tag::Tag::ALGORITHM => {
476                 Some(KeyParam::Algorithm(value_of!(val, Algorithm)?.try_innto()?))
477             }
478             keymint::Tag::Tag::BLOCK_MODE => {
479                 Some(KeyParam::BlockMode(value_of!(val, BlockMode)?.try_innto()?))
480             }
481             keymint::Tag::Tag::DIGEST => {
482                 Some(KeyParam::Digest(value_of!(val, Digest)?.try_innto()?))
483             }
484             keymint::Tag::Tag::PADDING => {
485                 Some(KeyParam::Padding(value_of!(val, PaddingMode)?.try_innto()?))
486             }
487             keymint::Tag::Tag::EC_CURVE => {
488                 Some(KeyParam::EcCurve(value_of!(val, EcCurve)?.try_innto()?))
489             }
490             keymint::Tag::Tag::RSA_OAEP_MGF_DIGEST => {
491                 Some(KeyParam::RsaOaepMgfDigest(value_of!(val, Digest)?.try_innto()?))
492             }
493             keymint::Tag::Tag::ORIGIN => {
494                 Some(KeyParam::Origin(value_of!(val, Origin)?.try_innto()?))
495             }
496 
497             // Special case: although `Tag::USER_AUTH_TYPE` claims to have an associated enum, it's
498             // actually a bitmask rather than an enum.
499             keymint::Tag::Tag::USER_AUTH_TYPE => {
500                 let val = value_of!(val, HardwareAuthenticatorType)?;
501                 Some(KeyParam::UserAuthType(val.0 as u32))
502             }
503 
504             // `u32`-holding variants.
505             keymint::Tag::Tag::KEY_SIZE => {
506                 Some(KeyParam::KeySize(KeySizeInBits(value_of!(val, Integer)? as u32)))
507             }
508             keymint::Tag::Tag::MIN_MAC_LENGTH => {
509                 Some(KeyParam::MinMacLength(value_of!(val, Integer)? as u32))
510             }
511             keymint::Tag::Tag::MAX_USES_PER_BOOT => {
512                 Some(KeyParam::MaxUsesPerBoot(value_of!(val, Integer)? as u32))
513             }
514             keymint::Tag::Tag::USAGE_COUNT_LIMIT => {
515                 Some(KeyParam::UsageCountLimit(value_of!(val, Integer)? as u32))
516             }
517             keymint::Tag::Tag::USER_ID => Some(KeyParam::UserId(value_of!(val, Integer)? as u32)),
518             keymint::Tag::Tag::AUTH_TIMEOUT => {
519                 Some(KeyParam::AuthTimeout(value_of!(val, Integer)? as u32))
520             }
521             keymint::Tag::Tag::OS_VERSION => {
522                 Some(KeyParam::OsVersion(value_of!(val, Integer)? as u32))
523             }
524             keymint::Tag::Tag::OS_PATCHLEVEL => {
525                 Some(KeyParam::OsPatchlevel(value_of!(val, Integer)? as u32))
526             }
527             keymint::Tag::Tag::VENDOR_PATCHLEVEL => {
528                 Some(KeyParam::VendorPatchlevel(value_of!(val, Integer)? as u32))
529             }
530             keymint::Tag::Tag::BOOT_PATCHLEVEL => {
531                 Some(KeyParam::BootPatchlevel(value_of!(val, Integer)? as u32))
532             }
533             keymint::Tag::Tag::MAC_LENGTH => {
534                 Some(KeyParam::MacLength(value_of!(val, Integer)? as u32))
535             }
536             keymint::Tag::Tag::MAX_BOOT_LEVEL => {
537                 Some(KeyParam::MaxBootLevel(value_of!(val, Integer)? as u32))
538             }
539 
540             // `u64`-holding variants.
541             keymint::Tag::Tag::RSA_PUBLIC_EXPONENT => {
542                 Some(KeyParam::RsaPublicExponent(RsaExponent(value_of!(val, LongInteger)? as u64)))
543             }
544             keymint::Tag::Tag::USER_SECURE_ID => {
545                 Some(KeyParam::UserSecureId(value_of!(val, LongInteger)? as u64))
546             }
547 
548             // `bool`-holding variants; only `true` is allowed.
549             keymint::Tag::Tag::CALLER_NONCE => {
550                 check_bool!(val)?;
551                 Some(KeyParam::CallerNonce)
552             }
553             keymint::Tag::Tag::INCLUDE_UNIQUE_ID => {
554                 check_bool!(val)?;
555                 Some(KeyParam::IncludeUniqueId)
556             }
557             keymint::Tag::Tag::BOOTLOADER_ONLY => {
558                 check_bool!(val)?;
559                 Some(KeyParam::BootloaderOnly)
560             }
561             keymint::Tag::Tag::ROLLBACK_RESISTANCE => {
562                 check_bool!(val)?;
563                 Some(KeyParam::RollbackResistance)
564             }
565             keymint::Tag::Tag::EARLY_BOOT_ONLY => {
566                 check_bool!(val)?;
567                 Some(KeyParam::EarlyBootOnly)
568             }
569             keymint::Tag::Tag::NO_AUTH_REQUIRED => {
570                 check_bool!(val)?;
571                 Some(KeyParam::NoAuthRequired)
572             }
573             keymint::Tag::Tag::ALLOW_WHILE_ON_BODY => {
574                 check_bool!(val)?;
575                 Some(KeyParam::AllowWhileOnBody)
576             }
577             keymint::Tag::Tag::TRUSTED_USER_PRESENCE_REQUIRED => {
578                 check_bool!(val)?;
579                 Some(KeyParam::TrustedUserPresenceRequired)
580             }
581             keymint::Tag::Tag::TRUSTED_CONFIRMATION_REQUIRED => {
582                 check_bool!(val)?;
583                 Some(KeyParam::TrustedConfirmationRequired)
584             }
585             keymint::Tag::Tag::UNLOCKED_DEVICE_REQUIRED => {
586                 check_bool!(val)?;
587                 Some(KeyParam::UnlockedDeviceRequired)
588             }
589             keymint::Tag::Tag::DEVICE_UNIQUE_ATTESTATION => {
590                 check_bool!(val)?;
591                 Some(KeyParam::DeviceUniqueAttestation)
592             }
593             keymint::Tag::Tag::STORAGE_KEY => {
594                 check_bool!(val)?;
595                 Some(KeyParam::StorageKey)
596             }
597             keymint::Tag::Tag::RESET_SINCE_ID_ROTATION => {
598                 check_bool!(val)?;
599                 Some(KeyParam::ResetSinceIdRotation)
600             }
601 
602             // `DateTime`-holding variants.
603             keymint::Tag::Tag::ACTIVE_DATETIME => Some(KeyParam::ActiveDatetime(DateTime {
604                 ms_since_epoch: value_of!(val, DateTime)?,
605             })),
606             keymint::Tag::Tag::ORIGINATION_EXPIRE_DATETIME => {
607                 Some(KeyParam::OriginationExpireDatetime(DateTime {
608                     ms_since_epoch: value_of!(val, DateTime)?,
609                 }))
610             }
611             keymint::Tag::Tag::USAGE_EXPIRE_DATETIME => {
612                 Some(KeyParam::UsageExpireDatetime(DateTime {
613                     ms_since_epoch: value_of!(val, DateTime)?,
614                 }))
615             }
616             keymint::Tag::Tag::CREATION_DATETIME => Some(KeyParam::CreationDatetime(DateTime {
617                 ms_since_epoch: value_of!(val, DateTime)?,
618             })),
619             keymint::Tag::Tag::CERTIFICATE_NOT_BEFORE => {
620                 Some(KeyParam::CertificateNotBefore(DateTime {
621                     ms_since_epoch: value_of!(val, DateTime)?,
622                 }))
623             }
624             keymint::Tag::Tag::CERTIFICATE_NOT_AFTER => {
625                 Some(KeyParam::CertificateNotAfter(DateTime {
626                     ms_since_epoch: value_of!(val, DateTime)?,
627                 }))
628             }
629 
630             // `Vec<u8>`-holding variants.
631             keymint::Tag::Tag::APPLICATION_ID => Some(KeyParam::ApplicationId(clone_blob!(val)?)),
632             keymint::Tag::Tag::APPLICATION_DATA => {
633                 Some(KeyParam::ApplicationData(clone_blob!(val)?))
634             }
635             keymint::Tag::Tag::ROOT_OF_TRUST => Some(KeyParam::RootOfTrust(clone_blob!(val)?)),
636             keymint::Tag::Tag::ATTESTATION_CHALLENGE => {
637                 Some(KeyParam::AttestationChallenge(clone_blob!(val)?))
638             }
639             keymint::Tag::Tag::ATTESTATION_APPLICATION_ID => {
640                 Some(KeyParam::AttestationApplicationId(clone_blob!(val)?))
641             }
642             keymint::Tag::Tag::ATTESTATION_ID_BRAND => {
643                 Some(KeyParam::AttestationIdBrand(clone_blob!(val)?))
644             }
645             keymint::Tag::Tag::ATTESTATION_ID_DEVICE => {
646                 Some(KeyParam::AttestationIdDevice(clone_blob!(val)?))
647             }
648             keymint::Tag::Tag::ATTESTATION_ID_PRODUCT => {
649                 Some(KeyParam::AttestationIdProduct(clone_blob!(val)?))
650             }
651             keymint::Tag::Tag::ATTESTATION_ID_SERIAL => {
652                 Some(KeyParam::AttestationIdSerial(clone_blob!(val)?))
653             }
654             keymint::Tag::Tag::ATTESTATION_ID_IMEI => {
655                 Some(KeyParam::AttestationIdImei(clone_blob!(val)?))
656             }
657             keymint::Tag::Tag::ATTESTATION_ID_SECOND_IMEI => {
658                 Some(KeyParam::AttestationIdSecondImei(clone_blob!(val)?))
659             }
660             keymint::Tag::Tag::ATTESTATION_ID_MEID => {
661                 Some(KeyParam::AttestationIdMeid(clone_blob!(val)?))
662             }
663             keymint::Tag::Tag::ATTESTATION_ID_MANUFACTURER => {
664                 Some(KeyParam::AttestationIdManufacturer(clone_blob!(val)?))
665             }
666             keymint::Tag::Tag::ATTESTATION_ID_MODEL => {
667                 Some(KeyParam::AttestationIdModel(clone_blob!(val)?))
668             }
669             keymint::Tag::Tag::NONCE => Some(KeyParam::Nonce(clone_blob!(val)?)),
670             keymint::Tag::Tag::CERTIFICATE_SERIAL => {
671                 Some(KeyParam::CertificateSerial(clone_blob!(val)?))
672             }
673             keymint::Tag::Tag::CERTIFICATE_SUBJECT => {
674                 Some(KeyParam::CertificateSubject(clone_blob!(val)?))
675             }
676 
677             // Unsupported variants
678             keymint::Tag::Tag::UNIQUE_ID
679             | keymint::Tag::Tag::HARDWARE_TYPE
680             | keymint::Tag::Tag::MIN_SECONDS_BETWEEN_OPS
681             | keymint::Tag::Tag::IDENTITY_CREDENTIAL_KEY
682             | keymint::Tag::Tag::ASSOCIATED_DATA
683             | keymint::Tag::Tag::CONFIRMATION_TOKEN => {
684                 error!("Unsupported tag {:?} encountered", val.tag);
685                 return Err(wire::ValueNotRecognized);
686             }
687             _ => {
688                 warn!("Unknown tag {:?} silently dropped", val.tag);
689                 None
690             }
691         })
692     }
693 }
694 
695 /// Macro that emits conversion implementations for `wire` and HAL enums.
696 /// - The `hal::keymint` version of the enum is a newtype holding `i32`
697 /// - The `wire::keymint` version of the enum is an exhaustive enum with `[repr(i32)]`
698 macro_rules! enum_convert {
699     {
700         $wenum:ty => $henum:ty
701     } => {
702         impl Fromm<$wenum> for $henum {
703             fn fromm(val: $wenum) -> Self {
704                 Self(val as i32)
705             }
706         }
707         impl TryFromm<$henum> for $wenum {
708             type Error = wire::ValueNotRecognized;
709             fn try_fromm(val: $henum) -> Result<Self, Self::Error> {
710                 Self::try_from(val.0)
711             }
712         }
713     };
714 }
715 enum_convert! { wire::keymint::ErrorCode => keymint::ErrorCode::ErrorCode }
716 enum_convert! { wire::keymint::Algorithm => keymint::Algorithm::Algorithm }
717 enum_convert! { wire::keymint::BlockMode => keymint::BlockMode::BlockMode }
718 enum_convert! { wire::keymint::Digest => keymint::Digest::Digest }
719 enum_convert! { wire::keymint::EcCurve => keymint::EcCurve::EcCurve }
720 enum_convert! { wire::keymint::HardwareAuthenticatorType =>
721 keymint::HardwareAuthenticatorType::HardwareAuthenticatorType }
722 enum_convert! { wire::keymint::KeyFormat => keymint::KeyFormat::KeyFormat }
723 enum_convert! { wire::keymint::KeyOrigin => keymint::KeyOrigin::KeyOrigin }
724 enum_convert! { wire::keymint::KeyPurpose => keymint::KeyPurpose::KeyPurpose }
725 enum_convert! { wire::keymint::PaddingMode => keymint::PaddingMode::PaddingMode }
726 enum_convert! { wire::keymint::SecurityLevel => keymint::SecurityLevel::SecurityLevel }
727 enum_convert! { wire::keymint::Tag => keymint::Tag::Tag }
728 enum_convert! { wire::keymint::TagType => keymint::TagType::TagType }
729