xref: /aosp_15_r20/system/keymint/common/src/tag/info.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! 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