[Skiboot] [PATCH 17/19] libstb: integrate changes made to support POWER9

Oliver oohall at gmail.com
Tue Nov 21 16:44:59 AEDT 2017


On Sun, Nov 12, 2017 at 4:28 AM, Claudio Carvalho
<cclaudio at linux.vnet.ibm.com> wrote:
> The stb.c code was imported into the secureboot.c, trustedboot.c and
> cvc.c. Now it has only duplicated code.
>
> This removes the current stb.c code, except the stb_init() function,
> which is updated to call only secureboot_init() and trustedboot_init().
>
> The libstb calls are also replaced with a correspondent function from
> secureboot.h and trustedboot.h.
>
> Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
> ---
>  core/flash.c |   5 +-
>  core/init.c  |   3 +-
>  libstb/stb.c | 316 ++---------------------------------------------------------
>  libstb/stb.h |  56 +----------
>  4 files changed, 16 insertions(+), 364 deletions(-)
>
> diff --git a/core/flash.c b/core/flash.c
> index 66568e7..4d5108c 100644
> --- a/core/flash.c
> +++ b/core/flash.c
> @@ -26,7 +26,6 @@
>  #include <libflash/blocklevel.h>
>  #include <libflash/ecc.h>
>  #include <libstb/stb.h>
> -#include <libstb/container.h>
>  #include <elf.h>
>
>  struct flash {
> @@ -799,8 +798,8 @@ done_reading:
>          * Verify and measure the retrieved PNOR partition as part of the
>          * secure boot and trusted boot requirements
>          */
> -       sb_verify(id, buf, *len);
> -       tb_measure(id, buf, *len);
> +       secureboot_verify(id, buf, *len);
> +       trustedboot_measure(id, buf, *len);
>
>         /* Find subpartition */
>         if (subid != RESOURCE_SUBID_NONE) {
> diff --git a/core/init.c b/core/init.c
> index 8289dc9..e095338 100644
> --- a/core/init.c
> +++ b/core/init.c
> @@ -47,7 +47,6 @@
>  #include <nvram.h>
>  #include <vas.h>
>  #include <libstb/stb.h>
> -#include <libstb/container.h>
>  #include <phys-map.h>
>  #include <imc.h>
>
> @@ -417,7 +416,7 @@ static bool load_kernel(void)
>                 return false;
>         }
>
> -       stb_final();
> +       trustedboot_exit_boot_services();
>
>         return true;
>  }
> diff --git a/libstb/stb.c b/libstb/stb.c
> index f798bcb..d91e67a 100644
> --- a/libstb/stb.c
> +++ b/libstb/stb.c
> @@ -1,4 +1,4 @@
> -/* Copyright 2013-2016 IBM Corp.
> +/* Copyright 2013-2017 IBM Corp.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -14,315 +14,15 @@
>   * limitations under the License.
>   */
>
> -#include <skiboot.h>
> -#include <device.h>
> -#include <platform.h>
> -#include <string.h>
> -#include <stdio.h>
> -#include <nvram.h>
> -#include "stb.h"
> -#include "status_codes.h"
> -#include "container.h"
> -#include "rom.h"
> -#include "tpm_chip.h"
> -
> -/* For debugging only */
> -//#define STB_DEBUG
> -//#define STB_FORCE_SECURE_MODE
> -//#define STB_FORCE_TRUSTED_MODE
> -
> -static bool secure_mode = false;
> -static bool trusted_mode = false;
> -
> -static struct rom_driver_ops *rom_driver = NULL;
> -
> -#define MAX_RESOURCE_NAME      15
> -
> -/*
> - * This maps a PCR for each resource we can measure. The PCR number is
> - * mapped according to the TCG PC Client Platform Firmware Profile
> - * specification, Revision 00.21
> - * Only resources included in this whitelist can be measured.
> - */
> -static struct {
> -
> -       /* PNOR partition id */
> -       enum resource_id id;
> -
> -       /* PCR mapping for the resource id */
> -       TPM_Pcr pcr;
> -
> -       /* Resource name */
> -       const char name[MAX_RESOURCE_NAME+1];
> -
> -} resource_map[] = {
> -       { RESOURCE_ID_KERNEL, PCR_4, "BOOTKERNEL" },
> -       { RESOURCE_ID_CAPP,   PCR_2, "CAPP"},
> -};
> -
> -struct event_hash {
> -       const unsigned char *sha1;
> -       const unsigned char *sha256;
> -};
> -
> -/*
> - * Event Separator - digest of 0xFFFFFFFF
> - */
> -static struct event_hash evFF = {
> -       .sha1   = "\xd9\xbe\x65\x24\xa5\xf5\x04\x7d\xb5\x86"
> -                 "\x68\x13\xac\xf3\x27\x78\x92\xa7\xa3\x0a",
> -
> -       .sha256 = "\xad\x95\x13\x1b\xc0\xb7\x99\xc0\xb1\xaf"
> -                 "\x47\x7f\xb1\x4f\xcf\x26\xa6\xa9\xf7\x60"
> -                 "\x79\xe4\x8b\xf0\x90\xac\xb7\xe8\x36\x7b"
> -                 "\xfd\x0e"
> -};
> -
> -static int stb_resource_lookup(enum resource_id id)
> -{
> -       int i;
> -       for (i = 0; i < ARRAY_SIZE(resource_map); i++)
> -               if (resource_map[i].id == id)
> -                       return i;
> -       return -1;
> -}
> -
> -static void sb_enforce(void)
> -{
> -       /*
> -        * TODO: Ideally, the BMC should decide what security policy to apply
> -        * (power off, reboot, switch PNOR sides, etc). We may need
> -        * to provide extra info to BMC other than just abort.
> -        * Terminate Immediate Attention ? (TI)
> -        */
> -       prlog(PR_EMERG, "STB: Secure mode enforced, aborting.\n");
> -       abort();
> -}
> -
> -void stb_init(void)
> -{
> -       struct dt_node *ibm_secureboot;
> -       /*
> -        * The ibm,secureboot device tree properties are documented in
> -        * 'doc/device-tree/ibm,secureboot.rst'
> -        */
> -       ibm_secureboot = dt_find_by_path(dt_root, "/ibm,secureboot");
> -       if (ibm_secureboot == NULL) {
> -               prlog(PR_NOTICE,"STB: secure and trusted boot not supported\n");
> -               return;
> -       }
> -
> -#ifdef STB_FORCE_SECURE_MODE
> -       secure_mode = true;
> -       prlog(PR_NOTICE, "STB: secure mode on (forced!)\n");
> -#else
> -       secure_mode = dt_has_node_property(ibm_secureboot, "secure-enabled",
> -                                          NULL);
> -
> -       if (nvram_query_eq("force-secure-mode", "always")) {
> -               prlog(PR_NOTICE, "STB: secure mode on (FORCED by nvram)\n");
> -               secure_mode = true;
> -       } else if (secure_mode) {
> -               prlog(PR_NOTICE, "STB: secure mode on.\n");
> -       } else {
> -               prlog(PR_NOTICE, "STB: secure mode off\n");
> -       }
> -#endif
> -
> -#ifdef STB_FORCE_TRUSTED_MODE
> -       trusted_mode = true;
> -       prlog(PR_NOTICE, "STB: trusted mode on (forced!)\n");
> -#else
> -       trusted_mode = dt_has_node_property(ibm_secureboot, "trusted-enabled",
> -                                           NULL);
> -       if (nvram_query_eq("force-trusted-mode", "true")) {
> -               prlog(PR_NOTICE, "STB: trusted mode ON (from NVRAM)\n");
> -               trusted_mode = true;
> -       }
> -       prlog(PR_NOTICE, "STB: trusted mode %s\n",
> -             trusted_mode ? "on" : "off");
> -#endif
> -
> -       if (!secure_mode && !trusted_mode)
> -               return;
> -       rom_driver = rom_init(ibm_secureboot);
> -       if (secure_mode && !rom_driver) {
> -               prlog(PR_EMERG, "STB: compatible romcode driver not found\n");
> -               sb_enforce();
> -       }
> -       if (trusted_mode)
> -               tpm_init();
> -}
> -
> -int stb_final(void)
> -{
> -       uint32_t pcr;
> -       int rc;
> -       bool failed;
> -
> -       rc = 0;
> -       failed = false;
> -
> -       if (trusted_mode) {
> -#ifdef STB_DEBUG
> -               prlog(PR_NOTICE, "STB: evFF.sha1:\n");
> -               stb_print_data((uint8_t*) evFF.sha1, TPM_ALG_SHA1_SIZE);
> -               prlog(PR_NOTICE, "STB: evFF.sha256:\n");
> -               stb_print_data((uint8_t*) evFF.sha256, TPM_ALG_SHA256_SIZE);
> +#ifndef pr_fmt
> +#define pr_fmt(fmt) "STB: " fmt
>  #endif
> -               /*
> -                * We are done. Extending the digest of 0xFFFFFFFF
> -                * in PCR[0-7], and recording an EV_SEPARATOR event in
> -                * event log as defined in the TCG Platform Firmware Profile
> -                * specification, Revision 00.21
> -                */
> -               for (pcr = 0; pcr < 8; pcr++) {
> -                       rc = tpm_extendl(pcr, TPM_ALG_SHA256,
> -                                       (uint8_t*) evFF.sha256,
> -                                       TPM_ALG_SHA256_SIZE, TPM_ALG_SHA1,
> -                                       (uint8_t*) evFF.sha1,
> -                                       TPM_ALG_SHA1_SIZE, EV_SEPARATOR,
> -                                       "Skiboot Boot");
> -                       if (rc)
> -                               failed = true;
> -               }
> -               tpm_add_status_property();
> -       }
> -       if (rom_driver) {
> -               rom_driver->cleanup();
> -               rom_driver = NULL;
> -       }
> -       tpm_cleanup();
> -       secure_mode = false;
> -       trusted_mode = false;
> -       return (failed) ? STB_MEASURE_FAILED : 0;
> -}
>
> -int tb_measure(enum resource_id id, void *buf, size_t len)
> -{
> -       int r;
> -       uint8_t digest[SHA512_DIGEST_LENGTH];
> -       const uint8_t *digestp;
> -
> -       digestp = NULL;
> -       if (!trusted_mode) {
> -               prlog(PR_INFO, "STB: %s skipped resource %d, "
> -                     "trusted_mode=0\n", __func__, id);
> -               return STB_TRUSTED_MODE_DISABLED;
> -       }
> -       r = stb_resource_lookup(id);
> -       if (r == -1) {
> -               /**
> -                * @fwts-label STBMeasureResourceNotMapped
> -                * @fwts-advice The resource is not registered in the resource_map[]
> -                * array, but it should be otherwise the resource cannot be
> -                * measured if trusted mode is on.
> -                */
> -               prlog(PR_ERR, "STB: %s failed, resource %d not mapped\n",
> -                     __func__, id);
> -               return STB_ARG_ERROR;
> -       }
> -       if (!buf) {
> -               /**
> -                * @fwts-label STBNullResourceReceived
> -                * @fwts-advice Null resource passed to tb_measure. This has
> -                * come from the resource load framework and likely indicates a
> -                * bug in the framework.
> -                */
> -               prlog(PR_ERR, "STB: %s failed: resource %s, buf null\n",
> -                     __func__, resource_map[r].name);
> -               return STB_ARG_ERROR;
> -       }
> -       memset(digest, 0, SHA512_DIGEST_LENGTH);
> -       /*
> -        * In secure mode we can use the sw-payload-hash from the container
> -        * header to measure the container payload. Otherwise we must calculate
> -        * the hash of the container payload (if it's a container) or the image
> -        * (if it's not a container)
> -        */
> -       if (stb_is_container(buf, len)) {
> -               digestp = stb_sw_payload_hash(buf, len);
> -               if(!digestp) {
> -                       prlog(PR_EMERG, "STB Container is corrupt, can't find hash\n");
> -                       abort();
> -               }
> -
> -               rom_driver->sha512(
> -                             (void*)((uint8_t*)buf + SECURE_BOOT_HEADERS_SIZE),
> -                             len - SECURE_BOOT_HEADERS_SIZE, digest);
> -
> -               prlog(PR_INFO, "STB: %s sha512 hash re-calculated\n",
> -                     resource_map[r].name);
> -               if (memcmp(digestp, digest, TPM_ALG_SHA256_SIZE) != 0) {
> -                       prlog(PR_ALERT, "STB: HASH IN CONTAINER DOESN'T MATCH CONTENT!\n");
> -                       prlog(PR_ALERT, "STB: Container hash:\n");
> -                       stb_print_data(digestp, TPM_ALG_SHA256_SIZE);
> -                       prlog(PR_ALERT, "STB: Computed hash (on %lx bytes):\n", len);
> -                       stb_print_data(digest, TPM_ALG_SHA256_SIZE);
> -
> -                       if (secure_mode)
> -                               abort();
> -               }
> -       } else {
> -               rom_driver->sha512(buf, len, digest);
> -               prlog(PR_INFO, "STB: %s sha512 hash calculated\n",
> -                     resource_map[r].name);
> -       }
> -
> -#ifdef STB_DEBUG
> -       /* print the payload/image hash */
> -       prlog(PR_NOTICE, "STB: %s hash:\n", resource_map[r].name);
> -       stb_print_data(digest, TPM_ALG_SHA256_SIZE);
> -#endif
> -       /*
> -        * Measure the resource. Since the ROM code doesn't provide a sha1 hash
> -        * algorithm, the sha512 hash is truncated to match the size required
> -        * by each PCR bank.
> -        */
> -       return tpm_extendl(resource_map[r].pcr,
> -                          TPM_ALG_SHA256, digest, TPM_ALG_SHA256_SIZE,
> -                          TPM_ALG_SHA1,   digest, TPM_ALG_SHA1_SIZE,
> -                          EV_ACTION, resource_map[r].name);
> -}
> +#include "tpm_chip.h"
> +#include "stb.h"
>
> -int sb_verify(enum resource_id id, void *buf, size_t len)
> +void stb_init(void)
>  {
> -       int r;
> -       const char *name = NULL;
> -
> -       if (!secure_mode) {
> -               prlog(PR_INFO, "STB: %s skipped resource %d, "
> -                     "secure_mode=0\n", __func__, id);
> -               return STB_SECURE_MODE_DISABLED;
> -       }
> -       r = stb_resource_lookup(id);
> -       if (r == -1)
> -               /**
> -                * @fwts-label STBVerifyResourceNotMapped
> -                * @fwts-advice Unregistered resources can be verified, but not
> -                * measured. The resource should be registered in the
> -                * resource_map[] array, otherwise the resource cannot be
> -                * measured if trusted mode is on.
> -                */
> -               prlog(PR_WARNING, "STB: verifying the non-expected "
> -                     "resource %d\n", id);
> -       else
> -               name = resource_map[r].name;
> -       if (!rom_driver || !rom_driver->verify) {
> -               prlog(PR_EMERG, "STB: secure boot not initialized\n");
> -               sb_enforce();
> -       }
> -       if (!buf || len < SECURE_BOOT_HEADERS_SIZE) {
> -               prlog(PR_EMERG, "STB: %s arg error: id %d, buf %p, len %zd\n",
> -                     __func__, id, buf, len);
> -               sb_enforce();
> -       }
> -       if (rom_driver->verify(buf)) {
> -               prlog(PR_EMERG, "STB: %s failed: resource %s, "
> -                     "eyecatcher 0x%016llx\n", __func__, name,
> -                     *((uint64_t*)buf));
> -               sb_enforce();
> -       }
> -       prlog(PR_NOTICE, "STB: %s verified\n", name);
> -       return 0;
> +       secureboot_init();
> +       trustedboot_init();

Can you put this at the call site(s?) of stb_init() and get rid of
what's left here?

>  }
> diff --git a/libstb/stb.h b/libstb/stb.h
> index 6ca44ea..f5defa4 100644
> --- a/libstb/stb.h
> +++ b/libstb/stb.h
> @@ -1,4 +1,4 @@
> -/* Copyright 2013-2016 IBM Corp.
> +/* Copyright 2013-2017 IBM Corp.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -17,56 +17,10 @@
>  #ifndef __STB_H
>  #define __STB_H
>
> -/**
> - * This reads secure mode and trusted mode from device tree and
> - * loads drivers accordingly.
> - */
> -extern void stb_init(void);
> -
> -/**
> - * As defined in the TCG Platform Firmware Profile specification, the
> - * digest of 0xFFFFFFFF or 0x00000000  must be extended in PCR[0-7] and
> - * an EV_SEPARATOR event must be recorded in the event log for PCR[0-7]
> - * prior to the first invocation of the first Ready to Boot call.
> - *
> - * This function should be called before the control is passed to petitboot
> - * kernel in order to do the proper PCR extend and event log recording as
> - * defined above. This function also deallocates the memory allocated for secure
> - * and trusted boot.
> - */
> -extern int stb_final(void);
> -
> -/**
> - * sb_verify - verify a resource
> - * @id   : resource id
> - * @buf  : data to be verified
> - * @len  : buf length
> - *
> - * This verifies the integrity and authenticity of a resource downloaded from
> - * PNOR if secure mode is on. The verification is done by the
> - * verification code flashed in the secure ROM.
> - *
> - * For more information refer to 'doc/stb.rst'
> - *
> - * returns: 0 otherwise the boot process is aborted
> - */
> -extern int sb_verify(enum resource_id id, void *buf, size_t len);
> +#include <libstb/secureboot.h>
> +#include <libstb/trustedboot.h>
> +#include <libstb/container.h>
>
> -
> -/**
> - * tb_measure - measure a resource
> - * @id    : resource id
> - * @buf   : data to be measured
> - * @len   : buf length
> - *
> - * This measures a resource downloaded from PNOR if trusted mode is on. That is,
> - * an EV_ACTION event is recorded in the event log for the mapped PCR, and the
> - * the sha1 and sha256 measurements are extended in the mapped PCR.
> - *
> - * For more information please refer to 'doc/stb.rst'
> - *
> - * returns: 0 or an error as defined in status_codes.h
> - */
> -extern int tb_measure(enum resource_id id, void *buf, size_t len);
> +void stb_init(void);
>
>  #endif /* __STB_H */
> --
> 2.7.4
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot


More information about the Skiboot mailing list