Re: [Qemu-devel] [PATCH v4] hw/misc: Add simple measurement hardware
On 30/09/2016 12:45, Dr. David Alan Gilbert wrote: >> > >> > This version of the implementation depends on port io, but if there's >> > interest I'll add mmio as well. > Other than a couple of nits I'll mention below (and Stefan's comment) > I don't see why we shouldn't have this; although we'll need a full vTPM > for many uses, this is small and self-contained enough I can't > see why not to have it. I'd also be tempted to prefix the commands in > both qmp and hmp by an x- (i.e. mark experimental) so that you have the > freedom to change them after it goes in initially > > Paolo: Does the acpi stuff make sense? I think I'd prefer to use a QEMU identifier if it's not a problem for Matthew, but that's really all I have to complain about it. Paolo
Re: [Qemu-devel] [PATCH v4] hw/misc: Add simple measurement hardware
* Matthew Garrett (mj...@coreos.com) wrote: > Trusted Boot is based around having a trusted store of measurement data and > a secure communications channel between that store and an attestation > target. In actual hardware, that's a TPM. Since the TPM can only be accessed > via the host system, this in turn requires that the TPM be able to perform > reasonably complicated cryptographic functions in order to demonstrate its > trusted state. > > In cloud environments, qemu is inherently trusted and the hypervisor > infrastructure provides a trusted mechanism for extracting information from > qemu and providing it to another system. This means we can skip the crypto > and stick with the basic functionality - ie, providing a trusted store of > measurement data. > > This driver provides a very small subset of TPM 1.2 functionality in the > form of a bank of registers that can store SHA1 measurements of boot > components. Performing a write to one of these registers will append the new > 20 byte hash to the 20 bytes currently stored within the register, take a > SHA1 of this 40 byte value and then replace the existing register contents > with the new value. This ensures that a given value can only be obtained by > performing the same sequence of writes. It also adds a monitor command to > allow an external agent to extract this information from the running system > and provide it over a secure communications channel. Finally, it measures > each of the loaded ROMs into one of the registers at reset time. > > In combination with work in SeaBIOS and the kernel, this permits a fully > measured boot in a virtualised environment without the overhead of a full > TPM implementation. > > This version of the implementation depends on port io, but if there's > interest I'll add mmio as well. Other than a couple of nits I'll mention below (and Stefan's comment) I don't see why we shouldn't have this; although we'll need a full vTPM for many uses, this is small and self-contained enough I can't see why not to have it. I'd also be tempted to prefix the commands in both qmp and hmp by an x- (i.e. mark experimental) so that you have the freedom to change them after it goes in initially Paolo: Does the acpi stuff make sense? Dave > > Signed-off-by: Matthew Garrett> --- > > Updated based on David's feedback. > > default-configs/x86_64-softmmu.mak | 1 + > hmp-commands-info.hx | 14 ++ > hmp.c | 16 ++ > hmp.h | 1 + > hw/core/loader.c | 12 ++ > hw/i386/acpi-build.c | 29 +++- > hw/misc/Makefile.objs | 1 + > hw/misc/measurements.c | 328 > + > hw/misc/measurements.h | 5 + > hw/tpm/tpm_tis.c | 5 + > include/hw/isa/isa.h | 13 ++ > include/hw/loader.h| 1 + > monitor.c | 1 + > qapi-schema.json | 30 > qmp-commands.hx| 20 +++ > stubs/Makefile.objs| 1 + > stubs/measurements.c | 20 +++ > 17 files changed, 496 insertions(+), 2 deletions(-) > create mode 100644 hw/misc/measurements.c > create mode 100644 hw/misc/measurements.h > create mode 100644 stubs/measurements.c > > diff --git a/default-configs/x86_64-softmmu.mak > b/default-configs/x86_64-softmmu.mak > index 6e3b312..6f0fcc3 100644 > --- a/default-configs/x86_64-softmmu.mak > +++ b/default-configs/x86_64-softmmu.mak > @@ -58,3 +58,4 @@ CONFIG_IOH3420=y > CONFIG_I82801B11=y > CONFIG_SMBIOS=y > CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM) > +CONFIG_MEASUREMENTS=y > diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx > index 74446c6..bf1cf67 100644 > --- a/hmp-commands-info.hx > +++ b/hmp-commands-info.hx > @@ -816,6 +816,20 @@ STEXI > Show information about hotpluggable CPUs > ETEXI > > +{ > +.name = "measurements", > +.args_type = "", > +.params = "", > +.help = "show PCR measurements", > +.mhandler.cmd = hmp_info_measurements, > +}, > + > +STEXI > +@item info measurements > +@findex measurements > +Show PCR measurements > +ETEXI > + > STEXI > @end table > ETEXI > diff --git a/hmp.c b/hmp.c > index cc2056e..462e0c3 100644 > --- a/hmp.c > +++ b/hmp.c > @@ -2038,6 +2038,22 @@ void hmp_info_iothreads(Monitor *mon, const QDict > *qdict) > qapi_free_IOThreadInfoList(info_list); > } > > +void hmp_info_measurements(Monitor *mon, const QDict *qdict) > +{ > +Error *err = NULL; > +MeasurementList *info_list = qmp_query_measurements(); > +MeasurementList *info; > + > +if (err == NULL) { > +for (info = info_list; info; info = info->next) { > +monitor_printf(mon, "%02" PRId64 ":%s\n", info->value->pcr, > + info->value->hash); > +} > +
Re: [Qemu-devel] [PATCH v4] hw/misc: Add simple measurement hardware
Matthew Garrettwrote on 08/17/2016 03:48:52 PM: > From: Matthew Garrett > To: qemu-devel@nongnu.org > Cc: dgilb...@redhat.com, berra...@redhat.com, Stefan Berger/Watson/ > IBM@IBMUS, Matthew Garrett > Date: 08/17/2016 03:49 PM > Subject: [PATCH v4] hw/misc: Add simple measurement hardware > > Trusted Boot is based around having a trusted store of measurement data and > a secure communications channel between that store and an attestation > target. In actual hardware, that's a TPM. Since the TPM can only be accessed > via the host system, this in turn requires that the TPM be able to perform > reasonably complicated cryptographic functions in order to demonstrate its > trusted state. > > In cloud environments, qemu is inherently trusted and the hypervisor > infrastructure provides a trusted mechanism for extracting information from > qemu and providing it to another system. This means we can skip the crypto > and stick with the basic functionality - ie, providing a trusted store of > measurement data. > > This driver provides a very small subset of TPM 1.2 functionality in the > form of a bank of registers that can store SHA1 measurements of boot > components. Performing a write to one of these registers will append the new > 20 byte hash to the 20 bytes currently stored within the register, take a > SHA1 of this 40 byte value and then replace the existing register contents > with the new value. This ensures that a given value can only be obtained by > performing the same sequence of writes. It also adds a monitor command to > allow an external agent to extract this information from the running system > and provide it over a secure communications channel. Finally, it measures > each of the loaded ROMs into one of the registers at reset time. > > In combination with work in SeaBIOS and the kernel, this permits a fully > measured boot in a virtualised environment without the overhead of a full > TPM implementation. > > This version of the implementation depends on port io, but if there's > interest I'll add mmio as well. > > Signed-off-by: Matthew Garrett > --- > > Updated based on David's feedback. > > default-configs/x86_64-softmmu.mak | 1 + > hmp-commands-info.hx | 14 ++ > hmp.c | 16 ++ > hmp.h | 1 + > hw/core/loader.c | 12 ++ > hw/i386/acpi-build.c | 29 +++- > hw/misc/Makefile.objs | 1 + > hw/misc/measurements.c | 328 ++ > +++ > hw/misc/measurements.h | 5 + > hw/tpm/tpm_tis.c | 5 + There shouldn't be a change to tpm_tis.c since this is just one specific front end of possibly different one. I think the mutual exclusion test should go into more common code: tpm.c:tpm_init()
[Qemu-devel] [PATCH v4] hw/misc: Add simple measurement hardware
Trusted Boot is based around having a trusted store of measurement data and a secure communications channel between that store and an attestation target. In actual hardware, that's a TPM. Since the TPM can only be accessed via the host system, this in turn requires that the TPM be able to perform reasonably complicated cryptographic functions in order to demonstrate its trusted state. In cloud environments, qemu is inherently trusted and the hypervisor infrastructure provides a trusted mechanism for extracting information from qemu and providing it to another system. This means we can skip the crypto and stick with the basic functionality - ie, providing a trusted store of measurement data. This driver provides a very small subset of TPM 1.2 functionality in the form of a bank of registers that can store SHA1 measurements of boot components. Performing a write to one of these registers will append the new 20 byte hash to the 20 bytes currently stored within the register, take a SHA1 of this 40 byte value and then replace the existing register contents with the new value. This ensures that a given value can only be obtained by performing the same sequence of writes. It also adds a monitor command to allow an external agent to extract this information from the running system and provide it over a secure communications channel. Finally, it measures each of the loaded ROMs into one of the registers at reset time. In combination with work in SeaBIOS and the kernel, this permits a fully measured boot in a virtualised environment without the overhead of a full TPM implementation. This version of the implementation depends on port io, but if there's interest I'll add mmio as well. Signed-off-by: Matthew Garrett--- Updated based on David's feedback. default-configs/x86_64-softmmu.mak | 1 + hmp-commands-info.hx | 14 ++ hmp.c | 16 ++ hmp.h | 1 + hw/core/loader.c | 12 ++ hw/i386/acpi-build.c | 29 +++- hw/misc/Makefile.objs | 1 + hw/misc/measurements.c | 328 + hw/misc/measurements.h | 5 + hw/tpm/tpm_tis.c | 5 + include/hw/isa/isa.h | 13 ++ include/hw/loader.h| 1 + monitor.c | 1 + qapi-schema.json | 30 qmp-commands.hx| 20 +++ stubs/Makefile.objs| 1 + stubs/measurements.c | 20 +++ 17 files changed, 496 insertions(+), 2 deletions(-) create mode 100644 hw/misc/measurements.c create mode 100644 hw/misc/measurements.h create mode 100644 stubs/measurements.c diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 6e3b312..6f0fcc3 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -58,3 +58,4 @@ CONFIG_IOH3420=y CONFIG_I82801B11=y CONFIG_SMBIOS=y CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM) +CONFIG_MEASUREMENTS=y diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 74446c6..bf1cf67 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -816,6 +816,20 @@ STEXI Show information about hotpluggable CPUs ETEXI +{ +.name = "measurements", +.args_type = "", +.params = "", +.help = "show PCR measurements", +.mhandler.cmd = hmp_info_measurements, +}, + +STEXI +@item info measurements +@findex measurements +Show PCR measurements +ETEXI + STEXI @end table ETEXI diff --git a/hmp.c b/hmp.c index cc2056e..462e0c3 100644 --- a/hmp.c +++ b/hmp.c @@ -2038,6 +2038,22 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict) qapi_free_IOThreadInfoList(info_list); } +void hmp_info_measurements(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MeasurementList *info_list = qmp_query_measurements(); +MeasurementList *info; + +if (err == NULL) { +for (info = info_list; info; info = info->next) { +monitor_printf(mon, "%02" PRId64 ":%s\n", info->value->pcr, + info->value->hash); +} +qapi_free_MeasurementList(info_list); +} +hmp_handle_error(mon, ); +} + void hmp_qom_list(Monitor *mon, const QDict *qdict) { const char *path = qdict_get_try_str(qdict, "path"); diff --git a/hmp.h b/hmp.h index 0876ec0..6afb1d9 100644 --- a/hmp.h +++ b/hmp.h @@ -40,6 +40,7 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict); void hmp_info_block_jobs(Monitor *mon, const QDict *qdict); void hmp_info_tpm(Monitor *mon, const QDict *qdict); void hmp_info_iothreads(Monitor *mon, const QDict *qdict); +void hmp_info_measurements(Monitor *mon, const QDict *qdict); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict