From: tobin <tobin@linux.vnet.ibm.com>
To: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: thomas.lendacky@amd.com, brijesh.singh@amd.com,
jejb@linux.ibm.com, tobin@ibm.com, qemu-devel@nongnu.org,
pbonzini@redhat.com
Subject: Re: [PATCH 1/1] SEV: QMP support for Inject-Launch-Secret
Date: Thu, 02 Jul 2020 12:56:39 -0400 [thread overview]
Message-ID: <7880f4b376d4f6afe29288673575f20a@linux.vnet.ibm.com> (raw)
In-Reply-To: <20200702155240.GD14863@work-vm>
On 2020-07-02 11:53, Dr. David Alan Gilbert wrote:
> * Tobin Feldman-Fitzthum (tobin@linux.vnet.ibm.com) wrote:
>> From: Tobin Feldman-Fitzthum <tobin@ibm.com>
>>
>> AMD SEV allows a guest owner to inject a secret blob
>> into the memory of a virtual machine. The secret is
>> encrypted with the SEV Transport Encryption Key and
>> integrity is guaranteed with the Transport Integrity
>> Key. Although QEMU faciliates the injection of the
>> launch secret, it cannot access the secret.
>>
>> Signed-off-by: Tobin Feldman-Fitzthum <tobin@linux.vnet.ibm.com>
>> ---
>> include/monitor/monitor.h | 3 ++
>> include/sysemu/sev.h | 2 ++
>> monitor/misc.c | 8 ++---
>> qapi/misc-target.json | 18 +++++++++++
>> target/i386/monitor.c | 9 ++++++
>> target/i386/sev-stub.c | 5 +++
>> target/i386/sev.c | 66
>> +++++++++++++++++++++++++++++++++++++++
>> target/i386/trace-events | 1 +
>> 8 files changed, 108 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
>> index 1018d754a6..bf049c5b00 100644
>> --- a/include/monitor/monitor.h
>> +++ b/include/monitor/monitor.h
>> @@ -4,6 +4,7 @@
>> #include "block/block.h"
>> #include "qapi/qapi-types-misc.h"
>> #include "qemu/readline.h"
>> +#include "include/exec/hwaddr.h"
>>
>> extern __thread Monitor *cur_mon;
>> typedef struct MonitorHMP MonitorHMP;
>> @@ -36,6 +37,8 @@ void monitor_flush(Monitor *mon);
>> int monitor_set_cpu(int cpu_index);
>> int monitor_get_cpu_index(void);
>>
>> +void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error
>> **errp);
>> +
>> void monitor_read_command(MonitorHMP *mon, int show_prompt);
>> int monitor_read_password(MonitorHMP *mon, ReadLineFunc
>> *readline_func,
>> void *opaque);
>> diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
>> index 98c1ec8d38..b279b293e8 100644
>> --- a/include/sysemu/sev.h
>> +++ b/include/sysemu/sev.h
>> @@ -18,4 +18,6 @@
>>
>> void *sev_guest_init(const char *id);
>> int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
>> +int sev_inject_launch_secret(const char *hdr, const char *secret,
>> + uint64_t gpa);
>> #endif
>> diff --git a/monitor/misc.c b/monitor/misc.c
>> index 89bb970b00..b9ec8ba410 100644
>> --- a/monitor/misc.c
>> +++ b/monitor/misc.c
>> @@ -674,10 +674,10 @@ static void hmp_physical_memory_dump(Monitor
>> *mon, const QDict *qdict)
>> memory_dump(mon, count, format, size, addr, 1);
>> }
>>
>> -static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp)
>> +void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error
>> **errp)
>> {
>> MemoryRegionSection mrs = memory_region_find(get_system_memory(),
>> - addr, 1);
>> + addr, size);
>>
>> if (!mrs.mr) {
>> error_setg(errp, "No memory is mapped at address 0x%"
>> HWADDR_PRIx, addr);
>> @@ -701,7 +701,7 @@ static void hmp_gpa2hva(Monitor *mon, const QDict
>> *qdict)
>> MemoryRegion *mr = NULL;
>> void *ptr;
>>
>> - ptr = gpa2hva(&mr, addr, &local_err);
>> + ptr = gpa2hva(&mr, addr, 1, &local_err);
>> if (local_err) {
>> error_report_err(local_err);
>> return;
>> @@ -777,7 +777,7 @@ static void hmp_gpa2hpa(Monitor *mon, const QDict
>> *qdict)
>> void *ptr;
>> uint64_t physaddr;
>>
>> - ptr = gpa2hva(&mr, addr, &local_err);
>> + ptr = gpa2hva(&mr, addr, 1, &local_err);
>> if (local_err) {
>> error_report_err(local_err);
>> return;
>> diff --git a/qapi/misc-target.json b/qapi/misc-target.json
>> index dee3b45930..d145f916b3 100644
>> --- a/qapi/misc-target.json
>> +++ b/qapi/misc-target.json
>> @@ -200,6 +200,24 @@
>> { 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
>> 'if': 'defined(TARGET_I386)' }
>>
>> +##
>> +# @sev-inject-launch-secret:
>> +#
>> +# This command injects a secret blob into memory of SEV guest.
>> +#
>> +# @packet-header: the launch secret packet header encoded in base64
>> +#
>> +# @secret: the launch secret data to be injected encoded in base64
>> +#
>> +# @gpa: the guest physical address where secret will be injected.
>> +#
>> +# Since: 5.1
>> +#
>> +##
>> +{ 'command': 'sev-inject-launch-secret',
>> + 'data': { 'packet-header': 'str', 'secret': 'str', 'gpa': 'uint64'
>> },
>> + 'if': 'defined(TARGET_I386)' }
>> +
>> ##
>> # @dump-skeys:
>> #
>> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
>> index 27ebfa3ad2..42bcfe6dc0 100644
>> --- a/target/i386/monitor.c
>> +++ b/target/i386/monitor.c
>> @@ -736,3 +736,12 @@ SevCapability *qmp_query_sev_capabilities(Error
>> **errp)
>>
>> return data;
>> }
>> +
>> +void qmp_sev_inject_launch_secret(const char *packet_hdr,
>> + const char *secret, uint64_t gpa,
>> + Error **errp)
>> +{
>> + if (sev_inject_launch_secret(packet_hdr, secret, gpa) != 0) {
>> + error_setg(errp, "SEV inject secret failed");
>> + }
>> +}
>> diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
>> index e5ee13309c..fed4588185 100644
>> --- a/target/i386/sev-stub.c
>> +++ b/target/i386/sev-stub.c
>> @@ -48,3 +48,8 @@ SevCapability *sev_get_capabilities(void)
>> {
>> return NULL;
>> }
>> +int sev_inject_launch_secret(const char *hdr, const char *secret,
>> + uint64_t gpa)
>> +{
>> + return 1;
>> +}
>> diff --git a/target/i386/sev.c b/target/i386/sev.c
>> index d273174ad3..b35f1ddc0c 100644
>> --- a/target/i386/sev.c
>> +++ b/target/i386/sev.c
>> @@ -28,6 +28,8 @@
>> #include "sysemu/runstate.h"
>> #include "trace.h"
>> #include "migration/blocker.h"
>> +#include "exec/address-spaces.h"
>> +#include "monitor/monitor.h"
>>
>> #define TYPE_SEV_GUEST "sev-guest"
>> #define SEV_GUEST(obj) \
>> @@ -769,6 +771,70 @@ sev_encrypt_data(void *handle, uint8_t *ptr,
>> uint64_t len)
>> return 0;
>> }
>>
>> +int sev_inject_launch_secret(const char *packet_hdr,
>> + const char *secret, uint64_t gpa)
>> +{
>> + struct kvm_sev_launch_secret input;
>> + guchar *data = NULL, *hdr = NULL;
>> + int error, ret = 1;
>> + void *hva;
>> + gsize hdr_sz = 0, data_sz = 0;
>> + Error *local_err = NULL;
>> + MemoryRegion *mr = NULL;
>> +
>> + /* secret can be inject only in this state */
>> + if (!sev_check_state(SEV_STATE_LAUNCH_SECRET)) {
>
> This gives a build error for me; sev_check_state is declared as :
>
> static bool
> sev_check_state(const SevGuestState *sev, SevState state)
>
> so it's expecting the state.
>
Ah, my bad. I think I missed the change from sev_state to sev_guest.
I will send a v2 through with all the other fixes in the near future,
unless there is anything else.
Thanks,
Tobin
>> + error_report("SEV: Not in correct state. (LSECRET) %x",
>> + sev_state->state);
>
> also it's showing as sev_state undeclared.
>
>> + return 1;
>> + }
>> +
>> + hdr = g_base64_decode(packet_hdr, &hdr_sz);
>> + if (!hdr || hdr_sz != 52) {
>
> Here and ...
>
>> + error_report("SEV: Failed to decode sequence header");
>> + return 1;
>> + }
>> +
>> + data = g_base64_decode(secret, &data_sz);
>> + if (!data || data_sz <= 0 || data_sz > 0x3E80) {
>
> here - please don't embed magic constants; they should be a #define
> or const somewhere so we can tell what they are.
>
>> + error_report("SEV: Failed to decode data");
>> + goto err;
>> + }
>> +
>> + hva = gpa2hva(&mr, gpa, data_sz, &local_err);
>> + if (!hva) {
>> + error_report("SEV: Failed to calculate guest address.");
>> + goto err;
>> + }
>> +
>> + input.hdr_uaddr = (unsigned long)hdr;
>> + input.hdr_len = hdr_sz;
>> +
>> + input.trans_uaddr = (unsigned long)data;
>> + input.trans_len = data_sz;
>> +
>> + input.guest_uaddr = (unsigned long)hva;
>> + input.guest_len = data_sz;
>
> I'd probably use casts to uint64_t here for hdr, data, and hva
> since that's what the structure you are assigning to has.
>
>> +
>> + trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
>> + input.trans_uaddr, input.trans_len);
>> +
>> + ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_SECRET,
>> + &input, &error);
>> + if (ret) {
>> + error_report("SEV: failed to inject secret ret=%d fw_error=%d
>> '%s'",
>> + ret, error, fw_error_to_str(error));
>> + goto err;
>> + }
>> +
>> + ret = 0;
>> +
>> +err:
>> + g_free(data);
>> + g_free(hdr);
>> + return ret;
>> +}
>> +
>> static void
>> sev_register_types(void)
>> {
>> diff --git a/target/i386/trace-events b/target/i386/trace-events
>> index 789c700d4a..9f299e94a2 100644
>> --- a/target/i386/trace-events
>> +++ b/target/i386/trace-events
>> @@ -15,3 +15,4 @@ kvm_sev_launch_start(int policy, void *session, void
>> *pdh) "policy 0x%x session
>> kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len
>> 0x%" PRIu64
>> kvm_sev_launch_measurement(const char *value) "data %s"
>> kvm_sev_launch_finish(void) ""
>> +kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret,
>> int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len
>> %d"
>> --
>> 2.20.1 (Apple Git-117)
>>
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
prev parent reply other threads:[~2020-07-02 17:24 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-30 13:41 SEV: QMP support for Inject-Launch-Secret Tobin Feldman-Fitzthum
2020-06-30 13:41 ` [PATCH 1/1] " Tobin Feldman-Fitzthum
2020-07-02 15:53 ` Dr. David Alan Gilbert
2020-07-02 16:56 ` tobin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7880f4b376d4f6afe29288673575f20a@linux.vnet.ibm.com \
--to=tobin@linux.vnet.ibm.com \
--cc=brijesh.singh@amd.com \
--cc=dgilbert@redhat.com \
--cc=jejb@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=thomas.lendacky@amd.com \
--cc=tobin@ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.