Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 29 additions & 35 deletions src/migtd/src/mig_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,36 +149,12 @@ mod v2 {
VERIFIED_POLICY.get()
}

pub fn authenticate_remote(
is_src: bool,
quote_peer: &[u8],
policy_peer: &[u8],
event_log_peer: &[u8],
) -> Result<Vec<u8>, PolicyError> {
let policy_issuer_chain = get_policy_issuer_chain().ok_or(PolicyError::InvalidParameter)?;
if is_src {
authenticate_migration_dest(
quote_peer,
event_log_peer,
policy_peer,
policy_issuer_chain,
)
} else {
authenticate_migration_source(
quote_peer,
event_log_peer,
policy_peer,
policy_issuer_chain,
)
}
}

fn authenticate_migration_dest(
pub fn authenticate_migration_dest(
quote_dst: &[u8],
event_log_dst: &[u8],
mig_policy_dst: &[u8],
policy_issuer_chain: &[u8],
) -> Result<Vec<u8>, PolicyError> {
let policy_issuer_chain = get_policy_issuer_chain().ok_or(PolicyError::InvalidParameter)?;
let (evaluation_data_dst, verified_policy_dst, suppl_data) = authenticate_remote_common(
quote_dst,
event_log_dst,
Expand Down Expand Up @@ -207,26 +183,44 @@ mod v2 {
Ok(suppl_data)
}

fn authenticate_migration_source(
pub fn authenticate_migration_source(
quote_src: &[u8],
event_log_src: &[u8],
mig_policy_src: &[u8],
policy_issuer_chain: &[u8],
#[cfg(feature = "vmcall-raw")] init_policy: &[u8],
#[cfg(feature = "vmcall-raw")] init_td_report: &[u8],
#[cfg(feature = "vmcall-raw")] init_event_log: &[u8],
#[cfg(feature = "vmcall-raw")] servtd_ext_src: &[u8],
) -> Result<Vec<u8>, PolicyError> {
let policy_issuer_chain = get_policy_issuer_chain().ok_or(PolicyError::InvalidParameter)?;
let (evaluation_data_src, _verified_policy_src, suppl_data) = authenticate_remote_common(
quote_src,
event_log_src,
mig_policy_src,
policy_issuer_chain,
)?;
let relative_reference = get_local_tcb_evaluation_info()?;
let policy = get_verified_policy().ok_or(PolicyError::InvalidParameter)?;

policy.policy_data.evaluate_policy_backward(
&evaluation_data_src,
&relative_reference,
false,
)?;
#[cfg(feature = "vmcall-raw")]
{
let servtd_ext_src_obj =
ServtdExt::read_from_bytes(servtd_ext_src).ok_or(PolicyError::InvalidParameter)?;
let init_tdreport = verify_init_tdreport(init_td_report, &servtd_ext_src_obj)?;
let verified_policy_init = verify_policy_and_event_log(
init_event_log,
init_policy,
policy_issuer_chain,
&get_rtmrs_from_tdreport(&init_tdreport)?,
)?;
let relative_reference =
get_init_tcb_evaluation_info(&init_tdreport, &verified_policy_init)?;
let policy = get_verified_policy().ok_or(PolicyError::InvalidParameter)?;

policy.policy_data.evaluate_policy_backward(
&evaluation_data_src,
&relative_reference,
false,
)?;
}

Ok(suppl_data)
}
Expand Down
4 changes: 1 addition & 3 deletions src/migtd/src/migration/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,7 @@ fn create_migration_information(
mig_socket_hob: Option<&[u8]>,
policy_info_hob: Option<&[u8]>,
) -> Option<MigrationInformation> {
let mig_info = hob_lib::get_guid_data(mig_info_hob?)?
.pread::<MigtdMigrationInformation>(0)
.ok()?;
let mig_info = MigtdMigrationInformation::read_from_bytes(mig_info_hob?)?;

#[cfg(any(feature = "vmcall-vsock", feature = "virtio-vsock"))]
let mig_socket_info = hob_lib::get_guid_data(mig_socket_hob?)?
Expand Down
66 changes: 64 additions & 2 deletions src/migtd/src/migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub mod session;
pub mod transport;

use crate::driver::ticks::TimeoutError;
#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
use crate::migration::rebinding::InitData;
use crate::ratls::RatlsError;
use crate::ratls::{
INVALID_MIG_POLICY_ERROR, MIG_POLICY_UNSATISFIED_ERROR, MUTUAL_ATTESTATION_ERROR,
Expand Down Expand Up @@ -79,15 +81,17 @@ pub const STREAM_SOCKET_INFO_HOB_GUID: Guid = Guid::from_fields(
);

#[repr(C)]
#[derive(Debug, Pread, Pwrite, Clone, Default)]
pub struct MigtdMigrationInformation {
// ID for the migration request, which can be used in TDG.VP.VMCALL
// <Service.MigTD.ReportStatus>
pub mig_request_id: u64,

// If set, current MigTD is MigTD-s else current MigTD is MigTD-d
pub migration_source: u8,
_pad: [u8; 7],

#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
// Has init migtd data
pub has_init_data: u8,

// UUID of target TD
pub target_td_uuid: [u64; 4],
Expand All @@ -103,6 +107,64 @@ pub struct MigtdMigrationInformation {
// Unique identifier for the communication between MigTD and VMM
// It can be retrieved from MIGTD_STREAM_SOCKET_INFO HOB
pub communication_id: u64,

#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
pub init_migtd_data: Option<InitData>,
}

impl MigtdMigrationInformation {
pub fn read_from_bytes(b: &[u8]) -> Option<Self> {
let min_len = if cfg!(feature = "vmcall-raw") { 56 } else { 72 };

if b.len() < min_len {
return None;
}

if b[10..16] != [0; 6] {
return None;
}

let mig_request_id = u64::from_le_bytes(b[..8].try_into().unwrap());
let migration_source = b[8];
#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
let has_init_data = b[9];

let target_td_uuid: [u64; 4] = core::array::from_fn(|i| {
let offset = 16 + i * 8;
u64::from_le_bytes(b[offset..offset + 8].try_into().unwrap())
});

let binding_handle = u64::from_le_bytes(b[48..56].try_into().unwrap());

#[cfg(not(feature = "vmcall-raw"))]
let mig_policy_id = u64::from_le_bytes(b[56..64].try_into().unwrap());

#[cfg(not(feature = "vmcall-raw"))]
let communication_id = u64::from_le_bytes(b[64..72].try_into().unwrap());

#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
let mut init_migtd_data = None;

#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
if has_init_data == 1 {
init_migtd_data = Some(InitData::read_from_bytes(&b[56..])?);
}

Some(Self {
mig_request_id,
migration_source,
#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
has_init_data,
target_td_uuid,
binding_handle,
#[cfg(not(feature = "vmcall-raw"))]
mig_policy_id,
#[cfg(not(feature = "vmcall-raw"))]
communication_id,
#[cfg(all(feature = "vmcall-raw", feature = "policy_v2"))]
init_migtd_data,
})
}
}

#[repr(C)]
Expand Down
103 changes: 98 additions & 5 deletions src/migtd/src/migration/pre_session_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// SPDX-License-Identifier: BSD-2-Clause-Patent

use crate::{config, migration::transport::TransportType};

use super::MigrationResult;
use alloc::{vec, vec::Vec};
use async_io::{AsyncRead, AsyncWrite};
Expand Down Expand Up @@ -318,10 +320,9 @@ pub(super) async fn exchange_hello_packet<T: AsyncRead + AsyncWrite + Unpin>(
.ok_or(MigrationResult::InvalidParameter)
}

#[cfg(feature = "policy_v2")]
pub(super) async fn pre_session_data_exchange<T: AsyncRead + AsyncWrite + Unpin>(
transport: &mut T,
pre_session_data: &[u8],
pub(super) async fn source_pre_session_data_exchange(
transport: &mut TransportType,
#[cfg(feature = "vmcall-raw")] init_policy: &[u8],
) -> Result<Vec<u8>> {
let version = exchange_hello_packet(transport).await.map_err(|e| {
log::error!(
Expand All @@ -332,7 +333,13 @@ pub(super) async fn pre_session_data_exchange<T: AsyncRead + AsyncWrite + Unpin>
})?;
log::info!("Pre-Session-Message Version: 0x{:04x}\n", version);

send_pre_session_data_packet(pre_session_data, transport)
let policy = config::get_policy()
.ok_or(MigrationResult::InvalidParameter)
.map_err(|e| {
log::error!("pre_session_data_exchange: get_policy error: {:?}\n", e);
e
})?;
send_pre_session_data_packet(policy, transport)
.await
.map_err(|e| {
log::error!(
Expand All @@ -351,6 +358,17 @@ pub(super) async fn pre_session_data_exchange<T: AsyncRead + AsyncWrite + Unpin>
e
})?;

#[cfg(feature = "vmcall-raw")]
send_pre_session_data_packet(init_policy, transport)
.await
.map_err(|e| {
log::error!(
"pre_session_data_exchange: send_pre_session_data_packet error: {:?}\n",
e
);
e
})?;

send_start_session_packet(transport).await.map_err(|e| {
log::error!(
"pre_session_data_exchange: send_start_session_packet error: {:?}\n",
Expand All @@ -368,3 +386,78 @@ pub(super) async fn pre_session_data_exchange<T: AsyncRead + AsyncWrite + Unpin>

Ok(remote_policy)
}

pub(super) async fn dest_pre_session_data_exchange(
transport: &mut TransportType,
) -> Result<Vec<u8>> {
let version = exchange_hello_packet(transport).await.map_err(|e| {
log::error!(
"pre_session_data_exchange: exchange_hello_packet error: {:?}\n",
e
);
e
})?;
log::info!("Pre-Session-Message Version: 0x{:04x}\n", version);

let policy = config::get_policy()
.ok_or(MigrationResult::InvalidParameter)
.map_err(|e| {
log::error!("pre_session_data_exchange: get_policy error: {:?}\n", e);
e
})?;
send_pre_session_data_packet(policy, transport)
.await
.map_err(|e| {
log::error!(
"pre_session_data_exchange: send_pre_session_data_packet error: {:?}\n",
e
);
e
})?;
let remote_policy = receive_pre_session_data_packet(transport)
.await
.map_err(|e| {
log::error!(
"pre_session_data_exchange: receive_pre_session_data_packet error: {:?}\n",
e
);
e
})?;

#[cfg(feature = "vmcall-raw")]
let init_policy = receive_pre_session_data_packet(transport)
.await
.map_err(|e| {
log::error!(
"pre_session_data_exchange: send_pre_session_data_packet error: {:?}\n",
e
);
e
})?;

send_start_session_packet(transport).await.map_err(|e| {
log::error!(
"pre_session_data_exchange: send_start_session_packet error: {:?}\n",
e
);
e
})?;
receive_start_session_packet(transport).await.map_err(|e| {
log::error!(
"pre_session_data_exchange: receive_start_session_packet error: {:?}\n",
e
);
e
})?;

// FIXME: Refactor the TLS verification callback to enable easier access to pre-session data.
let mut policy_buffer = Vec::new();
policy_buffer.extend_from_slice(&(remote_policy.len() as u32).to_le_bytes());
policy_buffer.extend_from_slice(&remote_policy);
#[cfg(feature = "vmcall-raw")]
policy_buffer.extend_from_slice(&(init_policy.len() as u32).to_le_bytes());
#[cfg(feature = "vmcall-raw")]
policy_buffer.extend_from_slice(&init_policy);

Ok(policy_buffer)
}
Loading
Loading