Skip to content

Commit 82cca11

Browse files
authored
Merge pull request #342 from ionut-arm/nv-abstraction
Restructure NvOpenOptions
2 parents a301e33 + 81110e6 commit 82cca11

File tree

2 files changed

+59
-51
lines changed
  • tss-esapi

2 files changed

+59
-51
lines changed

tss-esapi/src/abstraction/nv.rs

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ pub fn read_full(
2020
auth_handle: NvAuth,
2121
nv_index_handle: NvIndexTpmHandle,
2222
) -> Result<Vec<u8>> {
23-
let mut rw = NvOpenOptions::new().open(context, auth_handle, nv_index_handle)?;
23+
let mut rw = NvOpenOptions::ExistingIndex {
24+
auth_handle,
25+
nv_index_handle,
26+
}
27+
.open(context)?;
2428
let mut result = Vec::with_capacity(rw.size());
2529

2630
let _ = rw.read_to_end(&mut result).map_err(|e| {
@@ -80,47 +84,34 @@ pub fn list(context: &mut Context) -> Result<Vec<(NvPublic, Name)>> {
8084
}
8185

8286
/// Options and flags which can be used to determine how a non-volatile storage index is opened.
83-
///
84-
/// This builder exposes the ability to determine how a [`NvReaderWriter`] is opened, and is typically used by
85-
/// calling [`NvOpenOptions::new`], chaining method calls to set each option and then calling [`NvOpenOptions::open`].
86-
#[derive(Debug, Clone, Default)]
87-
pub struct NvOpenOptions {
88-
nv_public: Option<NvPublic>,
87+
#[non_exhaustive]
88+
#[derive(Debug, Clone)]
89+
pub enum NvOpenOptions {
90+
/// Define a new NV space with given auth
91+
NewIndex {
92+
nv_public: NvPublic,
93+
auth_handle: NvAuth,
94+
},
95+
/// Open the NV space at the given handle, with the given auth
96+
ExistingIndex {
97+
nv_index_handle: NvIndexTpmHandle,
98+
auth_handle: NvAuth,
99+
},
89100
}
90101

91102
impl NvOpenOptions {
92-
/// Creates a new blank set of options for opening a non-volatile storage index
93-
///
94-
/// All options are initially set to `false`/`None`.
95-
pub fn new() -> Self {
96-
Self { nv_public: None }
97-
}
98-
99-
/// Sets the public attributes to use when creating the non-volatile storage index
100-
///
101-
/// If the public attributes are `None` then the non-volatile storage index will be opened or otherwise
102-
/// it will be created.
103-
pub fn with_nv_public(&mut self, nv_public: Option<NvPublic>) -> &mut Self {
104-
self.nv_public = nv_public;
105-
self
106-
}
107-
108103
/// Opens a non-volatile storage index using the options specified by `self`
109104
///
110105
/// The non-volatile storage index may be used for reading or writing or both.
111-
pub fn open<'a>(
112-
&self,
113-
context: &'a mut Context,
114-
auth_handle: NvAuth,
115-
nv_index_handle: NvIndexTpmHandle,
116-
) -> Result<NvReaderWriter<'a>> {
117-
let buffer_size = context
118-
.get_tpm_property(PropertyTag::NvBufferMax)?
119-
.unwrap_or(MaxNvBuffer::MAX_SIZE as u32) as usize;
106+
pub fn open<'a>(&self, context: &'a mut Context) -> Result<NvReaderWriter<'a>> {
107+
let buffer_size = max_nv_buffer_size(context)?;
120108

121-
let (data_size, nv_idx) = match &self.nv_public {
122-
None => {
123-
let nv_idx = TpmHandle::NvIndex(nv_index_handle);
109+
let (data_size, nv_idx, auth_handle) = match self {
110+
NvOpenOptions::ExistingIndex {
111+
nv_index_handle,
112+
auth_handle,
113+
} => {
114+
let nv_idx = TpmHandle::NvIndex(*nv_index_handle);
124115
let nv_idx = context
125116
.execute_without_session(|ctx| ctx.tr_from_tpm_public(nv_idx))?
126117
.into();
@@ -129,23 +120,26 @@ impl NvOpenOptions {
129120
.execute_without_session(|ctx| ctx.nv_read_public(nv_idx))
130121
.map(|(nvpub, _)| nvpub.data_size())?,
131122
nv_idx,
123+
auth_handle,
132124
)
133125
}
134-
Some(nv_public) => {
135-
if nv_public.nv_index() != nv_index_handle {
136-
return Err(Error::WrapperError(WrapperErrorKind::InconsistentParams));
137-
}
138-
let auth_handle = AuthHandle::from(auth_handle);
139-
(
140-
nv_public.data_size(),
141-
context.nv_define_space(auth_handle.try_into()?, None, nv_public.clone())?,
142-
)
143-
}
126+
NvOpenOptions::NewIndex {
127+
nv_public,
128+
auth_handle,
129+
} => (
130+
nv_public.data_size(),
131+
context.nv_define_space(
132+
AuthHandle::from(*auth_handle).try_into()?,
133+
None,
134+
nv_public.clone(),
135+
)?,
136+
auth_handle,
137+
),
144138
};
145139

146140
Ok(NvReaderWriter {
147141
context,
148-
auth_handle,
142+
auth_handle: *auth_handle,
149143
buffer_size,
150144
nv_idx,
151145
data_size,
@@ -154,6 +148,19 @@ impl NvOpenOptions {
154148
}
155149
}
156150

151+
/// Get the maximum buffer size for an NV space.
152+
pub fn max_nv_buffer_size(ctx: &mut Context) -> Result<usize> {
153+
Ok(ctx
154+
.get_tpm_property(PropertyTag::NvBufferMax)?
155+
.map(usize::try_from)
156+
.transpose()
157+
.map_err(|_| {
158+
log::error!("Failed to obtain valid maximum NV buffer size");
159+
Error::WrapperError(WrapperErrorKind::InternalError)
160+
})?
161+
.unwrap_or(MaxNvBuffer::MAX_SIZE))
162+
}
163+
157164
/// Non-volatile storage index reader/writer
158165
///
159166
/// Provides methods and trait implementations to interact with a non-volatile storage index that has been opened.

tss-esapi/tests/integration_tests/abstraction_tests/nv_tests.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ fn write() {
116116
.with_owner_write(true)
117117
.with_owner_read(true)
118118
.with_pp_read(true)
119-
.with_owner_read(true)
120119
.build()
121120
.expect("Failed to create owner nv index attributes");
122121
let owner_nv_public = NvPublicBuilder::new()
@@ -127,10 +126,12 @@ fn write() {
127126
.build()
128127
.unwrap();
129128

130-
let mut rw = nv::NvOpenOptions::new()
131-
.with_nv_public(Some(owner_nv_public))
132-
.open(&mut context, NvAuth::Owner, nv_index)
133-
.unwrap();
129+
let mut rw = nv::NvOpenOptions::NewIndex {
130+
nv_public: owner_nv_public,
131+
auth_handle: NvAuth::Owner,
132+
}
133+
.open(&mut context)
134+
.unwrap();
134135

135136
let value = [1, 2, 3, 4, 5, 6, 7];
136137
rw.write_all(&value).unwrap();

0 commit comments

Comments
 (0)