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 ¶m {
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