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