Message ID | 20190521044912.1375-3-bauerman@linux.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Secure Virtual Machine Enablement | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch next (8150a153c013aa2dd1ffae43370b89ac1347a7fb) |
snowpatch_ozlabs/apply_patch | fail | Failed to apply to any branch |
On Tue, May 21, 2019 at 01:49:02AM -0300, Thiago Jung Bauermann wrote: > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > For secure VMs, the signing tool will create a ticket called the "ESM blob" > for the Enter Secure Mode ultravisor call with the signatures of the kernel > and initrd among other things. > > This adds support to the wrapper script for adding that blob via the "-e" > option to the zImage.pseries. > > It also adds code to the zImage wrapper itself to retrieve and if necessary > relocate the blob, and pass its address to Linux via the device-tree, to be > later consumed by prom_init. Where does the "BLOB" come from? How is it licensed and how can we satisfy the GPL with it?
On Tue, May 21, 2019 at 07:13:26AM +0200, Christoph Hellwig wrote: > On Tue, May 21, 2019 at 01:49:02AM -0300, Thiago Jung Bauermann wrote: > > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > > > For secure VMs, the signing tool will create a ticket called the "ESM blob" > > for the Enter Secure Mode ultravisor call with the signatures of the kernel > > and initrd among other things. > > > > This adds support to the wrapper script for adding that blob via the "-e" > > option to the zImage.pseries. > > > > It also adds code to the zImage wrapper itself to retrieve and if necessary > > relocate the blob, and pass its address to Linux via the device-tree, to be > > later consumed by prom_init. > > Where does the "BLOB" come from? How is it licensed and how can we > satisfy the GPL with it? The "BLOB" is not a piece of code. Its just a piece of data that gets generated by our build tools. This data contains the signed hash of the kernel, initrd, and kernel command line parameters. Also it contains any information that the creator the the BLOB wants to be made available to anyone needing it, inside the secure-virtual-machine. All of this is integrity-protected and encrypted to safegaurd it when at rest and at runtime. Bottomline -- Blob is data, and hence no licensing implication. And due to some reason, even data needs to have licensing statement, we can make it available to have no conflicts with GPL.
On Tue, May 21, 2019 at 07:13:26AM +0200, Christoph Hellwig wrote: > On Tue, May 21, 2019 at 01:49:02AM -0300, Thiago Jung Bauermann wrote: > > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > > > For secure VMs, the signing tool will create a ticket called the "ESM blob" > > for the Enter Secure Mode ultravisor call with the signatures of the kernel > > and initrd among other things. > > > > This adds support to the wrapper script for adding that blob via the "-e" > > option to the zImage.pseries. > > > > It also adds code to the zImage wrapper itself to retrieve and if necessary > > relocate the blob, and pass its address to Linux via the device-tree, to be > > later consumed by prom_init. > > Where does the "BLOB" come from? How is it licensed and how can we > satisfy the GPL with it? The blob is data, not code, and it will be created by a tool that will be open source. My understanding is that most of it will be encrypted with a session key that is encrypted with the secret key of the ultravisor. Ram Pai's KVM Forum talk last year explained how this works. Paul.
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 78aaf4ffd7ab..ca612efd3e81 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -150,6 +150,46 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, return (struct addr_range){(void *)initrd_addr, initrd_size}; } +#ifdef __powerpc64__ +static void prep_esm_blob(struct addr_range vmlinux, void *chosen) +{ + unsigned long esm_blob_addr, esm_blob_size; + + /* Do we have an ESM (Enter Secure Mode) blob? */ + if (_esm_blob_end <= _esm_blob_start) + return; + + printf("Attached ESM blob at 0x%p-0x%p\n\r", + _esm_blob_start, _esm_blob_end); + esm_blob_addr = (unsigned long)_esm_blob_start; + esm_blob_size = _esm_blob_end - _esm_blob_start; + + /* + * If the ESM blob is too low it will be clobbered when the + * kernel relocates to its final location. In this case, + * allocate a safer place and move it. + */ + if (esm_blob_addr < vmlinux.size) { + void *old_addr = (void *)esm_blob_addr; + + printf("Allocating 0x%lx bytes for esm_blob ...\n\r", + esm_blob_size); + esm_blob_addr = (unsigned long)malloc(esm_blob_size); + if (!esm_blob_addr) + fatal("Can't allocate memory for ESM blob !\n\r"); + printf("Relocating ESM blob 0x%lx <- 0x%p (0x%lx bytes)\n\r", + esm_blob_addr, old_addr, esm_blob_size); + memmove((void *)esm_blob_addr, old_addr, esm_blob_size); + } + + /* Tell the kernel ESM blob address via device tree. */ + setprop_val(chosen, "linux,esm-blob-start", (u32)(esm_blob_addr)); + setprop_val(chosen, "linux,esm-blob-end", (u32)(esm_blob_addr + esm_blob_size)); +} +#else +static inline void prep_esm_blob(struct addr_range vmlinux, void *chosen) { } +#endif + /* A buffer that may be edited by tools operating on a zImage binary so as to * edit the command line passed to vmlinux (by setting /chosen/bootargs). * The buffer is put in it's own section so that tools may locate it easier. @@ -218,6 +258,7 @@ void start(void) vmlinux = prep_kernel(); initrd = prep_initrd(vmlinux, chosen, loader_info.initrd_addr, loader_info.initrd_size); + prep_esm_blob(vmlinux, chosen); prep_cmdline(chosen); printf("Finalizing device tree..."); diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index cd043726ed88..e0606766480f 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -251,6 +251,8 @@ extern char _initrd_start[]; extern char _initrd_end[]; extern char _dtb_start[]; extern char _dtb_end[]; +extern char _esm_blob_start[]; +extern char _esm_blob_end[]; static inline __attribute__((const)) int __ilog2_u32(u32 n) diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index f9141eaec6ff..36b2ad6cd5b7 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -14,6 +14,7 @@ # -i initrd specify initrd file # -d devtree specify device-tree blob # -s tree.dts specify device-tree source file (needs dtc installed) +# -e esm_blob specify ESM blob for secure images # -c cache $kernel.strip.gz (use if present & newer, else make) # -C prefix specify command prefix for cross-building tools # (strip, objcopy, ld) @@ -38,6 +39,7 @@ platform=of initrd= dtb= dts= +esm_blob= cacheit= binary= compression=.gz @@ -60,9 +62,9 @@ tmpdir=. usage() { echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 - echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2 - echo ' [-D datadir] [-W workingdir] [-Z (gz|xz|none)]' >&2 - echo ' [--no-compression] [vmlinux]' >&2 + echo ' [-d devtree] [-s tree.dts] [-e esm_blob]' >&2 + echo ' [-c] [-C cross-prefix] [-D datadir] [-W workingdir]' >&2 + echo ' [-Z (gz|xz|none)] [--no-compression] [vmlinux]' >&2 exit 1 } @@ -105,6 +107,11 @@ while [ "$#" -gt 0 ]; do [ "$#" -gt 0 ] || usage dtb="$1" ;; + -e) + shift + [ "$#" -gt 0 ] || usage + esm_blob="$1" + ;; -s) shift [ "$#" -gt 0 ] || usage @@ -211,9 +218,16 @@ objflags=-S tmp=$tmpdir/zImage.$$.o ksection=.kernel:vmlinux.strip isection=.kernel:initrd +esection=.kernel:esm_blob link_address='0x400000' make_space=y + +if [ -n "$esm_blob" -a "$platform" != "pseries" ]; then + echo "ESM blob not support on non-pseries platforms" >&2 + exit 1 +fi + case "$platform" in of) platformo="$object/of.o $object/epapr.o" @@ -463,6 +477,10 @@ if [ -n "$dtb" ]; then fi fi +if [ -n "$esm_blob" ]; then + addsec $tmp "$esm_blob" $esection +fi + if [ "$platform" != "miboot" ]; then if [ -n "$link_address" ] ; then text_start="-Ttext $link_address" diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 4ac1e36edfe7..a21f3a76e06f 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -68,6 +68,14 @@ SECTIONS _initrd_end = .; } + . = ALIGN(4096); + .kernel:esm_blob : + { + _esm_blob_start = .; + *(.kernel:esm_blob) + _esm_blob_end = .; + } + #ifdef CONFIG_PPC64_BOOT_WRAPPER . = ALIGN(256); .got :