1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use wolfhsm_sys::{
wh_Client_CounterDestroy, wh_Client_CounterIncrement, wh_Client_CounterInit,
wh_Client_CounterRead, wh_Client_CounterReset,
};
use crate::client::Client;
use crate::error::Error;
use crate::nvm::NvmId;
impl Client {
/// Create or reinitialize a counter with the given starting value.
///
/// Passes `value` to the server as the desired initial count. Returns the
/// server's confirmed value. Counters saturate at `u32::MAX` — they never
/// wrap.
pub fn counter_init(&mut self, id: NvmId, value: u32) -> Result<u32, Error> {
if id == NvmId::INVALID {
return Err(Error::InvalidInput {
msg: "id must not be NvmId::INVALID (0)",
});
}
let mut counter: u32 = value;
// SAFETY: ctx_ptr is valid for the duration of this call; counter is a
// valid stack location for the IN/OUT parameter.
let rc = unsafe { wh_Client_CounterInit(self.ctx_ptr(), id.0, &mut counter) };
Error::check(rc, "wh_Client_CounterInit")?;
Ok(counter)
}
/// Reset a counter to zero.
///
/// Returns the server's confirmed value (0).
pub fn counter_reset(&mut self, id: NvmId) -> Result<u32, Error> {
let mut counter: u32 = 0;
// SAFETY: ctx_ptr is valid for the duration of this call; counter is a
// valid stack location for the OUT parameter.
let rc = unsafe { wh_Client_CounterReset(self.ctx_ptr(), id.0, &mut counter) };
Error::check(rc, "wh_Client_CounterReset")?;
Ok(counter)
}
/// Increment a counter by 1.
///
/// Returns the value after increment. Saturates at `u32::MAX` per server
/// policy — the value never wraps.
pub fn counter_increment(&mut self, id: NvmId) -> Result<u32, Error> {
let mut counter: u32 = 0;
// SAFETY: ctx_ptr is valid for the duration of this call; counter is a
// valid stack location for the OUT parameter.
let rc = unsafe { wh_Client_CounterIncrement(self.ctx_ptr(), id.0, &mut counter) };
Error::check(rc, "wh_Client_CounterIncrement")?;
Ok(counter)
}
/// Read the current counter value without modifying it.
pub fn counter_read(&mut self, id: NvmId) -> Result<u32, Error> {
let mut counter: u32 = 0;
// SAFETY: ctx_ptr is valid for the duration of this call; counter is a
// valid stack location for the OUT parameter.
let rc = unsafe { wh_Client_CounterRead(self.ctx_ptr(), id.0, &mut counter) };
Error::check(rc, "wh_Client_CounterRead")?;
Ok(counter)
}
/// Permanently destroy a counter.
pub fn counter_destroy(&mut self, id: NvmId) -> Result<(), Error> {
// SAFETY: ctx_ptr is valid for the duration of this call.
let rc = unsafe { wh_Client_CounterDestroy(self.ctx_ptr(), id.0) };
Error::check(rc, "wh_Client_CounterDestroy")
}
}