Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752742AbdFUOcU (ORCPT ); Wed, 21 Jun 2017 10:32:20 -0400 Received: from lhrrgout.huawei.com ([194.213.3.17]:29082 "EHLO lhrrgout.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751191AbdFUOcR (ORCPT ); Wed, 21 Jun 2017 10:32:17 -0400 From: Roberto Sassu To: CC: , , , , Roberto Sassu Subject: [PATCH v3 0/6] Updated API for TPM 2.0 PCR extend Date: Wed, 21 Jun 2017 16:29:35 +0200 Message-ID: <20170621142941.32674-1-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.9.3 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.204.65.245] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.594A835F.0214,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 4e3a6ffc57a40e0e07d0aa09d4d654b8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5815 Lines: 159 The first version of the patch set can be retrieved at the URL: https://sourceforge.net/p/tpmdd/mailman/message/35756302/ The patches should be applied on top of the next branch of linux-security.git (commit cdac74d). This patch set updates the TPM driver API for extending Platform Configuration Registers (PCRs). These are special TPM registers which cannot be written directly, but can only be updated through the extend operation, by passing a digest as input: PCR_value_new = hash_func(PCR_value_old | digest) While TPM 1.2 can only use SHA1 as hash function, TPM 2.0 can support multiple algorithms. On a TPM 2.0, PCR values extended with the same algorithm are stored in a location called bank. Currently, PCRs can only be extended from the kernel with a SHA1 digest, through tpm_pcr_extend(). Remaining banks of a TPM 2.0 are extended with the SHA1 digest padded with zeros. In order to take advantage of stronger algorithms, the TPM driver should allow TPM users to extend a PCR with digests calculated with the same algorithm of the PCR bank. This patch set first introduces a new structure, called tpm_pcr_bank_info, for storing detailed information about each PCR bank: - TPM algorithm ID: algorithm identifier, defined by TCG; will be included by TPM users (e.g. IMA) in a measurement event log - digest size: digest size for a TPM algorithm; since this is retrieved from the TPM, PCR banks can be extended even if an algorithm is unknown for the crypto subsystem (which currently the TPM driver relies on) - crypto ID: will be used by TPM users to calculate a digest, to extend a PCR Then, the patch set introduces the new function tpm_get_pcr_banks_info(), to pass the information about PCR banks to TPM users, and finally, modifies the parameters of tpm_pcr_extend(), so that TPM users can pass multiple digests. Given this definition of the tpm2_digest structure: struct tpm2_digest { u16 alg_id; u8 digest[SHA512_DIGEST_SIZE]; } __packed; there will be two methods to extend PCRs: 1) by passing only one tpm2_digest structure containing a SHA1 digest (as it is done in the patch 6/6); in this case, the SHA1 digest is padded with zeros 2) by calling tpm_get_pcr_banks_info() to obtain PCR banks information, and by calling tpm_pcr_extend() with as many tpm2_digest structures as the number of tpm_pcr_bank_info structures retrieved in the first step (if a digest for a TPM algorithm is missing, the TPM driver pads/truncates the first digest provided by the TPM user) API Usage Examples In the following examples, an application extends PCR 16 with the digest of an event (e.g. record of a software measurement), with the methods described above. void app_calc_event_digest(struct crypto_shash *tfm, char *event, u8 *digest) { SHASH_DESC_ON_STACK(shash, tfm); shash->tfm = tfm; shash->flags = 0; crypto_shash_init(shash); crypto_shash_update(shash, event, strlen(event)); crypto_shash_final(shash, digest); } void app_pcr_extend_method_1(void) { char *event = "application event"; struct tpm2_digest digestarg = {.alg_id = TPM2_ALG_SHA1}; /* calculate event digest with current hash algorithm */ struct crypto_shash *tfm = crypto_alloc_shash("sha1", 0, 0); app_calc_event_digest(tfm, event, digestarg.digest); /* extend all PCR banks with SHA1 digest*/ tpm_pcr_extend(TPM_ANY_NUM, 16, 1, &digestarg); } void app_pcr_extend_method_2(void) { /* declare static arrays, limit is known */ struct tpm_pcr_bank_info active_banks[TPM_ACTIVE_BANKS_MAX]; struct tpm2_digest digest_array[TPM_ACTIVE_BANKS_MAX]; int i, num_algo; /* obtain algorithms supported by the TPM */ num_algo = tpm_get_pcr_banks_info(TPM_ANY_NUM, active_banks); for (i = 0; i < num_algo; i++) { char *event = "application event"; /* calculate event digest with current hash algorithm */ const char *algo_name = hash_algo_name[active_banks[i].crypto_id]; struct crypto_shash *tfm = crypto_alloc_shash(algo_name, 0, 0); app_calc_event_digest(tfm, event, digest_array[i].digest); digest_array[i].alg_id = active_banks[i].alg_id; } /* extend all PCR banks with calculated digests */ tpm_pcr_extend(TPM_ANY_NUM, 16, num_algo, digest_array); } Changelog v3 - introduced new structure tpm_pcr_bank_info - read a PCR to obtain the digest size for each TPM algorithm - tpm_pcr_algorithms() replaced by tpm_get_pcr_banks_info() - removed tpm_pcr_algo_to_crypto() and tpm_pcr_algo_from_crypto() - modification of tpm_pcr_extend() parameters and of callers of the function done in the same patch - removed tpm_pcr_check_input() v2 - tpm_pcr_algorithms() returns supported algorithms also for TPM 1.2 - fixed return values of tpm2_pcr_algo_to_crypto() and tpm2_pcr_algo_from_crypto() if TPM support is disabled in the kernel - tpm_pcr_extend() arguments checked by tpm_pcr_check_input() - modified parameters of tpm_pcr_extend() Roberto Sassu (6): tpm: use tpm_buf functions to perform a PCR read tpm: use tpm2_pcr_read_tpm_buf() in tpm2_do_selftest() tpm: introduce tpm_pcr_bank_info structure with digest_size from TPM tpm: replace TPM algorithms IDs with tpm_pcr_bank_info structs in tpm_chip tpm: introduce tpm_get_pcr_banks_info() tpm: pass multiple digests to tpm_pcr_extend() drivers/char/tpm/tpm-interface.c | 88 ++++++++++++++++++++++--- drivers/char/tpm/tpm.h | 19 +----- drivers/char/tpm/tpm2-cmd.c | 132 ++++++++++++++++++++++--------------- include/linux/tpm.h | 39 ++++++++++- security/integrity/ima/ima_queue.c | 4 +- security/keys/trusted.c | 6 +- 6 files changed, 202 insertions(+), 86 deletions(-) -- 2.9.3