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