Skip to content

Commit 6a7d636

Browse files
committed
psp/guest_request_cmd: Add send_request()
As described in the SNP Firmware ABI specification, SNP_GUEST_REQUEST commands are protected using AES_GCM 256 and a VMPCK key to encrypt/decrypt the message. The firmware generates and provides the VMPCK keys to the guest in a especial secrets page that only the guest and firmware have access to, so the hypervisor cannot alter messages without detection nor read the plaintext of the message. We are limiting the send_request() implementation to encrypt/decrypt messages using the VMPCK0 key only. From guest userspace we can send SNP_GUEST_REQUEST commands using other VMPCK keys. The send_request() also supports sending extended SNP_GUEST_REQUEST commands, where the extended part of it is provided by the hypervisor. For example, in an extended attestation report the PSP firmware provides the attestation report and the hypervisor provides the certificate chain needed to verify the attestation report. If a SNP_GUEST_REQUEST fails, we disable the VMPCK0 to prevent it from being used again to send SNP_GUEST_REQUEST commands to the PSP firmware. The only two exceptions are when the hypervisor returns the error codes below: - BUSY: in this case we re-send the message and if it resturns any error code, we disable the VMPCK0. - INVALID_DATA_BUFFER_LEN: the data buffer provided in the extended SNP_GUEST_REQUEST command is too small. So, we re-send the command, but as non-extended SNP_GUEST_REQUEST in order to protect the IV (sequence number) from replay attacks. If it returns any error code, we disable the VMPCK0. The two cases above could be improved later when, for example, timer support is added to the SVSM. Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
1 parent 46fc912 commit 6a7d636

2 files changed

Lines changed: 487 additions & 5 deletions

File tree

src/mem/snpsecrets.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
use crate::{funcs, get_svsm_secrets_page, prints};
1010

11-
use x86_64::addr::VirtAddr;
12-
1311
/// 32
1412
pub const VMPCK_SIZE: usize = 32;
1513

@@ -58,3 +56,15 @@ impl SnpSecrets {
5856
funcs!(svsm_guest_vmpl, u8);
5957
funcs!(vmpck0, [u8; VMPCK_SIZE]);
6058
}
59+
60+
pub fn disable_vmpck0() {
61+
let svsm_secrets_ptr: *mut SnpSecrets = get_svsm_secrets_page().as_mut_ptr();
62+
prints!("WARNING: VMPCK0 disabled!\n");
63+
unsafe { (*svsm_secrets_ptr).clear_vmpck0() }
64+
}
65+
66+
pub fn is_vmpck0_clear() -> bool {
67+
let svsm_secrets_ptr: *mut SnpSecrets = get_svsm_secrets_page().as_mut_ptr();
68+
69+
unsafe { (*svsm_secrets_ptr).is_vmpck0_clear() }
70+
}

0 commit comments

Comments
 (0)