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 //! Static information about tag behaviour.
16
17 use crate::{km_err, Error};
18 use kmr_wire::keymint::{Tag, TagType};
19
20 #[cfg(test)]
21 mod tests;
22
23 /// Indicate the allowed use of the tag as a key characteristic.
24 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
25 pub enum Characteristic {
26 /// Tag is a key characteristic that is enforced by KeyMint (at whatever security
27 /// level the KeyMint implementation is running at), and is visible to KeyMint
28 /// users (e.g. via GetKeyCharacteristics).
29 KeyMintEnforced,
30
31 /// Tag is a key characteristic that is enforced by KeyMint (at whatever security
32 /// level the KeyMint implementation is running at), but is not exposed to KeyMint
33 /// users. If a key has this tag associated with it, all operations on the key
34 /// must have this tag provided as an operation parameter.
35 KeyMintHidden,
36
37 /// Tag is a key characteristic that is enforced by Keystore.
38 KeystoreEnforced,
39
40 /// Tag is enforced by both KeyMint and Keystore, in different ways.
41 BothEnforced,
42
43 /// Tag is not a key characteristic, either because it only acts as an operation
44 /// parameter or because it never appears on the API.
45 NotKeyCharacteristic,
46 }
47
48 /// The set of characteristics that are necessarily enforced by Keystore.
49 pub const KEYSTORE_ENFORCED_CHARACTERISTICS: &[Tag] = &[
50 Tag::ActiveDatetime,
51 Tag::OriginationExpireDatetime,
52 Tag::UsageExpireDatetime,
53 Tag::UserId,
54 Tag::AllowWhileOnBody,
55 Tag::CreationDatetime,
56 Tag::MaxBootLevel,
57 Tag::UnlockedDeviceRequired,
58 ];
59
60 /// The set of characteristics that are enforced by KeyMint.
61 pub const KEYMINT_ENFORCED_CHARACTERISTICS: &[Tag] = &[
62 Tag::UserSecureId,
63 Tag::Algorithm,
64 Tag::EcCurve,
65 Tag::UserAuthType,
66 Tag::Origin,
67 Tag::Purpose,
68 Tag::BlockMode,
69 Tag::Digest,
70 Tag::Padding,
71 Tag::RsaOaepMgfDigest,
72 Tag::KeySize,
73 Tag::MinMacLength,
74 Tag::MaxUsesPerBoot,
75 Tag::AuthTimeout,
76 Tag::OsVersion,
77 Tag::OsPatchlevel,
78 Tag::VendorPatchlevel,
79 Tag::BootPatchlevel,
80 Tag::RsaPublicExponent,
81 Tag::CallerNonce,
82 Tag::BootloaderOnly,
83 Tag::RollbackResistance,
84 Tag::EarlyBootOnly,
85 Tag::NoAuthRequired,
86 Tag::TrustedUserPresenceRequired,
87 Tag::TrustedConfirmationRequired,
88 Tag::StorageKey,
89 ];
90
91 /// The set of characteristics that are automatically added by KeyMint on key generation.
92 pub const AUTO_ADDED_CHARACTERISTICS: &[Tag] =
93 &[Tag::Origin, Tag::OsVersion, Tag::OsPatchlevel, Tag::VendorPatchlevel, Tag::BootPatchlevel];
94
95 /// Indicate the allowed use of the tag as a parameter for an operation.
96 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
97 pub enum OperationParam {
98 /// Tag acts as an operation parameter for key generation/import operations.
99 KeyGenImport,
100
101 /// Tag is provided as an explicit argument for a cipher operation, and must
102 /// match one of the values for this tag in the key characteristics.
103 CipherExplicitArgOneOf,
104
105 /// Tag is provided as a parameter for a cipher operation, and must
106 /// match one of the values for this tag in the key characteristics.
107 CipherParamOneOf,
108
109 /// Tag is provided as a parameter for a cipher operation, and must
110 /// exactly match the (single) value for this tag in the key characteristics.
111 CipherParamExactMatch,
112
113 /// Tag is provided as a parameter for a cipher operation, and is not a key
114 /// characteristic.
115 CipherParam,
116
117 /// Tag is not an operation parameter; this *normally* means that it only acts
118 /// as a key characteristic (exception: ROOT_OF_TRUST is neither an operation
119 /// parameter nor a key characteristic).
120 NotOperationParam,
121 }
122
123 /// Indicate whether the KeyMint user is allowed to specify this tag.
124 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
125 pub struct UserSpecifiable(pub bool);
126
127 /// Indicate whether the KeyMint implementation auto-adds this tag as a characteristic to generated
128 /// or imported keys.
129 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
130 pub struct AutoAddedCharacteristic(pub bool);
131
132 /// Indicate the lifetime of the value associated with the tag.
133 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
134 pub enum ValueLifetime {
135 /// Indicates that the value of the tag is communicated to KeyMint from the bootloader, and
136 /// fixed thereafter.
137 FixedAtBoot,
138 /// Indicates that the value of the tag is communicated to KeyMint from the HAL service, and
139 /// fixed thereafter.
140 FixedAtStartup,
141 /// Indicates that the value of the tag varies from key to key, or operation to operation.
142 Variable,
143 }
144
145 /// Indicate whether a tag provided as an asymmetric key generation/import parameter is
146 /// required for the production of a certificate or attestation extension.
147 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
148 pub enum CertGenParam {
149 /// Tag not required as a parameter for certificate or extension generation (although its value
150 /// may appear in the extension as a key characteristic).
151 ///
152 /// Example: `Tag::KeySize` doesn't affect cert generation (but does appear in any attestation
153 /// extension).
154 NotRequired,
155 /// Tag must be specified as a parameter on key generation in order to get certificate
156 /// generation.
157 ///
158 /// Example: `Tag::CertificateNotBefore` must be specified to get a cert.
159 Required,
160 /// Tag must be specified as a parameter on key generation in order to get an attestation
161 /// extension in a generated certificate.
162 ///
163 /// Example: `Tag::AttestationChallenge` must be specified to get a cert with an attestation
164 /// extension.
165 RequiredForAttestation,
166 /// Tag need not be specified as a parameter on key generation, but if specified it does affect
167 /// the contents of the generated certificate (not extension).
168 ///
169 /// Example: `Tag::CertificateSerial` can be omitted, but if supplied it alters the cert.
170 Optional,
171 /// Tag need not be specified as a parameter on key generation, but if specified it does affect
172 /// the contents of the attestation extension.
173 ///
174 /// Example: `Tag::ResetSinceIdRotation` can be omitted, but if supplied (along with
175 /// `Tag::IncludeUniqueId`) then the attestation extension contents are altered.
176 OptionalForAttestation,
177 /// Special cases; see individual tags for information.
178 Special,
179 }
180
181 /// Information about a tag's behaviour.
182 #[derive(Debug, Clone)]
183 pub struct Info {
184 /// Tag name as a string for debug purposes.
185 pub name: &'static str,
186 /// Indication of the type of the corresponding value.
187 pub tt: TagType,
188 /// Indicates whether the tag value appears in an attestation extension, and as what ASN.1
189 /// type.
190 pub ext_asn1_type: Option<&'static str>,
191 /// Indicates whether the KeyMint user can specify this tag.
192 pub user_can_specify: UserSpecifiable,
193 /// Indicates how this tag acts as a key characteristic.
194 pub characteristic: Characteristic,
195 /// Indicates how this tag acts as an operation parameter.
196 pub op_param: OperationParam,
197 /// Indicates whether KeyMint automatically adds this tag to keys as a key characteristic.
198 pub keymint_auto_adds: AutoAddedCharacteristic,
199 /// Indicates the lifetime of the value associated with this tag.
200 pub lifetime: ValueLifetime,
201 /// Indicates the role this tag plays in certificate generation for asymmetric keys.
202 pub cert_gen: CertGenParam,
203 /// Unique bit index for tracking this tag.
204 bit_index: usize,
205 }
206
207 /// Global "map" of tags to information about their behaviour.
208 /// Encoded as an array to avoid allocation; lookup should only be slightly slower
209 /// for this few entries.
210 const INFO: [(Tag, Info); 61] = [
211 (
212 Tag::Purpose,
213 Info {
214 name: "PURPOSE",
215 tt: TagType::EnumRep,
216 ext_asn1_type: Some("SET OF INTEGER"),
217 user_can_specify: UserSpecifiable(true),
218 characteristic: Characteristic::KeyMintEnforced,
219 op_param: OperationParam::CipherExplicitArgOneOf,
220 keymint_auto_adds: AutoAddedCharacteristic(false),
221 lifetime: ValueLifetime::Variable,
222 cert_gen: CertGenParam::NotRequired,
223 bit_index: 0,
224 },
225 ),
226 (
227 Tag::Algorithm,
228 Info {
229 name: "ALGORITHM",
230 tt: TagType::Enum,
231 ext_asn1_type: Some("INTEGER"),
232 user_can_specify: UserSpecifiable(true),
233 characteristic: Characteristic::KeyMintEnforced,
234 op_param: OperationParam::NotOperationParam,
235 keymint_auto_adds: AutoAddedCharacteristic(false),
236 lifetime: ValueLifetime::Variable,
237 cert_gen: CertGenParam::NotRequired,
238 bit_index: 1,
239 },
240 ),
241 (
242 Tag::KeySize,
243 Info {
244 name: "KEY_SIZE",
245 tt: TagType::Uint,
246 ext_asn1_type: Some("INTEGER"),
247 user_can_specify: UserSpecifiable(true),
248 characteristic: Characteristic::KeyMintEnforced,
249 op_param: OperationParam::NotOperationParam,
250 keymint_auto_adds: AutoAddedCharacteristic(false),
251 lifetime: ValueLifetime::Variable,
252 cert_gen: CertGenParam::NotRequired,
253 bit_index: 2,
254 },
255 ),
256 (
257 Tag::BlockMode,
258 Info {
259 name: "BLOCK_MODE",
260 tt: TagType::EnumRep,
261 ext_asn1_type: None,
262 user_can_specify: UserSpecifiable(true),
263 characteristic: Characteristic::KeyMintEnforced,
264 op_param: OperationParam::CipherParamOneOf,
265 keymint_auto_adds: AutoAddedCharacteristic(false),
266 lifetime: ValueLifetime::Variable,
267 cert_gen: CertGenParam::NotRequired,
268 bit_index: 3,
269 },
270 ),
271 (
272 Tag::Digest,
273 Info {
274 name: "DIGEST",
275 tt: TagType::EnumRep,
276 ext_asn1_type: Some("SET OF INTEGER"),
277 user_can_specify: UserSpecifiable(true),
278 characteristic: Characteristic::KeyMintEnforced,
279 op_param: OperationParam::CipherParamOneOf,
280 keymint_auto_adds: AutoAddedCharacteristic(false),
281 lifetime: ValueLifetime::Variable,
282 cert_gen: CertGenParam::NotRequired,
283 bit_index: 4,
284 },
285 ),
286 (
287 Tag::Padding,
288 Info {
289 name: "PADDING",
290 tt: TagType::EnumRep,
291 ext_asn1_type: Some("SET OF INTEGER"),
292 user_can_specify: UserSpecifiable(true),
293 characteristic: Characteristic::KeyMintEnforced,
294 op_param: OperationParam::CipherParamOneOf,
295 keymint_auto_adds: AutoAddedCharacteristic(false),
296 lifetime: ValueLifetime::Variable,
297 cert_gen: CertGenParam::NotRequired,
298 bit_index: 5,
299 },
300 ),
301 (
302 Tag::CallerNonce,
303 Info {
304 name: "CALLER_NONCE",
305 tt: TagType::Bool,
306 ext_asn1_type: None,
307 user_can_specify: UserSpecifiable(true),
308 characteristic: Characteristic::KeyMintEnforced,
309 op_param: OperationParam::NotOperationParam,
310 keymint_auto_adds: AutoAddedCharacteristic(false),
311 lifetime: ValueLifetime::Variable,
312 cert_gen: CertGenParam::NotRequired,
313 bit_index: 6,
314 },
315 ),
316 (
317 Tag::MinMacLength,
318 Info {
319 name: "MIN_MAC_LENGTH",
320 tt: TagType::Uint,
321 ext_asn1_type: None,
322 user_can_specify: UserSpecifiable(true),
323 characteristic: Characteristic::KeyMintEnforced,
324 op_param: OperationParam::NotOperationParam,
325 keymint_auto_adds: AutoAddedCharacteristic(false),
326 lifetime: ValueLifetime::Variable,
327 cert_gen: CertGenParam::NotRequired,
328 bit_index: 7,
329 },
330 ),
331 (
332 Tag::EcCurve,
333 Info {
334 name: "EC_CURVE",
335 tt: TagType::Enum,
336 ext_asn1_type: Some("INTEGER"),
337 user_can_specify: UserSpecifiable(true),
338 characteristic: Characteristic::KeyMintEnforced,
339 op_param: OperationParam::NotOperationParam,
340 keymint_auto_adds: AutoAddedCharacteristic(false),
341 lifetime: ValueLifetime::Variable,
342 cert_gen: CertGenParam::NotRequired,
343 bit_index: 8,
344 },
345 ),
346 (
347 Tag::RsaPublicExponent,
348 Info {
349 name: "RSA_PUBLIC_EXPONENT",
350 tt: TagType::Ulong,
351 ext_asn1_type: Some("INTEGER"),
352 user_can_specify: UserSpecifiable(true),
353 characteristic: Characteristic::KeyMintEnforced,
354 op_param: OperationParam::NotOperationParam,
355 keymint_auto_adds: AutoAddedCharacteristic(false),
356 lifetime: ValueLifetime::Variable,
357 cert_gen: CertGenParam::NotRequired,
358 bit_index: 9,
359 },
360 ),
361 (
362 Tag::IncludeUniqueId,
363 Info {
364 name: "INCLUDE_UNIQUE_ID",
365 tt: TagType::Bool,
366 ext_asn1_type: None,
367 user_can_specify: UserSpecifiable(true),
368 characteristic: Characteristic::NotKeyCharacteristic,
369 op_param: OperationParam::KeyGenImport,
370 keymint_auto_adds: AutoAddedCharacteristic(false),
371 lifetime: ValueLifetime::Variable,
372 cert_gen: CertGenParam::OptionalForAttestation,
373 bit_index: 10,
374 },
375 ),
376 (
377 Tag::RsaOaepMgfDigest,
378 Info {
379 name: "RSA_OAEP_MGF_DIGEST",
380 tt: TagType::EnumRep,
381 ext_asn1_type: Some("SET OF INTEGER"),
382 user_can_specify: UserSpecifiable(true),
383 characteristic: Characteristic::KeyMintEnforced,
384 op_param: OperationParam::CipherParamOneOf,
385 keymint_auto_adds: AutoAddedCharacteristic(false),
386 lifetime: ValueLifetime::Variable,
387 cert_gen: CertGenParam::NotRequired,
388 bit_index: 11,
389 },
390 ),
391 (
392 Tag::BootloaderOnly,
393 Info {
394 name: "BOOTLOADER_ONLY",
395 tt: TagType::Bool,
396 ext_asn1_type: None,
397 user_can_specify: UserSpecifiable(false),
398 characteristic: Characteristic::KeyMintEnforced,
399 op_param: OperationParam::NotOperationParam,
400 keymint_auto_adds: AutoAddedCharacteristic(false),
401 lifetime: ValueLifetime::Variable,
402 cert_gen: CertGenParam::NotRequired,
403 bit_index: 12,
404 },
405 ),
406 (
407 Tag::RollbackResistance,
408 Info {
409 name: "ROLLBACK_RESISTANCE",
410 tt: TagType::Bool,
411 ext_asn1_type: Some("NULL"),
412 user_can_specify: UserSpecifiable(true),
413 characteristic: Characteristic::KeyMintEnforced,
414 op_param: OperationParam::NotOperationParam,
415 keymint_auto_adds: AutoAddedCharacteristic(false),
416 lifetime: ValueLifetime::Variable,
417 cert_gen: CertGenParam::NotRequired,
418 bit_index: 13,
419 },
420 ),
421 (
422 Tag::EarlyBootOnly,
423 Info {
424 name: "EARLY_BOOT_ONLY",
425 tt: TagType::Bool,
426 ext_asn1_type: Some("NULL"),
427 user_can_specify: UserSpecifiable(true),
428 characteristic: Characteristic::KeyMintEnforced,
429 op_param: OperationParam::NotOperationParam,
430 keymint_auto_adds: AutoAddedCharacteristic(false),
431 lifetime: ValueLifetime::Variable,
432 cert_gen: CertGenParam::NotRequired,
433 bit_index: 14,
434 },
435 ),
436 (
437 Tag::ActiveDatetime,
438 Info {
439 name: "ACTIVE_DATETIME",
440 tt: TagType::Date,
441 ext_asn1_type: Some("INTEGER"),
442 user_can_specify: UserSpecifiable(true),
443 characteristic: Characteristic::KeystoreEnforced,
444 op_param: OperationParam::NotOperationParam,
445 keymint_auto_adds: AutoAddedCharacteristic(false),
446 lifetime: ValueLifetime::Variable,
447 cert_gen: CertGenParam::NotRequired,
448 bit_index: 15,
449 },
450 ),
451 (
452 Tag::OriginationExpireDatetime,
453 Info {
454 name: "ORIGINATION_EXPIRE_DATETIME",
455 tt: TagType::Date,
456 ext_asn1_type: Some("INTEGER"),
457 user_can_specify: UserSpecifiable(true),
458 characteristic: Characteristic::KeystoreEnforced,
459 op_param: OperationParam::NotOperationParam,
460 keymint_auto_adds: AutoAddedCharacteristic(false),
461 lifetime: ValueLifetime::Variable,
462 cert_gen: CertGenParam::NotRequired,
463 bit_index: 16,
464 },
465 ),
466 (
467 Tag::UsageExpireDatetime,
468 Info {
469 name: "USAGE_EXPIRE_DATETIME",
470 tt: TagType::Date,
471 ext_asn1_type: Some("INTEGER"),
472 user_can_specify: UserSpecifiable(true),
473 characteristic: Characteristic::KeystoreEnforced,
474 op_param: OperationParam::NotOperationParam,
475 keymint_auto_adds: AutoAddedCharacteristic(false),
476 lifetime: ValueLifetime::Variable,
477 cert_gen: CertGenParam::NotRequired,
478 bit_index: 17,
479 },
480 ),
481 (
482 Tag::MaxUsesPerBoot,
483 Info {
484 name: "MAX_USES_PER_BOOT",
485 tt: TagType::Uint,
486 ext_asn1_type: None,
487 user_can_specify: UserSpecifiable(true),
488 characteristic: Characteristic::KeyMintEnforced,
489 op_param: OperationParam::NotOperationParam,
490 keymint_auto_adds: AutoAddedCharacteristic(false),
491 lifetime: ValueLifetime::Variable,
492 cert_gen: CertGenParam::NotRequired,
493 bit_index: 18,
494 },
495 ),
496 (
497 Tag::UsageCountLimit,
498 Info {
499 name: "USAGE_COUNT_LIMIT",
500 tt: TagType::Uint,
501 ext_asn1_type: Some("INTEGER"),
502 user_can_specify: UserSpecifiable(true),
503 characteristic: Characteristic::BothEnforced,
504 op_param: OperationParam::NotOperationParam,
505 keymint_auto_adds: AutoAddedCharacteristic(false),
506 lifetime: ValueLifetime::Variable,
507 cert_gen: CertGenParam::NotRequired,
508 bit_index: 19,
509 },
510 ),
511 (
512 Tag::UserId,
513 Info {
514 name: "USER_ID",
515 tt: TagType::Uint,
516 ext_asn1_type: None,
517 user_can_specify: UserSpecifiable(true),
518 characteristic: Characteristic::KeystoreEnforced,
519 op_param: OperationParam::NotOperationParam,
520 keymint_auto_adds: AutoAddedCharacteristic(false),
521 lifetime: ValueLifetime::Variable,
522 cert_gen: CertGenParam::NotRequired,
523 bit_index: 20,
524 },
525 ),
526 // Value must match userID or secureId in authToken param
527 (
528 Tag::UserSecureId,
529 Info {
530 name: "USER_SECURE_ID",
531 tt: TagType::UlongRep,
532 ext_asn1_type: None,
533 user_can_specify: UserSpecifiable(true),
534 characteristic: Characteristic::KeyMintEnforced,
535 op_param: OperationParam::CipherExplicitArgOneOf,
536 keymint_auto_adds: AutoAddedCharacteristic(false),
537 lifetime: ValueLifetime::Variable,
538 cert_gen: CertGenParam::NotRequired,
539 bit_index: 21,
540 },
541 ),
542 (
543 Tag::NoAuthRequired,
544 Info {
545 name: "NO_AUTH_REQUIRED",
546 tt: TagType::Bool,
547 ext_asn1_type: Some("NULL"),
548 user_can_specify: UserSpecifiable(true),
549 characteristic: Characteristic::KeyMintEnforced,
550 op_param: OperationParam::NotOperationParam,
551 keymint_auto_adds: AutoAddedCharacteristic(false),
552 lifetime: ValueLifetime::Variable,
553 cert_gen: CertGenParam::NotRequired,
554 bit_index: 22,
555 },
556 ),
557 (
558 Tag::UserAuthType,
559 Info {
560 name: "USER_AUTH_TYPE",
561 tt: TagType::Enum,
562 ext_asn1_type: Some("INTEGER"),
563 user_can_specify: UserSpecifiable(true),
564 characteristic: Characteristic::KeyMintEnforced,
565 op_param: OperationParam::CipherParamOneOf,
566 keymint_auto_adds: AutoAddedCharacteristic(false),
567 lifetime: ValueLifetime::Variable,
568 cert_gen: CertGenParam::NotRequired,
569 bit_index: 23,
570 },
571 ),
572 (
573 Tag::AuthTimeout,
574 Info {
575 name: "AUTH_TIMEOUT",
576 tt: TagType::Uint,
577 ext_asn1_type: Some("INTEGER"),
578 user_can_specify: UserSpecifiable(true),
579 characteristic: Characteristic::KeyMintEnforced,
580 op_param: OperationParam::NotOperationParam,
581 keymint_auto_adds: AutoAddedCharacteristic(false),
582 lifetime: ValueLifetime::Variable,
583 cert_gen: CertGenParam::NotRequired,
584 bit_index: 24,
585 },
586 ),
587 (
588 Tag::AllowWhileOnBody,
589 Info {
590 name: "ALLOW_WHILE_ON_BODY",
591 tt: TagType::Bool,
592 ext_asn1_type: Some("NULL"),
593 user_can_specify: UserSpecifiable(true),
594 characteristic: Characteristic::KeystoreEnforced,
595 op_param: OperationParam::NotOperationParam,
596 keymint_auto_adds: AutoAddedCharacteristic(false),
597 lifetime: ValueLifetime::Variable,
598 cert_gen: CertGenParam::NotRequired,
599 bit_index: 25,
600 },
601 ),
602 (
603 Tag::TrustedUserPresenceRequired,
604 Info {
605 name: "TRUSTED_USER_PRESENCE_REQUIRED",
606 tt: TagType::Bool,
607 ext_asn1_type: Some("NULL"),
608 user_can_specify: UserSpecifiable(true),
609 characteristic: Characteristic::KeyMintEnforced,
610 op_param: OperationParam::NotOperationParam,
611 keymint_auto_adds: AutoAddedCharacteristic(false),
612 lifetime: ValueLifetime::Variable,
613 cert_gen: CertGenParam::NotRequired,
614 bit_index: 26,
615 },
616 ),
617 (
618 Tag::TrustedConfirmationRequired,
619 Info {
620 name: "TRUSTED_CONFIRMATION_REQUIRED",
621 tt: TagType::Bool,
622 ext_asn1_type: Some("NULL"),
623 user_can_specify: UserSpecifiable(true),
624 characteristic: Characteristic::KeyMintEnforced,
625 op_param: OperationParam::NotOperationParam,
626 keymint_auto_adds: AutoAddedCharacteristic(false),
627 lifetime: ValueLifetime::Variable,
628 cert_gen: CertGenParam::NotRequired,
629 bit_index: 27,
630 },
631 ),
632 (
633 Tag::UnlockedDeviceRequired,
634 Info {
635 name: "UNLOCKED_DEVICE_REQUIRED",
636 tt: TagType::Bool,
637 ext_asn1_type: Some("NULL"),
638 user_can_specify: UserSpecifiable(true),
639 characteristic: Characteristic::KeystoreEnforced,
640 op_param: OperationParam::NotOperationParam,
641 keymint_auto_adds: AutoAddedCharacteristic(false),
642 lifetime: ValueLifetime::Variable,
643 cert_gen: CertGenParam::NotRequired,
644 bit_index: 28,
645 },
646 ),
647 (
648 Tag::ApplicationId,
649 Info {
650 name: "APPLICATION_ID",
651 tt: TagType::Bytes,
652 ext_asn1_type: None,
653 user_can_specify: UserSpecifiable(true),
654 characteristic: Characteristic::KeyMintHidden,
655 op_param: OperationParam::CipherParamExactMatch,
656 keymint_auto_adds: AutoAddedCharacteristic(false),
657 lifetime: ValueLifetime::Variable,
658 cert_gen: CertGenParam::NotRequired,
659 bit_index: 29,
660 },
661 ),
662 (
663 Tag::ApplicationData,
664 Info {
665 name: "APPLICATION_DATA",
666 tt: TagType::Bytes,
667 ext_asn1_type: None,
668 user_can_specify: UserSpecifiable(true),
669 characteristic: Characteristic::KeyMintHidden,
670 op_param: OperationParam::CipherParamExactMatch,
671 keymint_auto_adds: AutoAddedCharacteristic(false),
672 lifetime: ValueLifetime::Variable,
673 cert_gen: CertGenParam::NotRequired,
674 bit_index: 30,
675 },
676 ),
677 (
678 Tag::CreationDatetime,
679 Info {
680 name: "CREATION_DATETIME",
681 tt: TagType::Date,
682 ext_asn1_type: Some("INTEGER"),
683 user_can_specify: UserSpecifiable(true),
684 characteristic: Characteristic::KeystoreEnforced,
685 op_param: OperationParam::NotOperationParam,
686 keymint_auto_adds: AutoAddedCharacteristic(false),
687 lifetime: ValueLifetime::Variable,
688 // If `Tag::IncludeUniqueId` is specified for attestation extension
689 // generation, then a value for `Tag::CreationDatetime` is needed for
690 // the calculation of the unique ID value.
691 cert_gen: CertGenParam::Special,
692 bit_index: 31,
693 },
694 ),
695 (
696 Tag::Origin,
697 Info {
698 name: "ORIGIN",
699 tt: TagType::Enum,
700 ext_asn1_type: Some("INTEGER"),
701 user_can_specify: UserSpecifiable(false),
702 characteristic: Characteristic::KeyMintEnforced,
703 op_param: OperationParam::NotOperationParam,
704 keymint_auto_adds: AutoAddedCharacteristic(true),
705 lifetime: ValueLifetime::Variable,
706 cert_gen: CertGenParam::NotRequired,
707 bit_index: 32,
708 },
709 ),
710 (
711 Tag::RootOfTrust,
712 Info {
713 name: "ROOT_OF_TRUST",
714 tt: TagType::Bytes,
715 ext_asn1_type: Some("RootOfTrust SEQUENCE"),
716 user_can_specify: UserSpecifiable(false),
717 // The root of trust is neither a key characteristic nor an operation parameter.
718 // The tag exists only to reserve a numeric value that can be used in the
719 // attestation extension record.
720 characteristic: Characteristic::NotKeyCharacteristic,
721 op_param: OperationParam::NotOperationParam,
722 keymint_auto_adds: AutoAddedCharacteristic(false),
723 lifetime: ValueLifetime::FixedAtBoot,
724 cert_gen: CertGenParam::NotRequired,
725 bit_index: 33,
726 },
727 ),
728 (
729 Tag::OsVersion,
730 Info {
731 name: "OS_VERSION",
732 tt: TagType::Uint,
733 ext_asn1_type: Some("INTEGER"),
734 user_can_specify: UserSpecifiable(false),
735 characteristic: Characteristic::KeyMintEnforced,
736 op_param: OperationParam::NotOperationParam,
737 keymint_auto_adds: AutoAddedCharacteristic(true),
738 lifetime: ValueLifetime::FixedAtBoot,
739 cert_gen: CertGenParam::NotRequired,
740 bit_index: 34,
741 },
742 ),
743 (
744 Tag::OsPatchlevel,
745 Info {
746 name: "OS_PATCHLEVEL",
747 tt: TagType::Uint,
748 ext_asn1_type: Some("INTEGER"),
749 user_can_specify: UserSpecifiable(false),
750 characteristic: Characteristic::KeyMintEnforced,
751 op_param: OperationParam::NotOperationParam,
752 keymint_auto_adds: AutoAddedCharacteristic(true),
753 lifetime: ValueLifetime::FixedAtBoot,
754 cert_gen: CertGenParam::NotRequired,
755 bit_index: 35,
756 },
757 ),
758 (
759 Tag::UniqueId,
760 Info {
761 name: "UNIQUE_ID",
762 tt: TagType::Bytes,
763 ext_asn1_type: Some("OCTET STRING"),
764 user_can_specify: UserSpecifiable(false),
765 // The unique ID is neither a key characteristic nor an operation parameter.
766 //
767 // The docs claim that tag exists only to reserve a numeric value that can be used in
768 // the attestation extension record created on key generation.
769 //
770 // However, the unique ID gets a field of its own in the top-level KeyDescription
771 // SEQUENCE; it does not appear in the AuthorizationList SEQUENCE, so this tag value
772 // should never be seen anywhere.
773 characteristic: Characteristic::NotKeyCharacteristic,
774 op_param: OperationParam::NotOperationParam,
775 keymint_auto_adds: AutoAddedCharacteristic(false),
776 lifetime: ValueLifetime::Variable,
777 cert_gen: CertGenParam::Special,
778 bit_index: 36,
779 },
780 ),
781 (
782 Tag::AttestationChallenge,
783 Info {
784 name: "ATTESTATION_CHALLENGE",
785 tt: TagType::Bytes,
786 ext_asn1_type: Some("OCTET STRING"),
787 user_can_specify: UserSpecifiable(true),
788 characteristic: Characteristic::NotKeyCharacteristic,
789 op_param: OperationParam::KeyGenImport,
790 keymint_auto_adds: AutoAddedCharacteristic(false),
791 lifetime: ValueLifetime::Variable,
792 cert_gen: CertGenParam::RequiredForAttestation,
793 bit_index: 37,
794 },
795 ),
796 (
797 Tag::AttestationApplicationId,
798 Info {
799 name: "ATTESTATION_APPLICATION_ID",
800 tt: TagType::Bytes,
801 ext_asn1_type: Some("OCTET STRING"),
802 user_can_specify: UserSpecifiable(true),
803 characteristic: Characteristic::NotKeyCharacteristic,
804 op_param: OperationParam::KeyGenImport,
805 keymint_auto_adds: AutoAddedCharacteristic(false),
806 lifetime: ValueLifetime::Variable,
807 cert_gen: CertGenParam::RequiredForAttestation,
808 bit_index: 38,
809 },
810 ),
811 (
812 Tag::AttestationIdBrand,
813 Info {
814 name: "ATTESTATION_ID_BRAND",
815 tt: TagType::Bytes,
816 ext_asn1_type: Some("OCTET STRING"),
817 user_can_specify: UserSpecifiable(true),
818 characteristic: Characteristic::NotKeyCharacteristic,
819 op_param: OperationParam::KeyGenImport,
820 keymint_auto_adds: AutoAddedCharacteristic(false),
821 lifetime: ValueLifetime::FixedAtBoot,
822 cert_gen: CertGenParam::OptionalForAttestation,
823 bit_index: 39,
824 },
825 ),
826 (
827 Tag::AttestationIdDevice,
828 Info {
829 name: "ATTESTATION_ID_DEVICE",
830 tt: TagType::Bytes,
831 ext_asn1_type: Some("OCTET STRING"),
832 user_can_specify: UserSpecifiable(true),
833 characteristic: Characteristic::NotKeyCharacteristic,
834 op_param: OperationParam::KeyGenImport,
835 keymint_auto_adds: AutoAddedCharacteristic(false),
836 lifetime: ValueLifetime::FixedAtBoot,
837 cert_gen: CertGenParam::OptionalForAttestation,
838 bit_index: 40,
839 },
840 ),
841 (
842 Tag::AttestationIdProduct,
843 Info {
844 name: "ATTESTATION_ID_PRODUCT",
845 tt: TagType::Bytes,
846 ext_asn1_type: Some("OCTET STRING"),
847 user_can_specify: UserSpecifiable(true),
848 characteristic: Characteristic::NotKeyCharacteristic,
849 op_param: OperationParam::KeyGenImport,
850 keymint_auto_adds: AutoAddedCharacteristic(false),
851 lifetime: ValueLifetime::FixedAtBoot,
852 cert_gen: CertGenParam::OptionalForAttestation,
853 bit_index: 41,
854 },
855 ),
856 (
857 Tag::AttestationIdSerial,
858 Info {
859 name: "ATTESTATION_ID_SERIAL",
860 tt: TagType::Bytes,
861 ext_asn1_type: Some("OCTET STRING"),
862 user_can_specify: UserSpecifiable(true),
863 characteristic: Characteristic::NotKeyCharacteristic,
864 op_param: OperationParam::KeyGenImport,
865 keymint_auto_adds: AutoAddedCharacteristic(false),
866 lifetime: ValueLifetime::FixedAtBoot,
867 cert_gen: CertGenParam::OptionalForAttestation,
868 bit_index: 42,
869 },
870 ),
871 (
872 Tag::AttestationIdImei,
873 Info {
874 name: "ATTESTATION_ID_IMEI",
875 tt: TagType::Bytes,
876 ext_asn1_type: Some("OCTET STRING"),
877 user_can_specify: UserSpecifiable(true),
878 characteristic: Characteristic::NotKeyCharacteristic,
879 op_param: OperationParam::KeyGenImport,
880 keymint_auto_adds: AutoAddedCharacteristic(false),
881 lifetime: ValueLifetime::FixedAtBoot,
882 cert_gen: CertGenParam::OptionalForAttestation,
883 bit_index: 43,
884 },
885 ),
886 (
887 Tag::AttestationIdSecondImei,
888 Info {
889 name: "ATTESTATION_ID_SECOND_IMEI",
890 tt: TagType::Bytes,
891 ext_asn1_type: Some("OCTET STRING"),
892 user_can_specify: UserSpecifiable(true),
893 characteristic: Characteristic::NotKeyCharacteristic,
894 op_param: OperationParam::KeyGenImport,
895 keymint_auto_adds: AutoAddedCharacteristic(false),
896 lifetime: ValueLifetime::FixedAtBoot,
897 cert_gen: CertGenParam::OptionalForAttestation,
898 bit_index: 44,
899 },
900 ),
901 (
902 Tag::AttestationIdMeid,
903 Info {
904 name: "ATTESTATION_ID_MEID",
905 tt: TagType::Bytes,
906 ext_asn1_type: Some("OCTET STRING"),
907 user_can_specify: UserSpecifiable(true),
908 characteristic: Characteristic::NotKeyCharacteristic,
909 op_param: OperationParam::KeyGenImport,
910 keymint_auto_adds: AutoAddedCharacteristic(false),
911 lifetime: ValueLifetime::FixedAtBoot,
912 cert_gen: CertGenParam::OptionalForAttestation,
913 bit_index: 45,
914 },
915 ),
916 (
917 Tag::AttestationIdManufacturer,
918 Info {
919 name: "ATTESTATION_ID_MANUFACTURER",
920 tt: TagType::Bytes,
921 ext_asn1_type: Some("OCTET STRING"),
922 user_can_specify: UserSpecifiable(true),
923 characteristic: Characteristic::NotKeyCharacteristic,
924 op_param: OperationParam::KeyGenImport,
925 keymint_auto_adds: AutoAddedCharacteristic(false),
926 lifetime: ValueLifetime::FixedAtBoot,
927 cert_gen: CertGenParam::OptionalForAttestation,
928 bit_index: 46,
929 },
930 ),
931 (
932 Tag::AttestationIdModel,
933 Info {
934 name: "ATTESTATION_ID_MODEL",
935 tt: TagType::Bytes,
936 ext_asn1_type: Some("OCTET STRING"),
937 user_can_specify: UserSpecifiable(true),
938 characteristic: Characteristic::NotKeyCharacteristic,
939 op_param: OperationParam::KeyGenImport,
940 keymint_auto_adds: AutoAddedCharacteristic(false),
941 lifetime: ValueLifetime::FixedAtBoot,
942 cert_gen: CertGenParam::OptionalForAttestation,
943 bit_index: 47,
944 },
945 ),
946 (
947 Tag::VendorPatchlevel,
948 Info {
949 name: "VENDOR_PATCHLEVEL",
950 tt: TagType::Uint,
951 ext_asn1_type: Some("INTEGER"),
952 user_can_specify: UserSpecifiable(false),
953 characteristic: Characteristic::KeyMintEnforced,
954 op_param: OperationParam::NotOperationParam,
955 keymint_auto_adds: AutoAddedCharacteristic(true),
956 lifetime: ValueLifetime::FixedAtStartup,
957 cert_gen: CertGenParam::NotRequired,
958 bit_index: 48,
959 },
960 ),
961 (
962 Tag::BootPatchlevel,
963 Info {
964 name: "BOOT_PATCHLEVEL",
965 tt: TagType::Uint,
966 ext_asn1_type: Some("INTEGER"),
967 user_can_specify: UserSpecifiable(false),
968 characteristic: Characteristic::KeyMintEnforced,
969 op_param: OperationParam::NotOperationParam,
970 keymint_auto_adds: AutoAddedCharacteristic(true),
971 lifetime: ValueLifetime::FixedAtBoot,
972 cert_gen: CertGenParam::NotRequired,
973 bit_index: 49,
974 },
975 ),
976 (
977 Tag::DeviceUniqueAttestation,
978 Info {
979 name: "DEVICE_UNIQUE_ATTESTATION",
980 tt: TagType::Bool,
981 ext_asn1_type: Some("NULL"),
982 user_can_specify: UserSpecifiable(true),
983 characteristic: Characteristic::NotKeyCharacteristic,
984 op_param: OperationParam::KeyGenImport,
985 keymint_auto_adds: AutoAddedCharacteristic(false),
986 lifetime: ValueLifetime::Variable,
987 // Device unique attestation does not affect the contents of the `tbsCertificate`,
988 // but it does change the chain used to sign the resulting certificate.
989 cert_gen: CertGenParam::Special,
990 bit_index: 50,
991 },
992 ),
993 // A key marked as a storage key cannot be used via most of the KeyMint API. Instead, it
994 // can be passed to `convertStorageKeyToEphemeral` to convert it to an ephemeral key.
995 (
996 Tag::StorageKey,
997 Info {
998 name: "STORAGE_KEY",
999 tt: TagType::Bool,
1000 ext_asn1_type: None,
1001 user_can_specify: UserSpecifiable(true),
1002 characteristic: Characteristic::KeyMintEnforced,
1003 op_param: OperationParam::NotOperationParam,
1004 keymint_auto_adds: AutoAddedCharacteristic(false),
1005 lifetime: ValueLifetime::Variable,
1006 cert_gen: CertGenParam::NotRequired,
1007 bit_index: 51,
1008 },
1009 ),
1010 // Can only be user-specified if CALLER_NONCE set in key characteristics.
1011 (
1012 Tag::Nonce,
1013 Info {
1014 name: "NONCE",
1015 tt: TagType::Bytes,
1016 ext_asn1_type: None,
1017 user_can_specify: UserSpecifiable(true),
1018 characteristic: Characteristic::NotKeyCharacteristic,
1019 op_param: OperationParam::CipherParam,
1020 keymint_auto_adds: AutoAddedCharacteristic(false),
1021 lifetime: ValueLifetime::Variable,
1022 cert_gen: CertGenParam::NotRequired,
1023 bit_index: 52,
1024 },
1025 ),
1026 (
1027 Tag::MacLength,
1028 Info {
1029 name: "MAC_LENGTH",
1030 tt: TagType::Uint,
1031 ext_asn1_type: None,
1032 user_can_specify: UserSpecifiable(true),
1033 characteristic: Characteristic::NotKeyCharacteristic,
1034 op_param: OperationParam::CipherParam,
1035 keymint_auto_adds: AutoAddedCharacteristic(false),
1036 lifetime: ValueLifetime::Variable,
1037 cert_gen: CertGenParam::NotRequired,
1038 bit_index: 53,
1039 },
1040 ),
1041 (
1042 Tag::ResetSinceIdRotation,
1043 Info {
1044 name: "RESET_SINCE_ID_ROTATION",
1045 tt: TagType::Bool,
1046 ext_asn1_type: Some("part of UniqueID"),
1047 user_can_specify: UserSpecifiable(true),
1048 characteristic: Characteristic::NotKeyCharacteristic,
1049 op_param: OperationParam::KeyGenImport,
1050 keymint_auto_adds: AutoAddedCharacteristic(false),
1051 lifetime: ValueLifetime::Variable,
1052 cert_gen: CertGenParam::OptionalForAttestation,
1053 bit_index: 54,
1054 },
1055 ),
1056 // Default to 1 if not present
1057 (
1058 Tag::CertificateSerial,
1059 Info {
1060 name: "CERTIFICATE_SERIAL",
1061 tt: TagType::Bignum,
1062 ext_asn1_type: None,
1063 user_can_specify: UserSpecifiable(true),
1064 characteristic: Characteristic::NotKeyCharacteristic,
1065 op_param: OperationParam::KeyGenImport,
1066 keymint_auto_adds: AutoAddedCharacteristic(false),
1067 lifetime: ValueLifetime::Variable,
1068 cert_gen: CertGenParam::Optional,
1069 bit_index: 55,
1070 },
1071 ),
1072 // Default to "CN=Android Keystore Key" if not present
1073 (
1074 Tag::CertificateSubject,
1075 Info {
1076 name: "CERTIFICATE_SUBJECT",
1077 tt: TagType::Bytes,
1078 ext_asn1_type: None,
1079 user_can_specify: UserSpecifiable(true),
1080 characteristic: Characteristic::NotKeyCharacteristic,
1081 op_param: OperationParam::KeyGenImport,
1082 keymint_auto_adds: AutoAddedCharacteristic(false),
1083 lifetime: ValueLifetime::Variable,
1084 cert_gen: CertGenParam::Optional,
1085 bit_index: 56,
1086 },
1087 ),
1088 (
1089 Tag::CertificateNotBefore,
1090 Info {
1091 name: "CERTIFICATE_NOT_BEFORE",
1092 tt: TagType::Date,
1093 ext_asn1_type: None,
1094 user_can_specify: UserSpecifiable(true),
1095 characteristic: Characteristic::NotKeyCharacteristic,
1096 op_param: OperationParam::KeyGenImport,
1097 keymint_auto_adds: AutoAddedCharacteristic(false),
1098 lifetime: ValueLifetime::Variable,
1099 cert_gen: CertGenParam::Required,
1100 bit_index: 57,
1101 },
1102 ),
1103 (
1104 Tag::CertificateNotAfter,
1105 Info {
1106 name: "CERTIFICATE_NOT_AFTER",
1107 tt: TagType::Date,
1108 ext_asn1_type: None,
1109 user_can_specify: UserSpecifiable(true),
1110 characteristic: Characteristic::NotKeyCharacteristic,
1111 op_param: OperationParam::KeyGenImport,
1112 keymint_auto_adds: AutoAddedCharacteristic(false),
1113 lifetime: ValueLifetime::Variable,
1114 cert_gen: CertGenParam::Required,
1115 bit_index: 58,
1116 },
1117 ),
1118 (
1119 Tag::MaxBootLevel,
1120 Info {
1121 name: "MAX_BOOT_LEVEL",
1122 tt: TagType::Uint,
1123 ext_asn1_type: None,
1124 user_can_specify: UserSpecifiable(true),
1125 characteristic: Characteristic::KeystoreEnforced,
1126 op_param: OperationParam::NotOperationParam,
1127 keymint_auto_adds: AutoAddedCharacteristic(false),
1128 lifetime: ValueLifetime::Variable,
1129 cert_gen: CertGenParam::NotRequired,
1130 bit_index: 59,
1131 },
1132 ),
1133 (
1134 Tag::ModuleHash,
1135 Info {
1136 name: "MODULE_HASH",
1137 tt: TagType::Bytes,
1138 ext_asn1_type: Some("OCTET STRING"),
1139 user_can_specify: UserSpecifiable(false),
1140 // The module hash is neither a key characteristic nor an operation parameter.
1141 // The tag exists only to reserve a numeric value that can be used in the
1142 // attestation extension record.
1143 characteristic: Characteristic::NotKeyCharacteristic,
1144 op_param: OperationParam::NotOperationParam,
1145 keymint_auto_adds: AutoAddedCharacteristic(false),
1146 lifetime: ValueLifetime::FixedAtStartup,
1147 cert_gen: CertGenParam::NotRequired,
1148 bit_index: 60,
1149 },
1150 ),
1151 ];
1152
1153 /// Return behaviour information about the specified tag.
info(tag: Tag) -> Result<&'static Info, Error>1154 pub fn info(tag: Tag) -> Result<&'static Info, Error> {
1155 for (t, info) in &INFO {
1156 if tag == *t {
1157 return Ok(info);
1158 }
1159 }
1160 Err(km_err!(InvalidTag, "unknown tag {:?}", tag))
1161 }
1162
1163 /// Indicate whether a tag is allowed to have multiple values.
1164 #[inline]
multivalued(tag: Tag) -> bool1165 pub fn multivalued(tag: Tag) -> bool {
1166 matches!(
1167 kmr_wire::keymint::tag_type(tag),
1168 TagType::EnumRep | TagType::UintRep | TagType::UlongRep
1169 )
1170 }
1171
1172 /// Tracker for observed tag values.
1173 #[derive(Default)]
1174 pub struct DuplicateTagChecker(u64);
1175
1176 impl DuplicateTagChecker {
1177 /// Add the given tag to the set of seen tags, failing if the tag
1178 /// has already been observed (and is not multivalued).
add(&mut self, tag: Tag) -> Result<(), Error>1179 pub fn add(&mut self, tag: Tag) -> Result<(), Error> {
1180 let bit_idx = info(tag)?.bit_index;
1181 let bit_mask = 0x01u64 << bit_idx;
1182 if !multivalued(tag) && (self.0 & bit_mask) != 0 {
1183 return Err(km_err!(InvalidKeyBlob, "duplicate value for {:?}", tag));
1184 }
1185 self.0 |= bit_mask;
1186 Ok(())
1187 }
1188 }
1189