Created
June 8, 2023 12:27
-
-
Save dubek/0e0a419fecf2ca87dd65d483d5c446d5 to your computer and use it in GitHub Desktop.
Guest userspace program to retrieve attestation report from SVSM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* gcc -O2 -Wall -static -s svsm-report-2.c -o svsm-report-2 | |
*/ | |
#include <fcntl.h> | |
#include <memory.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/ioctl.h> | |
#include <unistd.h> | |
/* from linux/sev-guest.h */ | |
struct snp_guest_request_ioctl { | |
/* message version number (must be non-zero) */ | |
uint8_t msg_version; | |
/* Request and response structure address */ | |
uint64_t req_data; | |
uint64_t resp_data; | |
/* firmware error code on failure (see psp-sev.h) */ | |
uint64_t fw_err; | |
}; | |
/************************************************************/ | |
/* */ | |
/* SVSM_ATTEST_SERVICES ioctl call */ | |
/* */ | |
/************************************************************/ | |
#define SNP_GUEST_REQ_IOC_TYPE 'S' | |
#define SNP_SVSM_ATTEST_SERVICES _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x3, struct snp_guest_request_ioctl) | |
struct snp_svsm_attest_services_req { | |
/* nonce that should be included in the report */ | |
uint8_t nonce[32]; | |
/* where to copy the certificate blob */ | |
uint64_t certs_address; | |
/* length of the certificate blob */ | |
uint32_t certs_len; | |
}; | |
struct snp_svsm_attest_services_resp { | |
/* length of the returned attestation report */ | |
uint32_t report_len; | |
/* length of the returned services manifest */ | |
uint32_t services_manifest_len; | |
/* length of the returned certificates blob */ | |
uint32_t certs_len; | |
uint8_t rsvd[4]; | |
/* services manifest */ | |
uint8_t services_manifest[1024]; | |
/* attestation report, see SEV-SNP spec for the format */ | |
uint8_t report[3000]; | |
}; | |
/************************************************************/ | |
static const uint8_t nonce[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | |
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, | |
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; | |
int main(int argc, char *argv[]) { | |
struct snp_svsm_attest_services_req snp_request; | |
struct snp_svsm_attest_services_resp snp_response; | |
struct snp_guest_request_ioctl ioctl_request; | |
int snpdev, fd, rc; | |
snpdev = open("/dev/sev-guest", O_RDWR | O_CLOEXEC); | |
if (snpdev < 0) { | |
printf("Failed to open /dev/sev-guest\n"); | |
return 1; | |
} | |
uint8_t *certs = malloc(4 * 4096); | |
memset(&snp_request, 0, sizeof(snp_request)); | |
memcpy(snp_request.nonce, nonce, sizeof(snp_request.nonce)); | |
snp_request.certs_address = (uint64_t)certs; | |
snp_request.certs_len = 4 * 4096; | |
memset(&snp_response, 0, sizeof(snp_response)); | |
memset(&ioctl_request, 0, sizeof(ioctl_request)); | |
ioctl_request.msg_version = 1; | |
ioctl_request.req_data = (uint64_t)&snp_request; | |
ioctl_request.resp_data = (uint64_t)&snp_response; | |
rc = ioctl(snpdev, SNP_SVSM_ATTEST_SERVICES, &ioctl_request); | |
if (rc < 0) { | |
printf("ioctl SNP_SVSM_ATTEST_SERVICES failed\n"); | |
return 1; | |
} | |
printf("SVSM call response:\n"); | |
printf(">> ioctl_request.fw_err=0x%lx\n", ioctl_request.fw_err); | |
printf(">> snp_response.report_len=0x%x\n", snp_response.report_len); | |
printf(">> snp_response.services_manifest_len=0x%x\n", snp_response.services_manifest_len); | |
printf(">> snp_response.certs_len=0x%x\n", snp_response.certs_len); | |
fd = open("./attestation_report.bin", O_CREAT | O_WRONLY); | |
write(fd, snp_response.report, snp_response.report_len); | |
close(fd); | |
printf("Wrote: ./attestation_report.bin\n"); | |
fd = open("./services_manifest", O_CREAT | O_WRONLY); | |
write(fd, snp_response.services_manifest, snp_response.services_manifest_len); | |
close(fd); | |
printf("Wrote: ./services_manifest.bin\n"); | |
fd = open("./certs", O_CREAT | O_WRONLY); | |
write(fd, certs, snp_response.certs_len); | |
close(fd); | |
printf("Wrote: ./certs.bin\n"); | |
free(certs); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment