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 /// Whether the root certificate is allowed to have its mode set to debug. 39 pub(super) allow_root_mode_debug: bool, 40 41 /// Whether the root certificate's authority hash size is allowed to differ from its code hash size. 42 pub(super) allow_root_varied_auth_hash_size: bool, 43 } 44 45 /// Type allowed for the DICE certificate mode field. 46 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] 47 pub(super) enum ModeType { 48 /// The mode field must be a byte string holding a single byte as specified by the Open Profile 49 /// for DICE. 50 #[default] 51 Bytes, 52 /// The mode field can be either an int or a byte string holding a single byte. 53 IntOrBytes, 54 } 55 56 /// Type allowed for the DICE certificate configuration descriptor's component version field. 57 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] 58 pub(super) enum ComponentVersionType { 59 /// The component version can be either an int or a free-form string. 60 #[default] 61 IntOrString, 62 /// The component version must be an int. 63 Int, 64 } 65 66 impl Profile { 67 /// The rules for the profile used in Android 13. android13() -> Self68 pub(super) fn android13() -> Self { 69 Self { 70 // Context: b/262599829#comment65 71 key_ops_type: KeyOpsType::IntOrArray, 72 // Context: b/273552826 73 component_version_type: ComponentVersionType::Int, 74 config_hash_unverified: true, 75 security_version_optional: true, 76 ..Self::default() 77 } 78 } 79 80 /// The rules for the "android.14" profile. android14() -> Self81 pub(super) fn android14() -> Self { 82 Self { 83 // Context: b/273552826 84 mode_type: ModeType::IntOrBytes, 85 allow_big_endian_key_usage: true, 86 config_hash_unverified: true, 87 security_version_optional: true, 88 allow_root_mode_debug: true, 89 allow_root_varied_auth_hash_size: true, 90 ..Self::default() 91 } 92 } 93 94 /// The rules for the "android.15" profile. android15() -> Self95 pub(super) fn android15() -> Self { 96 Self { config_hash_unverified: true, security_version_optional: true, ..Self::default() } 97 } 98 99 /// The rules for the "android.16" profile.. android16() -> Self100 pub(super) fn android16() -> Self { 101 Self::default() 102 } 103 } 104 105 impl From<ProfileVersion> for Profile { from(version: ProfileVersion) -> Self106 fn from(version: ProfileVersion) -> Self { 107 match version { 108 ProfileVersion::Android13 => Profile::android13(), 109 ProfileVersion::Android14 => Profile::android14(), 110 ProfileVersion::Android15 => Profile::android15(), 111 ProfileVersion::Android16 => Profile::android16(), 112 } 113 } 114 } 115