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 } 26 27 /// The set of RKP instances associated to the session. 28 #[derive(Clone, Copy, Default, Debug, ValueEnum)] 29 pub enum RkpInstance { 30 /// The DICE chain is associated to the default instance. 31 #[default] 32 Default, 33 /// The DICE chain is associated to the strongbox instance. 34 Strongbox, 35 /// The DICE chain is associated to the avf instance. 36 /// This option performs additional checks to ensure the chain conforms to the requirements 37 /// for an RKP VM chain. For detailed information, refer to the RKP VM specification: 38 /// https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/docs/vm_remote_attestation.md#rkp-vm-marker 39 Avf, 40 /// The DICE chain is associated to the Widevine instance. 41 Widevine, 42 } 43 44 impl FromStr for RkpInstance { 45 type Err = anyhow::Error; 46 from_str(s: &str) -> Result<Self, Self::Err>47 fn from_str(s: &str) -> Result<Self, Self::Err> { 48 match s { 49 "default" => Ok(RkpInstance::Default), 50 "strongbox" => Ok(RkpInstance::Strongbox), 51 "avf" => Ok(RkpInstance::Avf), 52 "widevine" => Ok(RkpInstance::Widevine), 53 _ => bail!("invalid RKP instance: {}", s), 54 } 55 } 56 } 57 58 impl Session { 59 /// Set allow_any_mode. set_allow_any_mode(&mut self, allow_any_mode: bool)60 pub fn set_allow_any_mode(&mut self, allow_any_mode: bool) { 61 self.options.allow_any_mode = allow_any_mode 62 } 63 64 /// Sets the RKP instance associated to the session. set_rkp_instance(&mut self, rkp_instance: RkpInstance)65 pub fn set_rkp_instance(&mut self, rkp_instance: RkpInstance) { 66 self.options.rkp_instance = rkp_instance 67 } 68 } 69 70 /// An inclusive range of Android Profile for DICE versions. 71 #[derive(Clone, Debug, PartialEq, Eq)] 72 pub struct DiceProfileRange(RangeInclusive<ProfileVersion>); 73 74 impl DiceProfileRange { 75 /// Creates a new inclusive range of Android Profile for DICE versions. new(start: ProfileVersion, end: ProfileVersion) -> Self76 pub fn new(start: ProfileVersion, end: ProfileVersion) -> Self { 77 Self(RangeInclusive::new(start, end)) 78 } 79 80 /// Returns `true` if `version` is contained in the range. contains(&self, version: ProfileVersion) -> bool81 pub fn contains(&self, version: ProfileVersion) -> bool { 82 self.0.contains(&version) 83 } 84 85 /// Returns the lower bound of the range. start(&self) -> ProfileVersion86 pub fn start(&self) -> ProfileVersion { 87 *self.0.start() 88 } 89 90 /// Returns the upper bound of the range. end(&self) -> ProfileVersion91 pub fn end(&self) -> ProfileVersion { 92 *self.0.end() 93 } 94 } 95 96 impl Default for DiceProfileRange { default() -> Self97 fn default() -> Self { 98 Self::new(ProfileVersion::Android14, ProfileVersion::Android16) 99 } 100 } 101 102 impl Options { 103 /// The options use by VSR 13. vsr13() -> Self104 pub fn vsr13() -> Self { 105 Self { 106 dice_profile_range: DiceProfileRange::new( 107 ProfileVersion::Android13, 108 ProfileVersion::Android15, 109 ), 110 ..Default::default() 111 } 112 } 113 114 /// The options use by VSR 14. vsr14() -> Self115 pub fn vsr14() -> Self { 116 Self { 117 dice_profile_range: DiceProfileRange::new( 118 ProfileVersion::Android14, 119 ProfileVersion::Android15, 120 ), 121 ..Default::default() 122 } 123 } 124 125 /// The options use by VSR 15. vsr15() -> Self126 pub fn vsr15() -> Self { 127 Self { 128 dice_profile_range: DiceProfileRange::new( 129 ProfileVersion::Android14, 130 ProfileVersion::Android15, 131 ), 132 ..Default::default() 133 } 134 } 135 136 /// The options use by VSR 16. vsr16() -> Self137 pub fn vsr16() -> Self { 138 Self { 139 dice_profile_range: DiceProfileRange::new( 140 ProfileVersion::Android14, 141 ProfileVersion::Android16, 142 ), 143 ..Default::default() 144 } 145 } 146 } 147