1 //! Defines the set of validation rules to apply for a DICE profile.
2 
3 use super::KeyOpsType;
4 use crate::dice::ProfileVersion;
5 
6 /// Options that describe an Android Profile for DICE.
7 #[derive(Default)]
8 pub(super) struct Profile {
9     /// The types that are permitted for the key_ops field of COSE_Key objects in the DICE chain.
10     /// This option can be used for compatibility with the RKP HAL before v3 which diverged from
11     /// the COSE spec and allowed a single int instead of always requiring an array.
12     pub(super) key_ops_type: KeyOpsType,
13 
14     /// The types that are permitted for the mode field of the DICE certificates. This option can
15     /// be used for compatibility with the RKP HAL v3 which allowed some deviations from the Open
16     /// Profile for DICE specification.
17     pub(super) mode_type: ModeType,
18 
19     /// Whether to allow the key_usage field of the DICE certificates to be encoded in big-endian
20     /// byte order. This introduces ambiguity of the exact key usage being expressed but the keys
21     /// in the DICE chain are only used for verification so it may be preferable to allow for
22     /// compatibility with implementations that use the wrong endianness.
23     pub(super) allow_big_endian_key_usage: bool,
24 
25     /// The types that are permitted for the component version field in the configuration
26     /// descriptor. The specification has changed the allowed types over time and this option
27     /// can be used to select which rules to apply.
28     pub(super) component_version_type: ComponentVersionType,
29 
30     /// Whether the configuration hash is verified to be present and derived from the configuration
31     /// descriptor. This allows for compatibility with early versions of the RKP HAL which did not
32     /// enforce the requirements on the configuration hash as defined by the Open Profile for DICE.
33     pub(super) config_hash_unverified: bool,
34 
35     /// Whether the security version is a required field in the configuration descriptor.
36     pub(super) security_version_optional: bool,
37 }
38 
39 /// Type allowed for the DICE certificate mode field.
40 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
41 pub(super) enum ModeType {
42     /// The mode field must be a byte string holding a single byte as specified by the Open Profile
43     /// for DICE.
44     #[default]
45     Bytes,
46     /// The mode field can be either an int or a byte string holding a single byte.
47     IntOrBytes,
48 }
49 
50 /// Type allowed for the DICE certificate configuration descriptor's component version field.
51 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
52 pub(super) enum ComponentVersionType {
53     /// The component version can be either an int or a free-form string.
54     #[default]
55     IntOrString,
56     /// The component version must be an int.
57     Int,
58 }
59 
60 impl Profile {
61     /// The rules for the profile used in Android 13.
android13() -> Self62     pub(super) fn android13() -> Self {
63         Self {
64             // Context: b/262599829#comment65
65             key_ops_type: KeyOpsType::IntOrArray,
66             // Context: b/273552826
67             component_version_type: ComponentVersionType::Int,
68             config_hash_unverified: true,
69             security_version_optional: true,
70             ..Self::default()
71         }
72     }
73 
74     /// The rules for the "android.14" profile.
android14() -> Self75     pub(super) fn android14() -> Self {
76         Self {
77             // Context: b/273552826
78             mode_type: ModeType::IntOrBytes,
79             allow_big_endian_key_usage: true,
80             config_hash_unverified: true,
81             security_version_optional: true,
82             ..Self::default()
83         }
84     }
85 
86     /// The rules for the "android.15" profile.
android15() -> Self87     pub(super) fn android15() -> Self {
88         Self { config_hash_unverified: true, security_version_optional: true, ..Self::default() }
89     }
90 
91     /// The rules for the "android.16" profile..
android16() -> Self92     pub(super) fn android16() -> Self {
93         Self::default()
94     }
95 }
96 
97 impl From<ProfileVersion> for Profile {
from(version: ProfileVersion) -> Self98     fn from(version: ProfileVersion) -> Self {
99         match version {
100             ProfileVersion::Android13 => Profile::android13(),
101             ProfileVersion::Android14 => Profile::android14(),
102             ProfileVersion::Android15 => Profile::android15(),
103             ProfileVersion::Android16 => Profile::android16(),
104         }
105     }
106 }
107