pub struct RuntimeTcbFloor { /* private fields */ }Expand description
A resident TCB floor originating exclusively from trusted local hardware.
Obtain once from platform initialization (reusing boot reports), or use
Self::new before accepting worker events, then
retain the same instance across attempts and errors. Blocking hardware jobs
must hold the caller’s shared mutex for each complete method call. Never
recreate the floor on retry or initialize it from a VMGS protector header.
Trusted servicing may transfer it with Self::save and Self::restore.
The caller must provide an authenticated, VM-bound, fresh servicing channel;
the DTO is not proof of a hardware observation. Never deserialize a floor
from VMGS or host-controlled metadata. This is not a persisted anti-rollback
counter and does not protect an arbitrary restart from rollback. It has no
Clone, Copy, or Default implementation; restore validates the typed DTO
without observing hardware or bootstrapping a replacement floor.
SNP ordering is component-wise only for report versions 3, 4, and 5 within the exact same version/family/model. Milan/Genoa (family 0x19, models 0x00..=0x1f) and Turin (family 0x1a, models 0x90..=0xaf and 0xc0..=0xcf) use distinct layouts; reserved TCB bytes must remain equal. All other SNP domains require exact SVN equality. Version 2 has no trusted CPUID and is also equality-only. TDX uses a structural minimum-TCB policy: CPU SVN bytes must individually meet the floor. TEE SVN byte 1 must match, including legacy identity 0. For TD-preserving modules byte 0 is module ISVSVN and bytes 2..16 are platform components; these bytes must individually meet the floor in both layouts. This is not quote appraisal or an Intel TCB status decision, which requires authenticated TCB Info.
Implementations§
Source§impl RuntimeTcbFloor
impl RuntimeTcbFloor
Sourcepub fn save(&self) -> SavedRuntimeTcbFloor
pub fn save(&self) -> SavedRuntimeTcbFloor
Save only accepted SVN/domain metadata, never secrets or derived keys. The result is only for an authenticated, VM-bound, fresh servicing channel.
Sourcepub fn restore(
state: SavedRuntimeTcbFloor,
tee: &dyn TeeCall,
config: &AttestationVmConfig,
) -> Result<Self, Error>
pub fn restore( state: SavedRuntimeTcbFloor, tee: &dyn TeeCall, config: &AttestationVmConfig, ) -> Result<Self, Error>
Validate state from an authenticated, VM-bound, fresh servicing channel. The caller establishes that trust: the DTO itself is not a proof, and must never come from VMGS, protector headers, or other host-controlled metadata. No report, key derivation, VMGS access, or bootstrap occurs here. Only the configured policy and TEE capabilities are inspected, not the live TCB. Unknown SNP domains retain their existing equality-only interpretation.
When replacing an existing resident floor, first call its
Self::check_restored_successor while holding the shared state lock.
Do not replace the resident floor if either validation step fails.
Sourcepub fn check_restored_successor(&self, restored: &Self) -> Result<(), Error>
pub fn check_restored_successor(&self, restored: &Self) -> Result<(), Error>
Pure check that replacing this resident floor cannot decrease it or change its comparison domain. Equal floors are allowed. Neither instance is modified, including on failure. The caller must hold its shared state lock across this check and replacement; no hardware calls are made.
Sourcepub fn new(
tee: &dyn TeeCall,
config: &AttestationVmConfig,
) -> Result<Self, Error>
pub fn new( tee: &dyn TeeCall, config: &AttestationVmConfig, ) -> Result<Self, Error>
Initialize from a fresh trusted local report, without deriving any keys.
The tee must be the trusted local hardware interface, not report bytes
supplied by the root or by a persisted protector.
Sourcepub fn create_protector(
&mut self,
tee: &dyn TeeCall,
config: &AttestationVmConfig,
dek: &[u8; 32],
) -> Result<Vec<u8>, Error>
pub fn create_protector( &mut self, tee: &dyn TeeCall, config: &AttestationVmConfig, dek: &[u8; 32], ) -> Result<Vec<u8>, Error>
Validate and ratchet from a fresh report, then seal the active DEK using that same report’s SVN. Derivation/sealing errors cannot undo the ratchet. The caller performs candidate pre-write verification separately.
Sourcepub fn verify_protector(
&mut self,
tee: &dyn TeeCall,
config: &AttestationVmConfig,
protector: &[u8],
dek: &[u8; 32],
) -> Result<bool, Error>
pub fn verify_protector( &mut self, tee: &dyn TeeCall, config: &AttestationVmConfig, protector: &[u8], dek: &[u8; 32], ) -> Result<bool, Error>
Validate and ratchet from a fresh report before inspecting the candidate.
Return Ok(false) if its header SVN differs from the observed SVN, even
if hardware could still derive a key for that older candidate. Otherwise
freshly derive hardware keys and authenticate/unseal via the existing
stateless verifier. Neither mismatches nor errors undo a ratchet.
This does not make the report and derivation atomic with migration; the caller still needs pre-write and post-flush verification and retry logic.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for RuntimeTcbFloor
impl RefUnwindSafe for RuntimeTcbFloor
impl Send for RuntimeTcbFloor
impl Sync for RuntimeTcbFloor
impl Unpin for RuntimeTcbFloor
impl UnsafeUnpin for RuntimeTcbFloor
impl UnwindSafe for RuntimeTcbFloor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.