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