From patchwork Fri Nov 26 11:52:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruchika Gupta X-Patchwork-Id: 519688 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp2166612imj; Fri, 26 Nov 2021 03:53:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJySRyqSvtmbOA2vWp4YUafjnB1NjJadP0nD67B4hoiF/ti5C7QWn7IbTvrklQGa+h4SGlMQ X-Received: by 2002:a50:becf:: with SMTP id e15mr46740773edk.114.1637927602499; Fri, 26 Nov 2021 03:53:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637927602; cv=none; d=google.com; s=arc-20160816; b=vHP2PgRIgNmhIfIp/TGRW87rsQgcVKLk7NznTEIKaCB4kCQt/YqJgrZCJLlPRRF66i Vc2UWAgIcNir1FdxVKTcTU3nlplcbaVNwbhMhDVhN5K/hqKUiIkqRzcaRkUaw+k20SIj kH9GzFyuIn67Tk6fgRtBvSfyMwBn2vnm8yimW8V8LFWZZZY5MZirmfqWs/P/2V16AARc Y+1AZ5Q4aV6Q2Zt5xqZs/uZUwmoF4QxX58icG9cEmdO8f3DVSzFIdTGmbAQvdEH0todo Pq9gp27KZw5SiQluzilc5/ld0rI7jRSRhhJp0JnbuAAXkBlX8fXH1KJWrdboiNEGRGCg XqoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=oc8eOLT9u0LfNW7ixA6Z9uqPZ7AxcXSjQlhfEMXkUfA=; b=F0aVQ1qy5klgZdstbTrplSwkmgRWuOTzXp+1GP6rqI57sJNzPHcqF/Zpfg5fmxQd0b fbUrSNEEGwfcAmFmLmL5nZkC02wqq6FXOjl2X/aGvuZ+OjEF5/bv68IqISvxiYan6UtQ R3Fanstcc72+KdZa7/1U+TV82ydzlueEEcLQYPUWpi7X2xhUAQ/hbsu/dQuU3Dvt3YQL oVFBBVDx4NJZt5xtiZMlPHlvpddcDchmBkAXbTuhGjWK0sHtkuj7au1HneQJAsAbf+BX Qxahf1E/ehZyCvRRiFkFy0rdrRnFJ1Utazq0/rhiiiCEdjfp8xKX/ajYR+L9ETArIc2G ns7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wGiTGj8d; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id g3si13755959ejt.101.2021.11.26.03.53.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:22 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wGiTGj8d; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E813E83709; Fri, 26 Nov 2021 12:53:17 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="wGiTGj8d"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7E15482054; Fri, 26 Nov 2021 12:53:16 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) (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 04B5A82054 for ; Fri, 26 Nov 2021 12:53:11 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ruchika.gupta@linaro.org Received: by mail-pf1-x434.google.com with SMTP id o4so8685741pfp.13 for ; Fri, 26 Nov 2021 03:53:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=oc8eOLT9u0LfNW7ixA6Z9uqPZ7AxcXSjQlhfEMXkUfA=; b=wGiTGj8dVK9QgX1UvEo9KWqDkIrQ+f8qPQ2KPj2RK17Sk168qMEw30BG4SZ+qDHG0y dJ6qa36lg4+Pmwe42DOrp7Pbdd2zYBTcOEZ0Z9MY9keYhXQyE0PoqFvZi9aHtdOfzEMG dmgBcSYWAzlFoY/jf3/2SlPA98urMN4ZauriO/tkzvPFc8M+RkhI6FE+fQoYHdW22vql feuSwUI1E9R+QFGvXgxLsctYZKinlT7f2FL+1kec5XfkZ/21YJ3OW7WsKCXAOoOAUlYq C6OYgr6N8j/fTHtfLyS3A3+d+XpHU4QhvtA7npx0I+PWKyh66IFgz30cmdccfl+FbYOy WBSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=oc8eOLT9u0LfNW7ixA6Z9uqPZ7AxcXSjQlhfEMXkUfA=; b=IOk1azmNpVH7mw5ZjhMPElqjufHlOIqreVWTahCvBW2Aib6eMahp0RwP/qdVEwO6ND +F34Sn1HLmPbecsSB5dd65jFLY7sCEEyHgaJKN02XAy/IO6qwd2NUmj+5zMEWr6O0uKm geIhDgHPghxdVbkQCNlE7qzNvGCa1ZcHrb41KhqFO3zuRVbWyvcI2QRa00PoTVqhuOMt oaAWl8XQyNSbt7gSlpq8xOkp5IoMLJz7YxauTJmtnvhndpQItrOU2cdpvildWCJ+ZPfM BC3GBeMuFSjKAlxu+qm/Z1GvbqfSdSrNwTOAVA4qjylYB8vVlxwoRwd8hoOFi2380bwh GwBA== X-Gm-Message-State: AOAM531WuJKkZ2py+Xf6yCQCBRtPK48Lu3mcnBX4v/jeaU9UgODNm/Kw X2qcyG+jFSVzvMjwo5bfhqyRMxnBboCdAQ== X-Received: by 2002:a63:3481:: with SMTP id b123mr7064225pga.589.1637927588582; Fri, 26 Nov 2021 03:53:08 -0800 (PST) Received: from localhost.localdomain ([106.215.91.18]) by smtp.gmail.com with ESMTPSA id l11sm7128774pfu.129.2021.11.26.03.53.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:08 -0800 (PST) From: Ruchika Gupta To: u-boot@lists.denx.de, ilias.apalodimas@linaro.org, xypron.glpk@gmx.de, agraf@csgraf.de, masahisa.kojima@linaro.org Cc: Ruchika Gupta Subject: [PATCH v7 1/3] efi_loader: Add check for event log passed from firmware Date: Fri, 26 Nov 2021 17:22:59 +0530 Message-Id: <20211126115301.1103687-1-ruchika.gupta@linaro.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 Platforms may have support to measure their initial firmware components and pass the event log to u-boot. The event log address can be passed in property tpm_event_log_addr and tpm_event_log_size of the tpm node. Platforms may choose their own specific mechanism to do so. A weak function is added to check if even log has been passed to u-boot from earlier firmware components. If available, the eventlog is parsed to check for its correctness and further event logs are appended to the passed log. Signed-off-by: Ruchika Gupta Tested-by: Ilias Apalodimas Reviewed-by: Ilias Apalodimas --- v7: Addressed Heinrich's comments Changed functions not exported out of this file as static. Corrected function decsriptions and added few. Added declaration of weak function in header file Moved offset check to parse functions v6: No change v5: Shift the efi_init_event_log() to a different location in the file. This help fixes compilation issue introduced by calling efi_append_scrtm_version() from it. v4: Add SCRTM version to log only if previous firmware doesn't pass the eventlog v3: Return as soon as you detect error v2: Moved firmware eventlog code parsing to tcg2_get_fw_eventlog() include/efi_loader.h | 2 + lib/efi_loader/efi_tcg2.c | 472 ++++++++++++++++++++++++++++++++------ 2 files changed, 405 insertions(+), 69 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index d52e399841..67c40ca57a 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -988,4 +988,6 @@ efi_status_t efi_esrt_register(void); */ efi_status_t efi_esrt_populate(void); efi_status_t efi_load_capsule_drivers(void); + +efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 8c1f22e337..5ded57fd29 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -324,6 +324,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev) return EFI_NOT_FOUND; } +/** + * platform_get_eventlog() - retrieve the eventlog address and size + * + * This function retrieves the eventlog address and size if the underlying + * firmware has done some measurements and passed them. + * + * This function may be overridden based on platform specific method of + * passing the eventlog address and size. + * + * @dev: udevice + * @addr: eventlog address + * @sz: eventlog size + * Return: status code + */ +__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, + u32 *sz) +{ + const u64 *basep; + const u32 *sizep; + + basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); + if (!basep) + return EFI_NOT_FOUND; + + *addr = be64_to_cpup((__force __be64 *)basep); + + sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); + if (!sizep) + return EFI_NOT_FOUND; + + *sz = be32_to_cpup((__force __be32 *)sizep); + if (*sz == 0) { + log_debug("event log empty\n"); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + /** * tpm2_get_max_command_size() - get the supported max command size * @@ -1181,6 +1220,283 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = { .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, }; +/** + * parse_event_log_header() - Parse and verify the event log header fields + * + * @buffer: Pointer to the start of the eventlog + * @size: Size of the eventlog + * @pos: Return offset of the next event in buffer right + * after the event header i.e specID + * + * Return: status code + */ +static efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) +{ + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + int i = 0; + + if (size < sizeof(*event_header)) + return EFI_COMPROMISED_DATA; + + if (get_unaligned_le32(&event_header->pcr_index) != 0 || + get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) + return EFI_COMPROMISED_DATA; + + for (i = 0; i < sizeof(event_header->digest); i++) { + if (event_header->digest[i]) + return EFI_COMPROMISED_DATA; + } + + *pos += sizeof(*event_header); + + return EFI_SUCCESS; +} + +/** + * parse_specid_event() - Parse and verify the specID Event in the eventlog + * + * @dev: udevice + * @buffer: Pointer to the start of the eventlog + * @log_size: Size of the eventlog + * @pos: [in] Offset of specID event in the eventlog buffer + * [out] Return offset of the next event in the buffer + * after the specID + * @digest_list: list of digests in the event + * + * Return: status code + * @pos Offset in the eventlog where the specID event ends + * @digest_list: list of digests in the event + */ +static efi_status_t parse_specid_event(struct udevice *dev, void *buffer, + u32 log_size, u32 *pos, + struct tpml_digest_values *digest_list) +{ + struct tcg_efi_spec_id_event *spec_event; + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + size_t spec_event_size; + u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; + u32 spec_active = 0; + u16 hash_alg, hash_sz; + u8 vendor_sz; + int err, i; + + if (*pos >= log_size || (*pos + sizeof(*spec_event)) > log_size) + return EFI_COMPROMISED_DATA; + + /* Check specID event data */ + spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos); + /* Check for signature */ + if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { + log_err("specID Event: Signature mismatch\n"); + return EFI_COMPROMISED_DATA; + } + + if (spec_event->spec_version_minor != + TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || + spec_event->spec_version_major != + TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) + return EFI_COMPROMISED_DATA; + + if (spec_event->number_of_algorithms > MAX_HASH_COUNT || + spec_event->number_of_algorithms < 1) { + log_err("specID Event: Number of algorithms incorrect\n"); + return EFI_COMPROMISED_DATA; + } + + alg_count = spec_event->number_of_algorithms; + + err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count); + if (err) + return EFI_DEVICE_ERROR; + + digest_list->count = 0; + /* + * We have to take care that the sequence of algorithms that we record + * in digest_list matches the sequence in eventlog. + */ + for (i = 0; i < alg_count; i++) { + hash_alg = + get_unaligned_le16(&spec_event->digest_sizes[i].algorithm_id); + hash_sz = + get_unaligned_le16(&spec_event->digest_sizes[i].digest_size); + + if (!(supported & alg_to_mask(hash_alg))) { + log_err("specID Event: Unsupported algorithm\n"); + return EFI_COMPROMISED_DATA; + } + digest_list->digests[digest_list->count++].hash_alg = hash_alg; + + spec_active |= alg_to_mask(hash_alg); + } + + /* + * TCG specification expects the event log to have hashes for all + * active PCR's + */ + if (spec_active != active) { + /* + * Previous stage bootloader should know all the active PCR's + * and use them in the Eventlog. + */ + log_err("specID Event: All active hash alg not present\n"); + return EFI_COMPROMISED_DATA; + } + + /* + * the size of the spec event and placement of vendor_info_size + * depends on supported algoriths + */ + spec_event_size = + offsetof(struct tcg_efi_spec_id_event, digest_sizes) + + alg_count * sizeof(spec_event->digest_sizes[0]); + + if (*pos + spec_event_size >= log_size) + return EFI_COMPROMISED_DATA; + + vendor_sz = *(uint8_t *)((uintptr_t)buffer + *pos + spec_event_size); + + spec_event_size += sizeof(vendor_sz) + vendor_sz; + *pos += spec_event_size; + + if (get_unaligned_le32(&event_header->event_size) != spec_event_size) { + log_err("specID event: header event size mismatch\n"); + /* Right way to handle this can be to call SetActive PCR's */ + return EFI_COMPROMISED_DATA; + } + + return EFI_SUCCESS; +} + +/** + * tcg2_parse_event() - Parse the event in the eventlog + * + * @dev: udevice + * @buffer: Pointer to the start of the eventlog + * @log_size: Size of the eventlog + * @offset: [in] Offset of the event in the eventlog buffer + * [out] Return offset of the next event in the buffer + * @digest_list: list of digests in the event + * @pcr Index of the PCR in the event + * + * Return: status code + */ +static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer, + u32 log_size, u32 *offset, + struct tpml_digest_values *digest_list, + u32 *pcr) +{ + struct tcg_pcr_event2 *event = NULL; + u32 event_type, count, size, event_size; + size_t pos; + + event_size = tcg_event_final_size(digest_list); + if (*offset >= log_size || *offset + event_size > log_size) { + log_err("Event exceeds log size\n"); + return EFI_COMPROMISED_DATA; + } + + event = (struct tcg_pcr_event2 *)((uintptr_t)buffer + *offset); + *pcr = get_unaligned_le32(&event->pcr_index); + event_type = get_unaligned_le32(&event->event_type); + + /* get the count */ + count = get_unaligned_le32(&event->digests.count); + if (count != digest_list->count) + return EFI_COMPROMISED_DATA; + + pos = offsetof(struct tcg_pcr_event2, digests); + pos += offsetof(struct tpml_digest_values, digests); + + for (int i = 0; i < digest_list->count; i++) { + u16 alg; + u16 hash_alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + alg = get_unaligned_le16((void *)((uintptr_t)event + pos)); + + if (alg != hash_alg) + return EFI_COMPROMISED_DATA; + + pos += offsetof(struct tpmt_ha, digest); + memcpy(digest, (void *)((uintptr_t)event + pos), alg_to_len(hash_alg)); + pos += alg_to_len(hash_alg); + } + + size = get_unaligned_le32((void *)((uintptr_t)event + pos)); + event_size += size; + pos += sizeof(u32); /* tcg_pcr_event2 event_size*/ + pos += size; + + /* make sure the calculated buffer is what we checked against */ + if (pos != event_size) + return EFI_COMPROMISED_DATA; + + if (pos > log_size) + return EFI_COMPROMISED_DATA; + + *offset += pos; + + return EFI_SUCCESS; +} + +/** + * tcg2_get_fw_eventlog() - Get the eventlog address and size + * + * If the previous firmware has passed some eventlog, this function get it's + * location and check for it's validity. + * + * @dev: udevice + * @log_buffer: eventlog address + * @log_sz: eventlog size + * + * Return: status code + */ +static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, + size_t *log_sz) +{ + struct tpml_digest_values digest_list; + void *buffer; + efi_status_t ret; + u32 pcr, pos; + u64 base; + u32 sz; + + ret = platform_get_eventlog(dev, &base, &sz); + if (ret != EFI_SUCCESS) + return ret; + + if (sz > TPM2_EVENT_LOG_SIZE) + return EFI_VOLUME_FULL; + + buffer = (void *)base; + pos = 0; + /* Parse the eventlog to check for its validity */ + ret = parse_event_log_header(buffer, sz, &pos); + if (ret) + return ret; + + ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list); + if (ret) { + log_err("Error parsing SPEC ID Event\n"); + return ret; + } + + while (pos < sz) { + ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, + &pcr); + if (ret) { + log_err("Error parsing event\n"); + return ret; + } + } + + memcpy(log_buffer, buffer, sz); + *log_sz = sz; + + return ret; +} + /** * create_specid_event() - Create the first event in the eventlog * @@ -1312,69 +1628,6 @@ out: return ret; } -/** - * efi_init_event_log() - initialize an eventlog - */ -static efi_status_t efi_init_event_log(void) -{ - /* - * vendor_info_size is currently set to 0, we need to change the length - * and allocate the flexible array member if this changes - */ - struct tcg_pcr_event *event_header = NULL; - struct udevice *dev; - size_t spec_event_size; - efi_status_t ret; - - ret = platform_get_tpm2_device(&dev); - if (ret != EFI_SUCCESS) - goto out; - - ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, - (void **)&event_log.buffer); - if (ret != EFI_SUCCESS) - goto out; - - /* - * initialize log area as 0xff so the OS can easily figure out the - * last log entry - */ - memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); - event_log.pos = 0; - event_log.last_event_size = 0; - event_log.get_event_called = false; - event_log.ebs_called = false; - event_log.truncated = false; - - /* - * The log header is defined to be in SHA1 event log entry format. - * Setup event header - */ - event_header = (struct tcg_pcr_event *)event_log.buffer; - put_unaligned_le32(0, &event_header->pcr_index); - put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); - memset(&event_header->digest, 0, sizeof(event_header->digest)); - ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)), - &spec_event_size); - if (ret != EFI_SUCCESS) - goto free_pool; - put_unaligned_le32(spec_event_size, &event_header->event_size); - event_log.pos = spec_event_size + sizeof(*event_header); - event_log.last_event_size = event_log.pos; - - ret = create_final_event(); - if (ret != EFI_SUCCESS) - goto free_pool; - -out: - return ret; - -free_pool: - efi_free_pool(event_log.buffer); - event_log.buffer = NULL; - return ret; -} - /** * tcg2_measure_event() - common function to add event log and extend PCR * @@ -1427,6 +1680,93 @@ static efi_status_t efi_append_scrtm_version(struct udevice *dev) return ret; } +/** + * efi_init_event_log() - initialize an eventlog + * + * Return: status code + */ +static efi_status_t efi_init_event_log(void) +{ + /* + * vendor_info_size is currently set to 0, we need to change the length + * and allocate the flexible array member if this changes + */ + struct tcg_pcr_event *event_header = NULL; + struct udevice *dev; + size_t spec_event_size; + efi_status_t ret; + + ret = platform_get_tpm2_device(&dev); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, + (void **)&event_log.buffer); + if (ret != EFI_SUCCESS) + return ret; + + /* + * initialize log area as 0xff so the OS can easily figure out the + * last log entry + */ + memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); + + /* + * The log header is defined to be in SHA1 event log entry format. + * Setup event header + */ + event_header = (struct tcg_pcr_event *)event_log.buffer; + event_log.pos = 0; + event_log.last_event_size = 0; + event_log.get_event_called = false; + event_log.ebs_called = false; + event_log.truncated = false; + + /* + * Check if earlier firmware have passed any eventlog. Different + * platforms can use different ways to do so. + */ + ret = tcg2_get_fw_eventlog(dev, event_log.buffer, &event_log.pos); + /* + * If earlier firmware hasn't passed any eventlog, go ahead and + * create the eventlog header. + */ + if (ret == EFI_NOT_FOUND) { + put_unaligned_le32(0, &event_header->pcr_index); + put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); + memset(&event_header->digest, 0, sizeof(event_header->digest)); + ret = create_specid_event(dev, + (void *)((uintptr_t)event_log.buffer + + sizeof(*event_header)), + &spec_event_size); + if (ret != EFI_SUCCESS) + goto free_pool; + put_unaligned_le32(spec_event_size, &event_header->event_size); + event_log.pos = spec_event_size + sizeof(*event_header); + event_log.last_event_size = event_log.pos; + + /* + * Add SCRTM version to the log if previous firmmware + * doesn't pass an eventlog. + */ + ret = efi_append_scrtm_version(dev); + } + + if (ret != EFI_SUCCESS) + goto free_pool; + + ret = create_final_event(); + if (ret != EFI_SUCCESS) + goto free_pool; + + return ret; + +free_pool: + efi_free_pool(event_log.buffer); + event_log.buffer = NULL; + return ret; +} + /** * tcg2_measure_variable() - add variable event log and extend PCR * @@ -1963,12 +2303,6 @@ efi_status_t efi_tcg2_register(void) if (ret != EFI_SUCCESS) goto fail; - ret = efi_append_scrtm_version(dev); - if (ret != EFI_SUCCESS) { - tcg2_uninit(); - goto fail; - } - ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol, (void *)&efi_tcg2_protocol); if (ret != EFI_SUCCESS) { From patchwork Fri Nov 26 11:53:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruchika Gupta X-Patchwork-Id: 519689 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp2166765imj; Fri, 26 Nov 2021 03:53:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJykgLSM+gruTrC9EtVKaoTKRvY+PyElH8pAfyg2Z/JU9JjfrAHSOViOj0EAFr7fWeXwQ188 X-Received: by 2002:a05:6402:4404:: with SMTP id y4mr47051385eda.321.1637927612527; Fri, 26 Nov 2021 03:53:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637927612; cv=none; d=google.com; s=arc-20160816; b=VwwdjQMZ31i01RSJkPwDgHdE/stN1E45zx7b4J2JVKDdZFvfA9smtBhCU08zGqTw2W Ftf+7HdiCtti25YVCvi16YxjSTUBSF1CARyOcuRq1j9vyTxquvvTddL9o/FMQn1qIJ6B 92Zz6ckhK8/5z+Yen3Rjm3BRHzyAI70HxaClKGjw85zlhlrB/l7c+3HJlgZJKf20Raxr JY1ddQjfV5wSb4Y91MpqVwuMjMfdtcB98I2xHVf6Ktmv6F2RTbwwkx4ubjX6IjYig5IF /rlGNaG7SAVGko8bSj3IZ766tnhHgpBH9fwkYvzLX10PfaL5krv+ilbSOGcouWd9SLT6 zrqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4TcjVKPpVveDA94tH5bQHdtUE9NXstA3TFrOLoItu6Q=; b=z/sDQLROFmWBtTWzLJGXMqhfrsDWtMayiGoYKpj3frF4o17n1xekZFgw32V0mqJqLZ ncVqjgkNZ6NSudPoPjgBGt+fEaoU2ihzO+RIyCpTohwqTBXX1cyi7XELi3Pqe0dlRbEo +T7Rnn+vbhuIerxWFq4Zbm3hb2H7eSyJNcHxHRQSQiSIT3F222Zm45OpSvy5uZr0k9Ln Z9n9t5pcxTvbvMhPIiF1B60QDZXlwGyn7SJ6XiuNdwsKkbwAN6nSqnezNdclaQPTRLtM S6rxgDnAOw6nnM1bQPf4er50+nXoaeFuL+O/QvNjetAsK0YMxAJsM9WyH3BnDnpqwE4f l1VA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sBEow9A9; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id gb1si11129798ejc.606.2021.11.26.03.53.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:32 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sBEow9A9; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2204A83763; Fri, 26 Nov 2021 12:53:31 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="sBEow9A9"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AEC1E83763; Fri, 26 Nov 2021 12:53:21 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) (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 1E1C480F7A for ; Fri, 26 Nov 2021 12:53:15 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ruchika.gupta@linaro.org Received: by mail-pf1-x430.google.com with SMTP id 8so8724047pfo.4 for ; Fri, 26 Nov 2021 03:53:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4TcjVKPpVveDA94tH5bQHdtUE9NXstA3TFrOLoItu6Q=; b=sBEow9A9mTU0wSPkytgvlI+bWxaEYr1D/d3ysPI+DUbzs4+UBWiLSA+8mctk9huLlJ JofbZ6Cbes9EglCqNmt2palSKeem/uVRqVTx4iApK4MQtB/rf/FeBLPTa9c1gHrDgcmE DqwKHi8Ejts0tMLRKNq5LqC9BDTVesFgAmlO0+ueUf7RMUHZKcwmDT6gWuaIRK5HXmbr 6B8oEyN88lD4LWKsWmasCEf71sQgihYmaJwsWNuyq/bos3cZcf31fuvq9g0SzbVQZBLc 9lMvXfNmoAiXKPVP39jChSCB0IAl8dV7ijVZ4bqJFA1I0ouAQeLRTeDrw7Bt+uL40P0i rQyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4TcjVKPpVveDA94tH5bQHdtUE9NXstA3TFrOLoItu6Q=; b=Jx8f7ooedkDOu8O9Hj+PDljL7exZ8kB2p2FKBIubOMTETflMd0T7jSWkieL4mgm6rh vOGmO5QNztzLem+vskuYJyJ13tas77gPxOX6wwzNYLXIC1sh5+ruC3QwKJfNKnG8isvB LudKBXamSeIj8g0/Yu63nc1ED9UPV8PeSsigUEl6GJazZXGdMY9DG+chTNzH8rN78Myt TG8WSq6BVgkknOj/tOBylTkZG5AI2HRLSUEE3hutgnWJISKxE58VPiuOU85D1Y9oX4uT 56oDaveFzW8gKdTajvTk890ft5+PpyvJ8357189stXQZ52E7IMgxqOANj/4Cvs15Jm2t vBmw== X-Gm-Message-State: AOAM533yMNohFD3iqXXlnO3qunWvX+W2vpueGinxgCdyPd6lXJlxbY3s Ug3qWLyhwWLQN9Ixa3fInoMVj4uuRvM49A== X-Received: by 2002:a05:6a00:1688:b0:4a3:1451:9700 with SMTP id k8-20020a056a00168800b004a314519700mr20503336pfc.28.1637927593087; Fri, 26 Nov 2021 03:53:13 -0800 (PST) Received: from localhost.localdomain ([106.215.91.18]) by smtp.gmail.com with ESMTPSA id l11sm7128774pfu.129.2021.11.26.03.53.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:12 -0800 (PST) From: Ruchika Gupta To: u-boot@lists.denx.de, ilias.apalodimas@linaro.org, xypron.glpk@gmx.de, agraf@csgraf.de, masahisa.kojima@linaro.org Cc: Ruchika Gupta Subject: [v7 PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read Date: Fri, 26 Nov 2021 17:23:00 +0530 Message-Id: <20211126115301.1103687-2-ruchika.gupta@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211126115301.1103687-1-ruchika.gupta@linaro.org> References: <20211126115301.1103687-1-ruchika.gupta@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 The current tpm2_pcr_read is hardcoded using SHA256. Make the actual command to TPM configurable to use wider range of algorithms. The current command line is kept as is i.e limited to SHA-256 only. Signed-off-by: Ruchika Gupta Reviewed-by: Ilias Apalodimas --- v7: No change v6: No change v5: No change v4: No change v3: No change v2: Change algorithm from u32 to u16 Add parameter description in function declaration cmd/tpm-v2.c | 3 ++- include/tpm-v2.h | 5 ++++- lib/tpm-v2.c | 12 ++++++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index daae91100a..4ea5f9f094 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); - rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); + rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, + data, TPM2_DIGEST_LEN, &updates); if (!rc) { printf("PCR #%u content (%u known updates):\n", index, updates); print_byte_string(data, TPM2_DIGEST_LEN); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ceff7d245e..4e9dd52cb6 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, * @dev TPM device * @idx Index of the PCR * @idx_min_sz Minimum size in bytes of the pcrSelect array + * @algorithm Algorithm used, defined in 'enum tpm2_algorithms' * @data Output buffer for contents of the named PCR + * @digest_len len of the data * @updates Optional out parameter: number of updates for this PCR * * @return code of the operation */ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates); + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates); /** * Issue a TPM2_GetCapability command. This implementation is limited diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 2e7b27bd6b..1bf627853a 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, } u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates) + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates) { u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, /* TPML_PCR_SELECTION */ tpm_u32(1), /* Number of selections */ - tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + tpm_u16(algorithm), /* Algorithm of the hash */ idx_array_sz, /* Array size for selection */ /* bitmap(idx) Selected PCR bitmap */ }; @@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, if (ret) return ret; + if (digest_len > response_len) + return TPM_LIB_ERROR; + if (unpack_byte_string(response, response_len, "ds", 10, &counter, - response_len - TPM2_DIGEST_LEN, data, - TPM2_DIGEST_LEN)) + response_len - digest_len, data, + digest_len)) return TPM_LIB_ERROR; if (updates) From patchwork Fri Nov 26 11:53:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruchika Gupta X-Patchwork-Id: 519690 Delivered-To: patch@linaro.org Received: by 2002:ac0:c605:0:0:0:0:0 with SMTP id p5csp2166925imj; Fri, 26 Nov 2021 03:53:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJyrSXoczER2rh+j0pU3hYnzKM6GpyvVOERHUGkOcSFEjaDdj29q1pOULuS5RwpLHUh+bWIa X-Received: by 2002:a17:906:4792:: with SMTP id cw18mr39264422ejc.224.1637927622900; Fri, 26 Nov 2021 03:53:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637927622; cv=none; d=google.com; s=arc-20160816; b=Mjm02lcFQsWKdvx8UmZt6hoTaU5iCuAVr1Js2vTKt1DUMRM1VPv8XcZEg8kHvaUJyw ZQGv7lKpiD7f3sDwyOYR4HyK5sf43b1ynAudjzlR29MlOnXfTOZQvZJ0czrmlWVhYiWR ISq0h6xxqxQXs2oDom8Oma0FRKi7U3jGWNmnt9Gxbs8VIwx0DPUV7SnJn67sT+jiauYy eATM5JLJ4gnnvV18rLYovfKcUObWi9KFzw2Qb1KS9stMnw965rCT+5XjH6TSBhUk5oYJ KRljBj8iut2orMnqIfD3eK2tTJ3ihe3oJDDXGlTRto3ZTkvU1fzyQTtPnptilyPBqoWR gpmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vl/wGy7g0lDLqs6daPcstMz7bck9g4KcHz/anTfWs9g=; b=zpnQnVSePpD6vJwKRimeIegL/HTc7TQDz60lc9lP7d+6LsOvDnbgdk9u0mxAKTZ4SA FKKnoIK6L4o+QPYLYTlKOqjnXzAGjY9ehK6nmbjVXPH7OEG5En+mtp36yq+bjNYiKD3a U1przhSA8NYbW64QRbqZG95NqMJ/UwpIpWF5AjIpsVOncDoJP7EYug9MeMz2W3Uap6yz 3qfCdnWKep9+ytNM1ZaccFlUJdI7vxLQALHJUzDVQB6pAMhoYAalyJz9whI+HVnKDvD8 d7wqbuaDbcbqh0zTuaTFC6tLOjyyyKRb1Xw9AunihguaK088aO4pQbZUxBOU7nMAjLdp wJ4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B02PUrN+; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id qb12si12305902ejc.389.2021.11.26.03.53.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:42 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B02PUrN+; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5FC3E83778; Fri, 26 Nov 2021 12:53:41 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="B02PUrN+"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2C8BF80F7A; Fri, 26 Nov 2021 12:53:27 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) (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 0030883760 for ; Fri, 26 Nov 2021 12:53:18 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ruchika.gupta@linaro.org Received: by mail-pj1-x1031.google.com with SMTP id fv9-20020a17090b0e8900b001a6a5ab1392so7885970pjb.1 for ; Fri, 26 Nov 2021 03:53:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vl/wGy7g0lDLqs6daPcstMz7bck9g4KcHz/anTfWs9g=; b=B02PUrN+CBTxsOK7RMORGI7OKn9yXSlol0Wj1g2suwbxjfNvfXwjJnIknpAD/N+rVa YLFyOOpOzHtCQpAYbRgsNj2/nFF2NSrwjMX/3ZWBQRA3XIRrq+lNOvf65sTRzUorJRIV iGjnyeKpu5qf3CbyIXhipU4sBkqw2+q0p8CGBDeZJ3dz3VvIYf2eoNGKTZhRfq01pLRD i3zOCTbj0VuSXRcJdWJ3EsLVuyHOKUErO/S8wcMTwMUlPZ872890TaVOjhmtnY03efQt KQ0PwC5Eh7UA/rIAelqwIeF3FXsOIexuH3xcYWBrODYC/f4hFmnfVF+Tp2JhXURTD0DV SO4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vl/wGy7g0lDLqs6daPcstMz7bck9g4KcHz/anTfWs9g=; b=JQ51ac7TwuBNwXep1PlOxwsVX9GelbE0AC4rR75KXGWeKLvDMhGfDhZ5YAq7g8Y0et a/L42CAZW6H3WWeQzyPQvyF5+qdej/ZLpNwhNR5F3DgVJjNSPuAAQ05tlE3GghVoYxbI wx3TFK7cRmWn7PKQjaFm+8MaDY2o0Kuks09YNJk5e0ZHX8Xtwi95GdLg5sIlRunT+MUw twQmAASt87ZCZ6qD8w8VXZxyZJWfcEtWN/EJznj66E4SXmbEGu1l5+xuEyI1MbnZZfEm rvYWzBokVSQdaX2Tuw0/D5QLJ4PZVuKY6QXLDxIH/jBjgB0aJGC9ftD8jObfYTgQuw0n 74eg== X-Gm-Message-State: AOAM53238Pos3c9QUlfwr14igBd9Cn06ZIhtjyW8nTZr5qo9b32cWPwW D+TQiHV+d9P/2T0Y8Wi0UPQ/BqnpFAOlBw== X-Received: by 2002:a17:90b:3810:: with SMTP id mq16mr14930399pjb.128.1637927597151; Fri, 26 Nov 2021 03:53:17 -0800 (PST) Received: from localhost.localdomain ([106.215.91.18]) by smtp.gmail.com with ESMTPSA id l11sm7128774pfu.129.2021.11.26.03.53.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Nov 2021 03:53:16 -0800 (PST) From: Ruchika Gupta To: u-boot@lists.denx.de, ilias.apalodimas@linaro.org, xypron.glpk@gmx.de, agraf@csgraf.de, masahisa.kojima@linaro.org Cc: Ruchika Gupta Subject: [PATCH v7 3/3] efi_loader: Extend PCR's for firmware measurements Date: Fri, 26 Nov 2021 17:23:01 +0530 Message-Id: <20211126115301.1103687-3-ruchika.gupta@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211126115301.1103687-1-ruchika.gupta@linaro.org> References: <20211126115301.1103687-1-ruchika.gupta@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.37 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 Firmwares before U-Boot may be capable of doing tpm measurements and passing them to U-Boot in the form of eventlog. However there may be scenarios where the firmwares don't have TPM driver and are not capable of extending the measurements in the PCRs. Based on TCG spec, if previous firnware has extended PCR's, PCR0 would not be 0. So, read the PCR0 to determine if the PCR's need to be extended as eventlog is parsed or not. Signed-off-by: Ruchika Gupta Reviewed-by: Ilias Apalodimas Tested-by: Ilias Apalodimas --- v7: Addressed Heinrick's comments - Added missing parameter in function header v6: Changed TPM2_DIGEST_LEN to TPM2_SHA512_DIGEST_SIZE v5 : No change v4 : No change v3 : Rebase changes on top of changes made in first patch series v2 : Removed check for PCR0 in eventlog lib/efi_loader/efi_tcg2.c | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 5ded57fd29..d247179fbf 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -199,6 +199,44 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, return EFI_SUCCESS; } +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values + * + * @dev: device + * @pcr_index: PCR index + * @digest_list: list of digest algorithms to extend + * + * @Return: status code + */ +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + struct tpm_chip_priv *priv; + unsigned int updates, pcr_select_min; + u32 rc; + size_t i; + + priv = dev_get_uclass_priv(dev); + if (!priv) + return EFI_DEVICE_ERROR; + + pcr_select_min = priv->pcr_select_min; + + for (i = 0; i < digest_list->count; i++) { + u16 hash_alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, + hash_alg, digest, alg_to_len(hash_alg), + &updates); + if (rc) { + EFI_PRINT("Failed to read PCR\n"); + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + /* put_event - Append an agile event to an eventlog * * @pcr_index: PCR index @@ -1461,6 +1499,8 @@ static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, u32 pcr, pos; u64 base; u32 sz; + bool extend_pcr = false; + int i; ret = platform_get_eventlog(dev, &base, &sz); if (ret != EFI_SUCCESS) @@ -1482,6 +1522,26 @@ static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, return ret; } + ret = tcg2_pcr_read(dev, 0, &digest_list); + if (ret) { + log_err("Error reading PCR 0\n"); + return ret; + } + + /* + * If PCR0 is 0, previous firmware didn't have the capability + * to extend the PCR. In this scenario, extend the PCR as + * the eventlog is parsed. + */ + for (i = 0; i < digest_list.count; i++) { + u8 buffer[TPM2_SHA512_DIGEST_SIZE] = { 0 }; + u16 hash_alg = digest_list.digests[i].hash_alg; + + if (!memcmp((u8 *)&digest_list.digests[i].digest, buffer, + alg_to_len(hash_alg))) + extend_pcr = true; + } + while (pos < sz) { ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, &pcr); @@ -1489,6 +1549,22 @@ static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, log_err("Error parsing event\n"); return ret; } + if (extend_pcr) { + ret = tcg2_pcr_extend(dev, pcr, &digest_list); + if (ret != EFI_SUCCESS) { + log_err("Error in extending PCR\n"); + return ret; + } + + /* Clear the digest for next event */ + for (i = 0; i < digest_list.count; i++) { + u16 hash_alg = digest_list.digests[i].hash_alg; + u8 *digest = + (u8 *)&digest_list.digests[i].digest; + + memset(digest, 0, alg_to_len(hash_alg)); + } + } } memcpy(log_buffer, buffer, sz);