diff options
Diffstat (limited to 'target/i386/sev.c')
-rw-r--r-- | target/i386/sev.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/target/i386/sev.c b/target/i386/sev.c index 41f7800b5f..1a88f12703 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -492,6 +492,73 @@ out: return cap; } +SevAttestationReport * +sev_get_attestation_report(const char *mnonce, Error **errp) +{ + struct kvm_sev_attestation_report input = {}; + SevAttestationReport *report = NULL; + SevGuestState *sev = sev_guest; + guchar *data; + guchar *buf; + gsize len; + int err = 0, ret; + + if (!sev_enabled()) { + error_setg(errp, "SEV is not enabled"); + return NULL; + } + + /* lets decode the mnonce string */ + buf = g_base64_decode(mnonce, &len); + if (!buf) { + error_setg(errp, "SEV: failed to decode mnonce input"); + return NULL; + } + + /* verify the input mnonce length */ + if (len != sizeof(input.mnonce)) { + error_setg(errp, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT ")", + sizeof(input.mnonce), len); + g_free(buf); + return NULL; + } + + /* Query the report length */ + ret = sev_ioctl(sev->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, + &input, &err); + if (ret < 0) { + if (err != SEV_RET_INVALID_LEN) { + error_setg(errp, "failed to query the attestation report length " + "ret=%d fw_err=%d (%s)", ret, err, fw_error_to_str(err)); + g_free(buf); + return NULL; + } + } + + data = g_malloc(input.len); + input.uaddr = (unsigned long)data; + memcpy(input.mnonce, buf, sizeof(input.mnonce)); + + /* Query the report */ + ret = sev_ioctl(sev->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, + &input, &err); + if (ret) { + error_setg_errno(errp, errno, "Failed to get attestation report" + " ret=%d fw_err=%d (%s)", ret, err, fw_error_to_str(err)); + goto e_free_data; + } + + report = g_new0(SevAttestationReport, 1); + report->data = g_base64_encode(data, input.len); + + trace_kvm_sev_attestation_report(mnonce, report->data); + +e_free_data: + g_free(data); + g_free(buf); + return report; +} + static int sev_read_file_base64(const char *filename, guchar **data, gsize *len) { |