Skip to content

Commit f0f2906

Browse files
committed
Add marshall_offset to the Marshall trait
Adding a method to the Marshall trait that helps with marshalling multiple structures directly into a larger buffer, automatically keeping track of the offset within the buffer. Also adding a few implemenetations for this new method, and testing. Signed-off-by: Ionut Mihalcea <ionut.mihalcea@arm.com>
1 parent ac55b89 commit f0f2906

File tree

4 files changed

+108
-50
lines changed

4 files changed

+108
-50
lines changed

tss-esapi/src/constants/command_code.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,31 +163,40 @@ impl Marshall for CommandCode {
163163
let mut buffer = vec![0; Self::BUFFER_SIZE];
164164
let mut offset = 0;
165165

166+
self.marshall_offset(&mut buffer, &mut offset)?;
167+
168+
let checked_offset = usize::try_from(offset).map_err(|e| {
169+
error!("Failed to parse offset as usize: {}", e);
170+
Error::local_error(WrapperErrorKind::InvalidParam)
171+
})?;
172+
173+
buffer.truncate(checked_offset);
174+
175+
Ok(buffer)
176+
}
177+
178+
fn marshall_offset(
179+
&self,
180+
marshalled_data: &mut [u8],
181+
offset: &mut std::os::raw::c_ulong,
182+
) -> Result<()> {
166183
ReturnCode::ensure_success(
167184
unsafe {
168185
crate::tss2_esys::Tss2_MU_TPM2_CC_Marshal(
169186
(*self).into(),
170-
buffer.as_mut_ptr(),
171-
Self::BUFFER_SIZE.try_into().map_err(|e| {
187+
marshalled_data.as_mut_ptr(),
188+
marshalled_data.len().try_into().map_err(|e| {
172189
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
173190
Error::local_error(WrapperErrorKind::InvalidParam)
174191
})?,
175-
&mut offset,
192+
offset,
176193
)
177194
},
178195
|ret| {
179196
error!("Failed to marshal CommandCode: {}", ret);
180197
},
181198
)?;
182-
183-
let checked_offset = usize::try_from(offset).map_err(|e| {
184-
error!("Failed to parse offset as usize: {}", e);
185-
Error::local_error(WrapperErrorKind::InvalidParam)
186-
})?;
187-
188-
buffer.truncate(checked_offset);
189-
190-
Ok(buffer)
199+
Ok(())
191200
}
192201
}
193202

tss-esapi/src/interface_types/structure_tags.rs

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,31 +83,41 @@ impl Marshall for AttestationType {
8383
let mut buffer = vec![0; Self::BUFFER_SIZE];
8484
let mut offset = 0;
8585

86+
self.marshall_offset(&mut buffer, &mut offset)?;
87+
88+
let checked_offset = usize::try_from(offset).map_err(|e| {
89+
error!("Failed to parse offset as usize: {}", e);
90+
Error::local_error(WrapperErrorKind::InvalidParam)
91+
})?;
92+
93+
buffer.truncate(checked_offset);
94+
95+
Ok(buffer)
96+
}
97+
98+
fn marshall_offset(
99+
&self,
100+
marshalled_data: &mut [u8],
101+
offset: &mut std::os::raw::c_ulong,
102+
) -> Result<()> {
86103
ReturnCode::ensure_success(
87104
unsafe {
88105
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
89106
(*self).into(),
90-
buffer.as_mut_ptr(),
91-
Self::BUFFER_SIZE.try_into().map_err(|e| {
107+
marshalled_data.as_mut_ptr(),
108+
marshalled_data.len().try_into().map_err(|e| {
92109
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
93110
Error::local_error(WrapperErrorKind::InvalidParam)
94111
})?,
95-
&mut offset,
112+
offset,
96113
)
97114
},
98115
|ret| {
99116
error!("Failed to marshal AttestationType: {}", ret);
100117
},
101118
)?;
102119

103-
let checked_offset = usize::try_from(offset).map_err(|e| {
104-
error!("Failed to parse offset as usize: {}", e);
105-
Error::local_error(WrapperErrorKind::InvalidParam)
106-
})?;
107-
108-
buffer.truncate(checked_offset);
109-
110-
Ok(buffer)
120+
Ok(())
111121
}
112122
}
113123

@@ -195,31 +205,41 @@ impl Marshall for CommandTag {
195205
let mut buffer = vec![0; Self::BUFFER_SIZE];
196206
let mut offset = 0;
197207

208+
self.marshall_offset(&mut buffer, &mut offset)?;
209+
210+
let checked_offset = usize::try_from(offset).map_err(|e| {
211+
error!("Failed to parse offset as usize: {}", e);
212+
Error::local_error(WrapperErrorKind::InvalidParam)
213+
})?;
214+
215+
buffer.truncate(checked_offset);
216+
217+
Ok(buffer)
218+
}
219+
220+
fn marshall_offset(
221+
&self,
222+
marshalled_data: &mut [u8],
223+
offset: &mut std::os::raw::c_ulong,
224+
) -> Result<()> {
198225
ReturnCode::ensure_success(
199226
unsafe {
200227
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
201228
(*self).into(),
202-
buffer.as_mut_ptr(),
203-
Self::BUFFER_SIZE.try_into().map_err(|e| {
229+
marshalled_data.as_mut_ptr(),
230+
marshalled_data.len().try_into().map_err(|e| {
204231
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
205232
Error::local_error(WrapperErrorKind::InvalidParam)
206233
})?,
207-
&mut offset,
234+
offset,
208235
)
209236
},
210237
|ret| {
211238
error!("Failed to marshal CommandTag: {}", ret);
212239
},
213240
)?;
214241

215-
let checked_offset = usize::try_from(offset).map_err(|e| {
216-
error!("Failed to parse offset as usize: {}", e);
217-
Error::local_error(WrapperErrorKind::InvalidParam)
218-
})?;
219-
220-
buffer.truncate(checked_offset);
221-
222-
Ok(buffer)
242+
Ok(())
223243
}
224244
}
225245

tss-esapi/src/traits.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ pub trait Marshall: Sized {
1313
const BUFFER_SIZE: usize;
1414
/// Returns the type in the form of marshalled data
1515
fn marshall(&self) -> Result<Vec<u8>>;
16+
17+
/// Writes the type in the form of marshalled data to `marshalled_data`,
18+
/// and modifies the `offset` to point to the first byte in the buffer
19+
/// which was not written in the conversion.
20+
fn marshall_offset(
21+
&self,
22+
_marshalled_data: &mut [u8],
23+
_offset: &mut std::os::raw::c_ulong,
24+
) -> Result<()> {
25+
unimplemented!();
26+
}
1627
}
1728

1829
/// Trait for types that can be created from
@@ -40,31 +51,41 @@ impl Marshall for u32 {
4051
let mut buffer = vec![0; Self::BUFFER_SIZE];
4152
let mut offset = 0;
4253

54+
self.marshall_offset(&mut buffer, &mut offset)?;
55+
56+
let checked_offset = usize::try_from(offset).map_err(|e| {
57+
error!("Failed to parse offset as usize: {}", e);
58+
Error::local_error(WrapperErrorKind::InvalidParam)
59+
})?;
60+
61+
buffer.truncate(checked_offset);
62+
63+
Ok(buffer)
64+
}
65+
66+
fn marshall_offset(
67+
&self,
68+
marshalled_data: &mut [u8],
69+
offset: &mut std::os::raw::c_ulong,
70+
) -> Result<()> {
4371
ReturnCode::ensure_success(
4472
unsafe {
4573
crate::tss2_esys::Tss2_MU_UINT32_Marshal(
4674
*self,
47-
buffer.as_mut_ptr(),
48-
Self::BUFFER_SIZE.try_into().map_err(|e| {
75+
marshalled_data.as_mut_ptr(),
76+
marshalled_data.len().try_into().map_err(|e| {
4977
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
5078
Error::local_error(WrapperErrorKind::InvalidParam)
5179
})?,
52-
&mut offset,
80+
offset,
5381
)
5482
},
5583
|ret| {
5684
error!("Failed to marshall u32: {}", ret);
5785
},
5886
)?;
5987

60-
let checked_offset = usize::try_from(offset).map_err(|e| {
61-
error!("Failed to parse offset as usize: {}", e);
62-
Error::local_error(WrapperErrorKind::InvalidParam)
63-
})?;
64-
65-
buffer.truncate(checked_offset);
66-
67-
Ok(buffer)
88+
Ok(())
6889
}
6990
}
7091

tss-esapi/tests/integration_tests/common/marshall.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,28 @@ pub fn check_marshall_unmarshall<T: Marshall + UnMarshall + Eq + std::fmt::Debug
1111
}
1212

1313
pub fn check_marshall_unmarshall_offset<T: Marshall + UnMarshall + Eq + std::fmt::Debug>(val: &T) {
14-
let mut buf = val.marshall().expect("Failed to marshall value");
14+
let buf = val.marshall().expect("Failed to marshall value");
1515
let len = buf.len();
16+
17+
let mut buf = vec![0xff; 1024];
1618
let mut offset = 0;
1719

18-
buf.append(&mut buf.clone());
19-
buf.append(&mut vec![0xff; 256]);
20+
val.marshall_offset(&mut buf, &mut offset)
21+
.expect("Failed first marshall_offset");
22+
assert_eq!(offset, len as u64);
23+
24+
val.marshall_offset(&mut buf, &mut offset)
25+
.expect("Failed second marshall_offset");
26+
assert_eq!(offset, (len * 2) as u64);
2027

28+
offset = 0;
2129
let unmarshalled_one =
22-
T::unmarshall_offset(&buf, &mut offset).expect("Failed to unmarshall first copy");
30+
T::unmarshall_offset(&buf, &mut offset).expect("Failed to unmarshall_offset first copy");
2331
assert_eq!(offset, len as u64);
2432
assert_eq!(val, &unmarshalled_one);
2533

2634
let unmarshalled_two =
27-
T::unmarshall_offset(&buf, &mut offset).expect("Failed to unmarshall second copy");
35+
T::unmarshall_offset(&buf, &mut offset).expect("Failed to unmarshall_offset second copy");
2836
assert_eq!(offset, (len * 2) as u64);
2937
assert_eq!(val, &unmarshalled_two);
3038
}

0 commit comments

Comments
 (0)