lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAAH4kHaToau86TiYFmLqVKETomYSUmb=d4OjXSKi03C6HWYAQw@mail.gmail.com>
Date: Mon, 29 Jan 2024 08:57:49 -0800
From: Dionna Amalie Glaze <dionnaglaze@...gle.com>
To: Samuel Ortiz <sameo@...osinc.com>
Cc: Dan Williams <dan.j.williams@...el.com>, 
	Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>, Qinkun Bao <qinkun@...gle.com>, 
	"Yao, Jiewen" <jiewen.yao@...el.com>, "Xing, Cedric" <cedric.xing@...el.com>, biao.lu@...el.com, 
	linux-coco@...ts.linux.dev, linux-integrity@...r.kernel.org, 
	linux-kernel@...r.kernel.org
Subject: Re: [RFC PATCH v2 1/4] tsm: Runtime measurement register support

The rtmr backend doesn't specify the digest size it expects to user
space, so rtmr_extend could be zero-fill, or provide a truncated
update, or be strict and return an error. Should the expected digest
size for writes not also be a RO attribute?

On Sun, Jan 28, 2024 at 1:27 PM Samuel Ortiz <sameo@...osinc.com> wrote:
>
> Some confidential computing architecture (Intel TDX, ARM-CCA, RISC-V
> CoVE) provide the TVM (confidential computing guest) with a set of
> runtime measurement registers (RTMR). TVMs can extend those registers
> with their measurements at runtime, i.e. after the TVM initial
> measurements are finalized and the TVM actually runs.
>
> RTMRs are separated from the initial measurement registers set, and TSMs
> typically includes RTMR values into a distinct section of their signed
> attestion reports.
>
> We add support for extending and reading a TSM runtime measurement
> registers by extending the TSM ops structure with resp. an rtmr_extend()
> and an rtmr_read() function pointers. TSM providers/backends will
> implement those ops if they are capable of exposing RTMRs to their
> TVMs. This capability is now described by a tsm_capabilites structure,
> passed by the TSM provider to the TSM framework at registration time.
>
> TVMs can configure, extend and read RTMRs from the configfs-tsm interface.
>
> Signed-off-by: Samuel Ortiz <sameo@...osinc.com>
> ---
>  drivers/virt/coco/tsm.c | 80 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/tsm.h     | 39 +++++++++++++++++++-
>  2 files changed, 118 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c
> index d1c2db83a8ca..1a8c3c096120 100644
> --- a/drivers/virt/coco/tsm.c
> +++ b/drivers/virt/coco/tsm.c
> @@ -11,6 +11,7 @@
>  #include <linux/module.h>
>  #include <linux/cleanup.h>
>  #include <linux/configfs.h>
> +#include <linux/tpm.h>
>
>  static struct tsm_provider {
>         const struct tsm_ops *ops;
> @@ -50,6 +51,85 @@ enum tsm_data_select {
>         TSM_CERTS,
>  };
>
> +/**
> + * DOC: Trusted Security Module (TSM) Runtime Measurement Register (RTMR) Interface
> + *
> + * The TSM RTMR interface is a common ABI for allowing TVMs to extend
> + * and read measurement registers at runtime, i.e. after the TVM initial
> + * measurement is finalized. TSMs that support such capability will typically
> + * include all runtime measurement registers values into their signed
> + * attestation report, providing the TVM post-boot measurements to e.g. remote
> + * attestation services.
> + *
> + * A TVM uses the TSM RTMR configfs ABI to create all runtime measurement
> + * registers (RTMR) that it needs. Each created RTMR must be configured first
> + * before being readable and extensible. TVM configures an RTMR by setting its
> + * index and optionally by mapping it to one or more TCG PCR indexes.
> + *
> + * A TSM backend statically declares the number of RTMRs it supports and which
> + * hash algorithm must be used when extending them. This declaration is done
> + * through the tsm_capabilities structure, at TSM registration time (see
> + * tsm_register()).
> + */
> +
> +/**
> + * struct tsm_rtmr_state - tracks the state of a TSM RTMR.
> + * @index: The RTMR hardware index.
> + * @alg: The hash algorithm used for this RTMR.
> + * @digest: The RTMR cached digest value.
> + * @cached_digest: Is the RTMR cached digest valid or not.
> + * @cfg: The configfs item for this RTMR.
> + */
> +struct tsm_rtmr_state {
> +       u32 index;
> +       enum hash_algo alg;
> +       u8 digest[TSM_DIGEST_MAX];
> +       bool cached_digest;
> +       struct config_item cfg;
> +};
> +
> +static bool is_rtmr_configured(struct tsm_rtmr_state *rtmr_state)
> +{
> +       return rtmr_state->index != U32_MAX;
> +}
> +
> +/**
> + * struct tsm_rtmrs_state - tracks the state of all RTMRs for a TSM.
> + * @rtmrs: The array of all created RTMRs.
> + * @tcg_map: A mapping between TCG PCR and RTMRs, indexed by PCR indexes.
> + * Entry `i` on this map points to an RTMR that covers TCG PCR[i] for the TSM
> + * hash algorithm.
> + * @group: The configfs group for a TSM RTMRs.
> + */
> +static struct tsm_rtmrs_state {
> +       struct tsm_rtmr_state **rtmrs;
> +       const struct tsm_rtmr_state *tcg_map[TPM2_PLATFORM_PCR];
> +       struct config_group *group;
> +} *tsm_rtmrs;
> +
> +static int tsm_rtmr_read(struct tsm_provider *tsm, u32 idx,
> +                        u8 *digest, size_t digest_size)
> +{
> +       if (tsm->ops && tsm->ops->rtmr_read)
> +               return tsm->ops->rtmr_read(idx, digest, digest_size);
> +
> +       return -ENXIO;
> +}
> +
> +static int tsm_rtmr_extend(struct tsm_provider *tsm, u32 idx,
> +                          const u8 *digest, size_t digest_size)
> +{
> +       if (tsm->ops && tsm->ops->rtmr_extend)
> +               return tsm->ops->rtmr_extend(idx, digest, digest_size);
> +
> +       return -ENXIO;
> +}
> +
> +static struct tsm_rtmr_state *to_tsm_rtmr_state(struct config_item *cfg)
> +{
> +       return container_of(cfg, struct tsm_rtmr_state, cfg);
> +}
> +
>  static struct tsm_report *to_tsm_report(struct config_item *cfg)
>  {
>         struct tsm_report_state *state =
> diff --git a/include/linux/tsm.h b/include/linux/tsm.h
> index de8324a2223c..a546983c24fc 100644
> --- a/include/linux/tsm.h
> +++ b/include/linux/tsm.h
> @@ -2,11 +2,13 @@
>  #ifndef __TSM_H
>  #define __TSM_H
>
> +#include <crypto/hash_info.h>
>  #include <linux/sizes.h>
>  #include <linux/types.h>
>
>  #define TSM_INBLOB_MAX 64
>  #define TSM_OUTBLOB_MAX SZ_32K
> +#define TSM_DIGEST_MAX SHA512_DIGEST_SIZE
>
>  /*
>   * Privilege level is a nested permission concept to allow confidential
> @@ -42,12 +44,44 @@ struct tsm_report {
>         u8 *auxblob;
>  };
>
> +#define TSM_MAX_RTMR 32
> +
> +/**
> + * struct tsm_rtmr_desc - Describes a TSM Runtime Measurement Register (RTMR).
> + * @hash_alg: The hash algorithm used to extend this runtime measurement
> + *            register.
> + * @tcg_pcr_mask: A bit mask of all TCG PCRs mapped to this RTMR.
> + */
> +struct tsm_rtmr_desc {
> +       enum hash_algo hash_alg;
> +       unsigned long tcg_pcr_mask;
> +};
> +
> +/**
> + * struct tsm_capabilities - Describes a TSM capabilities.
> + * @num_rtmrs: The number of Runtime Measurement Registers (RTMR) available from
> + *             a TSM.
> + * @rtmr_hash_alg: The hash algorithm used to extend a runtime measurement
> + *                 register.
> + */
> +struct tsm_capabilities {
> +       size_t num_rtmrs;
> +       const struct tsm_rtmr_desc *rtmrs;
> +};
> +
>  /**
>   * struct tsm_ops - attributes and operations for tsm instances
>   * @name: tsm id reflected in /sys/kernel/config/tsm/report/$report/provider
>   * @privlevel_floor: convey base privlevel for nested scenarios
> + * @capabilities: Describe the TSM capabilities, e.g. the number of available
> + *                runtime measurement registers (see `struct tsm_capabilities`).
>   * @report_new: Populate @report with the report blob and auxblob
> - * (optional), return 0 on successful population, or -errno otherwise
> + *              (optional), return 0 on successful population, or -errno
> + *              otherwise
> + * @rtmr_extend: Extend an RTMR with the provided digest.
> + *               Return 0 on successful extension, or -errno otherwise.
> + * @rtmr_read: Reads the value of an RTMR.
> + *             Return the number of bytes read or -errno for errors.
>   *
>   * Implementation specific ops, only one is expected to be registered at
>   * a time i.e. only one of "sev-guest", "tdx-guest", etc.
> @@ -55,7 +89,10 @@ struct tsm_report {
>  struct tsm_ops {
>         const char *name;
>         const unsigned int privlevel_floor;
> +       const struct tsm_capabilities capabilities;
>         int (*report_new)(struct tsm_report *report, void *data);
> +       int (*rtmr_extend)(u32 idx, const u8 *digest, size_t digest_size);
> +       ssize_t (*rtmr_read)(u32 idx, u8 *digest, size_t digest_size);
>  };
>
>  extern const struct config_item_type tsm_report_default_type;
> --
> 2.42.0
>


-- 
-Dionna Glaze, PhD (she/her)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ