-
Notifications
You must be signed in to change notification settings - Fork 5
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,7 +147,6 @@ cleanup() { | |
|
||
stop-guests) | ||
;; | ||
|
||
*) | ||
>&2 echo -e "Unknown ERROR encountered" | ||
;; | ||
|
@@ -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)) | ||
) | ||
|
||
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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}" | ||
|
@@ -1196,6 +1261,7 @@ main() { | |
;; | ||
|
||
setup-host) | ||
verify_platform_snp_bit_status host | ||
install_dependencies | ||
|
||
if $UPM; then | ||
|
@@ -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 | ||
|
||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:" | ||
|
@@ -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 | ||
;; | ||
|
There was a problem hiding this comment.
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