@@ -20,7 +20,11 @@ pub fn read_full(
20
20
auth_handle : NvAuth ,
21
21
nv_index_handle : NvIndexTpmHandle ,
22
22
) -> 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) ?;
24
28
let mut result = Vec :: with_capacity ( rw. size ( ) ) ;
25
29
26
30
let _ = rw. read_to_end ( & mut result) . map_err ( |e| {
@@ -80,47 +84,34 @@ pub fn list(context: &mut Context) -> Result<Vec<(NvPublic, Name)>> {
80
84
}
81
85
82
86
/// 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
+ } ,
89
100
}
90
101
91
102
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
-
108
103
/// Opens a non-volatile storage index using the options specified by `self`
109
104
///
110
105
/// 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) ?;
120
108
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) ;
124
115
let nv_idx = context
125
116
. execute_without_session ( |ctx| ctx. tr_from_tpm_public ( nv_idx) ) ?
126
117
. into ( ) ;
@@ -129,23 +120,26 @@ impl NvOpenOptions {
129
120
. execute_without_session ( |ctx| ctx. nv_read_public ( nv_idx) )
130
121
. map ( |( nvpub, _) | nvpub. data_size ( ) ) ?,
131
122
nv_idx,
123
+ auth_handle,
132
124
)
133
125
}
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
+ ) ,
144
138
} ;
145
139
146
140
Ok ( NvReaderWriter {
147
141
context,
148
- auth_handle,
142
+ auth_handle : * auth_handle ,
149
143
buffer_size,
150
144
nv_idx,
151
145
data_size,
@@ -154,6 +148,19 @@ impl NvOpenOptions {
154
148
}
155
149
}
156
150
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
+
157
164
/// Non-volatile storage index reader/writer
158
165
///
159
166
/// Provides methods and trait implementations to interact with a non-volatile storage index that has been opened.
0 commit comments