• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Helper functionality for working with legacy tag serialization.
2 
3 use crate::{km_err, try_to_vec, vec_try, vec_try_with_capacity, Error, FallibleAllocExt};
4 use alloc::vec::Vec;
5 use core::cmp::Ordering;
6 use core::convert::{TryFrom, TryInto};
7 use kmr_wire::{
8     keymint::{
9         Algorithm, BlockMode, DateTime, Digest, EcCurve, KeyOrigin, KeyParam, KeyPurpose,
10         PaddingMode, Tag,
11     },
12     KeySizeInBits, RsaExponent,
13 };
14 
15 /// Retrieve a `u8` from the start of the given slice, if possible.
consume_u8(data: &mut &[u8]) -> Result<u8, Error>16 pub fn consume_u8(data: &mut &[u8]) -> Result<u8, Error> {
17     match data.first() {
18         Some(b) => {
19             *data = &(*data)[1..];
20             Ok(*b)
21         }
22         None => Err(km_err!(InvalidKeyBlob, "failed to find 1 byte")),
23     }
24 }
25 
26 /// Move past a bool value from the start of the given slice, if possible.
27 /// Bool values should only be included if `true`, so fail if the value
28 /// is anything other than 1.
consume_bool(data: &mut &[u8]) -> Result<(), Error>29 pub fn consume_bool(data: &mut &[u8]) -> Result<(), Error> {
30     let b = consume_u8(data)?;
31     if b == 0x01 {
32         Ok(())
33     } else {
34         Err(km_err!(InvalidKeyBlob, "bool value other than 1 encountered"))
35     }
36 }
37 
38 /// Retrieve a (host-ordered) `u32` from the start of the given slice, if possible.
consume_u32(data: &mut &[u8]) -> Result<u32, Error>39 pub fn consume_u32(data: &mut &[u8]) -> Result<u32, Error> {
40     if data.len() < 4 {
41         return Err(km_err!(InvalidKeyBlob, "failed to find 4 bytes"));
42     }
43     let chunk: [u8; 4] = data[..4].try_into().unwrap(); // safe: just checked
44     *data = &(*data)[4..];
45     Ok(u32::from_ne_bytes(chunk))
46 }
47 
48 /// Retrieve a (host-ordered) `i32` from the start of the given slice, if possible.
consume_i32(data: &mut &[u8]) -> Result<i32, Error>49 pub fn consume_i32(data: &mut &[u8]) -> Result<i32, Error> {
50     if data.len() < 4 {
51         return Err(km_err!(InvalidKeyBlob, "failed to find 4 bytes"));
52     }
53     let chunk: [u8; 4] = data[..4].try_into().unwrap(); // safe: just checked
54     *data = &(*data)[4..];
55     Ok(i32::from_ne_bytes(chunk))
56 }
57 
58 /// Retrieve a (host-ordered) `u64` from the start of the given slice, if possible.
consume_u64(data: &mut &[u8]) -> Result<u64, Error>59 pub fn consume_u64(data: &mut &[u8]) -> Result<u64, Error> {
60     if data.len() < 8 {
61         return Err(km_err!(InvalidKeyBlob, "failed to find 8 bytes"));
62     }
63     let chunk: [u8; 8] = data[..8].try_into().unwrap(); // safe: just checked
64     *data = &(*data)[8..];
65     Ok(u64::from_ne_bytes(chunk))
66 }
67 
68 /// Retrieve a (host-ordered) `i64` from the start of the given slice, if possible.
consume_i64(data: &mut &[u8]) -> Result<i64, Error>69 pub fn consume_i64(data: &mut &[u8]) -> Result<i64, Error> {
70     if data.len() < 8 {
71         return Err(km_err!(InvalidKeyBlob, "failed to find 8 bytes"));
72     }
73     let chunk: [u8; 8] = data[..8].try_into().unwrap(); // safe: just checked
74     *data = &(*data)[8..];
75     Ok(i64::from_ne_bytes(chunk))
76 }
77 
78 /// Retrieve a vector of bytes from the start of the given slice, if possible,
79 /// with the length of the data is expected to appear as a host-ordered `u32` prefix.
consume_vec(data: &mut &[u8]) -> Result<Vec<u8>, Error>80 pub fn consume_vec(data: &mut &[u8]) -> Result<Vec<u8>, Error> {
81     let len = consume_u32(data)? as usize;
82     if len > data.len() {
83         return Err(km_err!(InvalidKeyBlob, "failed to find {} bytes", len));
84     }
85     let result = try_to_vec(&data[..len])?;
86     *data = &(*data)[len..];
87     Ok(result)
88 }
89 
90 /// Serialize a collection of [`KeyParam`]s into a format that is compatible with previous
91 /// implementations:
92 ///
93 /// ```text
94 /// [0..4]              Size B of `TagType::Bytes` data, in host order.
95 /// [4..4+B]      (*)   Concatenated contents of each `TagType::Bytes` tag.
96 /// [4+B..4+B+4]        Count N of the number of parameters, in host order.
97 /// [8+B..8+B+4]        Size Z of encoded parameters.
98 /// [12+B..12+B+Z]      Serialized parameters one after another.
99 /// ```
100 ///
101 /// Individual parameters are serialized in the last chunk as:
102 ///
103 /// ```text
104 /// [0..4]              Tag number, in host order.
105 /// Followed by one of the following depending on the tag's `TagType`; all integers in host order:
106 ///   [4..5]            Bool value (`TagType::Bool`)
107 ///   [4..8]            i32 values (`TagType::Uint[Rep]`, `TagType::Enum[Rep]`)
108 ///   [4..12]           i64 values, in host order (`TagType::UlongRep`, `TagType::Date`)
109 ///   [4..8] + [8..12]  Size + offset of data in (*) above (`TagType::Bytes`, `TagType::Bignum`)
110 /// ```
serialize(params: &[KeyParam]) -> Result<Vec<u8>, Error>111 pub fn serialize(params: &[KeyParam]) -> Result<Vec<u8>, Error> {
112     // First 4 bytes are the length of the combined [`TagType::Bytes`] data; come back to set that
113     // in a moment.
114     let mut result = vec_try![0; 4]?;
115 
116     // Next append the contents of all of the [`TagType::Bytes`] data.
117     let mut blob_size = 0u32;
118     for param in params {
119         match param {
120             // Variants that hold `Vec<u8>`.
121             KeyParam::ApplicationId(v)
122             | KeyParam::ApplicationData(v)
123             | KeyParam::AttestationChallenge(v)
124             | KeyParam::AttestationApplicationId(v)
125             | KeyParam::AttestationIdBrand(v)
126             | KeyParam::AttestationIdDevice(v)
127             | KeyParam::AttestationIdProduct(v)
128             | KeyParam::AttestationIdSerial(v)
129             | KeyParam::AttestationIdImei(v)
130             | KeyParam::AttestationIdSecondImei(v)
131             | KeyParam::AttestationIdMeid(v)
132             | KeyParam::AttestationIdManufacturer(v)
133             | KeyParam::AttestationIdModel(v)
134             | KeyParam::Nonce(v)
135             | KeyParam::RootOfTrust(v)
136             | KeyParam::CertificateSerial(v)
137             | KeyParam::CertificateSubject(v) => {
138                 result.try_extend_from_slice(v)?;
139                 blob_size += v.len() as u32;
140             }
141             _ => {}
142         }
143     }
144     // Go back and fill in the combined blob length in native order at the start.
145     result[..4].clone_from_slice(&blob_size.to_ne_bytes());
146 
147     result.try_extend_from_slice(&(params.len() as u32).to_ne_bytes())?;
148 
149     let params_size_offset = result.len();
150     result.try_extend_from_slice(&[0u8; 4])?; // placeholder for size of elements
151     let first_param_offset = result.len();
152     let mut blob_offset = 0u32;
153     for param in params {
154         result.try_extend_from_slice(&(param.tag() as u32).to_ne_bytes())?;
155         match &param {
156             // Enum-holding variants.
157             KeyParam::Purpose(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
158             KeyParam::Algorithm(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
159             KeyParam::BlockMode(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
160             KeyParam::Digest(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
161             KeyParam::Padding(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
162             KeyParam::EcCurve(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
163             KeyParam::RsaOaepMgfDigest(v) => {
164                 result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?
165             }
166             KeyParam::Origin(v) => result.try_extend_from_slice(&(*v as u32).to_ne_bytes())?,
167 
168             // `u32`-holding variants.
169             KeyParam::KeySize(v) => result.try_extend_from_slice(&(v.0).to_ne_bytes())?,
170             KeyParam::MinMacLength(v)
171             | KeyParam::MaxUsesPerBoot(v)
172             | KeyParam::UsageCountLimit(v)
173             | KeyParam::UserId(v)
174             | KeyParam::UserAuthType(v)
175             | KeyParam::AuthTimeout(v)
176             | KeyParam::OsVersion(v)
177             | KeyParam::OsPatchlevel(v)
178             | KeyParam::VendorPatchlevel(v)
179             | KeyParam::BootPatchlevel(v)
180             | KeyParam::MacLength(v)
181             | KeyParam::MaxBootLevel(v) => result.try_extend_from_slice(&v.to_ne_bytes())?,
182 
183             // `u64`-holding variants.
184             KeyParam::RsaPublicExponent(v) => {
185                 result.try_extend_from_slice(&(v.0).to_ne_bytes())?
186             }
187             KeyParam::UserSecureId(v) => {
188                 result.try_extend_from_slice(&(*v).to_ne_bytes())?
189             }
190 
191             // `true`-holding variants.
192             KeyParam::CallerNonce
193             | KeyParam::IncludeUniqueId
194             | KeyParam::BootloaderOnly
195             | KeyParam::RollbackResistance
196             | KeyParam::EarlyBootOnly
197             | KeyParam::AllowWhileOnBody
198             | KeyParam::NoAuthRequired
199             | KeyParam::TrustedUserPresenceRequired
200             | KeyParam::TrustedConfirmationRequired
201             | KeyParam::UnlockedDeviceRequired
202             | KeyParam::DeviceUniqueAttestation
203             | KeyParam::StorageKey
204             | KeyParam::ResetSinceIdRotation => result.try_push(0x01u8)?,
205 
206             // `DateTime`-holding variants.
207             KeyParam::ActiveDatetime(v)
208             | KeyParam::OriginationExpireDatetime(v)
209             | KeyParam::UsageExpireDatetime(v)
210             | KeyParam::CreationDatetime(v)
211             | KeyParam::CertificateNotBefore(v)
212             | KeyParam::CertificateNotAfter(v) => {
213                 result.try_extend_from_slice(&(v.ms_since_epoch as u64).to_ne_bytes())?
214             }
215 
216             // `Vec<u8>`-holding variants.
217             KeyParam::ApplicationId(v)
218             | KeyParam::ApplicationData(v)
219             | KeyParam::AttestationChallenge(v)
220             | KeyParam::AttestationApplicationId(v)
221             | KeyParam::AttestationIdBrand(v)
222             | KeyParam::AttestationIdDevice(v)
223             | KeyParam::AttestationIdProduct(v)
224             | KeyParam::AttestationIdSerial(v)
225             | KeyParam::AttestationIdImei(v)
226             | KeyParam::AttestationIdSecondImei(v)
227             | KeyParam::AttestationIdMeid(v)
228             | KeyParam::AttestationIdManufacturer(v)
229             | KeyParam::AttestationIdModel(v)
230             | KeyParam::Nonce(v)
231             | KeyParam::RootOfTrust(v)
232             | KeyParam::CertificateSerial(v)
233             | KeyParam::CertificateSubject(v) => {
234                 let blob_len = v.len() as u32;
235                 result.try_extend_from_slice(&blob_len.to_ne_bytes())?;
236                 result.try_extend_from_slice(&blob_offset.to_ne_bytes())?;
237                 blob_offset += blob_len;
238             }
239         }
240     }
241     let serialized_size = (result.len() - first_param_offset) as u32;
242 
243     // Go back and fill in the total serialized size.
244     result[params_size_offset..params_size_offset + 4]
245         .clone_from_slice(&serialized_size.to_ne_bytes());
246     Ok(result)
247 }
248 
249 /// Retrieve the contents of a tag of `TagType::Bytes`.  The `data` parameter holds
250 /// the as-yet unparsed data, and a length and offset are read from this (and consumed).
251 /// This length and offset refer to a location in the combined `blob_data`; however,
252 /// the offset is expected to be the next unconsumed chunk of `blob_data`, as indicated
253 /// by `next_blob_offset` (which itself is updated as a result of consuming the data).
consume_blob( data: &mut &[u8], next_blob_offset: &mut usize, blob_data: &[u8], ) -> Result<Vec<u8>, Error>254 fn consume_blob(
255     data: &mut &[u8],
256     next_blob_offset: &mut usize,
257     blob_data: &[u8],
258 ) -> Result<Vec<u8>, Error> {
259     let data_len = consume_u32(data)? as usize;
260     let data_offset = consume_u32(data)? as usize;
261     // Expect the blob data to come from the next offset in the initial blob chunk.
262     if data_offset != *next_blob_offset {
263         return Err(km_err!(
264             InvalidKeyBlob,
265             "got blob offset {} instead of {}",
266             data_offset,
267             next_blob_offset
268         ));
269     }
270     if (data_offset + data_len) > blob_data.len() {
271         return Err(km_err!(
272             InvalidKeyBlob,
273             "blob at offset [{}..{}+{}] goes beyond blob data size {}",
274             data_offset,
275             data_offset,
276             data_len,
277             blob_data.len(),
278         ));
279     }
280 
281     let slice = &blob_data[data_offset..data_offset + data_len];
282     *next_blob_offset += data_len;
283     try_to_vec(slice)
284 }
285 
286 /// Deserialize a collection of [`KeyParam`]s in legacy serialized format. The provided slice is
287 /// modified to contain the unconsumed part of the data.
deserialize(data: &mut &[u8]) -> Result<Vec<KeyParam>, Error>288 pub fn deserialize(data: &mut &[u8]) -> Result<Vec<KeyParam>, Error> {
289     let blob_data_size = consume_u32(data)? as usize;
290 
291     let blob_data = &data[..blob_data_size];
292     let mut next_blob_offset = 0;
293 
294     // Move past the blob data.
295     *data = &data[blob_data_size..];
296 
297     let param_count = consume_u32(data)? as usize;
298     let param_size = consume_u32(data)? as usize;
299     if param_size > data.len() {
300         return Err(km_err!(
301             InvalidKeyBlob,
302             "size mismatch 4+{}+4+4+{} > {}",
303             blob_data_size,
304             param_size,
305             data.len()
306         ));
307     }
308 
309     let mut results = vec_try_with_capacity!(param_count)?;
310     for _i in 0..param_count {
311         let tag_num = consume_u32(data)? as i32;
312         let tag = <Tag>::try_from(tag_num)
313             .map_err(|_e| km_err!(InvalidKeyBlob, "unknown tag {} encountered", tag_num))?;
314         let enum_err = |_e| km_err!(InvalidKeyBlob, "unknown enum value for {:?}", tag);
315         results.try_push(match tag {
316             // Enum-holding variants.
317             Tag::Purpose => {
318                 KeyParam::Purpose(<KeyPurpose>::try_from(consume_i32(data)?).map_err(enum_err)?)
319             }
320             Tag::Algorithm => {
321                 KeyParam::Algorithm(<Algorithm>::try_from(consume_i32(data)?).map_err(enum_err)?)
322             }
323             Tag::BlockMode => {
324                 KeyParam::BlockMode(<BlockMode>::try_from(consume_i32(data)?).map_err(enum_err)?)
325             }
326             Tag::Digest => {
327                 KeyParam::Digest(<Digest>::try_from(consume_i32(data)?).map_err(enum_err)?)
328             }
329             Tag::Padding => {
330                 KeyParam::Padding(<PaddingMode>::try_from(consume_i32(data)?).map_err(enum_err)?)
331             }
332             Tag::EcCurve => {
333                 KeyParam::EcCurve(<EcCurve>::try_from(consume_i32(data)?).map_err(enum_err)?)
334             }
335             Tag::RsaOaepMgfDigest => KeyParam::RsaOaepMgfDigest(
336                 <Digest>::try_from(consume_i32(data)?).map_err(enum_err)?,
337             ),
338             Tag::Origin => {
339                 KeyParam::Origin(<KeyOrigin>::try_from(consume_i32(data)?).map_err(enum_err)?)
340             }
341 
342             // `u32`-holding variants.
343             Tag::KeySize => KeyParam::KeySize(KeySizeInBits(consume_u32(data)?)),
344             Tag::MinMacLength => KeyParam::MinMacLength(consume_u32(data)?),
345             Tag::MaxUsesPerBoot => KeyParam::MaxUsesPerBoot(consume_u32(data)?),
346             Tag::UsageCountLimit => KeyParam::UsageCountLimit(consume_u32(data)?),
347             Tag::UserId => KeyParam::UserId(consume_u32(data)?),
348             Tag::UserAuthType => KeyParam::UserAuthType(consume_u32(data)?),
349             Tag::AuthTimeout => KeyParam::AuthTimeout(consume_u32(data)?),
350             Tag::OsVersion => KeyParam::OsVersion(consume_u32(data)?),
351             Tag::OsPatchlevel => KeyParam::OsPatchlevel(consume_u32(data)?),
352             Tag::VendorPatchlevel => KeyParam::VendorPatchlevel(consume_u32(data)?),
353             Tag::BootPatchlevel => KeyParam::BootPatchlevel(consume_u32(data)?),
354             Tag::MacLength => KeyParam::MacLength(consume_u32(data)?),
355             Tag::MaxBootLevel => KeyParam::MaxBootLevel(consume_u32(data)?),
356 
357             // `u64`-holding variants.
358             Tag::RsaPublicExponent => KeyParam::RsaPublicExponent(RsaExponent(consume_u64(data)?)),
359             Tag::UserSecureId => KeyParam::UserSecureId(consume_u64(data)?),
360 
361             // `true`-holding variants.
362             Tag::CallerNonce => {
363                 consume_bool(data)?;
364                 KeyParam::CallerNonce
365             }
366             Tag::IncludeUniqueId => {
367                 consume_bool(data)?;
368                 KeyParam::IncludeUniqueId
369             }
370             Tag::BootloaderOnly => {
371                 consume_bool(data)?;
372                 KeyParam::BootloaderOnly
373             }
374             Tag::RollbackResistance => {
375                 consume_bool(data)?;
376                 KeyParam::RollbackResistance
377             }
378             Tag::EarlyBootOnly => {
379                 consume_bool(data)?;
380                 KeyParam::EarlyBootOnly
381             }
382             Tag::AllowWhileOnBody => {
383                 consume_bool(data)?;
384                 KeyParam::AllowWhileOnBody
385             }
386             Tag::NoAuthRequired => {
387                 consume_bool(data)?;
388                 KeyParam::NoAuthRequired
389             }
390             Tag::TrustedUserPresenceRequired => {
391                 consume_bool(data)?;
392                 KeyParam::TrustedUserPresenceRequired
393             }
394             Tag::TrustedConfirmationRequired => {
395                 consume_bool(data)?;
396                 KeyParam::TrustedConfirmationRequired
397             }
398             Tag::UnlockedDeviceRequired => {
399                 consume_bool(data)?;
400                 KeyParam::UnlockedDeviceRequired
401             }
402             Tag::DeviceUniqueAttestation => {
403                 consume_bool(data)?;
404                 KeyParam::DeviceUniqueAttestation
405             }
406             Tag::StorageKey => {
407                 consume_bool(data)?;
408                 KeyParam::StorageKey
409             }
410             Tag::ResetSinceIdRotation => {
411                 consume_bool(data)?;
412                 KeyParam::ResetSinceIdRotation
413             }
414 
415             // `DateTime`-holding variants.
416             Tag::ActiveDatetime => {
417                 KeyParam::ActiveDatetime(DateTime { ms_since_epoch: consume_i64(data)? })
418             }
419             Tag::OriginationExpireDatetime => {
420                 KeyParam::OriginationExpireDatetime(DateTime { ms_since_epoch: consume_i64(data)? })
421             }
422             Tag::UsageExpireDatetime => {
423                 KeyParam::UsageExpireDatetime(DateTime { ms_since_epoch: consume_i64(data)? })
424             }
425             Tag::CreationDatetime => {
426                 KeyParam::CreationDatetime(DateTime { ms_since_epoch: consume_i64(data)? })
427             }
428             Tag::CertificateNotBefore => {
429                 KeyParam::CertificateNotBefore(DateTime { ms_since_epoch: consume_i64(data)? })
430             }
431             Tag::CertificateNotAfter => {
432                 KeyParam::CertificateNotAfter(DateTime { ms_since_epoch: consume_i64(data)? })
433             }
434 
435             // `Vec<u8>`-holding variants.
436             Tag::ApplicationId => {
437                 KeyParam::ApplicationId(consume_blob(data, &mut next_blob_offset, blob_data)?)
438             }
439             Tag::ApplicationData => {
440                 KeyParam::ApplicationData(consume_blob(data, &mut next_blob_offset, blob_data)?)
441             }
442             Tag::AttestationChallenge => KeyParam::AttestationChallenge(consume_blob(
443                 data,
444                 &mut next_blob_offset,
445                 blob_data,
446             )?),
447             Tag::AttestationApplicationId => KeyParam::AttestationApplicationId(consume_blob(
448                 data,
449                 &mut next_blob_offset,
450                 blob_data,
451             )?),
452             Tag::AttestationIdBrand => {
453                 KeyParam::AttestationIdBrand(consume_blob(data, &mut next_blob_offset, blob_data)?)
454             }
455             Tag::AttestationIdDevice => {
456                 KeyParam::AttestationIdDevice(consume_blob(data, &mut next_blob_offset, blob_data)?)
457             }
458             Tag::AttestationIdProduct => KeyParam::AttestationIdProduct(consume_blob(
459                 data,
460                 &mut next_blob_offset,
461                 blob_data,
462             )?),
463             Tag::AttestationIdSerial => {
464                 KeyParam::AttestationIdSerial(consume_blob(data, &mut next_blob_offset, blob_data)?)
465             }
466             Tag::AttestationIdImei => {
467                 KeyParam::AttestationIdImei(consume_blob(data, &mut next_blob_offset, blob_data)?)
468             }
469             Tag::AttestationIdSecondImei => KeyParam::AttestationIdSecondImei(consume_blob(
470                 data,
471                 &mut next_blob_offset,
472                 blob_data,
473             )?),
474             Tag::AttestationIdMeid => {
475                 KeyParam::AttestationIdMeid(consume_blob(data, &mut next_blob_offset, blob_data)?)
476             }
477             Tag::AttestationIdManufacturer => KeyParam::AttestationIdManufacturer(consume_blob(
478                 data,
479                 &mut next_blob_offset,
480                 blob_data,
481             )?),
482             Tag::AttestationIdModel => {
483                 KeyParam::AttestationIdModel(consume_blob(data, &mut next_blob_offset, blob_data)?)
484             }
485             Tag::Nonce => KeyParam::Nonce(consume_blob(data, &mut next_blob_offset, blob_data)?),
486             Tag::RootOfTrust => {
487                 KeyParam::RootOfTrust(consume_blob(data, &mut next_blob_offset, blob_data)?)
488             }
489             Tag::CertificateSerial => {
490                 KeyParam::CertificateSerial(consume_blob(data, &mut next_blob_offset, blob_data)?)
491             }
492             Tag::CertificateSubject => {
493                 KeyParam::CertificateSubject(consume_blob(data, &mut next_blob_offset, blob_data)?)
494             }
495             // Invalid variants.
496             Tag::Invalid
497             | Tag::HardwareType
498             | Tag::MinSecondsBetweenOps
499             | Tag::UniqueId
500             | Tag::IdentityCredentialKey
501             | Tag::AssociatedData
502             | Tag::ConfirmationToken => {
503                 return Err(km_err!(InvalidKeyBlob, "invalid tag {:?} encountered", tag));
504             }
505         })?;
506     }
507 
508     Ok(results)
509 }
510 
511 /// Determine ordering of two [`KeyParam`] values for legacy key blob ordering.
512 /// Invalid parameters are likely to compare equal.
param_compare(left: &KeyParam, right: &KeyParam) -> Ordering513 pub fn param_compare(left: &KeyParam, right: &KeyParam) -> Ordering {
514     match (left, right) {
515         (KeyParam::Purpose(l), KeyParam::Purpose(r)) => l.cmp(r),
516         (KeyParam::Algorithm(l), KeyParam::Algorithm(r)) => l.cmp(r),
517         (KeyParam::KeySize(l), KeyParam::KeySize(r)) => l.cmp(r),
518         (KeyParam::BlockMode(l), KeyParam::BlockMode(r)) => l.cmp(r),
519         (KeyParam::Digest(l), KeyParam::Digest(r)) => l.cmp(r),
520         (KeyParam::Padding(l), KeyParam::Padding(r)) => l.cmp(r),
521         (KeyParam::CallerNonce, KeyParam::CallerNonce) => Ordering::Equal,
522         (KeyParam::MinMacLength(l), KeyParam::MinMacLength(r)) => l.cmp(r),
523         (KeyParam::EcCurve(l), KeyParam::EcCurve(r)) => l.cmp(r),
524         (KeyParam::RsaPublicExponent(l), KeyParam::RsaPublicExponent(r)) => l.cmp(r),
525         (KeyParam::IncludeUniqueId, KeyParam::IncludeUniqueId) => Ordering::Equal,
526         (KeyParam::RsaOaepMgfDigest(l), KeyParam::RsaOaepMgfDigest(r)) => l.cmp(r),
527         (KeyParam::BootloaderOnly, KeyParam::BootloaderOnly) => Ordering::Equal,
528         (KeyParam::RollbackResistance, KeyParam::RollbackResistance) => Ordering::Equal,
529         (KeyParam::EarlyBootOnly, KeyParam::EarlyBootOnly) => Ordering::Equal,
530         (KeyParam::ActiveDatetime(l), KeyParam::ActiveDatetime(r)) => l.cmp(r),
531         (KeyParam::OriginationExpireDatetime(l), KeyParam::OriginationExpireDatetime(r)) => {
532             l.cmp(r)
533         }
534         (KeyParam::UsageExpireDatetime(l), KeyParam::UsageExpireDatetime(r)) => l.cmp(r),
535         (KeyParam::MaxUsesPerBoot(l), KeyParam::MaxUsesPerBoot(r)) => l.cmp(r),
536         (KeyParam::UsageCountLimit(l), KeyParam::UsageCountLimit(r)) => l.cmp(r),
537         (KeyParam::UserId(l), KeyParam::UserId(r)) => l.cmp(r),
538         (KeyParam::UserSecureId(l), KeyParam::UserSecureId(r)) => l.cmp(r),
539         (KeyParam::NoAuthRequired, KeyParam::NoAuthRequired) => Ordering::Equal,
540         (KeyParam::UserAuthType(l), KeyParam::UserAuthType(r)) => l.cmp(r),
541         (KeyParam::AuthTimeout(l), KeyParam::AuthTimeout(r)) => l.cmp(r),
542         (KeyParam::AllowWhileOnBody, KeyParam::AllowWhileOnBody) => Ordering::Equal,
543         (KeyParam::TrustedUserPresenceRequired, KeyParam::TrustedUserPresenceRequired) => {
544             Ordering::Equal
545         }
546         (KeyParam::TrustedConfirmationRequired, KeyParam::TrustedConfirmationRequired) => {
547             Ordering::Equal
548         }
549         (KeyParam::UnlockedDeviceRequired, KeyParam::UnlockedDeviceRequired) => Ordering::Equal,
550         (KeyParam::ApplicationId(l), KeyParam::ApplicationId(r)) => l.cmp(r),
551         (KeyParam::ApplicationData(l), KeyParam::ApplicationData(r)) => l.cmp(r),
552         (KeyParam::CreationDatetime(l), KeyParam::CreationDatetime(r)) => l.cmp(r),
553         (KeyParam::Origin(l), KeyParam::Origin(r)) => l.cmp(r),
554         (KeyParam::RootOfTrust(l), KeyParam::RootOfTrust(r)) => l.cmp(r),
555         (KeyParam::OsVersion(l), KeyParam::OsVersion(r)) => l.cmp(r),
556         (KeyParam::OsPatchlevel(l), KeyParam::OsPatchlevel(r)) => l.cmp(r),
557         (KeyParam::AttestationChallenge(l), KeyParam::AttestationChallenge(r)) => l.cmp(r),
558         (KeyParam::AttestationApplicationId(l), KeyParam::AttestationApplicationId(r)) => l.cmp(r),
559         (KeyParam::AttestationIdBrand(l), KeyParam::AttestationIdBrand(r)) => l.cmp(r),
560         (KeyParam::AttestationIdDevice(l), KeyParam::AttestationIdDevice(r)) => l.cmp(r),
561         (KeyParam::AttestationIdProduct(l), KeyParam::AttestationIdProduct(r)) => l.cmp(r),
562         (KeyParam::AttestationIdSerial(l), KeyParam::AttestationIdSerial(r)) => l.cmp(r),
563         (KeyParam::AttestationIdImei(l), KeyParam::AttestationIdImei(r)) => l.cmp(r),
564         (KeyParam::AttestationIdSecondImei(l), KeyParam::AttestationIdSecondImei(r)) => l.cmp(r),
565         (KeyParam::AttestationIdMeid(l), KeyParam::AttestationIdMeid(r)) => l.cmp(r),
566         (KeyParam::AttestationIdManufacturer(l), KeyParam::AttestationIdManufacturer(r)) => {
567             l.cmp(r)
568         }
569         (KeyParam::AttestationIdModel(l), KeyParam::AttestationIdModel(r)) => l.cmp(r),
570         (KeyParam::VendorPatchlevel(l), KeyParam::VendorPatchlevel(r)) => l.cmp(r),
571         (KeyParam::BootPatchlevel(l), KeyParam::BootPatchlevel(r)) => l.cmp(r),
572         (KeyParam::DeviceUniqueAttestation, KeyParam::DeviceUniqueAttestation) => Ordering::Equal,
573         (KeyParam::StorageKey, KeyParam::StorageKey) => Ordering::Equal,
574         (KeyParam::Nonce(l), KeyParam::Nonce(r)) => l.cmp(r),
575         (KeyParam::MacLength(l), KeyParam::MacLength(r)) => l.cmp(r),
576         (KeyParam::ResetSinceIdRotation, KeyParam::ResetSinceIdRotation) => Ordering::Equal,
577         (KeyParam::CertificateSerial(l), KeyParam::CertificateSerial(r)) => l.cmp(r),
578         (KeyParam::CertificateSubject(l), KeyParam::CertificateSubject(r)) => l.cmp(r),
579         (KeyParam::CertificateNotBefore(l), KeyParam::CertificateNotBefore(r)) => l.cmp(r),
580         (KeyParam::CertificateNotAfter(l), KeyParam::CertificateNotAfter(r)) => l.cmp(r),
581         (KeyParam::MaxBootLevel(l), KeyParam::MaxBootLevel(r)) => l.cmp(r),
582 
583         (left, right) => left.tag().cmp(&right.tag()),
584     }
585 }
586