11
11
//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module
12
12
13
13
use super :: { v1, AlgorithmId , EventType , HashAlgorithm , PcrIndex } ;
14
- use crate :: data_types:: { PhysicalAddress , UnalignedSlice } ;
14
+ use crate :: data_types:: { Align , PhysicalAddress , UnalignedSlice } ;
15
15
use crate :: proto:: unsafe_protocol;
16
16
use crate :: util:: { ptr_write_unaligned_and_add, usize_from_u32} ;
17
17
use crate :: { Error , Result , Status , StatusExt } ;
18
18
use bitflags:: bitflags;
19
19
use core:: fmt:: { self , Debug , Formatter } ;
20
20
use core:: marker:: PhantomData ;
21
- use core:: mem:: MaybeUninit ;
22
21
use core:: { mem, ptr, slice} ;
23
22
use ptr_meta:: { Pointee , PtrExt } ;
24
23
24
+ #[ cfg( feature = "alloc" ) ]
25
+ use { crate :: mem:: make_boxed, alloc:: boxed:: Box } ;
26
+
27
+ #[ cfg( all( feature = "unstable" , feature = "alloc" ) ) ]
28
+ use { alloc:: alloc:: Global , core:: alloc:: Allocator } ;
29
+
25
30
/// Version information.
26
31
///
27
32
/// Layout compatible with the C type `EFI_TG2_VERSION`.
@@ -158,7 +163,7 @@ struct EventHeader {
158
163
/// `TCG_PCR_EVENT2` for reading events. To help clarify the usage, our
159
164
/// API renames these types to `PcrEventInputs` and `PcrEvent`,
160
165
/// respectively.
161
- #[ derive( Pointee ) ]
166
+ #[ derive( Eq , Pointee ) ]
162
167
#[ repr( C , packed) ]
163
168
pub struct PcrEventInputs {
164
169
size : u32 ,
@@ -172,24 +177,24 @@ impl PcrEventInputs {
172
177
/// # Errors
173
178
///
174
179
/// Returns [`Status::BUFFER_TOO_SMALL`] if the `buffer` is not large
175
- /// enough.
180
+ /// enough. The required size will be returned in the error data.
176
181
///
177
182
/// Returns [`Status::INVALID_PARAMETER`] if the `event_data` size is too
178
183
/// large.
179
184
pub fn new_in_buffer < ' buf > (
180
- buffer : & ' buf mut [ MaybeUninit < u8 > ] ,
185
+ buffer : & ' buf mut [ u8 ] ,
181
186
pcr_index : PcrIndex ,
182
187
event_type : EventType ,
183
188
event_data : & [ u8 ] ,
184
- ) -> Result < & ' buf Self > {
189
+ ) -> Result < & ' buf mut Self , Option < usize > > {
185
190
let required_size =
186
191
mem:: size_of :: < u32 > ( ) + mem:: size_of :: < EventHeader > ( ) + event_data. len ( ) ;
187
192
188
193
if buffer. len ( ) < required_size {
189
- return Err ( Status :: BUFFER_TOO_SMALL . into ( ) ) ;
194
+ return Err ( Error :: new ( Status :: BUFFER_TOO_SMALL , Some ( required_size ) ) ) ;
190
195
}
191
- let size_field =
192
- u32 :: try_from ( required_size ) . map_err ( |_| Error :: from ( Status :: INVALID_PARAMETER ) ) ?;
196
+ let size_field = u32 :: try_from ( required_size )
197
+ . map_err ( |_| Error :: new ( Status :: INVALID_PARAMETER , None ) ) ?;
193
198
194
199
let mut ptr: * mut u8 = buffer. as_mut_ptr ( ) . cast ( ) ;
195
200
@@ -206,13 +211,44 @@ impl PcrEventInputs {
206
211
) ;
207
212
ptr:: copy ( event_data. as_ptr ( ) , ptr, event_data. len ( ) ) ;
208
213
209
- let ptr: * const PcrEventInputs =
210
- ptr_meta:: from_raw_parts ( buffer. as_ptr ( ) . cast ( ) , event_data. len ( ) ) ;
211
- Ok ( & * ptr)
214
+ let ptr: * mut PcrEventInputs =
215
+ ptr_meta:: from_raw_parts_mut ( buffer. as_mut_ptr ( ) . cast ( ) , event_data. len ( ) ) ;
216
+ Ok ( & mut * ptr)
217
+ }
218
+ }
219
+
220
+ /// Create a new `PcrEventInputs` in a [`Box`].
221
+ ///
222
+ /// # Errors
223
+ ///
224
+ /// Returns [`Status::INVALID_PARAMETER`] if the `event_data` size is too
225
+ /// large.
226
+ #[ cfg( feature = "alloc" ) ]
227
+ pub fn new_in_box (
228
+ pcr_index : PcrIndex ,
229
+ event_type : EventType ,
230
+ event_data : & [ u8 ] ,
231
+ ) -> Result < Box < Self > > {
232
+ #[ cfg( not( feature = "unstable" ) ) ]
233
+ {
234
+ make_boxed ( |buf| Self :: new_in_buffer ( buf, pcr_index, event_type, event_data) )
235
+ }
236
+ #[ cfg( feature = "unstable" ) ]
237
+ {
238
+ make_boxed (
239
+ |buf| Self :: new_in_buffer ( buf, pcr_index, event_type, event_data) ,
240
+ Global ,
241
+ )
212
242
}
213
243
}
214
244
}
215
245
246
+ impl Align for PcrEventInputs {
247
+ fn alignment ( ) -> usize {
248
+ 1
249
+ }
250
+ }
251
+
216
252
impl Debug for PcrEventInputs {
217
253
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
218
254
f. debug_struct ( "PcrEventInputs" )
@@ -223,6 +259,15 @@ impl Debug for PcrEventInputs {
223
259
}
224
260
}
225
261
262
+ // Manual `PartialEq` implementation since it can't be derived for a packed DST.
263
+ impl PartialEq for PcrEventInputs {
264
+ fn eq ( & self , other : & PcrEventInputs ) -> bool {
265
+ self . size == other. size
266
+ && self . event_header == other. event_header
267
+ && self . event == other. event
268
+ }
269
+ }
270
+
226
271
#[ repr( C , packed) ]
227
272
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
228
273
struct AlgorithmDigestSize {
@@ -785,7 +830,7 @@ mod tests {
785
830
786
831
#[ test]
787
832
fn test_new_event ( ) {
788
- let mut buf = [ MaybeUninit :: uninit ( ) ; 22 ] ;
833
+ let mut buf = [ 0 ; 22 ] ;
789
834
let event_data = [ 0x12 , 0x13 , 0x14 , 0x15 ] ;
790
835
let event =
791
836
PcrEventInputs :: new_in_buffer ( & mut buf, PcrIndex ( 4 ) , EventType :: IPL , & event_data)
@@ -824,6 +869,12 @@ mod tests {
824
869
// Event data
825
870
0x12 , 0x13 , 0x14 , 0x15 ,
826
871
] ) ;
872
+
873
+ // Check that `new_in_box` gives the same value.
874
+ assert_eq ! (
875
+ event,
876
+ & * PcrEventInputs :: new_in_box( PcrIndex ( 4 ) , EventType :: IPL , & event_data) . unwrap( )
877
+ ) ;
827
878
}
828
879
829
880
#[ test]
0 commit comments