use crate::resource_envelope::VerifiedResourceEnvelope;
const TOKIO_VERSION: (u16, u16, u16) = (1, 53, 1);
const MAX_WORKERS: u16 = 8;
const MAX_ACTIVE_TASKS: u16 = 128;
const MAX_REGISTRATIONS: u16 = 259;
const RUNTIME_COMPONENT_WORK_IDENTITY: [u8; 32] = [0xd7; 32];
const POST_DRIVER_FINALIZER_IDENTITY: [u8; 32] = [0xe3; 32];
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[doc(hidden)]
pub struct RuntimeComponentWorkProof {
identity: [u8; 32],
max_worker_threads: u16,
max_active_tasks: u16,
max_registrations: u16,
max_runnable_polls: u64,
max_wake_deliveries: u64,
max_join_observations: u64,
max_timer_deliveries: u64,
}
#[doc(hidden)]
pub const fn runtime_component_work_proof() -> RuntimeComponentWorkProof {
RuntimeComponentWorkProof {
identity: RUNTIME_COMPONENT_WORK_IDENTITY,
max_worker_threads: MAX_WORKERS,
max_active_tasks: MAX_ACTIVE_TASKS,
max_registrations: MAX_REGISTRATIONS,
max_runnable_polls: MAX_ACTIVE_TASKS as u64,
max_wake_deliveries: MAX_ACTIVE_TASKS as u64,
max_join_observations: MAX_ACTIVE_TASKS as u64,
max_timer_deliveries: MAX_ACTIVE_TASKS as u64,
}
}
impl RuntimeComponentWorkProof {
#[doc(hidden)]
pub const fn identity(self) -> [u8; 32] {
self.identity
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[doc(hidden)]
pub enum RuntimeServiceTarget {
LinuxX86_64,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[doc(hidden)]
pub enum TerminationServiceProofError {
Unapproved,
InvalidIdentity,
UnsupportedTarget,
UnsupportedRuntime,
InvalidDomain,
InvalidService,
Overflow,
ObservationDrift,
MissingTrustedReceipt,
ObservationUnavailable,
}
#[doc(hidden)]
pub struct RuntimeDeploymentObservation {
identity: [u8; 32],
resource_attestation: [u8; 32],
environment_identity: [u8; 32],
build_identity: [u8; 32],
gate_identity: [u8; 32],
work_identity: [u8; 32],
post_driver_identity: [u8; 32],
}
#[doc(hidden)]
pub trait DeploymentSchedulerObservationReceipt: DeploymentSchedulerServiceAttestation {
fn observation_identity(&self) -> [u8; 32];
fn runtime_work_identity(&self) -> [u8; 32];
fn signal_delivery_observed(&self) -> bool;
fn timer_delivery_observed(&self) -> bool;
fn finalizer_delivery_observed(&self) -> bool;
fn receipt_identity(&self) -> [u8; 32];
}
#[doc(hidden)]
pub trait DeploymentSupervisorObservationReceipt: DeploymentSupervisorServiceAttestation {
fn observation_identity(&self) -> [u8; 32];
fn post_driver_finalizer_identity(&self) -> [u8; 32];
fn post_driver_finalizer_observed(&self) -> bool;
fn trusted_clock(&self) -> bool;
fn clock_receipt_identity(&self) -> [u8; 32];
fn receipt_identity(&self) -> [u8; 32];
}
#[doc(hidden)]
pub fn observe_runtime_deployment(
envelope: &VerifiedResourceEnvelope,
) -> Result<RuntimeDeploymentObservation, TerminationServiceProofError> {
if !cfg!(all(target_arch = "x86_64", target_os = "linux")) {
return Err(TerminationServiceProofError::UnsupportedTarget);
}
let work = runtime_component_work_proof();
let cgroup = read_live_identity("/proc/self/cgroup", 64 * 1024)?;
let boot = read_live_identity("/proc/sys/kernel/random/boot_id", 4 * 1024)?;
let identities = [
envelope.resource_attestation,
envelope.environment_identity,
envelope.build_identity,
envelope.gate_identity,
work.identity,
POST_DRIVER_FINALIZER_IDENTITY,
];
if identities.contains(&[0; 32]) {
return Err(TerminationServiceProofError::InvalidIdentity);
}
Ok(RuntimeDeploymentObservation {
identity: observation_identity(&identities, &[&cgroup, &boot]),
resource_attestation: identities[0],
environment_identity: identities[1],
build_identity: identities[2],
gate_identity: identities[3],
work_identity: identities[4],
post_driver_identity: identities[5],
})
}
#[doc(hidden)]
pub trait DeploymentSchedulerServiceAttestation: Sized {
fn approved(&self) -> bool;
fn reproducible_measurement(&self) -> bool;
fn conservative_upper_bound(&self) -> bool;
fn target(&self) -> RuntimeServiceTarget;
fn tokio_version(&self) -> (u16, u16, u16);
fn max_worker_threads(&self) -> u16;
fn max_active_tasks(&self) -> u16;
fn max_registrations(&self) -> u16;
fn max_runnable_polls(&self) -> u64;
fn max_wake_deliveries(&self) -> u64;
fn max_join_observations(&self) -> u64;
fn max_timer_deliveries(&self) -> u64;
fn poll_delivery_nanos(&self) -> u64;
fn wake_delivery_nanos(&self) -> u64;
fn join_delivery_nanos(&self) -> u64;
fn timer_delivery_nanos(&self) -> u64;
fn resource_attestation(&self) -> [u8; 32];
fn environment_identity(&self) -> [u8; 32];
fn calibration_identity(&self) -> [u8; 32];
fn service_attestation(&self) -> [u8; 32];
fn build_identity(&self) -> [u8; 32];
fn gate_identity(&self) -> [u8; 32];
}
#[doc(hidden)]
pub trait DeploymentSupervisorServiceAttestation: Sized {
fn approved(&self) -> bool;
fn reproducible_measurement(&self) -> bool;
fn conservative_upper_bound(&self) -> bool;
fn target(&self) -> RuntimeServiceTarget;
fn shutdown_signal_deliveries(&self) -> u16;
fn hard_kill_enforcements(&self) -> u16;
fn shutdown_signal_delivery_nanos(&self) -> u64;
fn hard_kill_enforcement_nanos(&self) -> u64;
fn delivery_headroom_nanos(&self) -> u64;
fn environment_identity(&self) -> [u8; 32];
fn supervisor_identity(&self) -> [u8; 32];
fn calibration_identity(&self) -> [u8; 32];
fn service_attestation(&self) -> [u8; 32];
fn build_identity(&self) -> [u8; 32];
fn gate_identity(&self) -> [u8; 32];
}
#[derive(Debug)]
#[doc(hidden)]
pub struct VerifiedSchedulerServiceOwner {
runtime_work_identity: [u8; 32],
target: RuntimeServiceTarget,
tokio_version: (u16, u16, u16),
max_worker_threads: u16,
max_active_tasks: u16,
max_registrations: u16,
max_delivery_nanos: u64,
resource_attestation: [u8; 32],
environment_identity: [u8; 32],
calibration_identity: [u8; 32],
service_attestation: [u8; 32],
build_identity: [u8; 32],
gate_identity: [u8; 32],
}
#[derive(Debug)]
#[doc(hidden)]
pub struct VerifiedSupervisorServiceOwner {
target: RuntimeServiceTarget,
shutdown_delivery_nanos: u64,
hard_kill_enforcement_nanos: u64,
delivery_headroom_nanos: u64,
environment_identity: [u8; 32],
supervisor_identity: [u8; 32],
calibration_identity: [u8; 32],
service_attestation: [u8; 32],
build_identity: [u8; 32],
gate_identity: [u8; 32],
}
impl VerifiedSchedulerServiceOwner {
#[doc(hidden)]
pub const fn target(&self) -> RuntimeServiceTarget {
self.target
}
#[doc(hidden)]
pub const fn runtime_work_identity(&self) -> [u8; 32] {
self.runtime_work_identity
}
#[doc(hidden)]
pub const fn tokio_version(&self) -> (u16, u16, u16) {
self.tokio_version
}
#[doc(hidden)]
pub const fn max_worker_threads(&self) -> u16 {
self.max_worker_threads
}
#[doc(hidden)]
pub const fn max_active_tasks(&self) -> u16 {
self.max_active_tasks
}
#[doc(hidden)]
pub const fn max_registrations(&self) -> u16 {
self.max_registrations
}
#[doc(hidden)]
pub const fn max_delivery_nanos(&self) -> u64 {
self.max_delivery_nanos
}
#[doc(hidden)]
pub const fn environment_identity(&self) -> [u8; 32] {
self.environment_identity
}
#[doc(hidden)]
pub const fn resource_attestation(&self) -> [u8; 32] {
self.resource_attestation
}
#[doc(hidden)]
pub const fn calibration_identity(&self) -> [u8; 32] {
self.calibration_identity
}
#[doc(hidden)]
pub const fn service_attestation(&self) -> [u8; 32] {
self.service_attestation
}
#[doc(hidden)]
pub const fn build_identity(&self) -> [u8; 32] {
self.build_identity
}
#[doc(hidden)]
pub const fn gate_identity(&self) -> [u8; 32] {
self.gate_identity
}
}
impl saddle_admission::VerifiedSchedulerTerminationServiceProofOwner
for VerifiedSchedulerServiceOwner
{
fn runtime_work_identity(&self) -> [u8; 32] {
self.runtime_work_identity()
}
fn service_attestation(&self) -> [u8; 32] {
self.service_attestation()
}
fn max_delivery_nanos(&self) -> u64 {
self.max_delivery_nanos()
}
}
impl VerifiedSupervisorServiceOwner {
#[doc(hidden)]
pub const fn target(&self) -> RuntimeServiceTarget {
self.target
}
#[doc(hidden)]
pub const fn shutdown_delivery_nanos(&self) -> u64 {
self.shutdown_delivery_nanos
}
#[doc(hidden)]
pub const fn hard_kill_enforcement_nanos(&self) -> u64 {
self.hard_kill_enforcement_nanos
}
#[doc(hidden)]
pub const fn delivery_headroom_nanos(&self) -> u64 {
self.delivery_headroom_nanos
}
#[doc(hidden)]
pub const fn environment_identity(&self) -> [u8; 32] {
self.environment_identity
}
#[doc(hidden)]
pub const fn supervisor_identity(&self) -> [u8; 32] {
self.supervisor_identity
}
#[doc(hidden)]
pub const fn calibration_identity(&self) -> [u8; 32] {
self.calibration_identity
}
#[doc(hidden)]
pub const fn service_attestation(&self) -> [u8; 32] {
self.service_attestation
}
#[doc(hidden)]
pub const fn build_identity(&self) -> [u8; 32] {
self.build_identity
}
#[doc(hidden)]
pub const fn gate_identity(&self) -> [u8; 32] {
self.gate_identity
}
}
impl saddle_admission::VerifiedSupervisorTerminationServiceProofOwner
for VerifiedSupervisorServiceOwner
{
fn service_attestation(&self) -> [u8; 32] {
self.service_attestation()
}
fn shutdown_delivery_nanos(&self) -> u64 {
self.shutdown_delivery_nanos()
}
fn delivery_headroom_nanos(&self) -> u64 {
self.delivery_headroom_nanos()
}
}
#[doc(hidden)]
pub fn verify_scheduler_service<A: DeploymentSchedulerServiceAttestation>(
envelope: &VerifiedResourceEnvelope,
attestation: A,
work: RuntimeComponentWorkProof,
) -> Result<VerifiedSchedulerServiceOwner, TerminationServiceProofError> {
verify_common_approval(
attestation.approved(),
attestation.reproducible_measurement(),
attestation.conservative_upper_bound(),
)?;
if attestation.target() != RuntimeServiceTarget::LinuxX86_64 {
return Err(TerminationServiceProofError::UnsupportedTarget);
}
if attestation.tokio_version() != TOKIO_VERSION {
return Err(TerminationServiceProofError::UnsupportedRuntime);
}
if work.identity == [0; 32]
|| attestation.max_worker_threads() < work.max_worker_threads
|| attestation.max_worker_threads() > MAX_WORKERS
|| attestation.max_active_tasks() < work.max_active_tasks
|| attestation.max_active_tasks() > MAX_ACTIVE_TASKS
|| attestation.max_registrations() < work.max_registrations
|| attestation.max_registrations() > MAX_REGISTRATIONS
|| attestation.max_runnable_polls() < work.max_runnable_polls
|| attestation.max_wake_deliveries() < work.max_wake_deliveries
|| attestation.max_join_observations() < work.max_join_observations
|| attestation.max_timer_deliveries() < work.max_timer_deliveries
{
return Err(TerminationServiceProofError::InvalidDomain);
}
verify_scheduler_identity(envelope, &attestation)?;
let max_delivery_nanos = checked_scheduler_bound(&attestation)?;
Ok(VerifiedSchedulerServiceOwner {
runtime_work_identity: work.identity,
target: attestation.target(),
tokio_version: attestation.tokio_version(),
max_worker_threads: attestation.max_worker_threads(),
max_active_tasks: attestation.max_active_tasks(),
max_registrations: attestation.max_registrations(),
max_delivery_nanos,
resource_attestation: attestation.resource_attestation(),
environment_identity: attestation.environment_identity(),
calibration_identity: attestation.calibration_identity(),
service_attestation: attestation.service_attestation(),
build_identity: attestation.build_identity(),
gate_identity: attestation.gate_identity(),
})
}
#[doc(hidden)]
pub fn verify_supervisor_service<A: DeploymentSupervisorServiceAttestation>(
envelope: &VerifiedResourceEnvelope,
attestation: A,
) -> Result<VerifiedSupervisorServiceOwner, TerminationServiceProofError> {
verify_common_approval(
attestation.approved(),
attestation.reproducible_measurement(),
attestation.conservative_upper_bound(),
)?;
if attestation.target() != RuntimeServiceTarget::LinuxX86_64 {
return Err(TerminationServiceProofError::UnsupportedTarget);
}
if attestation.shutdown_signal_deliveries() != 1 || attestation.hard_kill_enforcements() != 1 {
return Err(TerminationServiceProofError::InvalidDomain);
}
let values = [
attestation.shutdown_signal_delivery_nanos(),
attestation.hard_kill_enforcement_nanos(),
attestation.delivery_headroom_nanos(),
];
if values.contains(&0) {
return Err(TerminationServiceProofError::InvalidService);
}
values
.into_iter()
.try_fold(0_u64, u64::checked_add)
.ok_or(TerminationServiceProofError::Overflow)?;
verify_supervisor_identity(envelope, &attestation)?;
Ok(VerifiedSupervisorServiceOwner {
target: attestation.target(),
shutdown_delivery_nanos: attestation.shutdown_signal_delivery_nanos(),
hard_kill_enforcement_nanos: attestation.hard_kill_enforcement_nanos(),
delivery_headroom_nanos: attestation.delivery_headroom_nanos(),
environment_identity: attestation.environment_identity(),
supervisor_identity: attestation.supervisor_identity(),
calibration_identity: attestation.calibration_identity(),
service_attestation: attestation.service_attestation(),
build_identity: attestation.build_identity(),
gate_identity: attestation.gate_identity(),
})
}
#[doc(hidden)]
pub fn verify_observed_scheduler_service<A: DeploymentSchedulerObservationReceipt>(
envelope: &VerifiedResourceEnvelope,
observation: RuntimeDeploymentObservation,
receipt: A,
) -> Result<VerifiedSchedulerServiceOwner, TerminationServiceProofError> {
if receipt.observation_identity() != observation.identity
|| receipt.runtime_work_identity() != observation.work_identity
|| receipt.resource_attestation() != observation.resource_attestation
|| receipt.environment_identity() != observation.environment_identity
|| receipt.build_identity() != observation.build_identity
|| receipt.gate_identity() != observation.gate_identity
{
return Err(TerminationServiceProofError::ObservationDrift);
}
if !receipt.signal_delivery_observed()
|| !receipt.timer_delivery_observed()
|| !receipt.finalizer_delivery_observed()
|| receipt.receipt_identity() == [0; 32]
{
return Err(TerminationServiceProofError::MissingTrustedReceipt);
}
verify_scheduler_service(envelope, receipt, runtime_component_work_proof())
}
#[doc(hidden)]
pub fn verify_observed_supervisor_service<A: DeploymentSupervisorObservationReceipt>(
envelope: &VerifiedResourceEnvelope,
observation: RuntimeDeploymentObservation,
receipt: A,
) -> Result<VerifiedSupervisorServiceOwner, TerminationServiceProofError> {
if receipt.observation_identity() != observation.identity
|| receipt.post_driver_finalizer_identity() != observation.post_driver_identity
|| receipt.environment_identity() != observation.environment_identity
|| receipt.build_identity() != observation.build_identity
|| receipt.gate_identity() != observation.gate_identity
{
return Err(TerminationServiceProofError::ObservationDrift);
}
if !receipt.post_driver_finalizer_observed()
|| !receipt.trusted_clock()
|| receipt.clock_receipt_identity() == [0; 32]
|| receipt.receipt_identity() == [0; 32]
{
return Err(TerminationServiceProofError::MissingTrustedReceipt);
}
verify_supervisor_service(envelope, receipt)
}
fn read_live_identity(
path: &str,
maximum: usize,
) -> Result<Box<[u8]>, TerminationServiceProofError> {
let bytes =
std::fs::read(path).map_err(|_| TerminationServiceProofError::ObservationUnavailable)?;
if bytes.is_empty() || bytes.len() > maximum {
return Err(TerminationServiceProofError::ObservationUnavailable);
}
Ok(bytes.into_boxed_slice())
}
fn observation_identity(identities: &[[u8; 32]; 6], live: &[&[u8]]) -> [u8; 32] {
let mut lanes = [
0xcbf2_9ce4_8422_2325_u64,
0x9e37_79b1_85eb_ca87,
0xc2b2_ae3d_27d4_eb4f,
0x1656_67b1_9e37_79f9,
];
for (index, byte) in b"saddle-runtime-deployment-observation-v1"
.iter()
.chain(identities.iter().flatten())
.chain(live.iter().flat_map(|bytes| bytes.iter()))
.enumerate()
{
for lane in &mut lanes {
*lane ^= u64::from(*byte).wrapping_add(index as u64);
*lane = lane.wrapping_mul(0x0000_0100_0000_01b3);
*lane ^= *lane >> 29;
}
}
let mut output = [0; 32];
for (index, lane) in lanes.into_iter().enumerate() {
output[index * 8..(index + 1) * 8].copy_from_slice(&lane.to_le_bytes());
}
output
}
fn checked_scheduler_bound(
attestation: &impl DeploymentSchedulerServiceAttestation,
) -> Result<u64, TerminationServiceProofError> {
let pairs = [
(
attestation.max_runnable_polls(),
attestation.poll_delivery_nanos(),
),
(
attestation.max_wake_deliveries(),
attestation.wake_delivery_nanos(),
),
(
attestation.max_join_observations(),
attestation.join_delivery_nanos(),
),
(
attestation.max_timer_deliveries(),
attestation.timer_delivery_nanos(),
),
];
if pairs.iter().any(|(_, rate)| *rate == 0) {
return Err(TerminationServiceProofError::InvalidService);
}
pairs.into_iter().try_fold(0_u64, |total, (count, rate)| {
count
.checked_mul(rate)
.and_then(|cost| total.checked_add(cost))
.ok_or(TerminationServiceProofError::Overflow)
})
}
fn verify_common_approval(
approved: bool,
reproducible: bool,
conservative: bool,
) -> Result<(), TerminationServiceProofError> {
if !approved || !reproducible || !conservative {
return Err(TerminationServiceProofError::Unapproved);
}
Ok(())
}
fn verify_scheduler_identity(
envelope: &VerifiedResourceEnvelope,
attestation: &impl DeploymentSchedulerServiceAttestation,
) -> Result<(), TerminationServiceProofError> {
let identities = [
attestation.resource_attestation(),
attestation.environment_identity(),
attestation.calibration_identity(),
attestation.service_attestation(),
attestation.build_identity(),
attestation.gate_identity(),
];
if identities.contains(&[0; 32])
|| attestation.resource_attestation() != envelope.resource_attestation
|| attestation.environment_identity() != envelope.environment_identity
|| attestation.build_identity() != envelope.build_identity
|| attestation.gate_identity() != envelope.gate_identity
{
return Err(TerminationServiceProofError::InvalidIdentity);
}
Ok(())
}
fn verify_supervisor_identity(
envelope: &VerifiedResourceEnvelope,
attestation: &impl DeploymentSupervisorServiceAttestation,
) -> Result<(), TerminationServiceProofError> {
let identities = [
attestation.environment_identity(),
attestation.supervisor_identity(),
attestation.calibration_identity(),
attestation.service_attestation(),
attestation.build_identity(),
attestation.gate_identity(),
];
if identities.contains(&[0; 32])
|| attestation.environment_identity() != envelope.environment_identity
|| attestation.supervisor_identity() != envelope.supervisor_attestation
|| attestation.build_identity() != envelope.build_identity
|| attestation.gate_identity() != envelope.gate_identity
{
return Err(TerminationServiceProofError::InvalidIdentity);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::resource_envelope::{DeploymentResourceAttestation, verify_resource_envelope};
const RESOURCE: [u8; 32] = [0x11; 32];
const ENVIRONMENT: [u8; 32] = [0x22; 32];
const SUPERVISOR: [u8; 32] = [0x33; 32];
const BUILD: [u8; 32] = [0x44; 32];
const GATE: [u8; 32] = [0x55; 32];
struct Resource;
impl DeploymentResourceAttestation for Resource {
fn cpu_quota_us(&self) -> u64 {
800_000
}
fn cpu_period_us(&self) -> u64 {
100_000
}
fn effective_cpuset(&self) -> &[usize] {
&[0, 1, 2, 3, 4, 5, 6, 7]
}
fn memory_max_bytes(&self) -> usize {
16 << 30
}
fn memory_high_bytes(&self) -> usize {
15 << 30
}
fn saddle_logical_memory_bytes(&self) -> usize {
8 << 30
}
fn saddle_requested_memory_bytes(&self) -> usize {
8 << 30
}
fn registration_credits(&self) -> usize {
256
}
fn event_credits(&self) -> usize {
259
}
fn db_connection_credits(&self) -> usize {
64
}
fn db_operation_credits(&self) -> usize {
64
}
fn public_time_policy_ms(&self) -> [u64; 2] {
[1, 1]
}
fn resource_attestation(&self) -> [u8; 32] {
RESOURCE
}
fn public_time_policy_attestation(&self) -> [u8; 32] {
[0x66; 32]
}
fn environment_identity(&self) -> [u8; 32] {
ENVIRONMENT
}
fn supervisor_attestation(&self) -> [u8; 32] {
SUPERVISOR
}
fn build_identity(&self) -> [u8; 32] {
BUILD
}
fn gate_identity(&self) -> [u8; 32] {
GATE
}
}
#[derive(Clone, Copy)]
struct Scheduler {
approved: bool,
tokio: (u16, u16, u16),
workers: u16,
tasks: u16,
registrations: u16,
rate: u64,
resource: [u8; 32],
environment: [u8; 32],
observation: [u8; 32],
receipt: [u8; 32],
observed: bool,
}
impl Default for Scheduler {
fn default() -> Self {
Self {
approved: true,
tokio: TOKIO_VERSION,
workers: 8,
tasks: 128,
registrations: 259,
rate: 10,
resource: RESOURCE,
environment: ENVIRONMENT,
observation: [0; 32],
receipt: [0; 32],
observed: false,
}
}
}
impl DeploymentSchedulerObservationReceipt for Scheduler {
fn observation_identity(&self) -> [u8; 32] {
self.observation
}
fn runtime_work_identity(&self) -> [u8; 32] {
runtime_component_work_proof().identity()
}
fn signal_delivery_observed(&self) -> bool {
self.observed
}
fn timer_delivery_observed(&self) -> bool {
self.observed
}
fn finalizer_delivery_observed(&self) -> bool {
self.observed
}
fn receipt_identity(&self) -> [u8; 32] {
self.receipt
}
}
impl DeploymentSchedulerServiceAttestation for Scheduler {
fn approved(&self) -> bool {
self.approved
}
fn reproducible_measurement(&self) -> bool {
true
}
fn conservative_upper_bound(&self) -> bool {
true
}
fn target(&self) -> RuntimeServiceTarget {
RuntimeServiceTarget::LinuxX86_64
}
fn tokio_version(&self) -> (u16, u16, u16) {
self.tokio
}
fn max_worker_threads(&self) -> u16 {
self.workers
}
fn max_active_tasks(&self) -> u16 {
self.tasks
}
fn max_registrations(&self) -> u16 {
self.registrations
}
fn max_runnable_polls(&self) -> u64 {
128
}
fn max_wake_deliveries(&self) -> u64 {
128
}
fn max_join_observations(&self) -> u64 {
128
}
fn max_timer_deliveries(&self) -> u64 {
128
}
fn poll_delivery_nanos(&self) -> u64 {
self.rate
}
fn wake_delivery_nanos(&self) -> u64 {
self.rate
}
fn join_delivery_nanos(&self) -> u64 {
self.rate
}
fn timer_delivery_nanos(&self) -> u64 {
self.rate
}
fn resource_attestation(&self) -> [u8; 32] {
self.resource
}
fn environment_identity(&self) -> [u8; 32] {
self.environment
}
fn calibration_identity(&self) -> [u8; 32] {
[0x77; 32]
}
fn service_attestation(&self) -> [u8; 32] {
[0x88; 32]
}
fn build_identity(&self) -> [u8; 32] {
BUILD
}
fn gate_identity(&self) -> [u8; 32] {
GATE
}
}
#[derive(Clone, Copy)]
struct Supervisor {
approved: bool,
signal: u64,
kill: u64,
headroom: u64,
environment: [u8; 32],
supervisor: [u8; 32],
observation: [u8; 32],
receipt: [u8; 32],
clock_receipt: [u8; 32],
post_driver_observed: bool,
trusted_clock: bool,
}
impl Default for Supervisor {
fn default() -> Self {
Self {
approved: true,
signal: 10,
kill: 20,
headroom: 30,
environment: ENVIRONMENT,
supervisor: SUPERVISOR,
observation: [0; 32],
receipt: [0; 32],
clock_receipt: [0; 32],
post_driver_observed: false,
trusted_clock: false,
}
}
}
impl DeploymentSupervisorObservationReceipt for Supervisor {
fn observation_identity(&self) -> [u8; 32] {
self.observation
}
fn post_driver_finalizer_identity(&self) -> [u8; 32] {
POST_DRIVER_FINALIZER_IDENTITY
}
fn post_driver_finalizer_observed(&self) -> bool {
self.post_driver_observed
}
fn trusted_clock(&self) -> bool {
self.trusted_clock
}
fn clock_receipt_identity(&self) -> [u8; 32] {
self.clock_receipt
}
fn receipt_identity(&self) -> [u8; 32] {
self.receipt
}
}
impl DeploymentSupervisorServiceAttestation for Supervisor {
fn approved(&self) -> bool {
self.approved
}
fn reproducible_measurement(&self) -> bool {
true
}
fn conservative_upper_bound(&self) -> bool {
true
}
fn target(&self) -> RuntimeServiceTarget {
RuntimeServiceTarget::LinuxX86_64
}
fn shutdown_signal_deliveries(&self) -> u16 {
1
}
fn hard_kill_enforcements(&self) -> u16 {
1
}
fn shutdown_signal_delivery_nanos(&self) -> u64 {
self.signal
}
fn hard_kill_enforcement_nanos(&self) -> u64 {
self.kill
}
fn delivery_headroom_nanos(&self) -> u64 {
self.headroom
}
fn environment_identity(&self) -> [u8; 32] {
self.environment
}
fn supervisor_identity(&self) -> [u8; 32] {
self.supervisor
}
fn calibration_identity(&self) -> [u8; 32] {
[0x99; 32]
}
fn service_attestation(&self) -> [u8; 32] {
[0xaa; 32]
}
fn build_identity(&self) -> [u8; 32] {
BUILD
}
fn gate_identity(&self) -> [u8; 32] {
GATE
}
}
#[test]
fn approved_services_bind_to_the_same_verified_envelope() {
let envelope = verify_resource_envelope(Resource).unwrap();
let scheduler = verify_scheduler_service(
&envelope,
Scheduler::default(),
runtime_component_work_proof(),
)
.unwrap();
let supervisor = verify_supervisor_service(&envelope, Supervisor::default()).unwrap();
assert_eq!(scheduler.max_delivery_nanos(), 5_120);
assert_eq!(scheduler.max_worker_threads(), 8);
assert_eq!(scheduler.max_active_tasks(), 128);
assert_eq!(scheduler.max_registrations(), 259);
assert_eq!(
scheduler.runtime_work_identity(),
runtime_component_work_proof().identity()
);
assert_ne!(
scheduler.runtime_work_identity(),
scheduler.resource_attestation()
);
assert_eq!(supervisor.shutdown_delivery_nanos(), 10);
assert_eq!(supervisor.hard_kill_enforcement_nanos(), 20);
assert_eq!(supervisor.delivery_headroom_nanos(), 30);
assert_eq!(scheduler.environment_identity(), ENVIRONMENT);
assert_eq!(supervisor.environment_identity(), ENVIRONMENT);
}
#[test]
fn live_observation_requires_external_scheduler_and_clock_receipts() {
let envelope = verify_resource_envelope(Resource).unwrap();
let observation = observe_runtime_deployment(&envelope).unwrap();
let identity = observation.identity;
assert_eq!(
verify_observed_scheduler_service(&envelope, observation, Scheduler::default())
.unwrap_err(),
TerminationServiceProofError::ObservationDrift
);
let scheduler = verify_observed_scheduler_service(
&envelope,
observe_runtime_deployment(&envelope).unwrap(),
Scheduler {
observation: identity,
receipt: [0xb1; 32],
observed: true,
..Scheduler::default()
},
)
.unwrap();
assert_eq!(scheduler.environment_identity(), ENVIRONMENT);
assert_eq!(
verify_observed_supervisor_service(
&envelope,
observe_runtime_deployment(&envelope).unwrap(),
Supervisor {
observation: identity,
receipt: [0xb2; 32],
post_driver_observed: true,
..Supervisor::default()
},
)
.unwrap_err(),
TerminationServiceProofError::MissingTrustedReceipt
);
let supervisor = verify_observed_supervisor_service(
&envelope,
observe_runtime_deployment(&envelope).unwrap(),
Supervisor {
observation: identity,
receipt: [0xb2; 32],
clock_receipt: [0xb3; 32],
post_driver_observed: true,
trusted_clock: true,
..Supervisor::default()
},
)
.unwrap();
assert_eq!(supervisor.supervisor_identity(), SUPERVISOR);
}
#[test]
fn unapproved_unsupported_and_insufficient_domains_reject() {
let envelope = verify_resource_envelope(Resource).unwrap();
assert_eq!(
verify_scheduler_service(
&envelope,
Scheduler {
approved: false,
..Scheduler::default()
},
runtime_component_work_proof(),
)
.unwrap_err(),
TerminationServiceProofError::Unapproved
);
assert_eq!(
verify_scheduler_service(
&envelope,
Scheduler {
tokio: (1, 54, 0),
..Scheduler::default()
},
runtime_component_work_proof(),
)
.unwrap_err(),
TerminationServiceProofError::UnsupportedRuntime
);
assert_eq!(
verify_scheduler_service(
&envelope,
Scheduler {
tasks: 129,
..Scheduler::default()
},
runtime_component_work_proof(),
)
.unwrap_err(),
TerminationServiceProofError::InvalidDomain
);
}
#[test]
fn identity_drift_and_arithmetic_overflow_reject() {
let envelope = verify_resource_envelope(Resource).unwrap();
assert_eq!(
verify_scheduler_service(
&envelope,
Scheduler {
environment: [0xfe; 32],
..Scheduler::default()
},
runtime_component_work_proof(),
)
.unwrap_err(),
TerminationServiceProofError::InvalidIdentity
);
assert_eq!(
verify_scheduler_service(
&envelope,
Scheduler {
rate: u64::MAX,
..Scheduler::default()
},
runtime_component_work_proof(),
)
.unwrap_err(),
TerminationServiceProofError::Overflow
);
assert_eq!(
verify_supervisor_service(
&envelope,
Supervisor {
signal: u64::MAX,
..Supervisor::default()
}
)
.unwrap_err(),
TerminationServiceProofError::Overflow
);
assert_eq!(
verify_supervisor_service(
&envelope,
Supervisor {
supervisor: [0xfd; 32],
..Supervisor::default()
}
)
.unwrap_err(),
TerminationServiceProofError::InvalidIdentity
);
}
}