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