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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id AA128C61DA4 for ; Thu, 23 Feb 2023 17:53:15 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 973FB84528; Thu, 23 Feb 2023 18:53:12 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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=ibm.com header.i=@ibm.com header.b="Gg2j1h+N"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2474A851EB; Thu, 23 Feb 2023 18:53:11 +0100 (CET) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 196ED843B5 for ; Thu, 23 Feb 2023 18:53:03 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=eajames@linux.ibm.com Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 31NGSJYO007075; Thu, 23 Feb 2023 17:52:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=message-id : date : mime-version : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding; s=pp1; bh=hEy5qCy9oxe2HYeknLPHsppuYOP+74igSIPy+MjP4Zo=; b=Gg2j1h+NGaTAPGqic9HWBySzoBMDndCGIoGNOcEX3QQTqoYvOK3aWoTNdWW+SMYhqnbE CE6fYsfR68s/Y15Ppb/AA1MIVc25QbvttkMs9uyywAfpvKPHxqRbtK6E6cOhtHbCPNo5 KXXRx76KJs8OelxYhqqlhqCmnJbtVMbcnr4h3ESc03Slt2XUKuy5IjV4OWrjh7EF5nDy PUVTY2dC54HWslYf5AqSl/My0ZOPlSRlaU92AHnahZAWR0Sd4GOFsga3lfI4d6krrAft TLGyxpMVGRpHys72J7U5vPrer4KfW6pZ+5WuNnP36rdoe9fcv2Pp2PtyUjUMRMHA5ywN qw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3nxb7a30bx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 23 Feb 2023 17:52:57 +0000 Received: from m0098416.ppops.net (m0098416.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 31NG0d76027555; Thu, 23 Feb 2023 17:52:57 GMT Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3nxb7a30bm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 23 Feb 2023 17:52:57 +0000 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 31NHpdTm000567; Thu, 23 Feb 2023 17:52:56 GMT Received: from smtprelay05.dal12v.mail.ibm.com ([9.208.130.101]) by ppma04dal.us.ibm.com (PPS) with ESMTPS id 3ntpa7q7fy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 23 Feb 2023 17:52:56 +0000 Received: from smtpav04.dal12v.mail.ibm.com (smtpav04.dal12v.mail.ibm.com [10.241.53.103]) by smtprelay05.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 31NHqtJ540436042 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 23 Feb 2023 17:52:55 GMT Received: from smtpav04.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2B6265805E; Thu, 23 Feb 2023 17:52:55 +0000 (GMT) Received: from smtpav04.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5C6FF58052; Thu, 23 Feb 2023 17:52:54 +0000 (GMT) Received: from [9.160.56.187] (unknown [9.160.56.187]) by smtpav04.dal12v.mail.ibm.com (Postfix) with ESMTP; Thu, 23 Feb 2023 17:52:54 +0000 (GMT) Message-ID: <2e4e1a87-00dc-4a0f-9a84-162daf578292@linux.ibm.com> Date: Thu, 23 Feb 2023 11:52:53 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.6.0 Subject: Re: [PATCH v6 3/6] tpm: Support boot measurements To: Ilias Apalodimas Cc: u-boot@lists.denx.de, sjg@chromium.org, xypron.glpk@gmx.de, joel@jms.id.au References: <20230222180242.4040958-1-eajames@linux.ibm.com> <20230222180242.4040958-4-eajames@linux.ibm.com> Content-Language: en-US From: Eddie James In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-GUID: fWQFIGmS7R-FG_sQL_s-0sIWkGRpPgUf X-Proofpoint-ORIG-GUID: fPZjVPf4IAmm9JeCndcXdhBfEvNeiLI5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22 definitions=2023-02-23_10,2023-02-23_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 mlxlogscore=999 clxscore=1015 lowpriorityscore=0 mlxscore=0 malwarescore=0 priorityscore=1501 phishscore=0 impostorscore=0 suspectscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2302230145 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.6 at phobos.denx.de X-Virus-Status: Clean On 2/23/23 03:47, Ilias Apalodimas wrote: > On Thu, 23 Feb 2023 at 11:30, Ilias Apalodimas > wrote: >> On Thu, 23 Feb 2023 at 11:02, Ilias Apalodimas >> wrote: >>> Hi Eddie, >>> >>> final_event->number_of_events++; >>>> @@ -350,66 +142,6 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, >>>> return ret; >>>> } >>>> >>>> -/** >>>> - * platform_get_tpm_device() - retrieve TPM device >>>> - * >>>> - * This function retrieves the udevice implementing a TPM >>>> - * >>>> - * This function may be overridden if special initialization is needed. >>>> - * >>>> - * @dev: udevice >>>> - * Return: status code >>>> - */ >>>> -__weak efi_status_t platform_get_tpm2_device(struct udevice **dev) >>>> -{ >>>> - for_each_tpm_device(*dev) { >>>> - /* Only support TPMv2 devices */ >>>> - if (tpm_get_version(*dev) == TPM_V2) >>>> - return EFI_SUCCESS; >>>> - } >>>> - >>>> - 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 >>>> * >>>> @@ -485,239 +217,6 @@ static int tpm2_get_manufacturer_id(struct udevice *dev, u32 *manufacturer_id) >>>> return 0; >>>> } >>>> >>>> -/** >>>> - * tpm2_get_num_pcr() - get the number of PCRs >>>> - * >>>> - * @dev: TPM device >>>> - * @manufacturer_id: output buffer for the number >>>> - * >>>> - * Return: 0 on success, -1 on error >>>> - */ >>>> -static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr) >>>> -{ >>>> - u8 response[TPM2_RESPONSE_BUFFER_SIZE]; >>>> - u32 ret; >>>> - >>>> - memset(response, 0, sizeof(response)); >>>> - ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES, >>>> - TPM2_PT_PCR_COUNT, response, 1); >>>> - if (ret) >>>> - return -1; >>>> - >>>> - *num_pcr = get_unaligned_be32(response + properties_offset); >>>> - if (*num_pcr > TPM2_MAX_PCRS) >>>> - return -1; >>>> - >>>> - return 0; >>>> -} >>>> - >>>> -/** >>>> - * is_active_pcr() - Check if a supported algorithm is active >>>> - * >>>> - * @dev: TPM device >>>> - * @selection: struct of PCR information >>>> - * >>>> - * Return: true if PCR is active >>>> - */ >>>> -static bool is_active_pcr(struct tpms_pcr_selection *selection) >>>> -{ >>>> - int i; >>>> - /* >>>> - * check the pcr_select. If at least one of the PCRs supports the >>>> - * algorithm add it on the active ones >>>> - */ >>>> - for (i = 0; i < selection->size_of_select; i++) { >>>> - if (selection->pcr_select[i]) >>>> - return true; >>>> - } >>>> - >>>> - return false; >>>> -} >>>> - >>>> -/** >>>> - * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks >>>> - * >>>> - * @dev: TPM device >>>> - * @supported_pcr: bitmask with the algorithms supported >>>> - * @active_pcr: bitmask with the active algorithms >>>> - * @pcr_banks: number of PCR banks >>>> - * >>>> - * Return: 0 on success, -1 on error >>>> - */ >>>> -static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, >>>> - u32 *active_pcr, u32 *pcr_banks) >>>> -{ >>>> - u8 response[TPM2_RESPONSE_BUFFER_SIZE]; >>>> - struct tpml_pcr_selection pcrs; >>>> - u32 ret, num_pcr; >>>> - size_t i; >>>> - int tpm_ret; >>>> - >>>> - *supported_pcr = 0; >>>> - *active_pcr = 0; >>>> - *pcr_banks = 0; >>>> - memset(response, 0, sizeof(response)); >>>> - ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1); >>>> - if (ret) >>>> - goto out; >>>> - >>>> - pcrs.count = get_unaligned_be32(response); >>>> - /* >>>> - * We only support 5 algorithms for now so check against that >>>> - * instead of TPM2_NUM_PCR_BANKS >>>> - */ >>>> - if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1) >>>> - goto out; >>>> - >>>> - tpm_ret = tpm2_get_num_pcr(dev, &num_pcr); >>>> - if (tpm_ret) >>>> - goto out; >>>> - >>>> - for (i = 0; i < pcrs.count; i++) { >>>> - /* >>>> - * Definition of TPMS_PCR_SELECTION Structure >>>> - * hash: u16 >>>> - * size_of_select: u8 >>>> - * pcr_select: u8 array >>>> - * >>>> - * The offsets depend on the number of the device PCRs >>>> - * so we have to calculate them based on that >>>> - */ >>>> - u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) + >>>> - i * offsetof(struct tpms_pcr_selection, pcr_select) + >>>> - i * ((num_pcr + 7) / 8); >>>> - u32 size_select_offset = >>>> - hash_offset + offsetof(struct tpms_pcr_selection, >>>> - size_of_select); >>>> - u32 pcr_select_offset = >>>> - hash_offset + offsetof(struct tpms_pcr_selection, >>>> - pcr_select); >>>> - >>>> - pcrs.selection[i].hash = >>>> - get_unaligned_be16(response + hash_offset); >>>> - pcrs.selection[i].size_of_select = >>>> - __get_unaligned_be(response + size_select_offset); >>>> - if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) >>>> - goto out; >>>> - /* copy the array of pcr_select */ >>>> - memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset, >>>> - pcrs.selection[i].size_of_select); >>>> - } >>>> - >>>> - for (i = 0; i < pcrs.count; i++) { >>>> - u32 hash_mask = alg_to_mask(pcrs.selection[i].hash); >>>> - >>>> - if (hash_mask) { >>>> - *supported_pcr |= hash_mask; >>>> - if (is_active_pcr(&pcrs.selection[i])) >>>> - *active_pcr |= hash_mask; >>>> - } else { >>>> - EFI_PRINT("Unknown algorithm %x\n", pcrs.selection[i].hash); >>>> - } >>>> - } >>>> - >>>> - *pcr_banks = pcrs.count; >>>> - >>>> - return 0; >>>> -out: >>>> - return -1; >>>> -} >>>> - >>>> -/** >>>> - * __get_active_pcr_banks() - returns the currently active PCR banks >>>> - * >>>> - * @active_pcr_banks: pointer for receiving the bitmap of currently >>>> - * active PCR banks >>>> - * >>>> - * Return: status code >>>> - */ >>>> -static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks) >>>> -{ >>>> - struct udevice *dev; >>>> - u32 active = 0, supported = 0, pcr_banks = 0; >>>> - efi_status_t ret; >>>> - int err; >>>> - >>>> - ret = platform_get_tpm2_device(&dev); >>>> - if (ret != EFI_SUCCESS) >>>> - goto out; >>>> - >>>> - err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); >>>> - if (err) { >>>> - ret = EFI_DEVICE_ERROR; >>>> - goto out; >>>> - } >>>> - >>>> - *active_pcr_banks = active; >>>> - >>>> -out: >>>> - return ret; >>>> -} >>>> - >>>> -/* tcg2_create_digest - create a list of digests of the supported PCR banks >>>> - * for a given memory range >>>> - * >>>> - * @input: input memory >>>> - * @length: length of buffer to calculate the digest >>>> - * @digest_list: list of digests to fill in >>>> - * >>>> - * Return: status code >>>> - */ >>>> -static efi_status_t tcg2_create_digest(const u8 *input, u32 length, >>>> - struct tpml_digest_values *digest_list) >>>> -{ >>>> - sha1_context ctx; >>>> - sha256_context ctx_256; >>>> - sha512_context ctx_512; >>>> - u8 final[TPM2_SHA512_DIGEST_SIZE]; >>>> - efi_status_t ret; >>>> - u32 active; >>>> - size_t i; >>>> - >>>> - ret = __get_active_pcr_banks(&active); >>>> - if (ret != EFI_SUCCESS) >>>> - return ret; >>>> - >>>> - digest_list->count = 0; >>>> - for (i = 0; i < MAX_HASH_COUNT; i++) { >>>> - u16 hash_alg = hash_algo_list[i].hash_alg; >>>> - >>>> - if (!(active & alg_to_mask(hash_alg))) >>>> - continue; >>>> - switch (hash_alg) { >>>> - case TPM2_ALG_SHA1: >>>> - sha1_starts(&ctx); >>>> - sha1_update(&ctx, input, length); >>>> - sha1_finish(&ctx, final); >>>> - break; >>>> - case TPM2_ALG_SHA256: >>>> - sha256_starts(&ctx_256); >>>> - sha256_update(&ctx_256, input, length); >>>> - sha256_finish(&ctx_256, final); >>>> - break; >>>> - case TPM2_ALG_SHA384: >>>> - sha384_starts(&ctx_512); >>>> - sha384_update(&ctx_512, input, length); >>>> - sha384_finish(&ctx_512, final); >>>> - break; >>>> - case TPM2_ALG_SHA512: >>>> - sha512_starts(&ctx_512); >>>> - sha512_update(&ctx_512, input, length); >>>> - sha512_finish(&ctx_512, final); >>>> - break; >>>> - default: >>>> - EFI_PRINT("Unsupported algorithm %x\n", hash_alg); >>>> - return EFI_INVALID_PARAMETER; >>>> - } >>>> - digest_list->digests[digest_list->count].hash_alg = hash_alg; >>>> - memcpy(&digest_list->digests[digest_list->count].digest, final, >>>> - (u32)alg_to_len(hash_alg)); >>>> - digest_list->count++; >>>> - } >>>> - >>>> - return EFI_SUCCESS; >>>> -} >>>> - >>>> /** >>>> * efi_tcg2_get_capability() - protocol capability information and state information >>>> * >>>> @@ -759,7 +258,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this, >>>> capability->protocol_version.major = 1; >>>> capability->protocol_version.minor = 1; >>>> >>>> - efi_ret = platform_get_tpm2_device(&dev); >>>> + efi_ret = tcg2_platform_get_tpm2(&dev); >>>> if (efi_ret != EFI_SUCCESS) { >>>> capability->supported_event_logs = 0; >>>> capability->hash_algorithm_bitmap = 0; >>>> @@ -855,7 +354,7 @@ efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this, >>>> goto out; >>>> } >>>> >>>> - ret = platform_get_tpm2_device(&dev); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> if (ret != EFI_SUCCESS) { >>>> event_log_location = NULL; >>>> event_log_last_entry = NULL; >>>> @@ -890,6 +389,7 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size, >>>> struct efi_image_regions *regs = NULL; >>>> void *new_efi = NULL; >>>> u8 hash[TPM2_SHA512_DIGEST_SIZE]; >>>> + struct udevice *dev; >>>> efi_status_t ret; >>>> u32 active; >>>> int i; >>>> @@ -905,16 +405,20 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size, >>>> goto out; >>>> } >>>> >>>> - ret = __get_active_pcr_banks(&active); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> + if (ret != EFI_SUCCESS) >>>> + goto out; >>>> + >>>> + ret = tcg2_get_active_pcr_banks(dev, &active); >>>> if (ret != EFI_SUCCESS) { >>>> goto out; >>>> } >>>> >>>> digest_list->count = 0; >>>> - for (i = 0; i < MAX_HASH_COUNT; i++) { >>>> - u16 hash_alg = hash_algo_list[i].hash_alg; >>>> + for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); i++) { >>>> + u16 hash_alg = tpm2_supported_algorithms[i]; >>>> >>>> - if (!(active & alg_to_mask(hash_alg))) >>>> + if (!(active & tpm2_algorithm_to_mask(hash_alg))) >>>> continue; >>>> switch (hash_alg) { >>>> case TPM2_ALG_SHA1: >>>> @@ -935,7 +439,7 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size, >>>> } >>>> digest_list->digests[digest_list->count].hash_alg = hash_alg; >>>> memcpy(&digest_list->digests[digest_list->count].digest, hash, >>>> - (u32)alg_to_len(hash_alg)); >>>> + (u32)tpm2_algorithm_to_len(hash_alg)); >>>> digest_list->count++; >>>> } >>>> >>>> @@ -975,7 +479,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, >>>> if (!is_tcg2_protocol_installed()) >>>> return EFI_SUCCESS; >>>> >>>> - ret = platform_get_tpm2_device(&dev); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> if (ret != EFI_SUCCESS) >>>> return EFI_SECURITY_VIOLATION; >>>> >>>> @@ -1084,7 +588,7 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, >>>> goto out; >>>> } >>>> >>>> - ret = platform_get_tpm2_device(&dev); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> if (ret != EFI_SUCCESS) >>>> goto out; >>>> >>>> @@ -1119,7 +623,7 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, >>>> ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash, >>>> data_to_hash_len, &digest_list); >>>> } else { >>>> - ret = tcg2_create_digest((u8 *)(uintptr_t)data_to_hash, >>>> + ret = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash, >>>> data_to_hash_len, &digest_list); >>>> } >>>> >>>> @@ -1182,7 +686,7 @@ efi_tcg2_submit_command(struct efi_tcg2_protocol *this, >>>> goto out; >>>> } >>>> >>>> - ret = platform_get_tpm2_device(&dev); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> if (ret != EFI_SUCCESS) >>>> goto out; >>>> >>>> @@ -1211,6 +715,7 @@ static efi_status_t EFIAPI >>>> efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this, >>>> u32 *active_pcr_banks) >>>> { >>>> + struct udevice *dev; >>>> efi_status_t ret; >>>> >>>> if (!this || !active_pcr_banks) { >>>> @@ -1218,8 +723,12 @@ efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this, >>>> goto out; >>>> } >>>> >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> + if (ret != EFI_SUCCESS) >>>> + goto out; >>>> + >>>> EFI_ENTRY("%p, %p", this, active_pcr_banks); >>>> - ret = __get_active_pcr_banks(active_pcr_banks); >>>> + ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks); >>>> >>>> out: >>>> return EFI_EXIT(ret); >>>> @@ -1270,397 +779,6 @@ 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; >>>> - 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); >>>> - >>>> - 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 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); >>>> - >>>> - /* 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; >>>> - bool extend_pcr = false; >>>> - int i; >>>> - >>>> - 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 *)(uintptr_t)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; >>>> - } >>>> - >>>> - 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 hash_buf[TPM2_SHA512_DIGEST_SIZE] = { 0 }; >>>> - u16 hash_alg = digest_list.digests[i].hash_alg; >>>> - >>>> - if (!memcmp((u8 *)&digest_list.digests[i].digest, hash_buf, >>>> - alg_to_len(hash_alg))) >>>> - extend_pcr = true; >>>> - } >>>> - >>>> - while (pos < sz) { >>>> - ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, >>>> - &pcr); >>>> - if (ret) { >>>> - 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); >>>> - *log_sz = sz; >>>> - >>>> - return ret; >>>> -} >>>> - >>>> -/** >>>> - * create_specid_event() - Create the first event in the eventlog >>>> - * >>>> - * @dev: tpm device >>>> - * @event_header: Pointer to the final event header >>>> - * @event_size: final spec event size >>>> - * >>>> - * Return: status code >>>> - */ >>>> -static efi_status_t create_specid_event(struct udevice *dev, void *buffer, >>>> - size_t *event_size) >>>> -{ >>>> - struct tcg_efi_spec_id_event *spec_event; >>>> - size_t spec_event_size; >>>> - efi_status_t ret = EFI_DEVICE_ERROR; >>>> - u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; >>>> - int err; >>>> - size_t i; >>>> - >>>> - /* >>>> - * Create Spec event. This needs to be the first event in the log >>>> - * according to the TCG EFI protocol spec >>>> - */ >>>> - >>>> - /* Setup specID event data */ >>>> - spec_event = (struct tcg_efi_spec_id_event *)buffer; >>>> - memcpy(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, >>>> - sizeof(spec_event->signature)); >>>> - put_unaligned_le32(0, &spec_event->platform_class); /* type client */ >>>> - 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; >>>> - spec_event->spec_errata = >>>> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; >>>> - spec_event->uintn_size = sizeof(efi_uintn_t) / sizeof(u32); >>>> - >>>> - err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count); >>>> - >>>> - if (err) >>>> - goto out; >>>> - >>>> - for (i = 0; i < pcr_count; i++) { >>>> - u16 hash_alg = hash_algo_list[i].hash_alg; >>>> - u16 hash_len = hash_algo_list[i].hash_len; >>>> - >>>> - if (active & alg_to_mask(hash_alg)) { >>>> - put_unaligned_le16(hash_alg, >>>> - &spec_event->digest_sizes[alg_count].algorithm_id); >>>> - put_unaligned_le16(hash_len, >>>> - &spec_event->digest_sizes[alg_count].digest_size); >>>> - alg_count++; >>>> - } >>>> - } >>>> - >>>> - spec_event->number_of_algorithms = alg_count; >>>> - if (spec_event->number_of_algorithms > MAX_HASH_COUNT || >>>> - spec_event->number_of_algorithms < 1) >>>> - goto out; >>>> - >>>> - /* >>>> - * 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) + >>>> - spec_event->number_of_algorithms * sizeof(spec_event->digest_sizes[0]); >>>> - /* no vendor info for us */ >>>> - memset(buffer + spec_event_size, 0, 1); >>>> - /* add a byte for vendor_info_size in the spec event */ >>>> - spec_event_size += 1; >>>> - *event_size = spec_event_size; >>>> - >>>> - return EFI_SUCCESS; >>>> - >>>> -out: >>>> - return ret; >>>> -} >>>> - >>>> /** >>>> * tcg2_uninit - remove the final event table and free efi memory on failures >>>> */ >>>> @@ -1722,7 +840,7 @@ out: >>>> } >>>> >>>> /** >>>> - * tcg2_measure_event() - common function to add event log and extend PCR >>>> + * measure_event() - common function to add event log and extend PCR >>>> * >>>> * @dev: TPM device >>>> * @pcr_index: PCR index >>>> @@ -1732,14 +850,13 @@ out: >>>> * >>>> * Return: status code >>>> */ >>>> -static efi_status_t >>>> -tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type, >>>> - u32 size, u8 event[]) >>>> +static efi_status_t measure_event(struct udevice *dev, u32 pcr_index, >>>> + u32 event_type, u32 size, u8 event[]) >>>> { >>>> struct tpml_digest_values digest_list; >>>> efi_status_t ret; >>>> >>>> - ret = tcg2_create_digest(event, size, &digest_list); >>>> + ret = tcg2_create_digest(dev, event, size, &digest_list); >>>> if (ret != EFI_SUCCESS) >>>> goto out; >>>> >>>> @@ -1766,9 +883,8 @@ static efi_status_t efi_append_scrtm_version(struct udevice *dev) >>>> { >>>> efi_status_t ret; >>>> >>>> - ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION, >>>> - strlen(version_string) + 1, >>>> - (u8 *)version_string); >>>> + ret = measure_event(dev, 0, EV_S_CRTM_VERSION, >>>> + strlen(version_string) + 1, (u8 *)version_string); >>>> >>>> return ret; >>>> } >>>> @@ -1784,12 +900,11 @@ 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 tcg2_event_log elog; >>>> struct udevice *dev; >>>> - size_t spec_event_size; >>>> efi_status_t ret; >>>> >>>> - ret = platform_get_tpm2_device(&dev); >>>> + ret = tcg2_platform_get_tpm2(&dev); >>>> if (ret != EFI_SUCCESS) >>>> return ret; >>>> >>>> @@ -1808,7 +923,6 @@ static efi_status_t efi_init_event_log(void) >>>> * 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; >>>> @@ -1819,34 +933,19 @@ static efi_status_t efi_init_event_log(void) >>>> * 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); >>>> + ret = tcg2_init_log(dev, &elog); >>>> + if (ret != EFI_SUCCESS) >>>> + goto free_pool; >>> So I think this is the last bit we need to change in order to support EFI >>> properly. I read the email regarding the newly added reserved memory memory >>> to the TPM node and it's fine, but that won't work for the existing U-Boot >>> dtbs. Since this was working out of the box, I'd still prefer to keep that >>> working even if that entry is missing. >>> >>> If you look at this function, there is an efi_allocate_pool() call a few >>> lines above. What this does is allocate the EventLog memory for EFI. >>> Note here that this *has* to be EFI memory since the kernel's efi-stub >>> can still call into the firmware (and in fact it does, that's who we measure >>> the initrd in > 5.18 kernels). After the allocation it looks for those DT >>> entries, and if tpm_event_log_addr is found it parses the EventLog and >>> 1. Extends the PCRs >>> 2. Adds the events into the Eventlog >>> >>> The reason for that is that TF-A (the Arm first stage boot loader), >>> doesn't have any TPM drivers. So U-Boot is trying to be 'smart' here. >>> We are grabbing the EventLog from the previous bootloader and if PCR0!=0 we >>> replay that into the hardware and re-create the EventLog. >>> >>> [...] >> >> This will fix the protocol installation, however there's still still >> something missing on the EFI side, since reading the eventlog fails >> with >> >> tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements >> version: 1 >> events: >> ERROR: failed to parse tpm2 eventlog >> ERROR: Unable to run tpm2_eventlog >> But at least the kernel can find the EFI config tables properly. >> Also, note that the ret is efi_status_t and the new function you added >> returns an int. Just switch the ret here accordingly. >> >> >> * platforms can use different ways to do so. >> */ >> ret = tcg2_init_log(dev, &elog); >> - if (ret != EFI_SUCCESS) >> - goto free_pool; >> - >> - memcpy(event_log.buffer, elog.log, elog.log_position); >> - event_log.pos = elog.log_position; >> + if (ret == EFI_SUCCESS) { >> + memcpy(event_log.buffer, elog.log, elog.log_position); >> + event_log.pos = elog.log_position; >> + } >> >> >> I'll try digging into the EFI issues more once I get some time > Ok Ignore the previous mail. I just noticed that the specid event is > generated by tcg2_log_init() and that's where the errors come from. OK, I think I understand the problem. One problem with your solution below is that it's only useful for EFI; writing the event log to a temporary buffer in the non-EFI case is a waste of time, since it can't go anywhere. I have a solution where the user can pass in their buffer in the tcg2_event_log structure in the event that no memory region is discovered. EFI can use that path. Thanks for the debugging effort! Eddie > > So something like the *really ugly hack* fixes EFI. Can you please > turn it into human-readable code > > #include > #include > #include > +#include > > #include "tpm-utils.h" > > @@ -634,7 +635,7 @@ __weak int tcg2_platform_get_log(struct udevice > *dev, void **addr, u32 *size) > > if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, > 0, &args)) > - return -ENODEV; > + goto alloc; > > a = ofnode_get_addr_size(args.node, "reg", &s); > if (a == FDT_ADDR_T_NONE) > @@ -643,6 +644,9 @@ __weak int tcg2_platform_get_log(struct udevice > *dev, void **addr, u32 *size) > *addr = map_physmem(a, s, MAP_NOCACHE); > *size = (u32)s; > } > +alloc: > + *addr = calloc(1, 4096); > + *size = 4096; > > return 0; > } > > Cheers > /Ilias > >> Cheers >> /Ilias >>> Thanks! >>> /Ilias