• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::keymint::{
2     AttestationKey, HardwareAuthToken, KeyCharacteristics, KeyCreationResult, KeyFormat,
3     KeyMintHardwareInfo, KeyParam, KeyPurpose,
4 };
5 use crate::rpc;
6 use crate::secureclock::TimeStampToken;
7 use crate::sharedsecret::SharedSecretParameters;
8 use crate::{cbor, cbor_type_error, vec_try, AsCborValue, CborError};
9 use alloc::{
10     format,
11     string::{String, ToString},
12     vec::Vec,
13 };
14 use enumn::N;
15 use kmr_derive::AsCborValue;
16 
17 /// Key size in bits.
18 #[repr(transparent)]
19 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsCborValue)]
20 pub struct KeySizeInBits(pub u32);
21 
22 /// RSA exponent.
23 #[repr(transparent)]
24 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsCborValue)]
25 pub struct RsaExponent(pub u64);
26 
27 /// Default maximum supported size for CBOR-serialized messages.
28 pub const DEFAULT_MAX_SIZE: usize = 4096;
29 
30 /// Marker type indicating failure to convert into an `enum` variant.
31 #[derive(Debug)]
32 pub struct ValueNotRecognized;
33 
34 /// Trait that associates an enum value of the specified type with a type.
35 /// Values of the `enum` type `T` are used to identify particular message types.
36 /// A message type implements `Code<T>` to indicate which `enum` value it is
37 /// associated with.
38 ///
39 /// For example, an `enum WhichMsg { Hello, Goodbye }` could be used to distinguish
40 /// between `struct HelloMsg` and `struct GoodbyeMsg` instances, in which case the
41 /// latter types would both implement `Code<WhichMsg>` with `CODE` values of
42 /// `WhichMsg::Hello` and `WhichMsg::Goodbye` respectively.
43 pub trait Code<T> {
44     /// The enum value identifying this request/response.
45     const CODE: T;
46     /// Return the enum value associated with the underlying type of this item.
code(&self) -> T47     fn code(&self) -> T {
48         Self::CODE
49     }
50 }
51 
52 /// Internal equivalent of the `keymint::BeginResult` type; instead of the Binder object reference
53 /// there is an opaque `op_handle` value that the bottom half implementation uses to identify the
54 /// in-progress operation.  This field is included as an extra parameter in all of the per-operation
55 /// ...Request types.
56 #[derive(Debug, Default, AsCborValue)]
57 pub struct InternalBeginResult {
58     pub challenge: i64,
59     pub params: Vec<KeyParam>,
60     // Extra for internal use: returned by bottom half of KeyMint implementation, used on
61     // all subsequent operation methods to identify the operation.
62     pub op_handle: i64,
63 }
64 
65 // The following types encapsulate the arguments to each method into a corresponding ..Request
66 // struct, and the return value and out parameters into a corresponding ..Response struct.
67 // These are currently hand-generated, but they could be auto-generated from the AIDL spec.
68 
69 // IKeyMintDevice methods.
70 #[derive(Debug, AsCborValue)]
71 pub struct GetHardwareInfoRequest {}
72 #[derive(Debug, AsCborValue)]
73 pub struct GetHardwareInfoResponse {
74     pub ret: KeyMintHardwareInfo,
75 }
76 #[derive(Debug, AsCborValue)]
77 pub struct AddRngEntropyRequest {
78     pub data: Vec<u8>,
79 }
80 #[derive(Debug, AsCborValue)]
81 pub struct AddRngEntropyResponse {}
82 #[derive(Debug, AsCborValue)]
83 pub struct GenerateKeyRequest {
84     pub key_params: Vec<KeyParam>,
85     pub attestation_key: Option<AttestationKey>,
86 }
87 #[derive(Debug, AsCborValue)]
88 pub struct GenerateKeyResponse {
89     pub ret: KeyCreationResult,
90 }
91 #[derive(AsCborValue)]
92 pub struct ImportKeyRequest {
93     pub key_params: Vec<KeyParam>,
94     pub key_format: KeyFormat,
95     pub key_data: Vec<u8>,
96     pub attestation_key: Option<AttestationKey>,
97 }
98 #[derive(Debug, AsCborValue)]
99 pub struct ImportKeyResponse {
100     pub ret: KeyCreationResult,
101 }
102 #[derive(AsCborValue)]
103 pub struct ImportWrappedKeyRequest {
104     pub wrapped_key_data: Vec<u8>,
105     pub wrapping_key_blob: Vec<u8>,
106     pub masking_key: Vec<u8>,
107     pub unwrapping_params: Vec<KeyParam>,
108     pub password_sid: i64,
109     pub biometric_sid: i64,
110 }
111 #[derive(Debug, AsCborValue)]
112 pub struct ImportWrappedKeyResponse {
113     pub ret: KeyCreationResult,
114 }
115 #[derive(Debug, AsCborValue)]
116 pub struct UpgradeKeyRequest {
117     pub key_blob_to_upgrade: Vec<u8>,
118     pub upgrade_params: Vec<KeyParam>,
119 }
120 #[derive(Debug, AsCborValue)]
121 pub struct UpgradeKeyResponse {
122     pub ret: Vec<u8>,
123 }
124 #[derive(Debug, AsCborValue)]
125 pub struct DeleteKeyRequest {
126     pub key_blob: Vec<u8>,
127 }
128 #[derive(Debug, AsCborValue)]
129 pub struct DeleteKeyResponse {}
130 #[derive(Debug, AsCborValue)]
131 pub struct DeleteAllKeysRequest {}
132 #[derive(Debug, AsCborValue)]
133 pub struct DeleteAllKeysResponse {}
134 #[derive(Debug, AsCborValue)]
135 pub struct DestroyAttestationIdsRequest {}
136 #[derive(Debug, AsCborValue)]
137 pub struct DestroyAttestationIdsResponse {}
138 #[derive(Debug, AsCborValue)]
139 pub struct BeginRequest {
140     pub purpose: KeyPurpose,
141     pub key_blob: Vec<u8>,
142     pub params: Vec<KeyParam>,
143     pub auth_token: Option<HardwareAuthToken>,
144 }
145 #[derive(Debug, AsCborValue)]
146 pub struct BeginResponse {
147     pub ret: InternalBeginResult, // special case: no Binder ref here
148 }
149 #[derive(Debug, AsCborValue)]
150 pub struct DeviceLockedRequest {
151     pub password_only: bool,
152     pub timestamp_token: Option<TimeStampToken>,
153 }
154 #[derive(Debug, AsCborValue)]
155 pub struct DeviceLockedResponse {}
156 #[derive(Debug, AsCborValue)]
157 pub struct EarlyBootEndedRequest {}
158 #[derive(Debug, AsCborValue)]
159 pub struct EarlyBootEndedResponse {}
160 #[derive(Debug, AsCborValue)]
161 pub struct ConvertStorageKeyToEphemeralRequest {
162     pub storage_key_blob: Vec<u8>,
163 }
164 #[derive(Debug, AsCborValue)]
165 pub struct ConvertStorageKeyToEphemeralResponse {
166     pub ret: Vec<u8>,
167 }
168 #[derive(Debug, AsCborValue)]
169 pub struct GetKeyCharacteristicsRequest {
170     pub key_blob: Vec<u8>,
171     pub app_id: Vec<u8>,
172     pub app_data: Vec<u8>,
173 }
174 #[derive(Debug, AsCborValue)]
175 pub struct GetKeyCharacteristicsResponse {
176     pub ret: Vec<KeyCharacteristics>,
177 }
178 
179 #[derive(Debug, AsCborValue)]
180 pub struct GetRootOfTrustChallengeRequest {}
181 
182 #[derive(Debug, AsCborValue)]
183 pub struct GetRootOfTrustChallengeResponse {
184     pub ret: [u8; 16],
185 }
186 
187 #[derive(Debug, AsCborValue)]
188 pub struct GetRootOfTrustRequest {
189     pub challenge: [u8; 16],
190 }
191 #[derive(Debug, AsCborValue)]
192 pub struct GetRootOfTrustResponse {
193     pub ret: Vec<u8>,
194 }
195 
196 #[derive(Debug, AsCborValue)]
197 pub struct SendRootOfTrustRequest {
198     pub root_of_trust: Vec<u8>,
199 }
200 
201 #[derive(Debug, AsCborValue)]
202 pub struct SendRootOfTrustResponse {}
203 
204 // IKeyMintOperation methods.  These ...Request structures include an extra `op_handle` field whose
205 // value was returned in the `InternalBeginResult` type and which identifies the operation in
206 // progress.
207 //
208 // `Debug` deliberately not derived to reduce the chances of inadvertent leakage of private info.
209 #[derive(Clone, AsCborValue)]
210 pub struct UpdateAadRequest {
211     pub op_handle: i64, // Extra for internal use, from `InternalBeginResult`.
212     pub input: Vec<u8>,
213     pub auth_token: Option<HardwareAuthToken>,
214     pub timestamp_token: Option<TimeStampToken>,
215 }
216 #[derive(AsCborValue)]
217 pub struct UpdateAadResponse {}
218 #[derive(Clone, AsCborValue)]
219 pub struct UpdateRequest {
220     pub op_handle: i64, // Extra for internal use, from `InternalBeginResult`.
221     pub input: Vec<u8>,
222     pub auth_token: Option<HardwareAuthToken>,
223     pub timestamp_token: Option<TimeStampToken>,
224 }
225 #[derive(AsCborValue)]
226 pub struct UpdateResponse {
227     pub ret: Vec<u8>,
228 }
229 #[derive(AsCborValue)]
230 pub struct FinishRequest {
231     pub op_handle: i64, // Extra for internal use, from `InternalBeginResult`.
232     pub input: Option<Vec<u8>>,
233     pub signature: Option<Vec<u8>>,
234     pub auth_token: Option<HardwareAuthToken>,
235     pub timestamp_token: Option<TimeStampToken>,
236     pub confirmation_token: Option<Vec<u8>>,
237 }
238 #[derive(AsCborValue)]
239 pub struct FinishResponse {
240     pub ret: Vec<u8>,
241 }
242 #[derive(Debug, AsCborValue)]
243 pub struct AbortRequest {
244     pub op_handle: i64, // Extra for internal use, from `InternalBeginResult`.
245 }
246 #[derive(Debug, AsCborValue)]
247 pub struct AbortResponse {}
248 
249 // IRemotelyProvisionedComponent methods.
250 
251 #[derive(Debug, AsCborValue)]
252 pub struct GetRpcHardwareInfoRequest {}
253 #[derive(Debug, AsCborValue)]
254 pub struct GetRpcHardwareInfoResponse {
255     pub ret: rpc::HardwareInfo,
256 }
257 #[derive(Debug, AsCborValue)]
258 pub struct GenerateEcdsaP256KeyPairRequest {
259     pub test_mode: bool,
260 }
261 #[derive(Debug, AsCborValue)]
262 pub struct GenerateEcdsaP256KeyPairResponse {
263     pub maced_public_key: rpc::MacedPublicKey,
264     pub ret: Vec<u8>,
265 }
266 #[derive(Debug, AsCborValue)]
267 pub struct GenerateCertificateRequestRequest {
268     pub test_mode: bool,
269     pub keys_to_sign: Vec<rpc::MacedPublicKey>,
270     pub endpoint_encryption_cert_chain: Vec<u8>,
271     pub challenge: Vec<u8>,
272 }
273 #[derive(Debug, AsCborValue)]
274 pub struct GenerateCertificateRequestResponse {
275     pub device_info: rpc::DeviceInfo,
276     pub protected_data: rpc::ProtectedData,
277     pub ret: Vec<u8>,
278 }
279 #[derive(Debug, AsCborValue)]
280 pub struct GenerateCertificateRequestV2Request {
281     pub keys_to_sign: Vec<rpc::MacedPublicKey>,
282     pub challenge: Vec<u8>,
283 }
284 #[derive(Debug, AsCborValue)]
285 pub struct GenerateCertificateRequestV2Response {
286     pub ret: Vec<u8>,
287 }
288 
289 // ISharedSecret methods.
290 #[derive(Debug, AsCborValue)]
291 pub struct GetSharedSecretParametersRequest {}
292 #[derive(Debug, AsCborValue)]
293 pub struct GetSharedSecretParametersResponse {
294     pub ret: SharedSecretParameters,
295 }
296 #[derive(Debug, AsCborValue)]
297 pub struct ComputeSharedSecretRequest {
298     pub params: Vec<SharedSecretParameters>,
299 }
300 #[derive(Debug, AsCborValue)]
301 pub struct ComputeSharedSecretResponse {
302     pub ret: Vec<u8>,
303 }
304 
305 // ISecureClock methods.
306 #[derive(Debug, AsCborValue)]
307 pub struct GenerateTimeStampRequest {
308     pub challenge: i64,
309 }
310 #[derive(Debug, AsCborValue)]
311 pub struct GenerateTimeStampResponse {
312     pub ret: TimeStampToken,
313 }
314 
315 // The following messages have no equivalent on a HAL interface, but are used internally
316 // between components.
317 
318 // HAL->TA at start of day.
319 #[derive(Debug, PartialEq, Eq, AsCborValue)]
320 pub struct SetHalInfoRequest {
321     pub os_version: u32,
322     pub os_patchlevel: u32,     // YYYYMM format
323     pub vendor_patchlevel: u32, // YYYYMMDD format
324 }
325 #[derive(Debug, AsCborValue)]
326 pub struct SetHalInfoResponse {}
327 
328 // Boot loader->TA at start of day.
329 #[derive(Debug, AsCborValue)]
330 pub struct SetBootInfoRequest {
331     pub verified_boot_key: Vec<u8>,
332     pub device_boot_locked: bool,
333     pub verified_boot_state: i32,
334     pub verified_boot_hash: Vec<u8>,
335     pub boot_patchlevel: u32, // YYYYMMDD format
336 }
337 #[derive(Debug, AsCborValue)]
338 pub struct SetBootInfoResponse {}
339 
340 /// Attestation ID information.
341 #[derive(Clone, Debug, AsCborValue, PartialEq, Eq, Default)]
342 pub struct AttestationIdInfo {
343     // The following fields are byte vectors that typically hold UTF-8 string data.
344     pub brand: Vec<u8>,
345     pub device: Vec<u8>,
346     pub product: Vec<u8>,
347     pub serial: Vec<u8>,
348     pub imei: Vec<u8>,
349     pub imei2: Vec<u8>,
350     pub meid: Vec<u8>,
351     pub manufacturer: Vec<u8>,
352     pub model: Vec<u8>,
353 }
354 
355 // Provisioner->TA at device provisioning time.
356 #[derive(Debug, AsCborValue)]
357 pub struct SetAttestationIdsRequest {
358     pub ids: AttestationIdInfo,
359 }
360 #[derive(Debug, AsCborValue)]
361 pub struct SetAttestationIdsResponse {}
362 
363 // Result of an operation, as an error code and a response message (only present when
364 // `error_code` is zero).
365 #[derive(AsCborValue)]
366 pub struct PerformOpResponse {
367     pub error_code: i32,
368     pub rsp: Option<PerformOpRsp>,
369 }
370 
371 /// Declare a collection of related enums for a code and a pair of types.
372 ///
373 /// An invocation like:
374 /// ```ignore
375 /// declare_req_rsp_enums! { KeyMintOperation  => (PerformOpReq, PerformOpRsp) {
376 ///     DeviceGetHardwareInfo = 0x11 => (GetHardwareInfoRequest, GetHardwareInfoResponse),
377 ///     DeviceAddRngEntropy = 0x12 =>   (AddRngEntropyRequest, AddRngEntropyResponse),
378 /// } }
379 /// ```
380 /// will emit three `enum` types all of whose variant names are the same (taken from the leftmost
381 /// column), but whose contents are:
382 ///
383 /// - the numeric values (second column)
384 ///   ```ignore
385 ///   #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
386 ///   enum KeyMintOperation {
387 ///       DeviceGetHardwareInfo = 0x11,
388 ///       DeviceAddRngEntropy = 0x12,
389 ///   }
390 ///   ```
391 ///
392 /// - the types from the third column:
393 ///   ```ignore
394 ///   #[derive(Debug)]
395 ///   enum PerformOpReq {
396 ///       DeviceGetHardwareInfo(GetHardwareInfoRequest),
397 ///       DeviceAddRngEntropy(AddRngEntropyRequest),
398 ///   }
399 ///   ```
400 ///
401 /// - the types from the fourth column:
402 ///   ```ignore
403 ///   #[derive(Debug)]
404 ///   enum PerformOpRsp {
405 ///       DeviceGetHardwareInfo(GetHardwareInfoResponse),
406 ///       DeviceAddRngEntropy(AddRngEntropyResponse),
407 ///   }
408 //   ```
409 ///
410 /// Each of these enum types will also get an implementation of [`AsCborValue`]
411 macro_rules! declare_req_rsp_enums {
412     {
413         $cenum:ident => ($reqenum:ident, $rspenum:ident)
414         {
415             $( $cname:ident = $cvalue:expr => ($reqtyp:ty, $rsptyp:ty) , )*
416         }
417     } => {
418         declare_req_rsp_enums! { $cenum => ($reqenum, $rspenum)
419                                  ( concat!("&(\n",
420                                            $( "    [", stringify!($cname), ", {}],\n", )*
421                                            ")") )
422           {
423             $( $cname = $cvalue => ($reqtyp, $rsptyp), )*
424         } }
425     };
426     {
427         $cenum:ident => ($reqenum:ident, $rspenum:ident) ( $cddlfmt:expr )
428         {
429             $( $cname:ident = $cvalue:expr => ($reqtyp:ty, $rsptyp:ty) , )*
430         }
431     } => {
432 
433         #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, N)]
434         pub enum $cenum {
435             $( $cname = $cvalue, )*
436         }
437 
438         impl AsCborValue for $cenum {
439             /// Create an instance of the enum from a [`cbor::value::Value`], checking that the
440             /// value is valid.
441             fn from_cbor_value(value: $crate::cbor::value::Value) ->
442                 Result<Self, crate::CborError> {
443                 use core::convert::TryInto;
444                 // First get the int value as an `i32`.
445                 let v: i32 = match value {
446                     $crate::cbor::value::Value::Integer(i) => i.try_into().map_err(|_| {
447                         crate::CborError::OutOfRangeIntegerValue
448                     })?,
449                     v => return crate::cbor_type_error(&v, &"int"),
450                 };
451                 // Now check it is one of the defined enum values.
452                 Self::n(v).ok_or(crate::CborError::NonEnumValue)
453             }
454             /// Convert the enum value to a [`cbor::value::Value`] (without checking that the
455             /// contained enum value is valid).
456             fn to_cbor_value(self) -> Result<$crate::cbor::value::Value, crate::CborError> {
457                 Ok($crate::cbor::value::Value::Integer((self as i64).into()))
458             }
459             fn cddl_typename() -> Option<alloc::string::String> {
460                 use alloc::string::ToString;
461                 Some(stringify!($cenum).to_string())
462             }
463             fn cddl_schema() -> Option<alloc::string::String> {
464                 use alloc::string::ToString;
465                 Some( concat!("&(\n",
466                               $( "    ", stringify!($cname), ": ", stringify!($cvalue), ",\n", )*
467                               ")").to_string() )
468             }
469         }
470 
471         pub enum $reqenum {
472             $( $cname($reqtyp), )*
473         }
474 
475         impl $reqenum {
476             pub fn code(&self) -> $cenum {
477                 match self {
478                     $( Self::$cname(_) => $cenum::$cname, )*
479                 }
480             }
481         }
482 
483         pub enum $rspenum {
484             $( $cname($rsptyp), )*
485         }
486 
487         impl AsCborValue for $reqenum {
488             fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
489                 let mut a = match value {
490                     cbor::value::Value::Array(a) => a,
491                     _ => return crate::cbor_type_error(&value, "arr"),
492                 };
493                 if a.len() != 2 {
494                     return Err(CborError::UnexpectedItem("arr", "arr len 2"));
495                 }
496                 let ret_val = a.remove(1);
497                 let ret_type = <$cenum>::from_cbor_value(a.remove(0))?;
498                 match ret_type {
499                     $( $cenum::$cname => Ok(Self::$cname(<$reqtyp>::from_cbor_value(ret_val)?)), )*
500                 }
501             }
502             fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
503                 Ok(cbor::value::Value::Array(match self {
504                     $( Self::$cname(val) => {
505                         vec_try![
506                             $cenum::$cname.to_cbor_value()?,
507                             val.to_cbor_value()?
508                         ]?
509                     }, )*
510                 }))
511             }
512 
513             fn cddl_typename() -> Option<String> {
514                 use alloc::string::ToString;
515                 Some(stringify!($reqenum).to_string())
516             }
517 
518             fn cddl_schema() -> Option<String> {
519                 Some(format!($cddlfmt,
520                              $( <$reqtyp>::cddl_ref(), )*
521                 ))
522             }
523         }
524 
525         impl AsCborValue for $rspenum {
526             fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
527                 let mut a = match value {
528                     cbor::value::Value::Array(a) => a,
529                     _ => return crate::cbor_type_error(&value, "arr"),
530                 };
531                 if a.len() != 2 {
532                     return Err(CborError::UnexpectedItem("arr", "arr len 2"));
533                 }
534                 let ret_val = a.remove(1);
535                 let ret_type = <$cenum>::from_cbor_value(a.remove(0))?;
536                 match ret_type {
537                     $( $cenum::$cname => Ok(Self::$cname(<$rsptyp>::from_cbor_value(ret_val)?)), )*
538                 }
539             }
540             fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
541                 Ok(cbor::value::Value::Array(match self {
542                     $( Self::$cname(val) => {
543                         vec_try![
544                             $cenum::$cname.to_cbor_value()?,
545                             val.to_cbor_value()?
546                         ]?
547                     }, )*
548                 }))
549             }
550 
551             fn cddl_typename() -> Option<String> {
552                 use alloc::string::ToString;
553                 Some(stringify!($rspenum).to_string())
554             }
555 
556             fn cddl_schema() -> Option<String> {
557                 Some(format!($cddlfmt,
558                              $( <$rsptyp>::cddl_ref(), )*
559                 ))
560             }
561         }
562 
563         $(
564             impl Code<$cenum> for $reqtyp {
565                 const CODE: $cenum = $cenum::$cname;
566             }
567         )*
568 
569         $(
570             impl Code<$cenum> for $rsptyp {
571                 const CODE: $cenum = $cenum::$cname;
572             }
573         )*
574     };
575 }
576 
577 // Possible KeyMint operation requests, as:
578 // - an enum value with an explicit numeric value
579 // - a request enum which has an operation code associated to each variant
580 // - a response enum which has the same operation code associated to each variant.
581 declare_req_rsp_enums! { KeyMintOperation  =>    (PerformOpReq, PerformOpRsp) {
582     DeviceGetHardwareInfo = 0x11 =>                    (GetHardwareInfoRequest, GetHardwareInfoResponse),
583     DeviceAddRngEntropy = 0x12 =>                      (AddRngEntropyRequest, AddRngEntropyResponse),
584     DeviceGenerateKey = 0x13 =>                        (GenerateKeyRequest, GenerateKeyResponse),
585     DeviceImportKey = 0x14 =>                          (ImportKeyRequest, ImportKeyResponse),
586     DeviceImportWrappedKey = 0x15 =>                   (ImportWrappedKeyRequest, ImportWrappedKeyResponse),
587     DeviceUpgradeKey = 0x16 =>                         (UpgradeKeyRequest, UpgradeKeyResponse),
588     DeviceDeleteKey = 0x17 =>                          (DeleteKeyRequest, DeleteKeyResponse),
589     DeviceDeleteAllKeys = 0x18 =>                      (DeleteAllKeysRequest, DeleteAllKeysResponse),
590     DeviceDestroyAttestationIds = 0x19 =>              (DestroyAttestationIdsRequest, DestroyAttestationIdsResponse),
591     DeviceBegin = 0x1a =>                              (BeginRequest, BeginResponse),
592     DeviceDeviceLocked = 0x1b =>                       (DeviceLockedRequest, DeviceLockedResponse),
593     DeviceEarlyBootEnded = 0x1c =>                     (EarlyBootEndedRequest, EarlyBootEndedResponse),
594     DeviceConvertStorageKeyToEphemeral = 0x1d =>       (ConvertStorageKeyToEphemeralRequest, ConvertStorageKeyToEphemeralResponse),
595     DeviceGetKeyCharacteristics = 0x1e =>              (GetKeyCharacteristicsRequest, GetKeyCharacteristicsResponse),
596     OperationUpdateAad = 0x31 =>                       (UpdateAadRequest, UpdateAadResponse),
597     OperationUpdate = 0x32 =>                          (UpdateRequest, UpdateResponse),
598     OperationFinish = 0x33 =>                          (FinishRequest, FinishResponse),
599     OperationAbort = 0x34 =>                           (AbortRequest, AbortResponse),
600     RpcGetHardwareInfo = 0x41 =>                       (GetRpcHardwareInfoRequest, GetRpcHardwareInfoResponse),
601     RpcGenerateEcdsaP256KeyPair = 0x42 =>              (GenerateEcdsaP256KeyPairRequest, GenerateEcdsaP256KeyPairResponse),
602     RpcGenerateCertificateRequest = 0x43 =>            (GenerateCertificateRequestRequest, GenerateCertificateRequestResponse),
603     RpcGenerateCertificateV2Request = 0x44 =>          (GenerateCertificateRequestV2Request, GenerateCertificateRequestV2Response),
604     SharedSecretGetSharedSecretParameters = 0x51 =>    (GetSharedSecretParametersRequest, GetSharedSecretParametersResponse),
605     SharedSecretComputeSharedSecret = 0x52 =>          (ComputeSharedSecretRequest, ComputeSharedSecretResponse),
606     SecureClockGenerateTimeStamp = 0x61 =>             (GenerateTimeStampRequest, GenerateTimeStampResponse),
607     GetRootOfTrustChallenge = 0x71 =>                  (GetRootOfTrustChallengeRequest, GetRootOfTrustChallengeResponse),
608     GetRootOfTrust = 0x72 =>                           (GetRootOfTrustRequest, GetRootOfTrustResponse),
609     SendRootOfTrust = 0x73 =>                          (SendRootOfTrustRequest, SendRootOfTrustResponse),
610     SetHalInfo = 0x81 =>                               (SetHalInfoRequest, SetHalInfoResponse),
611     SetBootInfo = 0x82 =>                              (SetBootInfoRequest, SetBootInfoResponse),
612     SetAttestationIds = 0x83 =>                        (SetAttestationIdsRequest, SetAttestationIdsResponse),
613 } }
614 
615 /// Indicate whether an operation is part of the `IRemotelyProvisionedComponent` HAL.
is_rpc_operation(code: KeyMintOperation) -> bool616 pub fn is_rpc_operation(code: KeyMintOperation) -> bool {
617     matches!(
618         code,
619         KeyMintOperation::RpcGetHardwareInfo
620             | KeyMintOperation::RpcGenerateEcdsaP256KeyPair
621             | KeyMintOperation::RpcGenerateCertificateRequest
622             | KeyMintOperation::RpcGenerateCertificateV2Request
623     )
624 }
625