From patchwork Sun Jan 28 21:25:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Ortiz X-Patchwork-Id: 13534659 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CD593C466 for ; Sun, 28 Jan 2024 21:27:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477245; cv=none; b=keaKMVOrqnR1kQSyEe+iXlBvN6/bmTJhllMReSz3GS/8sKadktGn5QueuM3geE/nwfwGSaUWxonVW8oAIyhQpY3521g9vAlk35rHy42bjWPtJqbB/DB8ZbFMhbS5MLnpaOGdRpbK/DDj9D1MIl0DuQUUoxRBsoyIsnSKGempgTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477245; c=relaxed/simple; bh=iAvElGpmB/Rvg9W98fx+iYhTPLkcxixxyEQE/0lymRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q3ggIT3DWfabIyGyzBrANNoi4WTortP0hF5clh6r2tjBYP2eKKWBXZOogtVR9tU2yiVL2nlCahRBfxZEkc7BuCLPMbdm1WNE2rqhAv18M4ddyNZACGw6PfoJCJzGxNnCBmwZhemu5F68GW/OfWcqDCvxBT0YEFZBflVyHbtL5Oo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=KKoVHgND; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="KKoVHgND" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-40ed356a6ecso18501335e9.2 for ; Sun, 28 Jan 2024 13:27:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1706477241; x=1707082041; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FAdowOYiNk9LMfv+UynB8I9wUbUzkvAgTWLx2oynNk0=; b=KKoVHgNDN4keI6iixSCOcp0I5KEPyMlEl4nJPCXOSz9dvIA2sga7GBB4DZeGAiYLb1 xO6q8NyMyVMHoa80GACx2lHKWs1G/17FeOlxwo76dfockahmLq4/rMq6dccnwsqc4dCd aTGRImhHkwbm2g8ZaU2rjQyUsmqofgq3J30ZY8Zim+hSjxcWnq7z1IEQXjhhJYEPRp0h hh9tZLn+ct+NjXwZuY+dJcCTPADgbcNUeOIml6NyGa3deYynRiqzYLjvDklQaRZv0gOq uX7RgWZmGy7hTd1F+ZIc1820Es1c325sUEbQyCifiiKxyJKJVeIOOQxTvUWi9K6uNNGe UoFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706477241; x=1707082041; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FAdowOYiNk9LMfv+UynB8I9wUbUzkvAgTWLx2oynNk0=; b=ucqr8gtvp0ii6+qMBEZXXz9Jn+EZ6aYglg0zJzL3I7p7VsVaDQU83Ae1v73KGnLM9F tUrABtnplMXiYmhvR92ECe9+nVwbd7Y4jaQ5k6MMh9IoYNrL9bdLpAXCrqaNkg9tzR0Z FNDJD4XI0c7SON/AtJGjxuhk/8Utp5F0gxoPCZQGJ5SBBnG1fnWc77ZmV9GDsDmc2hav o0/89yhgsoUUyFRvHpdNNHe+Z4/lJ920m62AX9kFR8DfxyKcG4r7/cMaVm1GCANlSAmU g1iZtVweQK1tFB7ykpokc9m3qu+ZpFtQ8X8bDViYKbBlIpaaaJms/v5ahw32VLOD9n3W t/VA== X-Gm-Message-State: AOJu0YxMRabWyHqWJ5+/QImfWS6+iLQUvV95zDb2YeIClp9VOSnTUskB /B0XPUidGJHIf2Cx+TMZgoSZY01A74SSGFNk4qAgumu2xYZvqPE7XBiDKMTnqePHun3EA+oclwc l X-Google-Smtp-Source: AGHT+IG11VpZM9f0yxDJuq8DM4wLRKDiN+1lAEjzdzfh9r9Cl/M6Y5bSwrD4NhvWpmwjeSFcK4Shhg== X-Received: by 2002:a05:600c:4715:b0:40e:bed4:4d07 with SMTP id v21-20020a05600c471500b0040ebed44d07mr4395060wmo.8.1706477240534; Sun, 28 Jan 2024 13:27:20 -0800 (PST) Received: from vermeer.ba.rivosinc.com (lfbn-mon-1-1176-165.w90-113.abo.wanadoo.fr. [90.113.119.165]) by smtp.gmail.com with ESMTPSA id h17-20020a05600c315100b0040d62f89381sm8218208wmo.35.2024.01.28.13.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 13:27:20 -0800 (PST) From: Samuel Ortiz To: Dan Williams Cc: Samuel Ortiz , Kuppuswamy Sathyanarayanan , Qinkun Bao , "Yao, Jiewen" , "Xing, Cedric" , Dionna Amalie Glaze , biao.lu@intel.com, linux-coco@lists.linux.dev, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 1/4] tsm: Runtime measurement register support Date: Sun, 28 Jan 2024 22:25:20 +0100 Message-ID: <20240128212532.2754325-2-sameo@rivosinc.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240128212532.2754325-1-sameo@rivosinc.com> References: <20240128212532.2754325-1-sameo@rivosinc.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 --- 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 #include #include +#include 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 #include #include #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; From patchwork Sun Jan 28 21:25:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Ortiz X-Patchwork-Id: 13534660 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 812023C49C for ; Sun, 28 Jan 2024 21:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477245; cv=none; b=HQvv75fk6mCIumc7u78CaVaG9tdAvmTkZj9WZpVmrglG0uynEPeqqHPNad67UHpIVtbGQnQ7HV7U6I/UwsJtIiPghIph+d9T0hyUQYWaYIAxtDxHZ3l8dRdNdj5vpw1JCS9HkGkZEszUFImraXk1Wy/C0gJhWDLci38pPoIp0+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477245; c=relaxed/simple; bh=5BDRz7/kXrA/SKMGZUudnZHtf0X1AaM/GMriOO/cC7E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gapXP5+CwlCgHwNPUGCO5Mmdx94DMQISDOctwSiFge8/q9YBeNl0UjqeN2nORPHncoX5WVNe+Y1CDFYlNnkyvdMyp5d873yYrd2pGRFO8Rzt1RaZZrW3Xrr9tKt2targ+3lJI51eyXNHt/DWx0xB8cg9ZpqOjyCQRmt9z7sNKz8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=neVF0c65; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="neVF0c65" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-40e80046246so10847135e9.1 for ; Sun, 28 Jan 2024 13:27:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1706477241; x=1707082041; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=X2SAo9LdnR8uwhVnCuLDyqIe/++QGHcrtzG7xwQ0BCc=; b=neVF0c65R4jKbWs4kZX7/29HFelgX27F3iEMFyhjxSNH4qaxYdnpFP3/IQwnKC4OnL +gOigw9+rCf5Q/TX/QXuc1rQe9KU4CGSv2xOgkmxtD23YcscCDW1sz1HO+N50gHB/H3f AsACgi+PGQPb2G5En5J4lJcGjuNe/roqEN+M/2YGxFX7jvjZ6hG/FaxvrK5LxiKbLNs8 OYJ8kihxeRJN7Mtz/jNxpnmmjNYJoqBkz+JGziW75FUM2tT/KzSAAjjYFri331rRoifq 6n/7aZ7wc1TJwyr44bjD2OTaViavLakGRe7qyR3RFfBY316wj7T8aKLQdZn02599ASUo FYcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706477241; x=1707082041; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X2SAo9LdnR8uwhVnCuLDyqIe/++QGHcrtzG7xwQ0BCc=; b=MgzUgqjrxfXfIbBRu7+VrfBbrW3XH8HN95CJkFkac2iuMvIhQtd2eBl+VDoGv7K5SU 8WpT3hXuUNixvA47W8www364MryU56IkjwV8xCyg1aZOfgfDs7JRaKptytYRu+mVxu26 a/wbdBJLOSy6PgLtlBH0z8+I/vCQi45Ja+N75JZK2aQevHCn8Llz79dvYoMe1HphcmMU UkX9z5HY0Yg5EIrYMyJytMLPBo6PM0JQ5xklyxcA8aQgLh/5TGHxe0gy+29B/FN6DO8m 2LyfJNMnExJQ1opnktdP1m71y2UW/q/SpGNN0s+xlpU9H3vuLO9v7B2l4w7DNtExK8CJ f95A== X-Gm-Message-State: AOJu0YyHNZSFnrtzu8LTK3J6GYe5LfrrBlWv3yiTivdS/heJaFcqO4Oa qANXTAVqpzMCqthGgVmI4M5KQerakFoB5HsnqdpQlTctzJfeID1A8qopvN5rZWg= X-Google-Smtp-Source: AGHT+IH7I/Y0oeuRogEAXZZ4W+1eugSgt+2idcW2aYyaWuUEipfC6kDbb4se7qMFvg/EplAlKYj8Nw== X-Received: by 2002:a05:600c:1d1b:b0:40e:9fd3:6b75 with SMTP id l27-20020a05600c1d1b00b0040e9fd36b75mr2971518wms.2.1706477241698; Sun, 28 Jan 2024 13:27:21 -0800 (PST) Received: from vermeer.ba.rivosinc.com (lfbn-mon-1-1176-165.w90-113.abo.wanadoo.fr. [90.113.119.165]) by smtp.gmail.com with ESMTPSA id h17-20020a05600c315100b0040d62f89381sm8218208wmo.35.2024.01.28.13.27.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 13:27:21 -0800 (PST) From: Samuel Ortiz To: Dan Williams Cc: Samuel Ortiz , Kuppuswamy Sathyanarayanan , Qinkun Bao , "Yao, Jiewen" , "Xing, Cedric" , Dionna Amalie Glaze , biao.lu@intel.com, linux-coco@lists.linux.dev, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 2/4] tsm: Add RTMRs to the configfs-tsm hierarchy Date: Sun, 28 Jan 2024 22:25:21 +0100 Message-ID: <20240128212532.2754325-3-sameo@rivosinc.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240128212532.2754325-1-sameo@rivosinc.com> References: <20240128212532.2754325-1-sameo@rivosinc.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 RTMRs are defined and managed by their corresponding TSM provider. As such, they can be configured through the TSM configfs root. An additional `rtmrs` directory is added by default under the `tsm` one, where each supported RTMR can be configured: mkdir /sys/kernel/config/tsm/rtmrs/rtmr0 echo 0 > /sys/kernel/config/tsm/rtmrs/rtmr0/index An RTMR can not be extended nor read before its configured by assigning it an index. It is the TSM backend responsibility and choice to map that index to a hardware RTMR. Signed-off-by: Samuel Ortiz --- Documentation/ABI/testing/configfs-tsm | 11 ++ drivers/virt/coco/tsm.c | 164 +++++++++++++++++++++++++ 2 files changed, 175 insertions(+) diff --git a/Documentation/ABI/testing/configfs-tsm b/Documentation/ABI/testing/configfs-tsm index dd24202b5ba5..590e103a9bcd 100644 --- a/Documentation/ABI/testing/configfs-tsm +++ b/Documentation/ABI/testing/configfs-tsm @@ -80,3 +80,14 @@ Contact: linux-coco@lists.linux.dev Description: (RO) Indicates the minimum permissible value that can be written to @privlevel. + +What: /sys/kernel/config/tsm/rtmrs/$name/index +Date: January, 2024 +KernelVersion: v6.8 +Contact: linux-coco@lists.linux.dev +Description: + (RW) A Runtime Measurement Register (RTMR) hardware index. + Once created under /sys/kernel/config/tsm/rtmrs/, an RTMR entry + can be mapped to a hardware RTMR by writing into its index + attribute. The TSM provider will then map the configfs entry to + its corresponding hardware register. diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c index 1a8c3c096120..bb9ed2d2accc 100644 --- a/drivers/virt/coco/tsm.c +++ b/drivers/virt/coco/tsm.c @@ -419,6 +419,108 @@ static const struct config_item_type tsm_reports_type = { .ct_group_ops = &tsm_report_group_ops, }; +static ssize_t tsm_rtmr_index_store(struct config_item *cfg, + const char *buf, size_t len) +{ + struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg); + const struct tsm_ops *ops; + unsigned int val; + int rc; + + rc = kstrtouint(buf, 0, &val); + if (rc) + return rc; + + guard(rwsem_write)(&tsm_rwsem); + + /* Index can only be configured once */ + if (is_rtmr_configured(rtmr_state)) + return -EBUSY; + + /* Check that index stays within the TSM provided capabilities */ + ops = provider.ops; + if (!ops) + return -ENOTTY; + + if (val > ops->capabilities.num_rtmrs - 1) + return -EINVAL; + + /* Check that this index is available */ + if (tsm_rtmrs->rtmrs[val]) + return -EINVAL; + + rtmr_state->index = val; + rtmr_state->alg = ops->capabilities.rtmrs[val].hash_alg; + + tsm_rtmrs->rtmrs[val] = rtmr_state; + + return len; +} + +static ssize_t tsm_rtmr_index_show(struct config_item *cfg, + char *buf) +{ + struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg); + + guard(rwsem_read)(&tsm_rwsem); + + /* An RTMR is not available if it has not been configured */ + if (!is_rtmr_configured(rtmr_state)) + return -ENXIO; + + return sysfs_emit(buf, "%u\n", rtmr_state->index); +} +CONFIGFS_ATTR(tsm_rtmr_, index); + +static struct configfs_attribute *tsm_rtmr_attrs[] = { + &tsm_rtmr_attr_index, + NULL, +}; + +static void tsm_rtmr_item_release(struct config_item *cfg) +{ + struct tsm_rtmr_state *state = to_tsm_rtmr_state(cfg); + + kfree(state); +} + +static struct configfs_item_operations tsm_rtmr_item_ops = { + .release = tsm_rtmr_item_release, +}; + +const struct config_item_type tsm_rtmr_type = { + .ct_owner = THIS_MODULE, + .ct_attrs = tsm_rtmr_attrs, + .ct_item_ops = &tsm_rtmr_item_ops, +}; + +static struct config_item *tsm_rtmrs_make_item(struct config_group *group, + const char *name) +{ + struct tsm_rtmr_state *state; + + guard(rwsem_read)(&tsm_rwsem); + if (!(provider.ops && (provider.ops->capabilities.num_rtmrs > 0))) + return ERR_PTR(-ENXIO); + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return ERR_PTR(-ENOMEM); + state->index = U32_MAX; + + config_item_init_type_name(&state->cfg, name, &tsm_rtmr_type); + return &state->cfg; +} + +static struct configfs_group_operations tsm_rtmrs_group_ops = { + .make_item = tsm_rtmrs_make_item, +}; + +static const struct config_item_type tsm_rtmrs_type = { + .ct_owner = THIS_MODULE, + .ct_group_ops = &tsm_rtmrs_group_ops, +}; + static const struct config_item_type tsm_root_group_type = { .ct_owner = THIS_MODULE, }; @@ -433,10 +535,48 @@ static struct configfs_subsystem tsm_configfs = { .su_mutex = __MUTEX_INITIALIZER(tsm_configfs.su_mutex), }; +static int tsm_rtmr_register(const struct tsm_ops *ops) +{ + struct config_group *rtmrs_group; + + lockdep_assert_held_write(&tsm_rwsem); + + if (!ops || !ops->capabilities.num_rtmrs) + return 0; + + if (ops->capabilities.num_rtmrs > TSM_MAX_RTMR) + return -EINVAL; + + tsm_rtmrs = kzalloc(sizeof(struct tsm_rtmrs_state), GFP_KERNEL); + if (!tsm_rtmrs) + return -ENOMEM; + + tsm_rtmrs->rtmrs = kcalloc(ops->capabilities.num_rtmrs, + sizeof(struct tsm_rtmr_state *), + GFP_KERNEL); + if (!tsm_rtmrs->rtmrs) { + kfree(tsm_rtmrs); + return -ENOMEM; + } + + rtmrs_group = configfs_register_default_group(&tsm_configfs.su_group, "rtmrs", + &tsm_rtmrs_type); + if (IS_ERR(rtmrs_group)) { + kfree(tsm_rtmrs->rtmrs); + kfree(tsm_rtmrs); + return PTR_ERR(rtmrs_group); + } + + tsm_rtmrs->group = rtmrs_group; + + return 0; +} + int tsm_register(const struct tsm_ops *ops, void *priv, const struct config_item_type *type) { const struct tsm_ops *conflict; + int rc; if (!type) type = &tsm_report_default_type; @@ -450,6 +590,10 @@ int tsm_register(const struct tsm_ops *ops, void *priv, return -EBUSY; } + rc = tsm_rtmr_register(ops); + if (rc < 0) + return rc; + provider.ops = ops; provider.data = priv; provider.type = type; @@ -457,11 +601,31 @@ int tsm_register(const struct tsm_ops *ops, void *priv, } EXPORT_SYMBOL_GPL(tsm_register); +static int tsm_rtmr_unregister(const struct tsm_ops *ops) +{ + lockdep_assert_held_write(&tsm_rwsem); + + if ((ops) && (ops->capabilities.num_rtmrs > 0)) { + configfs_unregister_default_group(tsm_rtmrs->group); + kfree(tsm_rtmrs->rtmrs); + kfree(tsm_rtmrs); + } + + return 0; +} + int tsm_unregister(const struct tsm_ops *ops) { + int rc; + guard(rwsem_write)(&tsm_rwsem); if (ops != provider.ops) return -EBUSY; + + rc = tsm_rtmr_unregister(ops); + if (rc < 0) + return rc; + provider.ops = NULL; provider.data = NULL; provider.type = NULL; From patchwork Sun Jan 28 21:25:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Ortiz X-Patchwork-Id: 13534661 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7E8D3C463 for ; Sun, 28 Jan 2024 21:27:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477246; cv=none; b=tLuRY/6VCvbAF+e3bSRTuJflhU5eKGdmfRkUjKEyeVzqIKhhhhpOFk19TRFh5eNb/8qPBalZEuoBnLXtx15a7XE8qMqIiB2EVqCxueqsyDcgWX1iTSu3//FwFOUzMMRMGGvxLLoUlQnwohFi1c+1jHBg3LXiTCxQkQtUWsduRcA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477246; c=relaxed/simple; bh=uCMir8UpOW/6Sz8HK3q/nTaZiN/nTURZjTlJjYqsDCA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ng9eI1Zc0q4ZrW+k3C1eZ4qY1c+oE7cxzJhB2gG+/BcW+ZXp294vQANWGA4l6KSNcWIVkyz1qo7hOs9FzafPrj9c2p1jOC5ApJTveoPXc31/Xm2bKa74RC8ssozXGBcaqQav9sN2y2mceXUdUeespqwB/uubMJ9fYDhd7qNAFHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=OUnIzzVO; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="OUnIzzVO" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-40e86a9fc4bso31033355e9.2 for ; Sun, 28 Jan 2024 13:27:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1706477243; x=1707082043; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=z4CfMrpXU7mLg0Nr9hLBE9YLoMVHIJD5HpnMqiflm7A=; b=OUnIzzVOI4WcFVpRkm+qcb5JA/iLyEygneEyCn6PaF81yIZWw6kcTc7moA3JijrQV3 hDsRK2nNp2zmb6YigLTT+rmj0f0Wz2WMSok2koMpSdwP7/+ULRI6eEyF6Ha5f427QKu6 pnuYYPpmqm/VgOR87EIOyRJ7+NdtVXQmSgtslrZicrKKHNzw3XlocECogDqaZgquna5i RZJx/6UUC8sIJay/uaDFVJ8ZSIoO4lBaRmy2VZEYxm99+pxyhF7SJFNLbImJu1+p09+5 DnReHNWkYeHCKdzl/MMh+sOiaz4sj72inTKFxmPbQmCNzWTysgSax2qMBstGl3DxD/aW V/dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706477243; x=1707082043; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=z4CfMrpXU7mLg0Nr9hLBE9YLoMVHIJD5HpnMqiflm7A=; b=aDkIGNJaE/tpqX9sFOelrYFhRh83ML8ENwFIkYHNu+RH82pj2vzzm0qHMbWBjUvZkF pHbu6199OAJ1KoZdrvBkbfDZ9tgBeattP3WmLtj2wZ6CPaZ23ik1t3BK+WmtSqvz0CFX 6yeizx+B6JTVtzwnnHWAWXQ1RgLmSSA69g4h7EaOh0aB/z50V6QGakLWeT45kyTdaxUy Kpd/GaCZiqRpw8+DogBVqeuroZ/5TKSAjmc1dzohMDBuV0eRcOwSdXDMFBmo+EDx9Pot XbvBNowsz4hmJnmferFTDG+k2ZADUVQI15LExBsP/X9Z9K1yRd9d26wxXQUJnTP2NtyO FzeA== X-Gm-Message-State: AOJu0YzAy2AMpoes2RCHxSyNc1Qk9u4qL8h7MpPrSLKL3aIkep3vsBEb hOsM1Nvm43Yxrab0Y+nITUf22PLs4FoxdEIkhtTz9WrIHWm0VjUj1vNFx8auX9g= X-Google-Smtp-Source: AGHT+IFlkGrr3ppdEspRfcA7a89/Y0U2wI5XLbr2d3eVOIRo3fHhwMqy9985919yLYtc6tJ7AGn4WA== X-Received: by 2002:a05:600c:310d:b0:40e:ce97:445c with SMTP id g13-20020a05600c310d00b0040ece97445cmr3978490wmo.13.1706477242886; Sun, 28 Jan 2024 13:27:22 -0800 (PST) Received: from vermeer.ba.rivosinc.com (lfbn-mon-1-1176-165.w90-113.abo.wanadoo.fr. [90.113.119.165]) by smtp.gmail.com with ESMTPSA id h17-20020a05600c315100b0040d62f89381sm8218208wmo.35.2024.01.28.13.27.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 13:27:22 -0800 (PST) From: Samuel Ortiz To: Dan Williams Cc: Samuel Ortiz , Kuppuswamy Sathyanarayanan , Qinkun Bao , "Yao, Jiewen" , "Xing, Cedric" , Dionna Amalie Glaze , biao.lu@intel.com, linux-coco@lists.linux.dev, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 3/4] tsm: Map RTMRs to TCG TPM PCRs Date: Sun, 28 Jan 2024 22:25:22 +0100 Message-ID: <20240128212532.2754325-4-sameo@rivosinc.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240128212532.2754325-1-sameo@rivosinc.com> References: <20240128212532.2754325-1-sameo@rivosinc.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Many user space and internal kernel subsystems (e.g. the Linux IMA) expect a Root of Trust for Storage (RTS) that allows for extending and reading measurement registers that are compatible with the TCG TPM PCRs layout, e.g. a TPM. In order to allow those components to alternatively use a platform TSM as their RTS, a TVM could map the available RTMRs to one or more TCG TPM PCRs. Once configured, those PCR to RTMR mappings give the kernel TSM layer all the necessary information to be a RTS for e.g. the Linux IMA or any other components that expects a TCG compliant TPM PCRs layout. TPM PCR mappings are statically configured through the TSM provider capabilities. A TSM backend defines its number of RTMRs, and for each one of them can define a bitmask of TCG TPM PCR it maps to. As they are TSM backend specific, those mappings are to some extend architecture specific. Each architecture is free to decide and choose how it builds it, e.g. by requesting an EFI firmware when it supports the EFI_CC protocol. The tsm-configfs rtmrs/tcg_map describes these static mappings. Signed-off-by: Samuel Ortiz --- Documentation/ABI/testing/configfs-tsm | 14 +++++ drivers/virt/coco/tsm.c | 74 ++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/Documentation/ABI/testing/configfs-tsm b/Documentation/ABI/testing/configfs-tsm index 590e103a9bcd..5d20a872475e 100644 --- a/Documentation/ABI/testing/configfs-tsm +++ b/Documentation/ABI/testing/configfs-tsm @@ -91,3 +91,17 @@ Description: can be mapped to a hardware RTMR by writing into its index attribute. The TSM provider will then map the configfs entry to its corresponding hardware register. + +What: /sys/kernel/config/tsm/rtmrs/$name/tcg_map +Date: January, 2024 +KernelVersion: v6.8 +Contact: linux-coco@lists.linux.dev +Description: + (RO) A representation of the architecturally defined mapping + between this RTMR and one or more TCG TPM PCRs [1]. When using + a TSM as Root of Trust for Storage (RTS), TCG TPM PCRs + associated semantics and indexes can be used when RTMRs are + logically mapped to TPM PCRs. + + [1]: TCG PC Client Specific Platform Firmware Profile Specification + https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/ diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c index bb9ed2d2accc..d03cf5173bc9 100644 --- a/drivers/virt/coco/tsm.c +++ b/drivers/virt/coco/tsm.c @@ -419,6 +419,46 @@ static const struct config_item_type tsm_reports_type = { .ct_group_ops = &tsm_report_group_ops, }; +static int tsm_rtmr_build_tcg_map(const struct tsm_provider *tsm, + const struct tsm_rtmr_state *rtmr_state, + u32 rtmr_idx) +{ + const struct tsm_ops *ops; + unsigned long pcr_mask; + int i; + + lockdep_assert_held_write(&tsm_rwsem); + + ops = tsm->ops; + if (!ops) + return -ENOTTY; + + if (!ops->capabilities.rtmrs) + return -ENXIO; + + pcr_mask = ops->capabilities.rtmrs[rtmr_idx].tcg_pcr_mask; + + /* Check that the PCR mask is valid */ + for (i = 0; i < TPM2_PLATFORM_PCR; i++) { + if (!(pcr_mask & BIT(i))) + continue; + + /* If another RTMR maps to this PCR, the mask is discarded */ + if (tsm_rtmrs->tcg_map[i] && + tsm_rtmrs->tcg_map[i] != rtmr_state) + return -EBUSY; + } + + for (i = 0; i < TPM2_PLATFORM_PCR; i++) { + if (!(pcr_mask & BIT(i))) + continue; + + tsm_rtmrs->tcg_map[i] = rtmr_state; + } + + return 0; +} + static ssize_t tsm_rtmr_index_store(struct config_item *cfg, const char *buf, size_t len) { @@ -449,6 +489,10 @@ static ssize_t tsm_rtmr_index_store(struct config_item *cfg, if (tsm_rtmrs->rtmrs[val]) return -EINVAL; + rc = tsm_rtmr_build_tcg_map(&provider, rtmr_state, val); + if (rc) + return rc; + rtmr_state->index = val; rtmr_state->alg = ops->capabilities.rtmrs[val].hash_alg; @@ -472,8 +516,38 @@ static ssize_t tsm_rtmr_index_show(struct config_item *cfg, } CONFIGFS_ATTR(tsm_rtmr_, index); +static ssize_t tsm_rtmr_tcg_map_show(struct config_item *cfg, + char *buf) +{ + struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg); + unsigned int nr_pcrs = ARRAY_SIZE(tsm_rtmrs->tcg_map), i; + unsigned long *pcr_mask; + ssize_t len; + + /* Build a bitmap mask of all PCRs that this RTMR covers */ + pcr_mask = bitmap_zalloc(nr_pcrs, GFP_KERNEL); + if (!pcr_mask) + return -ENOMEM; + + guard(rwsem_read)(&tsm_rwsem); + for (i = 0; i < nr_pcrs; i++) { + if (tsm_rtmrs->tcg_map[i] != rtmr_state) + continue; + + __set_bit(i, pcr_mask); + } + + len = bitmap_print_list_to_buf(buf, pcr_mask, nr_pcrs, 0, + nr_pcrs * 3 /* 2 ASCII digits and one comma */); + bitmap_free(pcr_mask); + + return len; +} +CONFIGFS_ATTR_RO(tsm_rtmr_, tcg_map); + static struct configfs_attribute *tsm_rtmr_attrs[] = { &tsm_rtmr_attr_index, + &tsm_rtmr_attr_tcg_map, NULL, }; From patchwork Sun Jan 28 21:25:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Ortiz X-Patchwork-Id: 13534662 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD9D53C699 for ; Sun, 28 Jan 2024 21:27:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477248; cv=none; b=nffIVnruzsXWQDPQn1z80SSOwJJCQ9a7V1GCYeZLDUtco1vcPmoqfFHh7R4jG6nKM1BbbrvEzg9/4veiTqfO26YHmOjWMAB6xxEQFx7zOHEtp2mnPGvn+k1oDgBlZpLvM0vJ+cWGruDhJIWm7HkKRFUH8lqZcE9pT3mxh6XUlxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706477248; c=relaxed/simple; bh=Cdn7d+60o9Z2b5W5CTVwPHkjexWVeQnx20Mc20wdUWg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Gs4jd7NymTUPOnosraiCNlYGvltVWB0wvoPT+cC0JywmjtObcw2DraMQQeYdUHQGBLkEf/QYEktGFQJhcuhfvgiKgbjfkWKw4rlw/c0B3FGhPIlCqMCBDqRlb8stoHDJYql5WabNo+eMDOJKzE7XI/VZ5m64clxkVUev6VALOgI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=gqBmhocf; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="gqBmhocf" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-40ed3101ce3so36620145e9.2 for ; Sun, 28 Jan 2024 13:27:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1706477244; x=1707082044; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kOLVYYaf1UvrK+dMoL40KXaLx8e9ggkXqg3vK1jBmL4=; b=gqBmhocfEnOcHm+Ef3vW1SAh4wkufCryDVjYNuPsK82t3+MDKM6Z74wQQ3SZtZghwF GUPw7JFMY4sbFjO+qrCM215G2OVTQFpMoDai/AWOoM9HWmQIcUICNTo4pMVKKudx7E1a JgEWRctZEwY7Vg9QWlDZL2n9U1hKY4r58PQQpSSEUaRjdahNZTxO5vtK5UPRmI9j29ds zSgdgZgLvYdA9//ofkLIYBqI+mVRTlaS9rST/BteBBNC374cIW52eCAnvFog3WsQQtgF COAAVGeAVcO3sXCTBhrrpjWRyTfYQKD7fQelgmjVan+9MnSynw6frC4Cs6v4EV+eZiot hJAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706477244; x=1707082044; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kOLVYYaf1UvrK+dMoL40KXaLx8e9ggkXqg3vK1jBmL4=; b=t6Xdx086Z9HgBZRRJgS8udvkwEceKRfX+iUyQveiNVHV8mo3qpJffHQgljTbE9Ii/M wB3rtw9Yn0xwku/NzxPzEp/Ro3wmbED08+h9iA5OS2Q5uKKTHh8hKKayAmKS4PsJiWwy xktKAmNCEDV9A+GfZ8NDzKiozi5/SOZIZ5WKzoJMFiHKyoI9+VSj1BoObD6u/yo1SPke TFaL6/DhQsWfc/LmynCsmLKeq8NtBMIy/2G7vSlAuacqA3a2ZMVnTYd+KX4Dwil59Mv5 tBo4J3RVZTsRF4TWPh4q3lBo/QFu3Ur5RRJfYBB1VK6iFlhWCFSzHW4fFLsNF/6xPxlP 2TnQ== X-Gm-Message-State: AOJu0YxiMsCqqTFzlHzhzkj+99uFFnmwvK/MaaVNf3Og8HQBtX7XRpfe 0KbHBArdUFM7QeEP23RmCUi5GtGrhQt9df1eBxCQmGyBW3xhaQXn9rBM9K/lP4o= X-Google-Smtp-Source: AGHT+IHcccSLpqVa5Gax8fBJ+QP9ZYQIKEQzJv+EX6FX8D6Wnl0/1Io1Q3WQpGEhU1qry8Sut0xEhg== X-Received: by 2002:a05:600c:458a:b0:40e:dbdf:9fb4 with SMTP id r10-20020a05600c458a00b0040edbdf9fb4mr2991157wmo.23.1706477244090; Sun, 28 Jan 2024 13:27:24 -0800 (PST) Received: from vermeer.ba.rivosinc.com (lfbn-mon-1-1176-165.w90-113.abo.wanadoo.fr. [90.113.119.165]) by smtp.gmail.com with ESMTPSA id h17-20020a05600c315100b0040d62f89381sm8218208wmo.35.2024.01.28.13.27.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 13:27:23 -0800 (PST) From: Samuel Ortiz To: Dan Williams Cc: Samuel Ortiz , Kuppuswamy Sathyanarayanan , Qinkun Bao , "Yao, Jiewen" , "Xing, Cedric" , Dionna Amalie Glaze , biao.lu@intel.com, linux-coco@lists.linux.dev, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 4/4] tsm: Allow for extending and reading configured RTMRs Date: Sun, 28 Jan 2024 22:25:23 +0100 Message-ID: <20240128212532.2754325-5-sameo@rivosinc.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240128212532.2754325-1-sameo@rivosinc.com> References: <20240128212532.2754325-1-sameo@rivosinc.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The whole purpose of TSM supported RTMRs is for userspace to extend them with runtime measurements and to read them back. This can be done through a binary configfs attribute for each RTMR: rtmr0=/sys/kernel/config/tsm/rtmrs/rtmr0 mkdir $rtmr0 echo 0 > $rtmr0/index dd if=software_layer_digest > $rtmr0/digest hexdump $rtmr0/digest An RTMR digest can not be extended or read before the RTMR is configured by assigning it an index. Signed-off-by: Samuel Ortiz --- Documentation/ABI/testing/configfs-tsm | 11 +++++ drivers/virt/coco/Kconfig | 1 + drivers/virt/coco/tsm.c | 58 ++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/Documentation/ABI/testing/configfs-tsm b/Documentation/ABI/testing/configfs-tsm index 5d20a872475e..dc5c68a49625 100644 --- a/Documentation/ABI/testing/configfs-tsm +++ b/Documentation/ABI/testing/configfs-tsm @@ -81,6 +81,17 @@ Description: (RO) Indicates the minimum permissible value that can be written to @privlevel. +What: /sys/kernel/config/tsm/rtmrs/$name/digest +Date: January, 2024 +KernelVersion: v6.8 +Contact: linux-coco@lists.linux.dev +Description: + (RW) The value in this attribute is the Runtime Measurement + Register (RTMR) digest. Callers can extend this digest with + additional hashes by writing into it. Binary blobs written to + this attribute must be of the exact length used by the hash + algorithm for this RTMR. + What: /sys/kernel/config/tsm/rtmrs/$name/index Date: January, 2024 KernelVersion: v6.8 diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig index 87d142c1f932..5d924bae1ed8 100644 --- a/drivers/virt/coco/Kconfig +++ b/drivers/virt/coco/Kconfig @@ -5,6 +5,7 @@ config TSM_REPORTS select CONFIGFS_FS + select CRYPTO_HASH_INFO tristate source "drivers/virt/coco/efi_secret/Kconfig" diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c index d03cf5173bc9..b4f8cf6ca149 100644 --- a/drivers/virt/coco/tsm.c +++ b/drivers/virt/coco/tsm.c @@ -551,6 +551,63 @@ static struct configfs_attribute *tsm_rtmr_attrs[] = { NULL, }; +static ssize_t tsm_rtmr_digest_read(struct config_item *cfg, void *buf, + size_t count) +{ + struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg); + int rc, digest_size = hash_digest_size[rtmr_state->alg]; + + /* configfs is asking for the digest size */ + if (!buf) + return digest_size; + + if (!is_rtmr_configured(rtmr_state)) + return -ENXIO; + + if (count > TSM_DIGEST_MAX || count < digest_size) + return -EINVAL; + + /* Read from the cached digest */ + if (rtmr_state->cached_digest) { + memcpy(buf, rtmr_state->digest, count); + return digest_size; + } + + /* Slow path, this RTMR got extended */ + guard(rwsem_write)(&tsm_rwsem); + rc = tsm_rtmr_read(&provider, rtmr_state->index, buf, count); + if (rc < 0) + return rc; + + /* Update the cached digest */ + memcpy(rtmr_state->digest, buf, count); + rtmr_state->cached_digest = true; + + return rc; +} + +static ssize_t tsm_rtmr_digest_write(struct config_item *cfg, + const void *buf, size_t count) +{ + struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg); + + if (!is_rtmr_configured(rtmr_state)) + return -ENXIO; + + if (count > TSM_DIGEST_MAX || count < hash_digest_size[rtmr_state->alg]) + return -EINVAL; + + guard(rwsem_write)(&tsm_rwsem); + rtmr_state->cached_digest = false; + return tsm_rtmr_extend(&provider, rtmr_state->index, buf, count); +} +CONFIGFS_BIN_ATTR(tsm_rtmr_, digest, NULL, TSM_DIGEST_MAX); + +static struct configfs_bin_attribute *tsm_rtmr_bin_attrs[] = { + &tsm_rtmr_attr_digest, + NULL, +}; + static void tsm_rtmr_item_release(struct config_item *cfg) { struct tsm_rtmr_state *state = to_tsm_rtmr_state(cfg); @@ -564,6 +621,7 @@ static struct configfs_item_operations tsm_rtmr_item_ops = { const struct config_item_type tsm_rtmr_type = { .ct_owner = THIS_MODULE, + .ct_bin_attrs = tsm_rtmr_bin_attrs, .ct_attrs = tsm_rtmr_attrs, .ct_item_ops = &tsm_rtmr_item_ops, };