tpm2_protocol/macro/
response.rs1#[macro_export]
6macro_rules! tpm_response {
7 (
8 $(#[$meta:meta])*
9 $name:ident,
10 $cc:expr,
11 $no_sessions:expr,
12 $with_sessions:expr,
13 $(pub $handle_field:ident: $handle_type:ty,)*
14 {
15 $(pub $param_field:ident: $param_type:ty),*
16 $(,)?
17 }
18 ) => {
19 $(#[$meta])*
20 pub struct $name {
21 $(pub $handle_field: $handle_type,)*
22 $(pub $param_field: $param_type,)*
23 }
24
25 impl $crate::message::TpmHeader for $name {
26 const COMMAND: $crate::data::TpmCc = $cc;
27 const NO_SESSIONS: bool = $no_sessions;
28 const WITH_SESSIONS: bool = $with_sessions;
29 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
30 }
31
32 impl $crate::TpmSized for $name {
33 const SIZE: usize = 0 $(+ <$handle_type>::SIZE)* $(+ <$param_type>::SIZE)*;
34 fn len(&self) -> usize {
35 let params_len: usize = 0 $(+ $crate::TpmSized::len(&self.$param_field))*;
36 let handles_len: usize = 0 $(+ $crate::TpmSized::len(&self.$handle_field))*;
37 let parameter_area_size_field_len: usize = core::mem::size_of::<u32>();
38 handles_len + parameter_area_size_field_len + params_len
39 }
40 }
41
42 impl $crate::TpmBuild for $name {
43 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
44 let params_len: usize = 0 $(+ $crate::TpmSized::len(&self.$param_field))*;
45 let params_len_u32 = u32::try_from(params_len)
46 .map_err(|_| $crate::TpmErrorKind::ValueTooLarge)?;
47
48 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
49 $crate::TpmBuild::build(¶ms_len_u32, writer)?;
50 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
51
52 Ok(())
53 }
54 }
55
56 impl $crate::TpmParse for $name {
57 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
58 #[allow(unused_mut)]
59 let mut cursor = buf;
60 $(
61 let ($handle_field, tail) = <$handle_type>::parse(cursor)?;
62 cursor = tail;
63 )*
64
65 #[allow(unused_mut)]
66 let (mut params, tail) = $crate::TpmParameters::new(cursor)?;
67 $(
68 let $param_field = params.parse::<$param_type>()?;
69 )*
70 if !params.is_empty() {
71 return Err($crate::TpmErrorKind::TrailingData);
72 }
73
74 Ok((
75 Self {
76 $( $handle_field, )*
77 $( $param_field, )*
78 },
79 tail,
80 ))
81 }
82 }
83 };
84}