1 //! Defines the context type for a session handling hwtrust data structures. 2 3 use crate::dice::ProfileVersion; 4 use anyhow::bail; 5 use clap::ValueEnum; 6 use std::ops::RangeInclusive; 7 use std::str::FromStr; 8 9 /// The context for a session handling hwtrust data structures. 10 #[derive(Clone, Default, Debug)] 11 pub struct Session { 12 /// Options that control the behaviour during this session. 13 pub options: Options, 14 } 15 16 /// Options that control the behaviour of a session. 17 #[derive(Clone, Default, Debug)] 18 pub struct Options { 19 /// The range of supported Android Profile for DICE versions. 20 pub dice_profile_range: DiceProfileRange, 21 /// Allows DICE chains to have non-normal mode values. 22 pub allow_any_mode: bool, 23 /// The RKP instance associated to the session. 24 pub rkp_instance: RkpInstance, 25 /// This flag is used during DeviceInfo validation 26 pub is_factory: bool, 27 /// Verbose output 28 pub verbose: bool, 29 } 30 31 /// The set of RKP instances associated to the session. 32 #[derive(Clone, Copy, Default, Debug, ValueEnum, PartialEq, Eq)] 33 pub enum RkpInstance { 34 /// The DICE chain is associated to the default instance. 35 #[default] 36 Default, 37 /// The DICE chain is associated to the strongbox instance. 38 Strongbox, 39 /// The DICE chain is associated to the avf instance. 40 /// This option performs additional checks to ensure the chain conforms to the requirements 41 /// for an RKP VM chain. For detailed information, refer to the RKP VM specification: 42 /// https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/docs/vm_remote_attestation.md#rkp-vm-marker 43 Avf, 44 /// The DICE chain is associated to the Widevine instance. 45 Widevine, 46 } 47 48 impl FromStr for RkpInstance { 49 type Err = anyhow::Error; 50 from_str(s: &str) -> Result<Self, Self::Err>51 fn from_str(s: &str) -> Result<Self, Self::Err> { 52 match s { 53 "default" => Ok(RkpInstance::Default), 54 "strongbox" => Ok(RkpInstance::Strongbox), 55 "avf" => Ok(RkpInstance::Avf), 56 "widevine" => Ok(RkpInstance::Widevine), 57 _ => bail!("invalid RKP instance: {}", s), 58 } 59 } 60 } 61 62 impl Session { 63 /// Set is_factory set_is_factory(&mut self, is_factory: bool)64 pub fn set_is_factory(&mut self, is_factory: bool) { 65 self.options.is_factory = is_factory; 66 } 67 68 /// Set allow_any_mode. set_allow_any_mode(&mut self, allow_any_mode: bool)69 pub fn set_allow_any_mode(&mut self, allow_any_mode: bool) { 70 self.options.allow_any_mode = allow_any_mode 71 } 72 73 /// Sets the RKP instance associated to the session. set_rkp_instance(&mut self, rkp_instance: RkpInstance)74 pub fn set_rkp_instance(&mut self, rkp_instance: RkpInstance) { 75 self.options.rkp_instance = rkp_instance 76 } 77 } 78 79 /// An inclusive range of Android Profile for DICE versions. 80 #[derive(Clone, Debug, PartialEq, Eq)] 81 pub struct DiceProfileRange(RangeInclusive<ProfileVersion>); 82 83 impl DiceProfileRange { 84 /// Creates a new inclusive range of Android Profile for DICE versions. new(start: ProfileVersion, end: ProfileVersion) -> Self85 pub fn new(start: ProfileVersion, end: ProfileVersion) -> Self { 86 Self(RangeInclusive::new(start, end)) 87 } 88 89 /// Returns `true` if `version` is contained in the range. contains(&self, version: ProfileVersion) -> bool90 pub fn contains(&self, version: ProfileVersion) -> bool { 91 self.0.contains(&version) 92 } 93 94 /// Returns the lower bound of the range. start(&self) -> ProfileVersion95 pub fn start(&self) -> ProfileVersion { 96 *self.0.start() 97 } 98 99 /// Returns the upper bound of the range. end(&self) -> ProfileVersion100 pub fn end(&self) -> ProfileVersion { 101 *self.0.end() 102 } 103 } 104 105 impl Default for DiceProfileRange { default() -> Self106 fn default() -> Self { 107 Self::new(ProfileVersion::Android14, ProfileVersion::Android16) 108 } 109 } 110 111 impl Options { 112 /// The options use by VSR 13. vsr13() -> Self113 pub fn vsr13() -> Self { 114 Self { 115 dice_profile_range: DiceProfileRange::new( 116 ProfileVersion::Android13, 117 ProfileVersion::Android15, 118 ), 119 ..Default::default() 120 } 121 } 122 123 /// The options use by VSR 14. vsr14() -> Self124 pub fn vsr14() -> Self { 125 Self { 126 dice_profile_range: DiceProfileRange::new( 127 ProfileVersion::Android14, 128 ProfileVersion::Android15, 129 ), 130 ..Default::default() 131 } 132 } 133 134 /// The options use by VSR 15. vsr15() -> Self135 pub fn vsr15() -> Self { 136 Self { 137 dice_profile_range: DiceProfileRange::new( 138 ProfileVersion::Android14, 139 ProfileVersion::Android15, 140 ), 141 ..Default::default() 142 } 143 } 144 145 /// The options use by VSR 16. vsr16() -> Self146 pub fn vsr16() -> Self { 147 Self { 148 dice_profile_range: DiceProfileRange::new( 149 ProfileVersion::Android14, 150 ProfileVersion::Android16, 151 ), 152 ..Default::default() 153 } 154 } 155 } 156