tss_esapi/structures/nv/storage/
public.rs1use crate::{
5 attributes::NvIndexAttributes,
6 handles::NvIndexTpmHandle,
7 interface_types::algorithm::HashingAlgorithm,
8 structures::Digest,
9 tss2_esys::{TPM2B_NV_PUBLIC, TPMS_NV_PUBLIC},
10 Error, Result, WrapperErrorKind,
11};
12use log::error;
13use std::{
14 convert::{TryFrom, TryInto},
15 mem::size_of,
16};
17
18#[derive(Debug, Clone, Eq, PartialEq)]
24pub struct NvPublic {
25 nv_index: NvIndexTpmHandle,
26 name_algorithm: HashingAlgorithm,
27 attributes: NvIndexAttributes,
28 authorization_policy: Digest,
29 data_size: usize,
30}
31
32impl NvPublic {
33 const MAX_SIZE: usize = size_of::<TPMS_NV_PUBLIC>();
34
35 pub fn nv_index(&self) -> NvIndexTpmHandle {
36 self.nv_index
37 }
38
39 pub fn name_algorithm(&self) -> HashingAlgorithm {
40 self.name_algorithm
41 }
42
43 pub fn attributes(&self) -> NvIndexAttributes {
44 self.attributes
45 }
46
47 pub fn authorization_policy(&self) -> &Digest {
48 &self.authorization_policy
49 }
50
51 pub fn data_size(&self) -> usize {
52 self.data_size
53 }
54
55 pub const fn builder() -> NvPublicBuilder {
57 NvPublicBuilder::new()
58 }
59}
60
61impl TryFrom<TPM2B_NV_PUBLIC> for NvPublic {
62 type Error = Error;
63 fn try_from(tss_nv_public: TPM2B_NV_PUBLIC) -> Result<NvPublic> {
64 if tss_nv_public.size as usize > NvPublic::MAX_SIZE {
65 error!("Encountered an invalid size of the TPMS_NV_PUBLIC");
66 return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
67 }
68 Ok(NvPublic {
70 nv_index: tss_nv_public.nvPublic.nvIndex.try_into()?,
71 name_algorithm: tss_nv_public.nvPublic.nameAlg.try_into()?,
72 attributes: tss_nv_public.nvPublic.attributes.try_into()?,
73 authorization_policy: tss_nv_public.nvPublic.authPolicy.try_into()?,
74 data_size: tss_nv_public.nvPublic.dataSize as usize,
75 })
76 }
77}
78
79impl TryFrom<NvPublic> for TPM2B_NV_PUBLIC {
80 type Error = Error;
81 fn try_from(nv_public: NvPublic) -> Result<TPM2B_NV_PUBLIC> {
82 Ok(TPM2B_NV_PUBLIC {
83 size: 0,
87 nvPublic: TPMS_NV_PUBLIC {
88 nvIndex: nv_public.nv_index.into(),
89 nameAlg: nv_public.name_algorithm.into(),
90 attributes: nv_public.attributes.try_into()?,
91 authPolicy: nv_public.authorization_policy.into(),
92 dataSize: nv_public.data_size as u16,
93 },
94 })
95 }
96}
97
98#[derive(Debug, Default)]
102pub struct NvPublicBuilder {
103 nv_index: Option<NvIndexTpmHandle>,
104 name_algorithm: Option<HashingAlgorithm>,
105 attributes: Option<NvIndexAttributes>,
106 authorization_policy: Option<Digest>,
107 data_size: Option<usize>,
108}
109
110impl NvPublicBuilder {
111 pub const fn new() -> Self {
112 NvPublicBuilder {
113 nv_index: None,
114 name_algorithm: None,
115 attributes: None,
116 authorization_policy: None,
117 data_size: None,
118 }
119 }
120
121 pub fn with_nv_index(mut self, nv_index: NvIndexTpmHandle) -> Self {
122 self.nv_index = Some(nv_index);
123 self
124 }
125
126 pub fn with_index_name_algorithm(mut self, nv_index_name_algorithm: HashingAlgorithm) -> Self {
127 self.name_algorithm = Some(nv_index_name_algorithm);
128 self
129 }
130
131 pub fn with_index_attributes(mut self, nv_index_attributes: NvIndexAttributes) -> Self {
132 self.attributes = Some(nv_index_attributes);
133 self
134 }
135
136 pub fn with_index_auth_policy(mut self, nv_index_auth_policy: Digest) -> Self {
137 self.authorization_policy = Some(nv_index_auth_policy);
138 self
139 }
140
141 pub fn with_data_area_size(mut self, nv_index_data_area_size: usize) -> Self {
142 self.data_size = Some(nv_index_data_area_size);
143 self
144 }
145
146 pub fn build(self) -> Result<NvPublic> {
147 Ok(NvPublic {
153 nv_index: self.nv_index.ok_or_else(|| {
155 error!("No NV index was specified");
156 Error::local_error(WrapperErrorKind::ParamsMissing)
157 })?,
158 name_algorithm: self.name_algorithm.ok_or_else(|| {
160 error!("No name algorithm was specified");
161 Error::local_error(WrapperErrorKind::ParamsMissing)
162 })?,
163 attributes: self.attributes.ok_or_else(|| {
165 error!("No attributes were specified");
166 Error::local_error(WrapperErrorKind::ParamsMissing)
167 })?,
168 authorization_policy: self.authorization_policy.unwrap_or_default(),
170 data_size: self
172 .data_size
173 .ok_or_else(|| {
174 error!("No data size specified");
175 Error::local_error(WrapperErrorKind::ParamsMissing)
176 })
177 .and_then(|v| {
178 if v > u16::MAX.into() {
179 error!("data area size is too large (>{})", u16::MAX);
180 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
181 }
182 Ok(v)
183 })?,
184 })
185 }
186}