Skip to content

Commit 556c872

Browse files
committed
nv: add nv_increment function
Signed-off-by: Sergey Arnautov <[email protected]>
1 parent 450d20e commit 556c872

File tree

2 files changed

+118
-2
lines changed

2 files changed

+118
-2
lines changed

tss-esapi/src/context/tpm_commands/non_volatile_storage.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::{
66
interface_types::resource_handles::{NvAuth, Provision},
77
structures::{Auth, MaxNvBuffer, Name, NvPublic},
88
tss2_esys::{
9-
Esys_NV_DefineSpace, Esys_NV_Read, Esys_NV_ReadPublic, Esys_NV_UndefineSpace, Esys_NV_Write,
9+
Esys_NV_DefineSpace, Esys_NV_Increment, Esys_NV_Read, Esys_NV_ReadPublic,
10+
Esys_NV_UndefineSpace, Esys_NV_Write,
1011
},
1112
Context, Error, Result,
1213
};
@@ -157,7 +158,35 @@ impl Context {
157158
}
158159
}
159160

160-
// Missing function: NV_Increment
161+
/// Increment monotonic counter index
162+
///
163+
/// # Details
164+
/// This method is used to increment monotonic counter
165+
/// in the TPM.
166+
pub fn nv_increment(
167+
&mut self,
168+
auth_handle: NvAuth,
169+
nv_index_handle: NvIndexHandle,
170+
) -> Result<()> {
171+
let ret = unsafe {
172+
Esys_NV_Increment(
173+
self.mut_context(),
174+
AuthHandle::from(auth_handle).into(),
175+
nv_index_handle.into(),
176+
self.optional_session_1(),
177+
self.optional_session_2(),
178+
self.optional_session_3(),
179+
)
180+
};
181+
let ret = Error::from_tss_rc(ret);
182+
if ret.is_success() {
183+
Ok(())
184+
} else {
185+
error!("Error when incrementing NV: {}", ret);
186+
Err(ret)
187+
}
188+
}
189+
161190
// Missing function: NV_Extend
162191
// Missing function: NV_SetBits
163192
// Missing function: NV_WriteLock

tss-esapi/tests/integration_tests/context_tests/tpm_commands/non_volatile_storage_tests.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,90 @@ mod test_nv_read {
328328
assert_eq!(expected_data, actual_data);
329329
}
330330
}
331+
332+
mod test_nv_increment {
333+
use crate::common::create_ctx_with_session;
334+
use std::convert::TryInto;
335+
use tss_esapi::{
336+
attributes::NvIndexAttributesBuilder,
337+
constants::nv_index_type::NvIndexType,
338+
handles::NvIndexTpmHandle,
339+
interface_types::{
340+
algorithm::HashingAlgorithm,
341+
resource_handles::{NvAuth, Provision},
342+
},
343+
structures::NvPublicBuilder,
344+
};
345+
#[test]
346+
fn test_nv_increment() {
347+
let mut context = create_ctx_with_session();
348+
let nv_index = NvIndexTpmHandle::new(0x01500021).unwrap();
349+
350+
// Create owner nv public.
351+
let owner_nv_index_attributes = NvIndexAttributesBuilder::new()
352+
.with_owner_write(true)
353+
.with_owner_read(true)
354+
.with_nv_index_type(NvIndexType::Counter)
355+
.build()
356+
.expect("Failed to create owner nv index attributes");
357+
358+
let owner_nv_public = NvPublicBuilder::new()
359+
.with_nv_index(nv_index)
360+
.with_index_name_algorithm(HashingAlgorithm::Sha256)
361+
.with_index_attributes(owner_nv_index_attributes)
362+
.with_data_area_size(8)
363+
.build()
364+
.expect("Failed to build NvPublic for owner");
365+
366+
let owner_nv_index_handle = context
367+
.nv_define_space(Provision::Owner, None, owner_nv_public)
368+
.expect("Call to nv_define_space failed");
369+
370+
// Increment the counter using Owner authorization. This call initializes the counter
371+
let increment_result = context.nv_increment(NvAuth::Owner, owner_nv_index_handle);
372+
if let Err(e) = increment_result {
373+
panic!("Failed to perform nv increment: {}", e);
374+
}
375+
376+
// Read the counter using owner authorization (first call)
377+
let read_result_first_value = context.nv_read(NvAuth::Owner, owner_nv_index_handle, 8, 0);
378+
379+
// Increment the counter using Owner authorization (second increment)
380+
let increment_result = context.nv_increment(NvAuth::Owner, owner_nv_index_handle);
381+
if let Err(e) = increment_result {
382+
panic!("Failed to perform nv increment: {}", e);
383+
}
384+
385+
// Read the counter using owner authorization
386+
let read_result_second_value = context.nv_read(NvAuth::Owner, owner_nv_index_handle, 8, 0);
387+
388+
context
389+
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
390+
.expect("Call to nv_undefine_space failed");
391+
392+
// Report error
393+
if let Err(e) = read_result_first_value {
394+
panic!("Failed to read public of nv index: {}", e);
395+
}
396+
if let Err(e) = read_result_second_value {
397+
panic!("Failed to read public of nv index: {}", e);
398+
}
399+
400+
// Check result.
401+
let first_value = u64::from_be_bytes(
402+
read_result_first_value
403+
.unwrap()
404+
.to_vec()
405+
.try_into()
406+
.unwrap(),
407+
);
408+
let second_value = u64::from_be_bytes(
409+
read_result_second_value
410+
.unwrap()
411+
.to_vec()
412+
.try_into()
413+
.unwrap(),
414+
);
415+
assert_eq!(first_value + 1, second_value);
416+
}
417+
}

0 commit comments

Comments
 (0)