1111//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module
1212
1313use super :: { v1, AlgorithmId , EventType , HashAlgorithm , PcrIndex } ;
14- use crate :: data_types:: { PhysicalAddress , UnalignedSlice } ;
14+ use crate :: data_types:: { Align , PhysicalAddress , UnalignedSlice } ;
1515use crate :: proto:: unsafe_protocol;
1616use crate :: util:: { ptr_write_unaligned_and_add, usize_from_u32} ;
1717use crate :: { Error , Result , Status , StatusExt } ;
1818use bitflags:: bitflags;
1919use core:: fmt:: { self , Debug , Formatter } ;
2020use core:: marker:: PhantomData ;
21- use core:: mem:: MaybeUninit ;
2221use core:: { mem, ptr, slice} ;
2322use ptr_meta:: { Pointee , PtrExt } ;
2423
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+
2530/// Version information.
2631///
2732/// Layout compatible with the C type `EFI_TG2_VERSION`.
@@ -158,7 +163,7 @@ struct EventHeader {
158163/// `TCG_PCR_EVENT2` for reading events. To help clarify the usage, our
159164/// API renames these types to `PcrEventInputs` and `PcrEvent`,
160165/// respectively.
161- #[ derive( Pointee ) ]
166+ #[ derive( Eq , Pointee ) ]
162167#[ repr( C , packed) ]
163168pub struct PcrEventInputs {
164169 size : u32 ,
@@ -172,24 +177,24 @@ impl PcrEventInputs {
172177 /// # Errors
173178 ///
174179 /// 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.
176181 ///
177182 /// Returns [`Status::INVALID_PARAMETER`] if the `event_data` size is too
178183 /// large.
179184 pub fn new_in_buffer < ' buf > (
180- buffer : & ' buf mut [ MaybeUninit < u8 > ] ,
185+ buffer : & ' buf mut [ u8 ] ,
181186 pcr_index : PcrIndex ,
182187 event_type : EventType ,
183188 event_data : & [ u8 ] ,
184- ) -> Result < & ' buf Self > {
189+ ) -> Result < & ' buf mut Self , Option < usize > > {
185190 let required_size =
186191 mem:: size_of :: < u32 > ( ) + mem:: size_of :: < EventHeader > ( ) + event_data. len ( ) ;
187192
188193 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 ) ) ) ;
190195 }
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 ) ) ?;
193198
194199 let mut ptr: * mut u8 = buffer. as_mut_ptr ( ) . cast ( ) ;
195200
@@ -206,13 +211,44 @@ impl PcrEventInputs {
206211 ) ;
207212 ptr:: copy ( event_data. as_ptr ( ) , ptr, event_data. len ( ) ) ;
208213
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+ )
212242 }
213243 }
214244}
215245
246+ impl Align for PcrEventInputs {
247+ fn alignment ( ) -> usize {
248+ 1
249+ }
250+ }
251+
216252impl Debug for PcrEventInputs {
217253 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
218254 f. debug_struct ( "PcrEventInputs" )
@@ -223,6 +259,15 @@ impl Debug for PcrEventInputs {
223259 }
224260}
225261
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+
226271#[ repr( C , packed) ]
227272#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
228273struct AlgorithmDigestSize {
@@ -785,7 +830,7 @@ mod tests {
785830
786831 #[ test]
787832 fn test_new_event ( ) {
788- let mut buf = [ MaybeUninit :: uninit ( ) ; 22 ] ;
833+ let mut buf = [ 0 ; 22 ] ;
789834 let event_data = [ 0x12 , 0x13 , 0x14 , 0x15 ] ;
790835 let event =
791836 PcrEventInputs :: new_in_buffer ( & mut buf, PcrIndex ( 4 ) , EventType :: IPL , & event_data)
@@ -824,6 +869,12 @@ mod tests {
824869 // Event data
825870 0x12 , 0x13 , 0x14 , 0x15 ,
826871 ] ) ;
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+ ) ;
827878 }
828879
829880 #[ test]
0 commit comments