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

Added additional SNP checks on the host and guest via verification of SNP bit status from instruction set #12

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
81 changes: 78 additions & 3 deletions tools/snp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ cleanup() {

stop-guests)
;;

*)
>&2 echo -e "Unknown ERROR encountered"
;;
Expand All @@ -164,6 +163,72 @@ verify_snp_host() {
fi
}

verify_platform_snp_bit_status() {
if [ "$1" == "host" ]; then
# Get the host cpuid eax
local host_cpuid_eax
host_cpuid_eax=$(get_cpuid 0x8000001f eax)

# Map all the computed host sev/snp bit values in a single associative array
declare -A actual_sev_snp_bit_status=(
[SME]=$(( (${host_cpuid_eax} >> 0) & 1))
[SEV]=$(( (${host_cpuid_eax} >> 1) & 1))
[SEV-ES]=$(( (${host_cpuid_eax} >> 3) & 1))
[SNP]=$(( (${host_cpuid_eax} >> 4) & 1))
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally to the CPUID (which checks if the feature is supported by the CPU) there is also an MSR that you can use to check if SME and SNP are enabled.

MSR 0xC0010010 bit 23 checks SME
MSR 0xC0010010 bit 24 checks SNP

fi

if [ "$1" == "guest" ]; then
if [ ! -f "${GUEST_SSH_KEY_PATH}" ]; then
>&2 echo -e "Guest SSH key not present [${GUEST_SSH_KEY_PATH}], so cannot verify guest SNP enabled"
return 1
fi

# Install guest rdmsr package dependencies to insert & insert guest msr module
ssh_guest_command "sudo DEBIAN_FRONTEND=noninteractive sudo apt install -y msr-tools > /dev/null 2>&1" > /dev/null 2>&1
ssh_guest_command "sudo modprobe msr" > /dev/null 2>&1
Comment on lines +188 to +190
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this only work on Debian?


# Read the guest (MSR_AMD64_SEV) value
local guest_msr_read
guest_msr_read=$(ssh_guest_command "sudo rdmsr -p 0 0xc0010131")
guest_msr_read=$(echo "${guest_msr_read}" | tr -d '\r' | bc)
Comment on lines +194 to +195
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In one of my tools that I built out to do this, I had an issue with padding. If I had a bit number that looked like 0000001, my msr read would return 1 not the full number. So when I tried to reach a bit that was a 0 I'd get a an issue trying to reach a digit that was not there. Have you checked for this issue? Try running this command in a guest with no SEV enabled and see if the fail case doesn't cause an error.


# Map all the sev features in a single associative array for all guest SEV features
declare -A actual_sev_snp_bit_status=(
[SEV]=$(( ( ${guest_msr_read} >> 0) & 1))
[SEV-ES]=$(( (${guest_msr_read} >> 1) & 1))
[SNP]=$(( (${guest_msr_read} >> 2) & 1))
)

fi

# Checks for the presence of all the security feature support in the platform
local sev_snp_error
sev_snp_error=""
for sev_snp_key in "${!actual_sev_snp_bit_status[@]}";
do
if [[ ${actual_sev_snp_bit_status[$sev_snp_key]} != 1 ]]; then
# Capture the host SEV/SNP bit value mismatch
if [ "$1" == "host" ]; then
sev_snp_error+=$(echo "$sev_snp_key support is not found on the host.\n");
sev_snp_error+=$(echo "Swap of a processor that supports $sev_snp_key feature is required. \n");
sev_snp_error+=$(echo "$sev_snp_key current bit value is: ${actual_sev_snp_bit_status[$sev_snp_key]} .\n")
fi
# Capture the guest SEV/SNP bit value mismatch
if [ "$1" == "guest" ]; then
sev_snp_error+=$(echo "$sev_snp_key feature is not active on the guest.\n");
sev_snp_error+=$(echo "$sev_snp_key current bit value is: ${actual_sev_snp_bit_status[$sev_snp_key]} .\n");
fi
fi
done

if [[ ! -z "${sev_snp_error}" ]]; then
>&2 echo -e "ERROR: ${sev_snp_error}"
return 1
fi
}

install_nasm_from_source() {
local nasm_dir_name=$(echo "${NASM_SOURCE_TAR_URL}" | sed "s|.*/\(.*\)|\1|g" | sed "s|.tar.gz||g")
local nasm_dir="${WORKING_DIR}/${nasm_dir_name}"
Expand Down Expand Up @@ -1196,6 +1261,7 @@ main() {
;;

setup-host)
verify_platform_snp_bit_status host
install_dependencies

if $UPM; then
Expand All @@ -1218,6 +1284,7 @@ main() {
copy_launch_binaries
source "${LAUNCH_WORKING_DIR}/source-bins"

verify_platform_snp_bit_status host
verify_snp_host
install_dependencies

Expand All @@ -1227,7 +1294,11 @@ main() {
sudo modprobe kvm_amd debug_swap=0

setup_and_launch_guest
wait_and_retry_command verify_snp_guest
# Use of MSR checks over dmesg output for the SNP status check on guest
# wait_and_retry_command verify_snp_guest

# SNP test on guest via MSR check
wait_and_retry_command verify_platform_snp_bit_status guest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should maybe replace verify_snp_guest. They are essentially doing the same thing, the only difference is that the original function is checking dmesg, while the bit_status is looking at the guest MSR to verify enablement. No need to run both of them if the MSR check is working correctly.


echo -e "Guest SSH port forwarded to host port: ${HOST_SSH_PORT}"
echo -e "The guest is running in the background. Use the following command to access via SSH:"
Expand All @@ -1238,7 +1309,11 @@ main() {
install_rust
install_sev_snp_measure
install_dependencies
wait_and_retry_command verify_snp_guest
# Use of MSR checks over dmesg output for the SNP status check on guest
# wait_and_retry_command verify_snp_guest

# SNP test on guest via MSR check
wait_and_retry_command verify_platform_snp_bit_status guest
setup_guest_attestation
attest_guest
;;
Expand Down