-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
protocols: Implement the vTPM protocol
The vTPM protocol is introduced in the SVSM specification v1.0 to allow other software components (e.g. OVMF and guest kernel) to communicate with the SVSM vTPM at runtime. It follows the Microsoft TPM 2.0 Simulator protocol. The specification enumerates two call IDs supportted by the vTPM protocol: 1. SVSM_VTPM_QUERY: query vTPM command and features support. 2. SVSM_VTPM_CMD: Execute a TPM platform command. As for the SVSM_VTPM_CMD, the TPM platform commands are described in libvtpm/ms-tpm-20-ref/TPMCmd/Simulator/include/prototypes/Simulator_fp.h e.g.: - TPM_SIGNAL_HASH_DATA - TPM_SEND_COMMAND - TPM_REMOTE_HANDSHAKE - TPM_SET_ALTERNATIVE_RESULT This patch implements both the SVSM_VTPM_QUERY and the SVSM_VTPM_CMD call IDs. For the SVSM_VTPM_CMD, only the TPM_SEND_COMMAND platform command is implemented. Signed-off-by: Claudio Carvalho <[email protected]>
- Loading branch information
Showing
5 changed files
with
232 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
// | ||
// Copyright (c) 2023 IBM Corp | ||
// | ||
// Author: Claudio Carvalho <[email protected]> | ||
|
||
/// vTPM Protocol defined in the Chapter 8 of the SVSM spec v0.62. | ||
use crate::address::{Address, PhysAddr}; | ||
use crate::mm::{valid_phys_address, GuestPtr, PerCPUPageMappingGuard, PAGE_SIZE}; | ||
use crate::protocols::errors::SvsmReqError; | ||
use crate::protocols::RequestParams; | ||
use crate::vtpm::mssim::{mssim_platform_request, mssim_platform_supported_commands}; | ||
|
||
/// Table 14: vTPM Protocol Services | ||
const SVSM_VTPM_QUERY: u32 = 0; | ||
const SVSM_VTPM_COMMAND: u32 = 1; | ||
|
||
/// Table 15: vTPM Common Request/Response Structure | ||
/// | ||
/// Each MSSIM TPM command can build upon this common request/response | ||
/// structure to create a structure specific to the command. | ||
/// | ||
/// @command: gPA of the MSIM TPM Command structure. | ||
/// The first field of this structure must be | ||
/// the command number. | ||
#[derive(Clone, Copy, Debug)] | ||
#[repr(C, packed)] | ||
struct VtpmCmdRequest { | ||
command: u32, | ||
} | ||
|
||
/// Table 16: TPM_SEND_COMMAND request structure | ||
/// | ||
/// @command: The command (must be TPM_SEND_COMMAND) | ||
/// @locality: The locality | ||
/// @inbuf_size: The size of the input buffer following | ||
/// @inbuf: A buffer of size inbuf_size | ||
/// | ||
/// Note that @inbuf_size must be large enough to hold the response so | ||
/// it represents the maximum buffer size, not the size of the specific | ||
/// TPM command. | ||
#[derive(Clone, Copy, Debug)] | ||
#[repr(C, packed)] | ||
pub struct TpmSendCommandRequest { | ||
pub command: u32, | ||
pub locality: u8, | ||
pub inbuf_size: u32, | ||
//pub inbuf: u64, | ||
} | ||
|
||
/// Table 17: TPM_SEND_COMMAND response structure | ||
#[derive(Clone, Copy, Debug)] | ||
#[repr(C, packed)] | ||
pub struct TpmSendCommandResponse { | ||
pub outbuf_size: u32, | ||
//pub outbuf: u64, | ||
} | ||
|
||
fn vtpm_command_request(params: &mut RequestParams) -> Result<(), SvsmReqError> { | ||
// FIXME: Remove this check when the guest tpm driver is able to probe | ||
// using the SVSM_VTPM_QUERY call ID. | ||
if params.rcx == 0 { | ||
log::info!("SVSM: vtpm command probe"); | ||
return Ok(()); | ||
} | ||
|
||
let paddr = PhysAddr::from(params.rcx); | ||
|
||
if !valid_phys_address(paddr) { | ||
log::error!( | ||
"vTPM buffer not valid physical address {} {}", | ||
paddr, | ||
params.rcx | ||
); | ||
return Err(SvsmReqError::invalid_parameter()); | ||
} | ||
|
||
// The buffer gpa size is one page, but it not required to be page aligned. | ||
let start = paddr.page_align(); | ||
let offset = paddr.page_offset(); | ||
let end = (paddr + PAGE_SIZE).page_align_up(); | ||
|
||
let guard = PerCPUPageMappingGuard::create(start, end, 0)?; | ||
let vaddr = guard.virt_addr() + offset; | ||
|
||
let guest_page = GuestPtr::<VtpmCmdRequest>::new(vaddr); | ||
let request = guest_page.read()?; | ||
|
||
mssim_platform_request(request.command, vaddr)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
fn vtpm_query_request(params: &mut RequestParams) -> Result<(), SvsmReqError> { | ||
// Bitmap of the supported vTPM commands | ||
params.rcx = mssim_platform_supported_commands(); | ||
// Supported vTPM features. Must-be-zero | ||
params.rdx = 0; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn vtpm_protocol_request(request: u32, params: &mut RequestParams) -> Result<(), SvsmReqError> { | ||
match request { | ||
SVSM_VTPM_QUERY => vtpm_query_request(params), | ||
SVSM_VTPM_COMMAND => vtpm_command_request(params), | ||
_ => Err(SvsmReqError::unsupported_call()), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters