From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5CAEC636CA for ; Sun, 18 Jul 2021 20:18:25 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3C4CA610CB for ; Sun, 18 Jul 2021 20:18:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3C4CA610CB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5B5A782BB4; Sun, 18 Jul 2021 22:18:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="QDtBZ1tA"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5B83B829F9; Sun, 18 Jul 2021 22:18:15 +0200 (CEST) Received: from mail-ot1-x332.google.com (mail-ot1-x332.google.com [IPv6:2607:f8b0:4864:20::332]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CFD1780615 for ; Sun, 18 Jul 2021 22:18:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x332.google.com with SMTP id t4-20020a05683014c4b02904cd671b911bso7971357otq.1 for ; Sun, 18 Jul 2021 13:18:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1r9Ubgb9EFHdO3XJcTiMKOEAN8Cg8txNs4sWgxKAbtE=; b=QDtBZ1tAo6XX9FZm2a7CITi1+gGObc0H8dqw1+g5LyWOoByJi5uxf0Kg3aBKQDkogI n6zjvMVKLJQUFDaTumG16LIjro2oXBrUc1A+9sojorNRJceaBZR90gZB886Q2j1UHvpT vNDQsxJql28mKCd/6K3kTA4So//qhjG3sZmRk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1r9Ubgb9EFHdO3XJcTiMKOEAN8Cg8txNs4sWgxKAbtE=; b=p55M33g2vDHA25jP7asgc2meLpuDFT3kbUB0PZ+dVCCHVgCJPs+etRxJ7SP7BE3V+k 8UGYBKFYhn628iXOGwuqtW6glYKXjpz/ZYHjSm8qPdFoLktwJYNSnZegNXcdHE5Ot3LG MIyG1IfNSjDUG9zPObz7jkihGXBtx9r65lko/bMT5I76A4WAXwPSfirXdaIT+addfkX8 pfGwF9ujNsE18Lz7niss1GYHZZqpnRxyNb/osLOZmMfG+5sgtyGr6b4EkRHsbIDhR+sX Yidi5pWzCwJ4pS47xVpXUs3A9665rk3B6UWyObQmxtHrqa6G8q0JO228JpWm3vqMiqUa +0ig== X-Gm-Message-State: AOAM530xt2qy42JCbTbZDG9DaaOs56JH3Wdtrnx+v/vd5RosGzIAx8OZ dZKl3fIHvFAD+dmAnw23u63HXlhwakQVeL+G X-Google-Smtp-Source: ABdhPJzkdw62j23hdQWLjOp+bL/jPhFj/XcCfkQhokOY3XSDqEbSHDdV8QlM/URhg7iOWfqpW2Rj+Q== X-Received: by 2002:a05:6830:929:: with SMTP id v41mr4891847ott.16.1626639490285; Sun, 18 Jul 2021 13:18:10 -0700 (PDT) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id g1sm3031606ooi.34.2021.07.18.13.18.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Jul 2021 13:18:09 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Ilias Apalodimas , Thirupathaiah Annapureddy , Simon Glass Subject: [PATCH v2 01/10] sandbox: tpm: Split out common nvdata code Date: Sun, 18 Jul 2021 14:17:57 -0600 Message-Id: <20210718201806.761202-2-sjg@chromium.org> X-Mailer: git-send-email 2.32.0.402.g57bb445576-goog In-Reply-To: <20210718201806.761202-1-sjg@chromium.org> References: <20210718201806.761202-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean We want to support nvdata in TPM2 as well. To avoid code duplicating the associated code, move it into a common file. Drop the special-case logic for the kernel space. This can be handled by the higher-level code now, i.e. in vboot itself. Signed-off-by: Simon Glass --- (no changes since v1) drivers/tpm/Makefile | 4 +- drivers/tpm/sandbox_common.c | 66 ++++++++++++++++++++ drivers/tpm/sandbox_common.h | 96 +++++++++++++++++++++++++++++ drivers/tpm/tpm_tis_sandbox.c | 111 +++------------------------------- 4 files changed, 172 insertions(+), 105 deletions(-) create mode 100644 drivers/tpm/sandbox_common.c create mode 100644 drivers/tpm/sandbox_common.h diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile index f64d20067f8..c65be526700 100644 --- a/drivers/tpm/Makefile +++ b/drivers/tpm/Makefile @@ -6,11 +6,11 @@ obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-uclass.o obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o obj-$(CONFIG_TPM_TIS_INFINEON) += tpm_tis_infineon.o obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o -obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o +obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o sandbox_common.o obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o -obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o +obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o sandbox_common.o obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o diff --git a/drivers/tpm/sandbox_common.c b/drivers/tpm/sandbox_common.c new file mode 100644 index 00000000000..13f5e030a5f --- /dev/null +++ b/drivers/tpm/sandbox_common.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Common features for sandbox TPM1 and TPM2 implementations + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY UCLASS_TPM + +#include +#include +#include +#include +#include "sandbox_common.h" + +#define TPM_ERR_CODE_OFS (2 + 4) /* after tag and size */ + +int sb_tpm_index_to_seq(u32 index) +{ + index &= ~HR_NV_INDEX; + switch (index) { + case FIRMWARE_NV_INDEX: + return NV_SEQ_FIRMWARE; + case KERNEL_NV_INDEX: + return NV_SEQ_KERNEL; + case BACKUP_NV_INDEX: + return NV_SEQ_BACKUP; + case FWMP_NV_INDEX: + return NV_SEQ_FWMP; + case MRC_REC_HASH_NV_INDEX: + return NV_SEQ_REC_HASH; + case 0: + return NV_SEQ_GLOBAL_LOCK; + case TPM_NV_INDEX_LOCK: + return NV_SEQ_ENABLE_LOCKING; + } + + printf("Invalid nv index %#x\n", index); + return -1; +} + +void sb_tpm_read_data(const struct nvdata_state nvdata[NV_SEQ_COUNT], + enum sandbox_nv_space seq, u8 *buf, int data_ofs, + int length) +{ + const struct nvdata_state *nvd = &nvdata[seq]; + + if (!nvd->present) + put_unaligned_be32(TPM_BADINDEX, buf + TPM_ERR_CODE_OFS); + else if (length > nvd->length) + put_unaligned_be32(TPM_BAD_DATASIZE, buf + TPM_ERR_CODE_OFS); + else + memcpy(buf + data_ofs, &nvd->data, length); +} + +void sb_tpm_write_data(struct nvdata_state nvdata[NV_SEQ_COUNT], + enum sandbox_nv_space seq, const u8 *buf, int data_ofs, + int length) +{ + struct nvdata_state *nvd = &nvdata[seq]; + + if (length > nvd->length) + log_err("Invalid length %x (max %x)\n", length, nvd->length); + else + memcpy(&nvdata[seq].data, buf + data_ofs, length); +} diff --git a/drivers/tpm/sandbox_common.h b/drivers/tpm/sandbox_common.h new file mode 100644 index 00000000000..aa5292d7945 --- /dev/null +++ b/drivers/tpm/sandbox_common.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Common features for sandbox TPM1 and TPM2 implementations + * + * Copyright 2021 Google LLC + */ + +#ifndef __TPM_SANDBOX_COMMON_H +#define __TPM_SANDBOX_COMMON_H + +/* + * These numbers derive from adding the sizes of command fields as shown in + * the TPM commands manual. + */ +#define TPM_HDR_LEN 10 + +/* These are the different non-volatile spaces that we emulate */ +enum sandbox_nv_space { + NV_SEQ_ENABLE_LOCKING, + NV_SEQ_GLOBAL_LOCK, + NV_SEQ_FIRMWARE, + NV_SEQ_KERNEL, + NV_SEQ_BACKUP, + NV_SEQ_FWMP, + NV_SEQ_REC_HASH, + + NV_SEQ_COUNT, +}; + +/* TPM NVRAM location indices */ +#define FIRMWARE_NV_INDEX 0x1007 +#define KERNEL_NV_INDEX 0x1008 +#define BACKUP_NV_INDEX 0x1009 +#define FWMP_NV_INDEX 0x100a +#define MRC_REC_HASH_NV_INDEX 0x100b + +/* Size of each non-volatile space */ +#define NV_DATA_SIZE 0x28 + +/** + * struct nvdata_state - state of a single non-volatile-data 'space' + * + * @present: true if present + * @length: length in bytes (max NV_DATA_SIZE) + * @data: contents of non-volatile space + */ +struct nvdata_state { + bool present; + int length; + u8 data[NV_DATA_SIZE]; +}; + +/** + * sb_tpm_index_to_seq() - convert an index into a space sequence number + * + * This converts the index as used by the vboot code into an internal sequence + * number used by the sandbox emulation. + * + * @index: Index to use (FIRMWARE_NV_INDEX, etc.) + * @return associated space (enum sandbox_nv_space) + */ +int sb_tpm_index_to_seq(uint index); + +/** + * sb_tpm_read_data() - Read non-volatile data + * + * This handles a TPM read of nvdata. If the nvdata is not present, a + * TPM_BADINDEX error is put in the buffer. If @length is too large, + * TPM_BAD_DATASIZE is put in the buffer. + * + * @nvdata: Current nvdata state + * @seq: Sequence number to read + * @recvbuf: Buffer to update with the TPM response, assumed to contain zeroes + * @data_ofs: Offset of the 'data' portion of @recvbuf + * @length: Number of bytes to read + */ +void sb_tpm_read_data(const struct nvdata_state nvdata[NV_SEQ_COUNT], + enum sandbox_nv_space seq, u8 *recvbuf, int data_ofs, + int length); + +/** + * sb_tpm_write_data() - Write non-volatile data + * + * If @length is too large, an error is logged and nothing is written. + * + * @nvdata: Current nvdata state + * @seq: Sequence number to read + * @buf: Buffer containing the data to write + * @data_ofs: Offset of the 'data' portion of @buf + * @length: Number of bytes to write + */ +void sb_tpm_write_data(struct nvdata_state nvdata[NV_SEQ_COUNT], + enum sandbox_nv_space seq, const u8 *buf, int data_ofs, + int length); + +#endif diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 67139cea3be..294d98da606 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -9,61 +9,10 @@ #include #include #include - -/* TPM NVRAM location indices. */ -#define FIRMWARE_NV_INDEX 0x1007 -#define KERNEL_NV_INDEX 0x1008 -#define BACKUP_NV_INDEX 0x1009 -#define FWMP_NV_INDEX 0x100a -#define REC_HASH_NV_INDEX 0x100b -#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE +#include "sandbox_common.h" #define NV_DATA_PUBLIC_PERMISSIONS_OFFSET 60 -/* Kernel TPM space - KERNEL_NV_INDEX, locked with physical presence */ -#define ROLLBACK_SPACE_KERNEL_VERSION 2 -#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */ - -struct rollback_space_kernel { - /* Struct version, for backwards compatibility */ - uint8_t struct_version; - /* Unique ID to detect space redefinition */ - uint32_t uid; - /* Kernel versions */ - uint32_t kernel_versions; - /* Reserved for future expansion */ - uint8_t reserved[3]; - /* Checksum (v2 and later only) */ - uint8_t crc8; -} __packed rollback_space_kernel; - -/* - * These numbers derive from adding the sizes of command fields as shown in - * the TPM commands manual. - */ -#define TPM_REQUEST_HEADER_LENGTH 10 -#define TPM_RESPONSE_HEADER_LENGTH 10 - -/* These are the different non-volatile spaces that we emulate */ -enum { - NV_GLOBAL_LOCK, - NV_SEQ_FIRMWARE, - NV_SEQ_KERNEL, - NV_SEQ_BACKUP, - NV_SEQ_FWMP, - NV_SEQ_REC_HASH, - - NV_SEQ_COUNT, -}; - -/* Size of each non-volatile space */ -#define NV_DATA_SIZE 0x20 - -struct nvdata_state { - bool present; - u8 data[NV_DATA_SIZE]; -}; - /* * Information about our TPM emulation. This is preserved in the sandbox * state file if enabled. @@ -140,27 +89,6 @@ static int sandbox_tpm_write_state(void *blob, int node) SANDBOX_STATE_IO(sandbox_tpm, "google,sandbox-tpm", sandbox_tpm_read_state, sandbox_tpm_write_state); -static int index_to_seq(uint32_t index) -{ - switch (index) { - case FIRMWARE_NV_INDEX: - return NV_SEQ_FIRMWARE; - case KERNEL_NV_INDEX: - return NV_SEQ_KERNEL; - case BACKUP_NV_INDEX: - return NV_SEQ_BACKUP; - case FWMP_NV_INDEX: - return NV_SEQ_FWMP; - case REC_HASH_NV_INDEX: - return NV_SEQ_REC_HASH; - case 0: - return NV_GLOBAL_LOCK; - } - - printf("Invalid nv index %#x\n", index); - return -1; -} - static void handle_cap_flag_space(u8 **datap, uint index) { struct tpm_nv_data_public pub; @@ -246,48 +174,25 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, case TPM_CMD_NV_WRITE_VALUE: index = get_unaligned_be32(sendbuf + 10); length = get_unaligned_be32(sendbuf + 18); - seq = index_to_seq(index); + seq = sb_tpm_index_to_seq(index); if (seq < 0) return -EINVAL; printf("tpm: nvwrite index=%#02x, len=%#02x\n", index, length); - memcpy(&tpm->nvdata[seq].data, sendbuf + 22, length); - tpm->nvdata[seq].present = true; - *recv_len = 12; - memset(recvbuf, '\0', *recv_len); + sb_tpm_write_data(tpm->nvdata, seq, sendbuf, 22, length); break; case TPM_CMD_NV_READ_VALUE: /* nvread */ index = get_unaligned_be32(sendbuf + 10); length = get_unaligned_be32(sendbuf + 18); - seq = index_to_seq(index); + seq = sb_tpm_index_to_seq(index); if (seq < 0) return -EINVAL; printf("tpm: nvread index=%#02x, len=%#02x, seq=%#02x\n", index, length, seq); - *recv_len = TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t) + - length; + *recv_len = TPM_HDR_LEN + sizeof(uint32_t) + length; memset(recvbuf, '\0', *recv_len); - put_unaligned_be32(length, recvbuf + - TPM_RESPONSE_HEADER_LENGTH); - if (seq == NV_SEQ_KERNEL) { - struct rollback_space_kernel rsk; - - data = recvbuf + TPM_RESPONSE_HEADER_LENGTH + - sizeof(uint32_t); - memset(&rsk, 0, sizeof(struct rollback_space_kernel)); - rsk.struct_version = 2; - rsk.uid = ROLLBACK_SPACE_KERNEL_UID; - rsk.crc8 = crc8(0, (unsigned char *)&rsk, - offsetof(struct rollback_space_kernel, - crc8)); - memcpy(data, &rsk, sizeof(rsk)); - } else if (!tpm->nvdata[seq].present) { - put_unaligned_be32(TPM_BADINDEX, recvbuf + - sizeof(uint16_t) + sizeof(uint32_t)); - } else { - memcpy(recvbuf + TPM_RESPONSE_HEADER_LENGTH + - sizeof(uint32_t), &tpm->nvdata[seq].data, - length); - } + put_unaligned_be32(length, recvbuf + TPM_HDR_LEN); + sb_tpm_read_data(tpm->nvdata, seq, recvbuf, TPM_HDR_LEN + 4, + length); break; case TPM_CMD_EXTEND: *recv_len = 30; -- 2.32.0.402.g57bb445576-goog