Skip to content

Commit 1fa9408

Browse files
authored
Merge pull request #1246 from nicholasbishop/bishop-tcg-new-boxed
Add PcrEvent::new_in_box/PcrEventInputs::new_in_box
2 parents 7a0a8ee + 8bc7605 commit 1fa9408

File tree

4 files changed

+125
-28
lines changed

4 files changed

+125
-28
lines changed

uefi-test-runner/src/proto/tcg.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use alloc::vec::Vec;
2-
use core::mem::MaybeUninit;
32
use uefi::proto::tcg::{v1, v2, AlgorithmId, EventType, HashAlgorithm, PcrIndex};
43
use uefi::table::boot::BootServices;
54

@@ -63,7 +62,7 @@ fn test_tcg_v1(bt: &BootServices) {
6362

6463
let pcr_index = PcrIndex(8);
6564

66-
let mut event_buf = [MaybeUninit::uninit(); 256];
65+
let mut event_buf = [0; 256];
6766
let event = v1::PcrEvent::new_in_buffer(
6867
&mut event_buf,
6968
pcr_index,
@@ -279,7 +278,7 @@ pub fn test_tcg_v2(bt: &BootServices) {
279278

280279
// Create a PCR event.
281280
let pcr_index = PcrIndex(8);
282-
let mut event_buf = [MaybeUninit::uninit(); 256];
281+
let mut event_buf = [0; 256];
283282
let event_data = [0x12, 0x13, 0x14, 0x15];
284283
let data_to_hash = b"some-data";
285284
let event =

uefi/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
- `uefi::system` is a new module that provides freestanding functions for
55
accessing fields of the global system table.
66
- Add standard derives for `ConfigTableEntry`.
7+
- `PcrEvent`/`PcrEventInputs` impl `Align`, `Eq`, and `PartialEq`.
8+
- Added `PcrEvent::new_in_box` and `PcrEventInputs::new_in_box`.
79

810
## Changed
911
- **Breaking:** `uefi::helpers::init` no longer takes an argument.
@@ -14,6 +16,9 @@
1416
The old `MemoryMap` was renamed to `MemoryMapOwned`.
1517
- `pub fn memory_map(&self, mt: MemoryType) -> Result<MemoryMap>` now returns
1618
a `MemoryMapOwned`.
19+
- **Breaking:** `PcrEvent::new_in_buffer` and `PcrEventInputs::new_in_buffer`
20+
now take an initialized buffer (`[u8`] instead of `[MaybeUninit<u8>]`), and if
21+
the buffer is too small the required size is returned in the error data.
1722

1823

1924
# uefi - 0.29.0 (2024-07-02)

uefi/src/proto/tcg/v1.rs

+54-12
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,21 @@
99
//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module
1010
1111
use super::{AlgorithmId, EventType, HashAlgorithm, PcrIndex};
12-
use crate::data_types::PhysicalAddress;
13-
use crate::polyfill::maybe_uninit_slice_as_mut_ptr;
12+
use crate::data_types::{Align, PhysicalAddress};
1413
use crate::proto::unsafe_protocol;
1514
use crate::util::{ptr_write_unaligned_and_add, usize_from_u32};
1615
use crate::{Error, Result, Status, StatusExt};
1716
use core::fmt::{self, Debug, Formatter};
1817
use core::marker::PhantomData;
19-
use core::mem::{self, MaybeUninit};
20-
use core::ptr;
18+
use core::{mem, ptr};
2119
use ptr_meta::Pointee;
2220

21+
#[cfg(feature = "alloc")]
22+
use {crate::mem::make_boxed, alloc::boxed::Box};
23+
24+
#[cfg(all(feature = "unstable", feature = "alloc"))]
25+
use {alloc::alloc::Global, core::alloc::Allocator};
26+
2327
/// 20-byte SHA-1 digest.
2428
pub type Sha1Digest = [u8; 20];
2529

@@ -128,19 +132,19 @@ impl PcrEvent {
128132
/// # Errors
129133
///
130134
/// Returns [`Status::BUFFER_TOO_SMALL`] if the `buffer` is not large
131-
/// enough.
135+
/// enough. The required size will be returned in the error data.
132136
///
133137
/// Returns [`Status::INVALID_PARAMETER`] if the `event_data` size is too
134138
/// large.
135139
pub fn new_in_buffer<'buf>(
136-
buffer: &'buf mut [MaybeUninit<u8>],
140+
buffer: &'buf mut [u8],
137141
pcr_index: PcrIndex,
138142
event_type: EventType,
139143
digest: Sha1Digest,
140144
event_data: &[u8],
141-
) -> Result<&'buf mut Self> {
142-
let event_data_size =
143-
u32::try_from(event_data.len()).map_err(|_| Error::from(Status::INVALID_PARAMETER))?;
145+
) -> Result<&'buf mut Self, Option<usize>> {
146+
let event_data_size = u32::try_from(event_data.len())
147+
.map_err(|_| Error::new(Status::INVALID_PARAMETER, None))?;
144148

145149
let required_size = mem::size_of::<PcrIndex>()
146150
+ mem::size_of::<EventType>()
@@ -149,10 +153,10 @@ impl PcrEvent {
149153
+ event_data.len();
150154

151155
if buffer.len() < required_size {
152-
return Err(Status::BUFFER_TOO_SMALL.into());
156+
return Err(Error::new(Status::BUFFER_TOO_SMALL, Some(required_size)));
153157
}
154158

155-
let mut ptr: *mut u8 = maybe_uninit_slice_as_mut_ptr(buffer);
159+
let mut ptr: *mut u8 = buffer.as_mut_ptr().cast();
156160

157161
unsafe {
158162
ptr_write_unaligned_and_add(&mut ptr, pcr_index);
@@ -167,6 +171,32 @@ impl PcrEvent {
167171
}
168172
}
169173

174+
/// Create a new `PcrEvent` in a [`Box`].
175+
///
176+
/// # Errors
177+
///
178+
/// Returns [`Status::INVALID_PARAMETER`] if the `event_data` size is too
179+
/// large.
180+
#[cfg(feature = "alloc")]
181+
pub fn new_in_box(
182+
pcr_index: PcrIndex,
183+
event_type: EventType,
184+
digest: Sha1Digest,
185+
event_data: &[u8],
186+
) -> Result<Box<Self>> {
187+
#[cfg(not(feature = "unstable"))]
188+
{
189+
make_boxed(|buf| Self::new_in_buffer(buf, pcr_index, event_type, digest, event_data))
190+
}
191+
#[cfg(feature = "unstable")]
192+
{
193+
make_boxed(
194+
|buf| Self::new_in_buffer(buf, pcr_index, event_type, digest, event_data),
195+
Global,
196+
)
197+
}
198+
}
199+
170200
/// PCR index for the event.
171201
#[must_use]
172202
pub fn pcr_index(&self) -> PcrIndex {
@@ -200,6 +230,12 @@ impl PcrEvent {
200230
}
201231
}
202232

233+
impl Align for PcrEvent {
234+
fn alignment() -> usize {
235+
1
236+
}
237+
}
238+
203239
// Manual `Debug` implementation since it can't be derived for a packed DST.
204240
impl Debug for PcrEvent {
205241
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -533,7 +569,7 @@ mod tests {
533569

534570
#[test]
535571
fn test_new_pcr_event() {
536-
let mut event_buf = [MaybeUninit::uninit(); 256];
572+
let mut event_buf = [0; 256];
537573
#[rustfmt::skip]
538574
let digest = [
539575
0x00, 0x01, 0x02, 0x03,
@@ -571,6 +607,12 @@ mod tests {
571607
// Event data
572608
0x14, 0x15, 0x16, 0x17,
573609
]);
610+
611+
// Check that `new_in_box` gives the same value.
612+
assert_eq!(
613+
event,
614+
&*PcrEvent::new_in_box(PcrIndex(4), EventType::IPL, digest, &data).unwrap()
615+
);
574616
}
575617

576618
#[test]

uefi/src/proto/tcg/v2.rs

+64-13
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,22 @@
1111
//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module
1212
1313
use super::{v1, AlgorithmId, EventType, HashAlgorithm, PcrIndex};
14-
use crate::data_types::{PhysicalAddress, UnalignedSlice};
14+
use crate::data_types::{Align, PhysicalAddress, UnalignedSlice};
1515
use crate::proto::unsafe_protocol;
1616
use crate::util::{ptr_write_unaligned_and_add, usize_from_u32};
1717
use crate::{Error, Result, Status, StatusExt};
1818
use bitflags::bitflags;
1919
use core::fmt::{self, Debug, Formatter};
2020
use core::marker::PhantomData;
21-
use core::mem::MaybeUninit;
2221
use core::{mem, ptr, slice};
2322
use 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)]
163168
pub 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+
216252
impl 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)]
228273
struct 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

Comments
 (0)