[Skiboot] [PATCH 1/3] libstb/stb.c: add ibm, secureboot-v2 support

Stewart Smith stewart at linux.vnet.ibm.com
Wed Sep 20 18:25:10 AEST 2017


Claudio Carvalho <cclaudio at linux.vnet.ibm.com> writes:
> This extends libstb to add support to 'ibm,secureboot-v2' and also
> updates the device tree documentation accordingly.
>
> Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
> ---
>  .../ibm,container-verification-code.rst            |  57 ++++++++++++
>  doc/device-tree/ibm,secureboot.rst                 |  83 +++++++++++------
>  libstb/stb.c                                       | 101 +++++++++++++++++++++
>  3 files changed, 211 insertions(+), 30 deletions(-)
>  create mode 100644 doc/device-tree/ibm,container-verification-code.rst
>
> diff --git a/doc/device-tree/ibm,container-verification-code.rst b/doc/device-tree/ibm,container-verification-code.rst
> new file mode 100644
> index 0000000..9d92e7c
> --- /dev/null
> +++ b/doc/device-tree/ibm,container-verification-code.rst
> @@ -0,0 +1,57 @@
> +.. _device-tree/ibm,container-verification-code:
> +
> +ibm,container-verification-code
> +===============================
> +
> +This describes the container-verification-code from ``ibm,secureboot-v2``
> +onwards. Each ``ibm,code-offset`` child node defines an offset of the
> +container-verification-code.
> +
> +Required properties
> +-------------------
> +
> +.. code-block:: none
> +
> +    compatible:     Either one of the following values:
> +
> +                    ibm,cvc-container-v1  :  container-verification-code used
> +                                             to verify containers version 1.
> +
> +   memory-region:   this points to the hostboot reserved memory where the
> +                    container-verification-code is stored.
> +
> +Example
> +-------
> +
> +.. code-block:: dts
> +
> +	ibm,secureboot {

This would be separate from the ibm,secureboot node, just by convention
comes under it.

I question the need of having this information in the device tree
though, is it something an OS would *ever* be interested in?


> +		phandle = <0x5b>;
> +		compatible = "ibm,secureboot-v2";
> +		trusted-enabled;
> +		hw-key-hash-size = <0x40>;
> +		hw-key-hash = <0x40d487ff 0x7380ed6a 0xd54775d5 0x795fea0d
> +                               0xe2f541fe 0xa9db06b8 0x466a42a3 0x20e65f75
> +                               0xb4866546 0x17d907   0x515dc2a5 0xf9fc5095
> +                               0x4d6ee0c9 0xb67d219d 0xfb708535 0x1d01d6d1>;
> +
> +		ibm,container-verification-code {
> +			phandle = <0xd9>;
> +			#address-cells = <0x1>;
> +			#size-cells = <0x0>;
> +			compatible = "ibm,cvc-container-v1";
> +			memory-region = <0x81>;
> +
> +			ibm,code-offset at 40 {
> +				phandle = <0xda>;
> +				compatible = "ibm,sha512-hash";
> +				reg = <0x40>;
> +			};
> +
> +			ibm,code-offset at 50 {
> +				phandle = <0xdb>;
> +				compatible = "ibm,container-verify";
> +				reg = <0x50>;
> +			};
> +		};
> +	};
> diff --git a/doc/device-tree/ibm,secureboot.rst b/doc/device-tree/ibm,secureboot.rst
> index 948c7e0..9681199 100644
> --- a/doc/device-tree/ibm,secureboot.rst
> +++ b/doc/device-tree/ibm,secureboot.rst
> @@ -3,54 +3,77 @@
>  ibm,secureboot
>  ==============
>  
> -Secure boot and trusted boot relies on a code stored in the secure ROM at
> -manufacture time to verify and measure other codes before they are executed.
> -This ROM code is also referred to as ROM verification code.
> -
> -On POWER8, the presence of the ROM code is announced to skiboot (by Hostboot)
> -by the ``ibm,secureboot`` device tree node.
> -
> -If the system is booting up in secure mode, the ROM code is called for secure
> -boot to verify the integrity and authenticity of an image before it is executed.
> -
> -If the system is booting up in trusted mode, the ROM code is called for trusted
> -boot to calculate the SHA512 hash of an image only if the image is not a secure boot
> -container or the system is not booting up in secure mode.
> -
> -For further information about secure boot and trusted boot please refer to
> -:ref:`stb-overview`.
> +The ``ìbm,secureboot`` node provides secure boot and trusted boot information
> +up to the target OS.
>  
> +Further secure and trusted boot information can be found in :ref:`stb-overview`.
>  
>  Required properties
>  -------------------
>  
>  .. code-block:: none
>  
> -    compatible:         ibm,secureboot version. It is related to the ROM code version.
> -                
> -    hash-algo:          hash algorithm used for the hw-key-hash. Aspects such as the size
> -                        of the hw-key-hash can be infered from this property.
> -
> -    secure-enabled:     this property exists if the system is booting in secure mode.
> +    compatible:         Either one of the following values:
> +
> +                        ibm,secureboot-v1  :  The container-verification-code
> +                                              is stored in a secure ROM memory.
> +
> +                        ibm,secureboot-v2  :  The container-verification-code
> +                                              is described by the
> +                                              ibm,container-verification-code
> +                                              child node, which points to the
> +                                              hostboot reserved memory where
> +                                              the container-verification-code
> +                                              is stored.

I don't think we need to have a v2 here, it seems that everything would
still fit in the API to the OS we have with 'ibm,secureboot-v1'.

Our API out to the OS is just 'secure-enabled' and 'trusted-enabled' in
order to indicate what it should do, that is, enforce secure boot and
measure things in the TPM. This continues to be the case, we've just
changed some of the firmware implementation of doing that.

> +
> +    secure-enabled:     this property exists if the firmware stack is booting
> +                        in secure mode (hardware secure boot jumper asserted).
> +                        In this mode, the authenticity and integrity of every
> +                        firmware image is verified before it is executed using
> +                        the container-verification-code. If the verification
> +                        fails, the boot is halted.
> +
> +    trusted-enabled:    this property exists if the firmware stack is booting
> +                        in trusted mode. In this mode, every firmware image is
> +                        measured before it is executed using the
> +                        container-verification-code to calculate the SHA512
> +                        hash of the image. Interested parties can subsequently
> +                        assess the measurements to check whether or not only
> +                        trusted events happened during the boot.
> +
> +    hw-key-hash:        hash of the tree hardware public keys trusted by
> +                        firmware. The three hardware keys used to sign the
> +                        firmware image are stored in the secure boot headers
> +                        prepended to the image. At runtime, the
> +                        container-verification-code compares the hash of these
> +                        three public keys against the hw-key-hash to check if
> +                        the image was signed using the hardware keys trusted by
> +                        firmware.
> +
> +    hw-key-hash-size:   size of hw-key-hash. Added on 'ibm,secureboot-v2'. The
> +                        container-verification-code used to verify containers
> +                        version 1, expect this to be equal to the SHA512 hash
> +                        size.

Why no longer have the hash-algorithm?

do we need hash-size? Or is there a truncation thing going on?

> +Obsolete properties
> +-------------------
>  
> -    trusted-enabled:    this property exists if the system is booting in trusted mode.
> +.. code-block:: none
>  
> -    hw-key-hash:        hash of three concatenated hardware public key. This is required
> -                        by the ROM code to verify images.
> +    hash-algo:          Superseeded by the hw-key-hash-size property in
> +                        'ibm,secureboot-v2'.
>  
>  Example
>  -------
>  
> -For the first version ``ibm,secureboot-v1``, the ROM code expects the *hw-key-hash*
> -to be a SHA512 hash.
> -
>  .. code-block:: dts
>  
>      ibm,secureboot {
> -        compatible = "ibm,secureboot-v1";
> -        hash-algo = "sha512";
> +        compatible = "ibm,secureboot-v2";
>          secure-enabled;
>          trusted-enabled;
> +        hw-key-hash-size = <0x40>
>          hw-key-hash = <0x40d487ff 0x7380ed6a 0xd54775d5 0x795fea0d 0xe2f541fe
>                         0xa9db06b8 0x466a42a3 0x20e65f75 0xb4866546 0x17d907
>                         0x515dc2a5 0xf9fc5095 0x4d6ee0c9 0xb67d219d 0xfb708535
> diff --git a/libstb/stb.c b/libstb/stb.c
> index da0c534..eab04eb 100644
> --- a/libstb/stb.c
> +++ b/libstb/stb.c
> @@ -114,6 +114,105 @@ static void cvc_free(void)
>  	}
>  }
>  
> +static int c1vc_offsets(struct dt_node *parent)

What is c1vc?

> +{
> +	struct dt_node *mem_node, *node;
> +	uint32_t mem_phandle, offset;
> +	uint64_t mem_addr;
> +
> +	c1vc = malloc(sizeof(struct container_verification_code));
> +	assert(c1vc);
> +
> +	mem_phandle = dt_prop_get_u32(parent, "memory-region");
> +	mem_node = dt_find_by_phandle(dt_root, mem_phandle);
> +	assert(mem_node);
> +
> +	mem_addr = dt_get_address(mem_node, 0, NULL);
> +
> +	dt_for_each_child(parent, node) {
> +
> +		if (dt_node_is_compatible(node, "ibm,sha512-hash")) {
> +			offset = dt_prop_get_u32(node, "reg");
> +			offset = be32_to_cpu(offset);
> +			c1vc->sha512_addr = mem_addr + offset;
> +			c1vc->sha512 = c1vc_sha512;
> +		}
> +		else if (dt_node_is_compatible(node, "ibm,container-verify")) {
> +			offset = dt_prop_get_u32(node, "reg");
> +			offset = be32_to_cpu(offset);
> +			c1vc->verify_addr = mem_addr + offset;
> +			c1vc->verify = c1vc_verify;
> +		} else {
> +			prlog(PR_INFO, "unknown cvc offset %s\n", node->name);
> +		}
> +	}
> +
> +	if (!c1vc->sha512 || !c1vc->verify) {
> +		/**
> +		 * @fwts-label CVCV1OffsetsNotFound
> +		 * @fwts-advice This is a bug. The sha512 and verify offsets are
> +		 * required, but they were not found in the
> +		 * ibm,container-verification-code device tree node.
> +		 */
> +		prerror("STB: 'ibm,cvc-container-v1' init FAILED, offsets not found\n");
> +		goto out_error;
> +	}
> +
> +	prlog(PR_INFO, "STB: 'ibm,secureboot-v2' initialized\n");
> +	return 0;
> +
> +out_error:
> +	free(c1vc);
> +	c1vc = NULL;
> +	return -1;
> +}
> +
> +static int cvc_reserved_mem_init(struct dt_node *parent)
> +{
> +	struct dt_node *node;
> +	int rc = -1;
> +
> +	hw_key_hash_size = dt_prop_get_u32(parent, "hw-key-hash-size");
> +	if (hw_key_hash_size != SHA512_DIGEST_LENGTH) {
> +		/**
> +		 * @fwts-label CVCHashSizeInvalid
> +		 * @fwts-advice The hash algorithm used in secure boot container
> +		 * version 1 is sha512, which means that the hash size should be
> +		 * 64 bytes. Hostboot may not have indicated that correctly in
> +		 * the HDAT or skiboot may not have interpreted the HDAT
> +		 * correctly.
> +		 */
> +		prerror("STB: %s FAILED, hw-key-hash-size=%zd not supported\n",
> +			__func__, hw_key_hash_size);
> +		return -1;
> +	}
> +	hw_key_hash = dt_prop_get_def_size(parent, "hw-key-hash", NULL,
> +					   &hw_key_hash_size);
> +	assert(hw_key_hash);
> +
> +	dt_for_each_child(parent, node) {
> +		if (dt_node_is_compatible(node, "ibm,container-v1-verification-code"))
> +			rc = c1vc_offsets(node);
> +		else
> +			prlog(PR_INFO, "STB: %s unknown ibm,secureboot child\n",
> +			      node->name);
> +	}
> +
> +	if (rc) {
> +		/**
> +		 * @fwts-label CompatibleCVCNotFound
> +		 * @fwts-advice Compatible Container-Verification-Code driver
> +		 * not found. If you're running the latest skiboot version, so
> +		 * probably there is a bug in either the HDAT received from
> +		 * hostboot or the HDAT parser in skiboot.
> +		 */
> +		prerror("STB: COULD NOT FIND a compatible "
> +			"container-verification-code driver\n");
> +		return -1;
> +	}
> +	return 0;
> +}
> +
>  static int c1vc_mbedtls_init(struct dt_node *node)
>  {
>  	const char* hash_algo;
> @@ -237,6 +336,8 @@ void stb_init(void)
>  		rc = c1vc_rom_init(node);
>  	} else if (dt_node_is_compatible(node, "ibm,secureboot-v1-softrom")) {
>  		rc = c1vc_mbedtls_init(node);
> +	} else if (dt_node_is_compatible(node, "ibm,secureboot-v2")) {
> +		rc = cvc_reserved_mem_init(node);
>  	} else {
>  		/**
>  		 * @fwts-label SecureBootNotCompatible
> -- 
> 2.7.4
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot 
>

-- 
Stewart Smith
OPAL Architect, IBM.



More information about the Skiboot mailing list