Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attestation report support with openssl #55

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-std = ["core", "compiler_builtins", "alloc"]
# but don't change the README instructions as someone might not
# have .cargo/
[build]
target = "svsm-target.json"
target = "x86_64-unknown-none.json"

[target.svsm-target]
rustflags = [
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
- name: Prepare tests
run: rustup component add rust-src --toolchain nightly
run: make prereq RUST_INSTALLER_ARGS='-y'
- name: Run tests
run: cargo test --target=x86_64-unknown-linux-gnu -Z build-std
run: make test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ dkms.conf
# Others
*.lds
.prereq
bindgen_out.rs
27 changes: 10 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ memoffset = "0.6"
paste = "1.0"
memchr = { version = "2", default-features = false }
uuid = { version = "1", default-features = false }
cty = "0.2.2"

[dependencies.lazy_static]
version = "1.0"
Expand Down
25 changes: 20 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ GCC = gcc

SHELL := /bin/bash

ROOT_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))

A_FLAGS := -D__ASSEMBLY__

C_FLAGS := -g -O2
Expand All @@ -17,7 +19,7 @@ LD_FLAGS += -nostdlib
LD_FLAGS += -Wl,-Tsrc/start/svsm.lds -Wl,--build-id=none

TARGET_DIR := target
TARGET := $(TARGET_DIR)/svsm-target/debug
TARGET := $(TARGET_DIR)/x86_64-unknown-none/debug

OBJS := src/start/start.o
OBJS += $(TARGET)/liblinux_svsm.a
Expand Down Expand Up @@ -51,14 +53,25 @@ external/openssl/libcrypto.a: libcrypto
libcrypto: external/openssl/Makefile libcrt
$(MAKE) -C external/openssl -j$$(nproc)

bindgen_out.rs: libcrypto include/bindings.h
bindgen \
include/bindings.h \
-o bindgen_out.rs \
--use-core \
--rustfmt-configuration-file $(ROOT_DIR)/.rustfmt.toml \
--rust-target "nightly" -- \
-DOPENSSL_RAND_SEED_NONE \
-I$(ROOT_DIR)/external/libcrt/include \
-I$(ROOT_DIR)/external/openssl/include

svsm.bin: svsm.bin.elf
objcopy -g -O binary $< $@

# "-Wl,-u,malloc" prevents the linker from removing the wrapper.rs symbols
svsm.bin.elf: $(EXT_LIBS) $(OBJS) src/start/svsm.lds
$(GCC) $(LD_FLAGS) -o $@ $(OBJS) -Wl,-u,malloc -Wl,--start-group $(EXT_LIBS) -Wl,--end-group
$(GCC) $(LD_FLAGS) -o $@ $(OBJS) -Wl,-u,malloc -Wl,-u,abort -Wl,--start-group $(EXT_LIBS) -Wl,--end-group

%.a: src/*.rs src/cpu/*.rs src/mem/*.rs src/protocols/*.rs src/util/*.rs
%.a: src/*.rs src/cpu/*.rs src/mem/*.rs src/protocols/*.rs src/util/*.rs bindgen_out.rs
@xargo build --features $(FEATURES)

%.o: %.S src/start/svsm.h
Expand All @@ -67,19 +80,20 @@ svsm.bin.elf: $(EXT_LIBS) $(OBJS) src/start/svsm.lds
%.lds: %.lds.S src/start/svsm.h
$(GCC) $(A_FLAGS) $(LDS_FLAGS) -E -P -o $@ $<

test:
test: bindgen_out.rs
cargo test --features $(FEATURES) --target=x86_64-unknown-linux-gnu -Z build-std

prereq: .prereq

.prereq:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- $(RUST_INSTALLER_ARGS)
source $(HOME)/.cargo/env
echo "source $(HOME)/.cargo/env" >> ~/.bashrc
rustup component add rust-src
rustup component add llvm-tools-preview
cargo install xargo
cargo install bootimage
cargo install bindgen-cli
touch .prereq

external/openssl/Makefile:
Expand Down Expand Up @@ -147,6 +161,7 @@ clean:
clean_all: clean
$(MAKE) -C external/libcrt clean
$(MAKE) -C external/openssl clean
rm -f bindgen_out.rs

superclean: clean_all
rm -f .prereq
7 changes: 7 additions & 0 deletions include/bindings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: MIT */

/*
* Attestation report requirement. SNP_GUEST_REQUEST messages have to be
* encrypted using AES_GCM, which is accessible using the EVP interface.
*/
#include <openssl/evp.h>
8 changes: 8 additions & 0 deletions src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT */

#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

// Add bindgen generated FFI bindings and test cases.
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/bindgen_out.rs"));
42 changes: 1 addition & 41 deletions src/bios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use crate::cpu::smp_prepare_bios_vmpl;
use crate::cpu::smp_run_bios_vmpl;
use crate::cpu::vc::*;
use crate::mem::SnpSecrets;
use crate::*;

use core::cmp::min;
Expand Down Expand Up @@ -109,47 +110,6 @@ impl SnpSection {
}
}

#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
struct SnpSecrets {
version: u32,
flags: u32,
fms: u32,
reserved1: [u8; 4],

gosvw: [u8; 16],

vmpck0: [u8; 32],
vmpck1: [u8; 32],
vmpck2: [u8; 32],
vmpck3: [u8; 32],

os_reserved: [u8; 96],

reserved2: [u8; 64],

// SVSM fields start at offset 0x140 into the secrets page
svsm_base: u64,
svsm_size: u64,
svsm_caa: u64,
svsm_max_version: u32,
svsm_guest_vmpl: u8,
reserved3: [u8; 3],
}

#[allow(dead_code)]
impl SnpSecrets {
pub fn clear_vmpck0(&mut self) {
self.vmpck0.iter_mut().for_each(|e| *e = 0);
}

funcs!(svsm_base, u64);
funcs!(svsm_size, u64);
funcs!(svsm_caa, u64);
funcs!(svsm_max_version, u32);
funcs!(svsm_guest_vmpl, u8);
}

/// 96b582de-1fb2-45f7-baea-a366c55a082d
const OVMF_TABLE_GUID: Uuid = uuid!("96b582de-1fb2-45f7-baea-a366c55a082d");
/// dc886566-984a-4798-A75e-5585a7bf67cc
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/smp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ const SVSM_X87_FTW: u16 = 0x5555;
/// 0x40
const SVSM_X87_FCW: u16 = 0x40;

/// 5
const SVSM_STACK_PAGES: u64 = 5; /* 4 stack pages and one guard page */
/// 17
const SVSM_STACK_PAGES: u64 = 17; /* 16 stack pages and one guard page */

static mut AP_SYNC: u8 = 0;
/// 1
Expand Down
46 changes: 46 additions & 0 deletions src/cpu/vc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::globals::*;
use crate::mem::ghcb::Ghcb;
use crate::mem::ghcb::*;
use crate::mem::*;
use crate::psp::guest_request_cmd::{SnpGuestRequestCmd, SNP_GUEST_REQ_INVALID_LEN};
use crate::util::util::memset;
use crate::*;

Expand Down Expand Up @@ -115,6 +116,10 @@ const GHCB_NAE_CPUID: u64 = 0x72;
const GHCB_NAE_IOIO: u64 = 0x7b;
/// 0x80000010
const GHCB_NAE_PSC: u64 = 0x80000010;
/// 0x80000011
const GHCB_NAE_SNP_GUEST_REQUEST: u64 = 0x80000011;
/// 0x80000012
const GHCB_NAE_SNP_EXT_GUEST_REQUEST: u64 = 0x80000012;
/// 0x80000013
const GHCB_NAE_SNP_AP_CREATION: u64 = 0x80000013;
/// 1
Expand Down Expand Up @@ -376,6 +381,47 @@ pub fn vc_ap_create(vmsa_va: VirtAddr, apic_id: u32) {
}
}

pub fn vc_snp_guest_request(
extended: bool,
psp_rc: &mut u64,
cmd: &mut SnpGuestRequestCmd,
) -> Result<(), ()> {
let ghcb: *mut Ghcb = vc_get_ghcb();
let info1: u64 = pgtable_va_to_pa((*cmd).req_shared_page()).as_u64();
let info2: u64 = pgtable_va_to_pa((*cmd).resp_shared_page()).as_u64();

let exit_code: u64 = if extended {
GHCB_NAE_SNP_EXT_GUEST_REQUEST
} else {
GHCB_NAE_SNP_GUEST_REQUEST
};

unsafe {
if extended {
let data_gpa: u64 = pgtable_va_to_pa((*cmd).data_gva()).as_u64();
(*ghcb).set_rax(data_gpa);
(*ghcb).set_rbx((*cmd).data_npages() as u64);
}

vc_perform_vmgexit(ghcb, exit_code, info1, info2);

if !(*ghcb).is_sw_exit_info_2_valid() {
return Err(());
}

*psp_rc = (*ghcb).sw_exit_info_2();

// The number of expected pages are returned in RBX
if extended && *psp_rc == SNP_GUEST_REQ_INVALID_LEN {
(*cmd).set_data_npages((*ghcb).rbx() as usize);
}

(*ghcb).clear();
}

Ok(())
}

pub fn vc_get_apic_ids(bsp_apic_id: u32) -> Vec<u32> {
let mut apic_ids: Vec<u32>;
let ghcb: *mut Ghcb = vc_get_ghcb();
Expand Down
12 changes: 12 additions & 0 deletions src/crypto/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (C) 2023 IBM
*
* Authors:
* Claudio Carvalho <[email protected]>
*/

/// SSL
#[cfg_attr(test, path = "nossl.rs")]
#[cfg_attr(not(test), path = "openssl.rs")]
pub mod ssl;
Loading