Skip to content
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
113 changes: 113 additions & 0 deletions tools/snp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,65 @@ cleanup() {
return $exit_code
}

verify_all_security_bits() {

local feature_error=''
for feature in "${!security_bit_values[@]}"
do
if [[ ${security_bit_values[$feature]} != 1 ]]; then
feature_error+=$(echo "${feature} bit value is ${security_bit_values[$feature]} .\n");
fi
done

if [[ -n "${feature_error}" ]]; then
echo ${feature_error}
fi
}

verify_host_snp_support() {
echo -e "Verifying host CPU support for SNP from CPUID 0x8000001f ..."
local host_cpuid_eax=$(get_cpuid 0x8000001f eax)

# Map all the security bit values in a single associative array
declare -A security_bit_values=(
[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))
)

Comment thread
LakshmiSaiHarika marked this conversation as resolved.
local feature_error=$(verify_all_security_bits "${security_bit_values[@]}")
if [[ -n "${feature_error}" ]]; then
>&2 echo -e "ERROR: SNP feature is not supported by the host CPU"
>&2 echo -e "${feature_error}"
return 1
fi
}

verify_host_snp_enablement() {
echo -e "Verifying if SME, SNP are enabled in the host from MSR 0xC0010010..."

if ! sudo modprobe msr; then
>&2 echo "ERROR: Failed to load MSR kernel module. Ensure you have the necessary sudo permissions."
return 1
fi

local host_msr_read=$(echo "$(sudo rdmsr -d 0xc0010010)")

# Map all the security bit values in a single associative array
declare -A security_bit_values=(
[SME]=$(echo $((((${host_msr_read} & (1 << 23)) >> 23))))
[SNP]=$(echo $((((${host_msr_read} & (1 << 24)) >> 24))))
)

local feature_error=$(verify_all_security_bits "${security_bit_values[@]}")
if [[ -n "${feature_error}" ]]; then
>&2 echo -e "ERROR: SME, SNP are not enabled in the host BIOS"
>&2 echo -e "${feature_error}"
return 1
fi
}

verify_snp_host() {
if ! sudo dmesg | grep -i "SEV-SNP enabled\|SEV-SNP supported" 2>&1 >/dev/null; then
echo -e "SEV-SNP not enabled on the host. Please follow these steps to enable:\n\
Expand Down Expand Up @@ -1099,6 +1158,55 @@ setup_guest_attestation() {
echo "true" > "${guest_setup_file}"
}

install_guest_rdmsr_dependencies() {
wait_and_retry_command "ssh_guest_command "uname -r""

# Retrieve guest linux distribution
local guest_linux_distro=$(ssh_guest_command "lsb_release -is")
guest_linux_distro=$(echo "${guest_linux_distro}" | tr -d '\r')
guest_linux_distro="${guest_linux_distro,,}"

case ${guest_linux_distro} in
ubuntu)
ssh_guest_command "sudo DEBIAN_FRONTEND=noninteractive sudo apt install -y msr-tools > /dev/null 2>&1" > /dev/null 2>&1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are we assuming that the user will have sudo permissions by default?
If yes, disregard my comments.
Else, we might have to modify the code to handle that permission errors aren't misconstrued as actual errors

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes, I tested this, this works by default

;;
*)
>&2 echo -e "ERROR: Unsupported guest linux distribution: ${guest_linux_distro}"
return 1
;;
esac
}

verify_guest_snp_bit_status() {
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 & insert guest msr module
install_guest_rdmsr_dependencies
ssh_guest_command "sudo modprobe msr" > /dev/null 2>&1

# Read the guest (MSR_AMD64_SEV) value
local guest_msr_read=$(ssh_guest_command "sudo rdmsr -p 0 0xc0010131")
guest_msr_read=$(echo "${guest_msr_read}" | tr -d '\r' | bc)

# Map all the security bit values in a single associative array
declare -A security_bit_values=(
[SEV]=$(( ( ${guest_msr_read} >> 0) & 1))
[SEV-ES]=$(( (${guest_msr_read} >> 1) & 1))
[SNP]=$(( (${guest_msr_read} >> 2) & 1))
)

local feature_error=$(verify_all_security_bits "${security_bit_values[@]}")

if [[ -n "${feature_error}" ]]; then
>&2 echo -e "ERROR: SEV/SEV-ES/SNP is not active in the guest"
>&2 echo -e "${feature_error}"
return 1
fi
}

# Pass a function and a register to collect its value
get_cpuid() {
local function=$1
Expand Down Expand Up @@ -1366,6 +1474,8 @@ main() {
;;

setup-host)
verify_host_snp_support
verify_host_snp_enablement
install_dependencies

if $UPM; then
Expand All @@ -1388,10 +1498,12 @@ main() {
copy_launch_binaries
source "${LAUNCH_WORKING_DIR}/source-bins"

verify_host_snp_enablement
verify_snp_host
install_dependencies

setup_and_launch_guest
verify_guest_snp_bit_status
wait_and_retry_command verify_snp_guest

echo -e "Guest SSH port forwarded to host port: ${HOST_SSH_PORT}"
Expand All @@ -1403,6 +1515,7 @@ main() {
install_rust
install_sev_snp_measure
install_dependencies
verify_guest_snp_bit_status
wait_and_retry_command verify_snp_guest
setup_guest_attestation
attest_guest
Expand Down