From 1d9f48fcab1f89ab53354b2fc75aac08bf62e655 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 15 May 2024 09:03:00 +0000 Subject: [PATCH] Import from AlmaLinux stable repository --- SOURCES/0001-Fix-nv_readpublic.patch | 62 +++ ...bject-New-tool-to-encode-TPM2-object.patch | 385 ++++++++++++++++ ...conrol-fix-for-call-to-Esys_TR_Close.patch | 104 +++++ ...ument-parsing-in-tpm2_policylocality.patch | 45 ++ ...c-Fix-an-issue-where-LOG_WARN-is-alw.patch | 82 ++++ .../0006-import-fix-bug-on-using-scheme.patch | 100 ++++ ...policyor-fix-unallocated-policy-list.patch | 85 ++++ ...l.c-Fix-potential-null-pointer-deref.patch | 35 ++ ...2_provision-fix-usage-of-L-parameter.patch | 30 ++ ...010-tpm2_encodeobject-fix-formatting.patch | 26 ++ ...2_encodeobject-fix-auth-boolean-flag.patch | 99 ++++ ...x-convert-sm2-public-key-in-openssl3.patch | 30 ++ ...x-reading-and-writing-serialized-trs.patch | 46 ++ ...fix-wrong-function-name-of-Esys_Load.patch | 29 ++ ...tpm-errata-switch-to-twos-complement.patch | 224 +++++++++ ...c-Fix-pcr-extension-for-EV_NO_ACTION.patch | 159 +++++++ ...roblem-with-FORTIFY_SOURCE-on-Fedora.patch | 52 +++ SOURCES/add_pregenerated_doc.patch | 434 ++++++++++++++++++ SPECS/tpm2-tools.spec | 26 +- 19 files changed, 2052 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0001-Fix-nv_readpublic.patch create mode 100644 SOURCES/0002-tpm2_encodeobject-New-tool-to-encode-TPM2-object.patch create mode 100644 SOURCES/0003-tools-tpm2_evictconrol-fix-for-call-to-Esys_TR_Close.patch create mode 100644 SOURCES/0004-Fix-argument-parsing-in-tpm2_policylocality.patch create mode 100644 SOURCES/0005-tools-tpm2_tool.c-Fix-an-issue-where-LOG_WARN-is-alw.patch create mode 100644 SOURCES/0006-import-fix-bug-on-using-scheme.patch create mode 100644 SOURCES/0007-tpm2_policyor-fix-unallocated-policy-list.patch create mode 100644 SOURCES/0008-lib-tpm2_alg_util.c-Fix-potential-null-pointer-deref.patch create mode 100644 SOURCES/0009-tss2_provision-fix-usage-of-L-parameter.patch create mode 100644 SOURCES/0010-tpm2_encodeobject-fix-formatting.patch create mode 100644 SOURCES/0011-tpm2_encodeobject-fix-auth-boolean-flag.patch create mode 100644 SOURCES/0012-bugfix-fix-convert-sm2-public-key-in-openssl3.patch create mode 100644 SOURCES/0013-readpublic-fix-reading-and-writing-serialized-trs.patch create mode 100644 SOURCES/0014-fix-wrong-function-name-of-Esys_Load.patch create mode 100644 SOURCES/0015-tpm-errata-switch-to-twos-complement.patch create mode 100644 SOURCES/0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch create mode 100644 SOURCES/0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch create mode 100644 SOURCES/add_pregenerated_doc.patch diff --git a/SOURCES/0001-Fix-nv_readpublic.patch b/SOURCES/0001-Fix-nv_readpublic.patch new file mode 100644 index 0000000..24f16b3 --- /dev/null +++ b/SOURCES/0001-Fix-nv_readpublic.patch @@ -0,0 +1,62 @@ +From 4dffb4295392f69f00003b2879f60bd36076f22d Mon Sep 17 00:00:00 2001 +From: Imran Desai +Date: Tue, 7 Dec 2021 13:21:58 -0700 +Subject: [PATCH 01/17] Fix nv_readpublic + +Based on 4af3e6b4 tpm2_nvreadpublic: Add option to output cpHash +--- + lib/tpm2.c | 11 +++++++++-- + lib/tpm2_nv_util.h | 14 +------------- + 2 files changed, 10 insertions(+), 15 deletions(-) + +diff --git a/lib/tpm2.c b/lib/tpm2.c +index 4ee27c8c..d91072ae 100644 +--- a/lib/tpm2.c ++++ b/lib/tpm2.c +@@ -101,9 +101,16 @@ tool_rc tpm2_close(ESYS_CONTEXT *esys_context, ESYS_TR *rsrc_handle) { + tool_rc tpm2_nv_readpublic(ESYS_CONTEXT *esys_context, ESYS_TR nv_index, + TPM2B_NV_PUBLIC **nv_public, TPM2B_NAME **nv_name) { + +- TSS2_RC rval = Esys_NV_ReadPublic(esys_context, nv_index, +- ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, nv_public, nv_name); ++ ESYS_TR esys_tr_nv_index; ++ TSS2_RC rval = Esys_TR_FromTPMPublic(esys_context, nv_index, ESYS_TR_NONE, ++ ESYS_TR_NONE, ESYS_TR_NONE, &esys_tr_nv_index); ++ if (rval != TPM2_RC_SUCCESS) { ++ LOG_PERR(Esys_TR_FromTPMPublic, rval); ++ return tool_rc_from_tpm(rval); ++ } + ++ rval = Esys_NV_ReadPublic(esys_context, esys_tr_nv_index, ++ ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, nv_public, nv_name); + if (rval != TSS2_RC_SUCCESS) { + LOG_PERR(Esys_NV_ReadPublic, rval); + return tool_rc_from_tpm(rval); +diff --git a/lib/tpm2_nv_util.h b/lib/tpm2_nv_util.h +index 99843156..daf8b624 100644 +--- a/lib/tpm2_nv_util.h ++++ b/lib/tpm2_nv_util.h +@@ -28,19 +28,7 @@ + static inline tool_rc tpm2_util_nv_read_public(ESYS_CONTEXT *context, + TPMI_RH_NV_INDEX nv_index, TPM2B_NV_PUBLIC **nv_public) { + +- ESYS_TR tr_object; +- tool_rc rc = tpm2_from_tpm_public(context, nv_index, ESYS_TR_NONE, +- ESYS_TR_NONE, ESYS_TR_NONE, &tr_object); +- if (rc != tool_rc_success) { +- return rc; +- } +- +- rc = tpm2_nv_readpublic(context, tr_object, nv_public, NULL); +- tool_rc tmp_rc = tpm2_close(context, &tr_object); +- if (tmp_rc != tool_rc_success) { +- rc = tmp_rc; +- } +- return rc; ++ return tpm2_nv_readpublic(context, nv_index, nv_public, 0); + } + + /** +-- +2.40.1 + diff --git a/SOURCES/0002-tpm2_encodeobject-New-tool-to-encode-TPM2-object.patch b/SOURCES/0002-tpm2_encodeobject-New-tool-to-encode-TPM2-object.patch new file mode 100644 index 0000000..6cc7b12 --- /dev/null +++ b/SOURCES/0002-tpm2_encodeobject-New-tool-to-encode-TPM2-object.patch @@ -0,0 +1,385 @@ +From ba7682dc511f4ef6bbb8a15ca3bb0edf67ec39ce Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Fri, 17 Sep 2021 07:14:20 +0200 +Subject: [PATCH 02/17] tpm2_encodeobject: New tool to encode TPM2 object + +This adds a new tool tpm2_encodeobject in tools/misc. It takes +public and private portions of an object and encode them in a combined +PEM form used by tpm2-tss-engine and other applications. + +Signed-off-by: Daiki Ueno +--- + Makefile.am | 2 + + man/tpm2_encodeobject.1.md | 92 +++++++++++++ + tools/misc/tpm2_encodeobject.c | 240 +++++++++++++++++++++++++++++++++ + 3 files changed, 334 insertions(+) + create mode 100644 man/tpm2_encodeobject.1.md + create mode 100644 tools/misc/tpm2_encodeobject.c + +diff --git a/Makefile.am b/Makefile.am +index 71322159..e1a51ebf 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -103,6 +103,7 @@ tools_tpm2_SOURCES = \ + tpm2_tools = \ + tools/misc/tpm2_certifyX509certutil.c \ + tools/misc/tpm2_checkquote.c \ ++ tools/misc/tpm2_encodeobject.c \ + tools/misc/tpm2_eventlog.c \ + tools/misc/tpm2_print.c \ + tools/misc/tpm2_rc_decode.c \ +@@ -376,6 +377,7 @@ if HAVE_MAN_PAGES + man/man1/tpm2_createprimary.1 \ + man/man1/tpm2_dictionarylockout.1 \ + man/man1/tpm2_duplicate.1 \ ++ man/man1/tpm2_encodeobject.1 \ + man/man1/tpm2_getcap.1 \ + man/man1/tpm2_encryptdecrypt.1 \ + man/man1/tpm2_eventlog.1 \ +diff --git a/man/tpm2_encodeobject.1.md b/man/tpm2_encodeobject.1.md +new file mode 100644 +index 00000000..791eafbd +--- /dev/null ++++ b/man/tpm2_encodeobject.1.md +@@ -0,0 +1,92 @@ ++% tpm2_encodeobject(1) tpm2-tools | General Commands Manual ++ ++# NAME ++ ++**tpm2_encodeobject**(1) - Encode an object into a combined PEM format. ++ ++# SYNOPSIS ++ ++**tpm2_encodeobject** [*OPTIONS*] ++ ++# DESCRIPTION ++ ++**tpm2_encodeobject**(1) - Encode both the private and public portions of an ++object into a combined PEM format used by tpm2-tss-engine. ++ ++The tool reads private and public portions of an object and encodes it ++into a combined PEM format used by tpm2-tss-engine and other ++applications. ++ ++**NOTE**: Both private and public portions of the tpm key must be specified. ++ ++# OPTIONS ++ ++ * **-C**, **\--parent-context**=_OBJECT_: ++ ++ The parent object. ++ ++ * **-P**, **\--auth**=_AUTH_: ++ ++ The authorization value of the parent object specified by **-C**. ++ ++ * **-u**, **\--public**=_FILE_: ++ ++ A file containing the public portion of the object. ++ ++ * **-r**, **\--private**=_FILE_: ++ ++ A file containing the sensitive portion of the object. ++ ++ * **-o**, **\--output**=_FILE_: ++ ++ The output file path, recording the public portion of the object. ++ ++## References ++ ++[context object format](common/ctxobj.md) details the methods for specifying ++_OBJECT_. ++ ++[authorization formatting](common/authorizations.md) details the methods for ++specifying _AUTH_. ++ ++[common options](common/options.md) collection of common options that provide ++information many users may expect. ++ ++[common tcti options](common/tcti.md) collection of options used to configure ++the various known TCTI modules. ++ ++# EXAMPLES ++ ++## Setup ++To load an object you first must create an object under a primary object. So the ++first step is to create the primary object. ++ ++```bash ++tpm2_createprimary -c primary.ctx ++``` ++ ++Step 2 is to create an object under the primary object. ++ ++```bash ++tpm2_create -C primary.ctx -u key.pub -r key.priv -f pem -o pub.pem ++``` ++ ++This creates the private and public portions of the TPM object. With these ++object portions, it is now possible to load that object into the TPM for ++subsequent use. ++ ++## Encoding an Object into a combined PEM format ++ ++The final step, is encoding the public and private portions of the object into a ++PEM format. ++ ++```bash ++tpm2_encodeobject -C primary.ctx -u key.pub -r key.priv -c priv.pem ++``` ++ ++The generated `priv.pem` can be used together with `pub.pem` created in the ++step 2 of Setup section. ++ ++[returns](common/returns.md) ++ ++[footer](common/footer.md) +diff --git a/tools/misc/tpm2_encodeobject.c b/tools/misc/tpm2_encodeobject.c +new file mode 100644 +index 00000000..2341c3a1 +--- /dev/null ++++ b/tools/misc/tpm2_encodeobject.c +@@ -0,0 +1,240 @@ ++/* SPDX-License-Identifier: BSD-3-Clause */ ++ ++/* ++ * Part of this file is copied from tpm2-tss-engine. ++ * ++ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG ++ * All rights reserved. ++ * Copyright (c) 2019, Wind River Systems. ++ * All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "files.h" ++#include "log.h" ++#include "tpm2.h" ++#include "tpm2_options.h" ++#include "tpm2_tool.h" ++ ++#define OID_loadableKey "2.23.133.10.1.3" ++ ++typedef struct { ++ ASN1_OBJECT *type; ++ ASN1_BOOLEAN emptyAuth; ++ ASN1_INTEGER *parent; ++ ASN1_OCTET_STRING *pubkey; ++ ASN1_OCTET_STRING *privkey; ++} TSSPRIVKEY; ++ ++DECLARE_ASN1_FUNCTIONS(TSSPRIVKEY); ++DECLARE_PEM_write_bio(TSSPRIVKEY, TSSPRIVKEY); ++ ++ASN1_SEQUENCE(TSSPRIVKEY) = { ++ ASN1_SIMPLE(TSSPRIVKEY, type, ASN1_OBJECT), ++ ASN1_EXP_OPT(TSSPRIVKEY, emptyAuth, ASN1_BOOLEAN, 0), ++ ASN1_SIMPLE(TSSPRIVKEY, parent, ASN1_INTEGER), ++ ASN1_SIMPLE(TSSPRIVKEY, pubkey, ASN1_OCTET_STRING), ++ ASN1_SIMPLE(TSSPRIVKEY, privkey, ASN1_OCTET_STRING) ++} ASN1_SEQUENCE_END(TSSPRIVKEY) ++ ++#define TSSPRIVKEY_PEM_STRING "TSS2 PRIVATE KEY" ++ ++IMPLEMENT_ASN1_FUNCTIONS(TSSPRIVKEY); ++IMPLEMENT_PEM_write_bio(TSSPRIVKEY, TSSPRIVKEY, TSSPRIVKEY_PEM_STRING, TSSPRIVKEY); ++IMPLEMENT_PEM_read_bio(TSSPRIVKEY, TSSPRIVKEY, TSSPRIVKEY_PEM_STRING, TSSPRIVKEY); ++ ++typedef struct tpm_encodeobject_ctx tpm_encodeobject_ctx; ++struct tpm_encodeobject_ctx { ++ struct { ++ const char *ctx_path; ++ const char *auth_str; ++ tpm2_loaded_object object; ++ } parent; ++ ++ struct { ++ const char *pubpath; ++ TPM2B_PUBLIC public; ++ const char *privpath; ++ TPM2B_PRIVATE private; ++ ESYS_TR handle; ++ } object; ++ ++ char *output_path; ++}; ++ ++static tpm_encodeobject_ctx ctx; ++ ++static bool on_option(char key, char *value) { ++ switch (key) { ++ case 'P': ++ ctx.parent.auth_str = value; ++ break; ++ case 'u': ++ ctx.object.pubpath = value; ++ break; ++ case 'r': ++ ctx.object.privpath = value; ++ break; ++ case 'C': ++ ctx.parent.ctx_path = value; ++ break; ++ case 'o': ++ ctx.output_path = value; ++ break; ++ } ++ ++ return true; ++} ++ ++static bool tpm2_tool_onstart(tpm2_options **opts) { ++ const struct option topts[] = { ++ { "auth", required_argument, NULL, 'P' }, ++ { "public", required_argument, NULL, 'u' }, ++ { "private", required_argument, NULL, 'r' }, ++ { "parent-context", required_argument, NULL, 'C' }, ++ { "output", required_argument, NULL, 'o' }, ++ }; ++ ++ *opts = tpm2_options_new("P:u:r:C:o:", ARRAY_LEN(topts), topts, on_option, ++ NULL, 0); ++ ++ return *opts != NULL; ++} ++ ++static tool_rc check_opts(void) { ++ tool_rc rc = tool_rc_success; ++ if (!ctx.parent.ctx_path) { ++ LOG_ERR("Expected parent object via -C"); ++ rc = tool_rc_option_error; ++ } ++ ++ if (!ctx.object.pubpath) { ++ LOG_ERR("Expected public object portion via -u"); ++ rc = tool_rc_option_error; ++ } ++ ++ if (!ctx.object.privpath) { ++ LOG_ERR("Expected private object portion via -r"); ++ rc = tool_rc_option_error; ++ } ++ ++ if (!ctx.output_path) { ++ LOG_ERR("Expected output file path via -o"); ++ rc = tool_rc_option_error; ++ } ++ ++ return rc; ++} ++ ++static tool_rc init(ESYS_CONTEXT *ectx) { ++ bool res = files_load_public(ctx.object.pubpath, &ctx.object.public); ++ if (!res) { ++ return tool_rc_general_error; ++ } ++ ++ res = files_load_private(ctx.object.privpath, &ctx.object.private); ++ if (!res) { ++ return tool_rc_general_error; ++ } ++ ++ return tpm2_util_object_load_auth(ectx, ctx.parent.ctx_path, ++ ctx.parent.auth_str, &ctx.parent.object, false, ++ TPM2_HANDLE_ALL_W_NV); ++} ++ ++static int ++encode(void) ++{ ++ TSS2_RC rc; ++ BIO *bio = NULL; ++ TSSPRIVKEY *tpk = NULL; ++ ++ uint8_t private_buf[sizeof(ctx.object.private)]; ++ uint8_t public_buf[sizeof(ctx.object.public)]; ++ size_t private_len = 0, public_len = 0; ++ ++ rc = Tss2_MU_TPM2B_PRIVATE_Marshal(&ctx.object.private, private_buf, ++ sizeof(private_buf), &private_len); ++ if (rc) { ++ LOG_ERR("Error serializing private portion of object"); ++ goto error; ++ } ++ ++ rc = Tss2_MU_TPM2B_PUBLIC_Marshal(&ctx.object.public, public_buf, ++ sizeof(public_buf), &public_len); ++ if (rc) { ++ LOG_ERR("Error serializing public portion of object"); ++ goto error; ++ } ++ ++ tpk = TSSPRIVKEY_new(); ++ if (!tpk) { ++ LOG_ERR("oom"); ++ goto error; ++ } ++ ++ tpk->type = OBJ_txt2obj(OID_loadableKey, 1); ++ tpk->parent = ASN1_INTEGER_new(); ++ tpk->privkey = ASN1_OCTET_STRING_new(); ++ tpk->pubkey = ASN1_OCTET_STRING_new(); ++ if (!tpk->type || !tpk->privkey || !tpk->pubkey || !tpk->parent) { ++ LOG_ERR("oom"); ++ goto error; ++ } ++ ++ tpk->emptyAuth = ctx.parent.auth_str == NULL ? 0xFF : 0; ++ ++ if ((ctx.parent.object.handle >> TPM2_HR_SHIFT) == TPM2_HT_PERSISTENT) { ++ ASN1_INTEGER_set(tpk->parent, ctx.parent.object.handle); ++ } else { ++ /* Indicate that the parent is a primary object generated on the fly. */ ++ ASN1_INTEGER_set(tpk->parent, TPM2_RH_OWNER); ++ } ++ ++ ASN1_STRING_set(tpk->privkey, private_buf, private_len); ++ ASN1_STRING_set(tpk->pubkey, public_buf, public_len); ++ ++ if ((bio = BIO_new_file(ctx.output_path, "w")) == NULL) { ++ LOG_ERR("Could not open file: \"%s\"", ctx.output_path); ++ goto error; ++ } ++ ++ PEM_write_bio_TSSPRIVKEY(bio, tpk); ++ TSSPRIVKEY_free(tpk); ++ BIO_free(bio); ++ ++ return tool_rc_success; ++ error: ++ if (bio) ++ BIO_free(bio); ++ if (tpk) ++ TSSPRIVKEY_free(tpk); ++ return tool_rc_general_error; ++} ++ ++static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { ++ UNUSED(flags); ++ ++ tool_rc rc = check_opts(); ++ if (rc != tool_rc_success) { ++ return rc; ++ } ++ ++ rc = init(ectx); ++ if (rc != tool_rc_success) { ++ return rc; ++ } ++ ++ return encode(); ++} ++ ++// Register this tool with tpm2_tool.c ++TPM2_TOOL_REGISTER("encodeobject", tpm2_tool_onstart, tpm2_tool_onrun, NULL, NULL) +-- +2.40.1 + diff --git a/SOURCES/0003-tools-tpm2_evictconrol-fix-for-call-to-Esys_TR_Close.patch b/SOURCES/0003-tools-tpm2_evictconrol-fix-for-call-to-Esys_TR_Close.patch new file mode 100644 index 0000000..990d1d3 --- /dev/null +++ b/SOURCES/0003-tools-tpm2_evictconrol-fix-for-call-to-Esys_TR_Close.patch @@ -0,0 +1,104 @@ +From be8b4cb178332f24fb06f30d3211a24ea3c9e632 Mon Sep 17 00:00:00 2001 +From: Imran Desai +Date: Fri, 3 Sep 2021 11:24:31 -0700 +Subject: [PATCH 03/17] tools/tpm2_evictconrol: fix for call to Esys_TR_Close + on bad handle + +Fixes #2254 + +Signed-off-by: Imran Desai +--- + tools/tpm2_evictcontrol.c | 36 +++++++++++++++--------------------- + 1 file changed, 15 insertions(+), 21 deletions(-) + +diff --git a/tools/tpm2_evictcontrol.c b/tools/tpm2_evictcontrol.c +index 0ae4edc6..8199be39 100644 +--- a/tools/tpm2_evictcontrol.c ++++ b/tools/tpm2_evictcontrol.c +@@ -106,20 +106,18 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + bool evicted = false; + + /* load up the object/handle to work on */ +- tool_rc tmp_rc = tpm2_util_object_load(ectx, ctx.to_persist_key.ctx_path, +- &ctx.to_persist_key.object, TPM2_HANDLE_ALL_W_NV); +- if (tmp_rc != tool_rc_success) { +- rc = tmp_rc; +- goto out; ++ rc = tpm2_util_object_load(ectx, ctx.to_persist_key.ctx_path, ++ &ctx.to_persist_key.object, TPM2_HANDLE_ALL_W_NV); ++ if (rc != tool_rc_success) { ++ return rc; + } + + /* load up the auth hierarchy */ +- tmp_rc = tpm2_util_object_load_auth(ectx, ctx.auth_hierarchy.ctx_path, ++ rc = tpm2_util_object_load_auth(ectx, ctx.auth_hierarchy.ctx_path, + ctx.auth_hierarchy.auth_str, &ctx.auth_hierarchy.object, false, + TPM2_HANDLE_FLAGS_O | TPM2_HANDLE_FLAGS_P); +- if (tmp_rc != tool_rc_success) { +- rc = tmp_rc; +- goto out; ++ if (rc != tool_rc_success) { ++ return rc; + } + + if (ctx.to_persist_key.object.handle >> TPM2_HR_SHIFT +@@ -136,11 +134,10 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + */ + if (ctx.flags.c && !ctx.flags.p) { + bool is_platform = ctx.auth_hierarchy.object.handle == TPM2_RH_PLATFORM; +- tmp_rc = tpm2_capability_find_vacant_persistent_handle(ectx, ++ rc = tpm2_capability_find_vacant_persistent_handle(ectx, + is_platform, &ctx.persist_handle); +- if (tmp_rc != tool_rc_success) { +- rc = tmp_rc; +- goto out; ++ if (rc != tool_rc_success) { ++ return rc; + } + /* we searched and found a persistent handle, so mark that peristent handle valid */ + ctx.flags.p = 1; +@@ -148,7 +145,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + + if (ctx.flags.o && !ctx.flags.p) { + LOG_ERR("Cannot specify -o without using a persistent handle"); +- goto out; ++ return tool_rc_option_error; + } + + ESYS_TR out_tr; +@@ -175,7 +172,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + rc = tpm2_evictcontrol(ectx, &ctx.auth_hierarchy.object, + &ctx.to_persist_key.object, ctx.persist_handle, &out_tr, NULL); + if (rc != tool_rc_success) { +- goto out; ++ return rc; + } + + /* +@@ -191,19 +188,16 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + evicted = out_tr == ESYS_TR_NONE; + tpm2_tool_output("persistent-handle: 0x%x\n", ctx.persist_handle); + tpm2_tool_output("action: %s\n", evicted ? "evicted" : "persisted"); +- ++ tool_rc tmp_rc = tool_rc_success; + if (ctx.output_arg) { +- rc = files_save_ESYS_TR(ectx, out_tr, ctx.output_arg); +- } else { +- rc = tool_rc_success; ++ tmp_rc = files_save_ESYS_TR(ectx, out_tr, ctx.output_arg); + } + +-out: + if (!evicted) { + rc = tpm2_close(ectx, &out_tr); + } + +- return rc; ++ return (tmp_rc == tool_rc_success) ? rc : tmp_rc; + } + + static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) { +-- +2.40.1 + diff --git a/SOURCES/0004-Fix-argument-parsing-in-tpm2_policylocality.patch b/SOURCES/0004-Fix-argument-parsing-in-tpm2_policylocality.patch new file mode 100644 index 0000000..6913a58 --- /dev/null +++ b/SOURCES/0004-Fix-argument-parsing-in-tpm2_policylocality.patch @@ -0,0 +1,45 @@ +From f365a0adca8379ce89ff86fdf740082cf6a56f1b Mon Sep 17 00:00:00 2001 +From: Tien-Ren Chen +Date: Thu, 25 Nov 2021 12:41:52 -0500 +Subject: [PATCH 04/17] Fix argument parsing in tpm2_policylocality + +This patch fixes a bug that caused tpm2_policylocality to almost +always generate PolicyLocality(0). + +There was a logical inversion that caused almost any argument +(including invalid ones) to be interpreted as zero, except "zero" +would be interpreted as one. + +Signed-off-by: Tien-Ren Chen +--- + tools/tpm2_policylocality.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tools/tpm2_policylocality.c b/tools/tpm2_policylocality.c +index 81edbe65..b1d43d02 100644 +--- a/tools/tpm2_policylocality.c ++++ b/tools/tpm2_policylocality.c +@@ -54,15 +54,15 @@ static bool on_arg(int argc, char **argv) { + return false; + } + +- if (strcmp(argv[0], "zero")) { ++ if (strcmp(argv[0], "zero") == 0) { + ctx.locality = TPMA_LOCALITY_TPM2_LOC_ZERO; +- } else if (strcmp(argv[0], "one")) { ++ } else if (strcmp(argv[0], "one") == 0) { + ctx.locality = TPMA_LOCALITY_TPM2_LOC_ONE; +- } else if (strcmp(argv[0], "two")) { ++ } else if (strcmp(argv[0], "two") == 0) { + ctx.locality = TPMA_LOCALITY_TPM2_LOC_TWO; +- } else if (strcmp(argv[0], "three")) { ++ } else if (strcmp(argv[0], "three") == 0) { + ctx.locality = TPMA_LOCALITY_TPM2_LOC_THREE; +- } else if (strcmp(argv[0], "four")) { ++ } else if (strcmp(argv[0], "four") == 0) { + ctx.locality = TPMA_LOCALITY_TPM2_LOC_FOUR; + } else { + bool result = tpm2_util_string_to_uint8(argv[0], &ctx.locality); +-- +2.40.1 + diff --git a/SOURCES/0005-tools-tpm2_tool.c-Fix-an-issue-where-LOG_WARN-is-alw.patch b/SOURCES/0005-tools-tpm2_tool.c-Fix-an-issue-where-LOG_WARN-is-alw.patch new file mode 100644 index 0000000..329a342 --- /dev/null +++ b/SOURCES/0005-tools-tpm2_tool.c-Fix-an-issue-where-LOG_WARN-is-alw.patch @@ -0,0 +1,82 @@ +From 221d8e557ab5a00246f7b09746377819cfbaec5e Mon Sep 17 00:00:00 2001 +From: Imran Desai +Date: Wed, 9 Mar 2022 10:24:45 -0700 +Subject: [PATCH 05/17] tools/tpm2_tool.c: Fix an issue where LOG_WARN is + always displayed + +Despite setting the 'quiet' flag with -Q the warning messages were +always displayed. + +Signed-off-by: Imran Desai +--- + lib/tpm2_options.c | 12 +++++++++--- + tools/tpm2_makecredential.c | 9 ++++++--- + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/lib/tpm2_options.c b/lib/tpm2_options.c +index 8c8af2af..1238e440 100644 +--- a/lib/tpm2_options.c ++++ b/lib/tpm2_options.c +@@ -456,12 +456,16 @@ tpm2_option_code tpm2_handle_options(int argc, char **argv, + + /* tool doesn't request a sapi, don't initialize one */ + if (flags->tcti_none && is_optional_sapi) { +- LOG_WARN("Tool optionally uses SAPI. Continuing with tcti=none"); ++ if (!flags->quiet) { ++ LOG_WARN("Tool optionally uses SAPI. Continuing with tcti=none"); ++ } + goto none; + } + + if (flags->tcti_none && is_no_sapi) { +- LOG_WARN("Tool does not use SAPI. Continuing with tcti=none"); ++ if (!flags->quiet) { ++ LOG_WARN("Tool does not use SAPI. Continuing with tcti=none"); ++ } + goto none; + } + +@@ -481,7 +485,9 @@ tpm2_option_code tpm2_handle_options(int argc, char **argv, + bool is_optional_fake_tcti = (flags->tcti_none && tool_opts && + tool_opts->flags & TPM2_OPTIONS_OPTIONAL_SAPI_AND_FAKE_TCTI); + if (is_optional_fake_tcti) { +- LOG_WARN("Tool optionally uses SAPI. Continuing with tcti=fake"); ++ if (!flags->quiet) { ++ LOG_WARN("Tool optionally uses SAPI. Continuing with tcti=fake"); ++ } + *tcti = (TSS2_TCTI_CONTEXT *)&fake_tcti; + goto none; + } +diff --git a/tools/tpm2_makecredential.c b/tools/tpm2_makecredential.c +index 0b0fa123..5bd5b484 100644 +--- a/tools/tpm2_makecredential.c ++++ b/tools/tpm2_makecredential.c +@@ -310,11 +310,14 @@ static void set_default_TCG_EK_template(TPMI_ALG_PUBLIC alg) { + ctx.public.publicArea.nameAlg = TPM2_ALG_SHA256; + } + +-static tool_rc process_input(void) { ++static tool_rc process_input(tpm2_option_flags flags) { + + TPMI_ALG_PUBLIC alg = TPM2_ALG_NULL; + if (ctx.key_type) { +- LOG_WARN("Because **-G** is specified, assuming input encryption public key is in PEM format."); ++ if (!flags.quiet) { ++ LOG_WARN("Because **-G** is specified, assuming input encryption " ++ "public key is in PEM format."); ++ } + alg = tpm2_alg_util_from_optarg(ctx.key_type, + tpm2_alg_util_flags_asymmetric); + if (alg == TPM2_ALG_ERROR || +@@ -379,7 +382,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + + UNUSED(flags); + +- tool_rc rc = process_input(); ++ tool_rc rc = process_input(flags); + if (rc != tool_rc_success) { + return rc; + } +-- +2.40.1 + diff --git a/SOURCES/0006-import-fix-bug-on-using-scheme.patch b/SOURCES/0006-import-fix-bug-on-using-scheme.patch new file mode 100644 index 0000000..b6fd8a2 --- /dev/null +++ b/SOURCES/0006-import-fix-bug-on-using-scheme.patch @@ -0,0 +1,100 @@ +From acc82191f519f8bcdfcc0827faf024dcd2f56f78 Mon Sep 17 00:00:00 2001 +From: William Roberts +Date: Fri, 20 May 2022 10:49:04 -0500 +Subject: [PATCH 06/17] import: fix bug on using scheme + +When scheme is specified in the template, the openssl load functions +clobber the scheme value and set it to TPM2_ALG_NULL. Only set the +algorithm to NULL if zero value is specified. + +Fixes: #2997 + +Signed-off-by: William Roberts +--- + lib/tpm2_openssl.c | 24 ++++++++++++++++++------ + test/integration/tests/import.sh | 13 +++++++++---- + 2 files changed, 27 insertions(+), 10 deletions(-) + +diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c +index 01bfc9ef..ad43c8e1 100644 +--- a/lib/tpm2_openssl.c ++++ b/lib/tpm2_openssl.c +@@ -534,9 +534,15 @@ static bool load_public_RSA_from_key(EVP_PKEY *key, TPM2B_PUBLIC *pub) { + pt->type = TPM2_ALG_RSA; + + TPMS_RSA_PARMS *rdetail = &pub->publicArea.parameters.rsaDetail; +- rdetail->scheme.scheme = TPM2_ALG_NULL; +- rdetail->symmetric.algorithm = TPM2_ALG_NULL; +- rdetail->scheme.details.anySig.hashAlg = TPM2_ALG_NULL; ++ /* ++ * If the scheme is not TPM2_ALG_ERROR (0), ++ * its a valid scheme so don't set it to NULL scheme ++ */ ++ if (rdetail->scheme.scheme == TPM2_ALG_ERROR) { ++ rdetail->scheme.scheme = TPM2_ALG_NULL; ++ rdetail->symmetric.algorithm = TPM2_ALG_NULL; ++ rdetail->scheme.details.anySig.hashAlg = TPM2_ALG_NULL; ++ } + + /* NULL out sym details */ + TPMT_SYM_DEF_OBJECT *sym = &rdetail->symmetric; +@@ -809,9 +815,15 @@ static bool load_public_ECC_from_key(EVP_PKEY *key, TPM2B_PUBLIC *pub) { + * no kdf - not sure what this should be + */ + pp->kdf.scheme = TPM2_ALG_NULL; +- pp->scheme.scheme = TPM2_ALG_NULL; +- pp->symmetric.algorithm = TPM2_ALG_NULL; +- pp->scheme.details.anySig.hashAlg = TPM2_ALG_NULL; ++ ++ /* ++ * If the scheme is not TPM2_ALG_ERROR (0), ++ * its a valid scheme so don't set it to NULL scheme ++ */ ++ if (pp->scheme.scheme == TPM2_ALG_ERROR) { ++ pp->scheme.scheme = TPM2_ALG_NULL; ++ pp->scheme.details.anySig.hashAlg = TPM2_ALG_NULL; ++ } + + /* NULL out sym details */ + TPMT_SYM_DEF_OBJECT *sym = &pp->symmetric; +diff --git a/test/integration/tests/import.sh b/test/integration/tests/import.sh +index 9f6a474e..9cb6096f 100644 +--- a/test/integration/tests/import.sh ++++ b/test/integration/tests/import.sh +@@ -4,8 +4,8 @@ source helpers.sh + + cleanup() { + rm -f import_key.ctx import_key.name import_key.priv import_key.pub \ +- parent.ctx plain.dec.ssl plain.enc plain.txt sym.key import_rsa_key.pub \ +- import_rsa_key.priv import_rsa_key.ctx import_rsa_key.name private.pem \ ++ parent.ctx plain.dec.ssl plain.enc plain.txt sym.key import_rsa_key*.pub \ ++ import_rsa_key*.priv import_rsa_key.ctx import_rsa_key.name private.pem \ + public.pem plain.rsa.enc plain.rsa.dec public.pem data.in.raw \ + data.in.digest data.out.signed ticket.out ecc.pub ecc.priv ecc.name \ + ecc.ctx private.ecc.pem public.ecc.pem passfile aes.key policy.dat \ +@@ -67,6 +67,10 @@ run_rsa_import_test() { + tpm2 import -Q -G rsa -g "$name_alg" -i private.pem -C $1 \ + -u import_rsa_key.pub -r import_rsa_key.priv + ++ # test in import with scheme and discard ++ tpm2 import -G rsa:rsassa-sha256 -g "$name_alg" -i private.pem -C $1 \ ++ -u import_rsa_key2.pub -r import_rsa_key2.priv | grep -q 'rsassa' ++ + tpm2 load -Q -C $1 -u import_rsa_key.pub -r import_rsa_key.priv \ + -n import_rsa_key.name -c import_rsa_key.ctx + +@@ -118,8 +122,9 @@ run_ecc_import_test() { + shasum -a 256 data.in.raw | awk '{ print "000000 " $1 }' | xxd -r -c 32 > \ + data.in.digest + +- tpm2 import -Q -G ecc -g "$name_alg" -i private.ecc.pem -C $1 -u ecc.pub \ +- -r ecc.priv ++ # test import with scheme ++ tpm2 import -G ecc:ecdsa-sha256 -g "$name_alg" -i private.ecc.pem -C $1 -u ecc.pub \ ++ -r ecc.priv | grep -q 'ecdsa' + + tpm2 load -Q -C $1 -u ecc.pub -r ecc.priv -n ecc.name -c ecc.ctx + +-- +2.40.1 + diff --git a/SOURCES/0007-tpm2_policyor-fix-unallocated-policy-list.patch b/SOURCES/0007-tpm2_policyor-fix-unallocated-policy-list.patch new file mode 100644 index 0000000..1c4b962 --- /dev/null +++ b/SOURCES/0007-tpm2_policyor-fix-unallocated-policy-list.patch @@ -0,0 +1,85 @@ +From d35bff8cf06cec386afd24bdbed9828caf063a2f Mon Sep 17 00:00:00 2001 +From: William Roberts +Date: Mon, 18 Jul 2022 11:31:51 -0500 +Subject: [PATCH 07/17] tpm2_policyor: fix unallocated policy list + +The TPML_DIGEST policy list was calloc'd for some reason, however it +could just be statically allocated in the context. The side effect is +that when no options or arguments were given a NPD occured when checking +the count of the policy list. TO fix this, just statically allocate it. + +Signed-off-by: William Roberts +--- + tools/tpm2_policyor.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/tools/tpm2_policyor.c b/tools/tpm2_policyor.c +index e4f6541b..d27fff8b 100644 +--- a/tools/tpm2_policyor.c ++++ b/tools/tpm2_policyor.c +@@ -14,7 +14,7 @@ struct tpm2_policyor_ctx { + //File path for the session context data + const char *session_path; + //List of policy digests that will be compounded +- TPML_DIGEST *policy_list; ++ TPML_DIGEST policy_list; + //File path for storing the policy digest output + const char *out_policy_dgst_path; + +@@ -36,8 +36,7 @@ static bool on_option(char key, char *value) { + ctx.session_path = value; + break; + case 'l': +- ctx.policy_list = calloc(1, sizeof(TPML_DIGEST)); +- result = tpm2_policy_parse_policy_list(value, ctx.policy_list); ++ result = tpm2_policy_parse_policy_list(value, &ctx.policy_list); + if (!result) { + return false; + } +@@ -54,8 +53,7 @@ static bool on_arg(int argc, char **argv) { + return false; + } + +- ctx.policy_list = calloc(1, sizeof(TPML_DIGEST)); +- bool result = tpm2_policy_parse_policy_list(argv[0], ctx.policy_list); ++ bool result = tpm2_policy_parse_policy_list(argv[0], &ctx.policy_list); + if (!result) { + return false; + } +@@ -85,7 +83,7 @@ static bool is_input_option_args_valid(void) { + } + + //Minimum two policies needed to be specified for compounding +- if (ctx.policy_list->count < 1) { ++ if (ctx.policy_list.count < 1) { + LOG_ERR("Must specify at least 2 policy digests for compounding."); + return false; + } +@@ -109,14 +107,14 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + } + + /* Policy digest hash alg should match that of the session */ +- if (ctx.policy_list->digests[0].size ++ if (ctx.policy_list.digests[0].size + != tpm2_alg_util_get_hash_size( + tpm2_session_get_authhash(ctx.session))) { + LOG_ERR("Policy digest hash alg should match that of the session."); + return tool_rc_general_error; + } + +- rc = tpm2_policy_build_policyor(ectx, ctx.session, ctx.policy_list); ++ rc = tpm2_policy_build_policyor(ectx, ctx.session, &ctx.policy_list); + if (rc != tool_rc_success) { + LOG_ERR("Could not build policyor TPM"); + return rc; +@@ -127,7 +125,6 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + + static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) { + UNUSED(ectx); +- free(ctx.policy_list); + free(ctx.policy_digest); + return tpm2_session_close(&ctx.session); + } +-- +2.40.1 + diff --git a/SOURCES/0008-lib-tpm2_alg_util.c-Fix-potential-null-pointer-deref.patch b/SOURCES/0008-lib-tpm2_alg_util.c-Fix-potential-null-pointer-deref.patch new file mode 100644 index 0000000..b5067d8 --- /dev/null +++ b/SOURCES/0008-lib-tpm2_alg_util.c-Fix-potential-null-pointer-deref.patch @@ -0,0 +1,35 @@ +From cfb18410e8f706646adce2bd9f6cffecbd363d2b Mon Sep 17 00:00:00 2001 +From: Imran Desai +Date: Thu, 21 Jul 2022 15:19:36 -0700 +Subject: [PATCH 08/17] lib/tpm2_alg_util.c: Fix potential null pointer + dereference + +Must test ext_alg_str before dereferencing in +tpm2_alg_util_handle_rsa_ext_alg + +char *ext_alg_str = calloc(1, strlen(alg_spec) + strlen("rsa") + + RSA_KEYBITS_STRLEN) + +Signed-off-by: Imran Desai +--- + lib/tpm2_alg_util.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/tpm2_alg_util.c b/lib/tpm2_alg_util.c +index 1e984d74..580f41cb 100644 +--- a/lib/tpm2_alg_util.c ++++ b/lib/tpm2_alg_util.c +@@ -601,6 +601,10 @@ tool_rc tpm2_alg_util_handle_rsa_ext_alg(const char *alg_spec, + #define RSA_KEYBITS_STRLEN 6 + char *ext_alg_str = calloc(1, strlen(alg_spec) + strlen("rsa") + + RSA_KEYBITS_STRLEN); ++ if (ext_alg_str == NULL) { ++ LOG_ERR("oom"); ++ return tool_rc_general_error; ++ } + + strcat(ext_alg_str, "rsa"); + switch(public->publicArea.parameters.rsaDetail.keyBits) { +-- +2.40.1 + diff --git a/SOURCES/0009-tss2_provision-fix-usage-of-L-parameter.patch b/SOURCES/0009-tss2_provision-fix-usage-of-L-parameter.patch new file mode 100644 index 0000000..ce92907 --- /dev/null +++ b/SOURCES/0009-tss2_provision-fix-usage-of-L-parameter.patch @@ -0,0 +1,30 @@ +From d783e7962e268b45c13ad800fca636bb922005fa Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 18 Oct 2022 10:32:43 +0200 +Subject: [PATCH 09/17] tss2_provision: fix usage of -L parameter. + +The -L short parameter was not marked as parameter with required +arg in the short opt list. +Fixes #3147. + +Signed-off-by: Juergen Repp +--- + tools/fapi/tss2_provision.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/fapi/tss2_provision.c b/tools/fapi/tss2_provision.c +index 5be7b4dc..7edf2dd3 100644 +--- a/tools/fapi/tss2_provision.c ++++ b/tools/fapi/tss2_provision.c +@@ -33,7 +33,7 @@ static bool tss2_tool_onstart(tpm2_options **opts) { + {"authValueSh", required_argument, NULL, 'S'}, + {"authValueLockout", required_argument, NULL, 'L'}, + }; +- return (*opts = tpm2_options_new ("E:S:L", ++ return (*opts = tpm2_options_new ("E:S:L:", + ARRAY_LEN(topts), topts, on_option, NULL, 0)) != NULL; + } + +-- +2.40.1 + diff --git a/SOURCES/0010-tpm2_encodeobject-fix-formatting.patch b/SOURCES/0010-tpm2_encodeobject-fix-formatting.patch new file mode 100644 index 0000000..c1f9cae --- /dev/null +++ b/SOURCES/0010-tpm2_encodeobject-fix-formatting.patch @@ -0,0 +1,26 @@ +From 0582b619c3a2c407bf5eace8d83d832688781789 Mon Sep 17 00:00:00 2001 +From: William Roberts +Date: Mon, 24 Oct 2022 10:31:05 -0500 +Subject: [PATCH 10/17] tpm2_encodeobject: fix formatting + +Signed-off-by: William Roberts +--- + tools/misc/tpm2_encodeobject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/misc/tpm2_encodeobject.c b/tools/misc/tpm2_encodeobject.c +index 2341c3a1..ccbd0e01 100644 +--- a/tools/misc/tpm2_encodeobject.c ++++ b/tools/misc/tpm2_encodeobject.c +@@ -87,7 +87,7 @@ static bool on_option(char key, char *value) { + ctx.parent.ctx_path = value; + break; + case 'o': +- ctx.output_path = value; ++ ctx.output_path = value; + break; + } + +-- +2.40.1 + diff --git a/SOURCES/0011-tpm2_encodeobject-fix-auth-boolean-flag.patch b/SOURCES/0011-tpm2_encodeobject-fix-auth-boolean-flag.patch new file mode 100644 index 0000000..7bbdf93 --- /dev/null +++ b/SOURCES/0011-tpm2_encodeobject-fix-auth-boolean-flag.patch @@ -0,0 +1,99 @@ +From 579bb674b5bdf2a0d50e8d3a3d6f5391d233bdff Mon Sep 17 00:00:00 2001 +From: William Roberts +Date: Mon, 24 Oct 2022 10:48:18 -0500 +Subject: [PATCH 11/17] tpm2_encodeobject: fix auth boolean flag + +The flag for wether or not a key needs a password was being set based on +if the parent needed a password or not when it should be set based on if +the child object needs a password or not. + +Correct this by adding a -p/--key-auth option to indicate the value of +this boolean. + +$ tpm2 encodeobject -C 0x81000000 -u key.pub -r key.priv -o key.pem +$ openssl asn1parse -dump -inform PEM -in key.pem + + 14:d=2 hl=2 l= 1 prim: BOOLEAN :0 + + +$ tpm2 encodeobject -C 0x81000000 -u key.pub -r key.priv -o key.pem -p +$ openssl asn1parse -dump -inform PEM -in key.pem + + 14:d=2 hl=2 l= 1 prim: BOOLEAN :1 + + +A workaround would be manually modifying the ASN1 PEM file boolean flag +OR creating the same parent key but with a password and specifying the +password via `-P`. Note that a primary key is the same given the same +inputs and password doesn't change the generated key. + +Fixes: #3152 + +Signed-off-by: William Roberts +--- + man/tpm2_encodeobject.1.md | 5 +++++ + tools/misc/tpm2_encodeobject.c | 9 +++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/man/tpm2_encodeobject.1.md b/man/tpm2_encodeobject.1.md +index 791eafbd..2e83fa7d 100644 +--- a/man/tpm2_encodeobject.1.md ++++ b/man/tpm2_encodeobject.1.md +@@ -37,6 +37,11 @@ applications. + + A file containing the sensitive portion of the object. + ++ * **-p**, **\--key-auth**: ++ ++ Indicates if an authorization value is needed for the object specified by ++ **-r** and **-u**. ++ + * **-o**, **\--output**=_FILE_: + + The output file path, recording the public portion of the object. +diff --git a/tools/misc/tpm2_encodeobject.c b/tools/misc/tpm2_encodeobject.c +index ccbd0e01..80de14f5 100644 +--- a/tools/misc/tpm2_encodeobject.c ++++ b/tools/misc/tpm2_encodeobject.c +@@ -65,6 +65,7 @@ struct tpm_encodeobject_ctx { + const char *privpath; + TPM2B_PRIVATE private; + ESYS_TR handle; ++ bool needs_auth; + } object; + + char *output_path; +@@ -89,6 +90,9 @@ static bool on_option(char key, char *value) { + case 'o': + ctx.output_path = value; + break; ++ case 'p': ++ ctx.object.needs_auth = true; ++ break; + } + + return true; +@@ -101,9 +105,10 @@ static bool tpm2_tool_onstart(tpm2_options **opts) { + { "private", required_argument, NULL, 'r' }, + { "parent-context", required_argument, NULL, 'C' }, + { "output", required_argument, NULL, 'o' }, ++ { "key-auth", no_argument, NULL, 'p' }, + }; + +- *opts = tpm2_options_new("P:u:r:C:o:", ARRAY_LEN(topts), topts, on_option, ++ *opts = tpm2_options_new("P:u:r:C:o:p", ARRAY_LEN(topts), topts, on_option, + NULL, 0); + + return *opts != NULL; +@@ -190,7 +195,7 @@ encode(void) + goto error; + } + +- tpk->emptyAuth = ctx.parent.auth_str == NULL ? 0xFF : 0; ++ tpk->emptyAuth = ctx.object.needs_auth; + + if ((ctx.parent.object.handle >> TPM2_HR_SHIFT) == TPM2_HT_PERSISTENT) { + ASN1_INTEGER_set(tpk->parent, ctx.parent.object.handle); +-- +2.40.1 + diff --git a/SOURCES/0012-bugfix-fix-convert-sm2-public-key-in-openssl3.patch b/SOURCES/0012-bugfix-fix-convert-sm2-public-key-in-openssl3.patch new file mode 100644 index 0000000..81ffcb4 --- /dev/null +++ b/SOURCES/0012-bugfix-fix-convert-sm2-public-key-in-openssl3.patch @@ -0,0 +1,30 @@ +From 3848000b934b9e2546a506ab0922c028491d2284 Mon Sep 17 00:00:00 2001 +From: mayuanchen <94815698+mayuanchenma@users.noreply.github.com> +Date: Thu, 1 Dec 2022 21:44:22 +0800 +Subject: [PATCH 12/17] bugfix: fix convert sm2 public key in openssl3. + +Signed-off-by: mayuanchen <94815698+mayuanchenma@users.noreply.github.com> +--- + lib/tpm2_convert.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/tpm2_convert.c b/lib/tpm2_convert.c +index 1bba370f..edb9bed0 100644 +--- a/lib/tpm2_convert.c ++++ b/lib/tpm2_convert.c +@@ -335,7 +335,11 @@ EVP_PKEY *convert_pubkey_ECC(TPMT_PUBLIC *public) { + goto out; + } + +- ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); ++ if (nid == NID_sm2) { ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); ++ } else { ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); ++ } + if (!ctx) { + print_ssl_error("Failed to allocate EC key context"); + goto out; +-- +2.40.1 + diff --git a/SOURCES/0013-readpublic-fix-reading-and-writing-serialized-trs.patch b/SOURCES/0013-readpublic-fix-reading-and-writing-serialized-trs.patch new file mode 100644 index 0000000..437a9bf --- /dev/null +++ b/SOURCES/0013-readpublic-fix-reading-and-writing-serialized-trs.patch @@ -0,0 +1,46 @@ +From 62f6cdaa36e1c9e8f39e1ca60d8e3049de6860bf Mon Sep 17 00:00:00 2001 +From: William Roberts +Date: Mon, 27 Feb 2023 15:32:55 -0600 +Subject: [PATCH 13/17] readpublic: fix reading and writing serialized trs + +Fix reading and writing a serialized persistent ESYS_TR handles. This +occurs becuase the TPM2_HANDLE is never set after loading and decisions +are made on it. + +Fixes: +tpm2_readpublic -t handle2.tr -c handle.tr +ERROR: Can only output a serialized handle for persistent object handles +ERROR: Unable to run tpm2_readpublic + +Signed-off-by: William Roberts +--- + lib/object.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/lib/object.c b/lib/object.c +index c186a820..1279a8e5 100644 +--- a/lib/object.c ++++ b/lib/object.c +@@ -15,7 +15,18 @@ static tool_rc do_ctx_file(ESYS_CONTEXT *ctx, const char *objectstr, FILE *f, + /* assign a dummy transient handle */ + outobject->handle = TPM2_TRANSIENT_FIRST; + outobject->path = objectstr; +- return files_load_tpm_context_from_file(ctx, &outobject->tr_handle, f); ++ tool_rc rc = files_load_tpm_context_from_file(ctx, &outobject->tr_handle, f); ++ if (rc != tool_rc_success) { ++ return rc; ++ } ++ ++ TSS2_RC rval = Esys_TR_GetTpmHandle(ctx, outobject->tr_handle, &outobject->handle); ++ if (rval != TPM2_RC_SUCCESS) { ++ LOG_ERR("Failed to acquire SAPI handle"); ++ return tool_rc_general_error; ++ } ++ ++ return tool_rc_success; + } + + static tool_rc tpm2_util_object_load2(ESYS_CONTEXT *ctx, const char *objectstr, +-- +2.40.1 + diff --git a/SOURCES/0014-fix-wrong-function-name-of-Esys_Load.patch b/SOURCES/0014-fix-wrong-function-name-of-Esys_Load.patch new file mode 100644 index 0000000..3e7086a --- /dev/null +++ b/SOURCES/0014-fix-wrong-function-name-of-Esys_Load.patch @@ -0,0 +1,29 @@ +From f1515918ebba36a540432425f7cd01ca3c44aaac Mon Sep 17 00:00:00 2001 +From: yuxiaojun +Date: Wed, 1 Feb 2023 11:47:40 +0800 +Subject: [PATCH 14/17] fix:wrong function name of "Esys_Load" + +LOG_PERR(Eys_Load, rval); +The first parameter in the function should be Esys_Load. + +Signed-off-by: yuxiaojun +--- + lib/tpm2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/tpm2.c b/lib/tpm2.c +index d91072ae..27f101e9 100644 +--- a/lib/tpm2.c ++++ b/lib/tpm2.c +@@ -1921,7 +1921,7 @@ tpm2_load_free_name1: + parent_object_session_handle, ESYS_TR_NONE, ESYS_TR_NONE, in_private, + in_public, object_handle); + if (rval != TPM2_RC_SUCCESS) { +- LOG_PERR(Eys_Load, rval); ++ LOG_PERR(Esys_Load, rval); + return tool_rc_from_tpm(rval); + } + +-- +2.40.1 + diff --git a/SOURCES/0015-tpm-errata-switch-to-twos-complement.patch b/SOURCES/0015-tpm-errata-switch-to-twos-complement.patch new file mode 100644 index 0000000..b90ed76 --- /dev/null +++ b/SOURCES/0015-tpm-errata-switch-to-twos-complement.patch @@ -0,0 +1,224 @@ +From 510d570d9c4f34d4768af3453dcfcc4f74006e32 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Fri, 7 Apr 2023 14:02:33 +0200 +Subject: [PATCH 15/17] tpm errata: switch to twos-complement. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Errata TCG Trusted Platform Module Library Revision 1.59 Version 1.4, +Section 2.5 TPM_EO – two’s complement states: +"The signed arithmetic operations are performed using twos-complement." +The tests policynv and policycountertimer were adapted to work with the +complement representation of signed numbers. If the tests return the error 0x126 +the test will be skipped. + +Signed-off-by: Juergen Repp +--- + .../tests/abrmd_policycountertimer.sh | 35 +++++++-- + test/integration/tests/abrmd_policynv.sh | 75 +++++++++++++------ + 2 files changed, 78 insertions(+), 32 deletions(-) + +diff --git a/test/integration/tests/abrmd_policycountertimer.sh b/test/integration/tests/abrmd_policycountertimer.sh +index 58fcf1b9..80afc541 100644 +--- a/test/integration/tests/abrmd_policycountertimer.sh ++++ b/test/integration/tests/abrmd_policycountertimer.sh +@@ -11,6 +11,27 @@ cleanup() { + fi + } + ++call_policy_countertimer () { ++ trap - ERR ++ output=$(tpm2 policycountertimer $@ 2>&1) ++ result=$? ++ ++ if [ $result != 0 ] && echo $output | grep "ErrorCode.*0126" > /dev/null ++ then ++ echo "This test failed due to a TPM bug regarding signed comparison as described" ++ echo "in TCG's Errata for TCG Trusted Platform Module Library Revision 1.59 Version 1.4," ++ echo "Section 2.5 TPM_EO – two’s complement" ++ tpm2 flushcontext session.ctx ++ skip_test ++ else ++ if [ $result != 0 ]; then ++ tpm2 flushcontext session.ctx ++ exit 1 ++ fi ++ fi ++ trap onerror ERR ++} ++ + trap cleanup EXIT + + start_up +@@ -25,8 +46,7 @@ tpm2 clear + # + tpm2 startauthsession -S session.ctx + +-tpm2 policycountertimer -S session.ctx -L policy.countertimer.minute --ult \ +-60000 ++call_policy_countertimer -S session.ctx -L policy.countertimer.minute --ult 60000 + + tpm2 flushcontext session.ctx + +@@ -42,8 +62,7 @@ tpm2 create -Q -u key.pub -r key.priv -i- -C prim.ctx \ + # + tpm2 startauthsession -S session.ctx --policy-session + +-tpm2 policycountertimer -S session.ctx -L policy.countertimer.minute --ult \ +-60000 ++call_policy_countertimer -S session.ctx -L policy.countertimer.minute --ult 60000 + + tpm2 unseal -c key.ctx -p session:session.ctx + +@@ -54,7 +73,7 @@ tpm2 flushcontext session.ctx + # + tpm2 clear + tpm2 startauthsession -S session.ctx --policy-session +-tpm2 policycountertimer -S session.ctx --ult clock=60000 ++call_policy_countertimer -S session.ctx --ult clock=60000 + tpm2 flushcontext session.ctx + + # +@@ -63,7 +82,7 @@ tpm2 flushcontext session.ctx + # + tpm2 clear + tpm2 startauthsession -S session.ctx --policy-session +-tpm2 policycountertimer -S session.ctx safe ++call_policy_countertimer -S session.ctx safe + tpm2 flushcontext session.ctx + + # +@@ -72,7 +91,7 @@ tpm2 flushcontext session.ctx + # + tpm2 clear + tpm2 startauthsession -S session.ctx --policy-session +-tpm2 policycountertimer -S session.ctx resets=0 ++call_policy_countertimer -S session.ctx resets=0 + tpm2 flushcontext session.ctx + + # +@@ -81,7 +100,7 @@ tpm2 flushcontext session.ctx + # + tpm2 clear + tpm2 startauthsession -S session.ctx --policy-session +-tpm2 policycountertimer -S session.ctx restarts=0 ++call_policy_countertimer -S session.ctx restarts=0 + tpm2 flushcontext session.ctx + + exit 0 +diff --git a/test/integration/tests/abrmd_policynv.sh b/test/integration/tests/abrmd_policynv.sh +index b75cabb8..220edec0 100644 +--- a/test/integration/tests/abrmd_policynv.sh ++++ b/test/integration/tests/abrmd_policynv.sh +@@ -36,10 +36,34 @@ evaluate_failing_test_case() { + } + + evaluate_passing_test_case() { +- tpm2 startauthsession -S session.ctx --policy-session +- echo $operandB | xxd -r -p | \ +- tpm2 policynv -S session.ctx -i- -P nvpass $nv_test_index $1 +- tpm2 flushcontext session.ctx ++ tpm2 startauthsession -S session.ctx --policy-session ++ if [[ ${1:0:1} == "s" ]]; then ++ echo "Test sign: $1 $operandA $operandB" ++ # check whether sign compare fails with 0x126 ++ trap - ERR ++ output=$(echo $operandB | xxd -r -p | \ ++ tpm2 policynv -S session.ctx -i- -P nvpass $nv_test_index $1 2>&1) ++ result=$? ++ if [ $result != 0 ] && echo $output | grep "ErrorCode.*0126" > /dev/null ++ then ++ echo "This test failed due to a TPM bug regarding signed comparison as described" ++ echo "in TCG's Errata for TCG Trusted Platform Module Library Revision 1.59 Version 1.4," ++ echo "Section 2.5 TPM_EO – two’s complement" ++ tpm2 flushcontext session.ctx ++ skip_test ++ else ++ if [ $result != 0 ]; then ++ tpm2 flushcontext session.ctx ++ exit 1 ++ fi ++ fi ++ tpm2 flushcontext session.ctx ++ trap onerror ERR ++ else ++ echo $operandB | xxd -r -p | \ ++ tpm2 policynv -S session.ctx -i- -P nvpass $nv_test_index $1 ++ tpm2 flushcontext session.ctx ++ fi + } + + trap cleanup EXIT +@@ -70,40 +94,20 @@ evaluate_passing_test_case eq + operandB=0x80 + evaluate_passing_test_case neq + +-# Perform comparison operation "sgt" +-operandB=0x82 +-evaluate_passing_test_case sgt +- + # Perform comparison operation "ugt" + operandB=0x80 + evaluate_passing_test_case ugt + +-# Perform comparison operation "slt" +-operandB=0x80 +-evaluate_passing_test_case slt +- + # Perform comparison operation "ult" + operandB=0x82 + evaluate_passing_test_case ult + +-# Perform comparison operation "sge" +-operandB=0x82 +-evaluate_passing_test_case sge +-operandB=0x81 +-evaluate_passing_test_case sge +- + # Perform comparison operation "uge" + operandB=0x80 + evaluate_passing_test_case uge + operandB=0x81 + evaluate_passing_test_case uge + +-# Perform comparison operation "sle" +-operandB=0x80 +-evaluate_passing_test_case sle +-operandB=0x81 +-evaluate_passing_test_case sle +- + # Perform comparison operation "ule" + operandB=0x82 + evaluate_passing_test_case ule +@@ -118,4 +122,27 @@ evaluate_passing_test_case bs + operandB=0x7E + evaluate_passing_test_case bc + ++operandA=0xfe # -1 ++echo $operandA | xxd -r -p | tpm2 nvwrite -P nvpass -i- $nv_test_index ++ ++# Perform comparison operation "sgt" ++operandB=0xfd # -2 ++evaluate_passing_test_case sgt ++ ++# Perform comparison operation "slt" ++operandB=0xff # 0 ++evaluate_passing_test_case slt ++ ++# Perform comparison operation "sle" ++operandB=0xff #0 ++evaluate_passing_test_case sle ++operandB=0xfe # -1 ++evaluate_passing_test_case sle ++ ++# Perform comparison operation "sge" ++operandB=0xfd # -2 ++evaluate_passing_test_case sge ++operandB=0xfe # -1 ++evaluate_passing_test_case sge ++ + exit 0 +-- +2.40.1 + diff --git a/SOURCES/0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch b/SOURCES/0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch new file mode 100644 index 0000000..857eb07 --- /dev/null +++ b/SOURCES/0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch @@ -0,0 +1,159 @@ +From 2f6a737efddce480803c02a5e3b65ce739c6acf2 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 28 Mar 2023 17:29:36 +0200 +Subject: [PATCH 16/17] tpm2_eventlog.c Fix pcr extension for EV_NO_ACTION + +EV_NO_ACTION events should not be extended to PCR registers. +Fixes: #3224 + +Signed-off-by: Juergen Repp +--- + lib/tpm2_eventlog.c | 14 +++++++++----- + lib/tpm2_eventlog.h | 2 +- + test/unit/test_tpm2_eventlog.c | 15 ++++++++------- + 3 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/lib/tpm2_eventlog.c b/lib/tpm2_eventlog.c +index 1b59eeeb..e2e27f02 100644 +--- a/lib/tpm2_eventlog.c ++++ b/lib/tpm2_eventlog.c +@@ -30,7 +30,8 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + * hold the digest. The size of the digest is passed to the callback in the + * 'size' parameter. + */ +-bool foreach_digest2(tpm2_eventlog_context *ctx, unsigned pcr_index, TCG_DIGEST2 const *digest, size_t count, size_t size) { ++bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, ++ TCG_DIGEST2 const *digest, size_t count, size_t size) { + + if (digest == NULL) { + LOG_ERR("digest cannot be NULL"); +@@ -80,7 +81,8 @@ bool foreach_digest2(tpm2_eventlog_context *ctx, unsigned pcr_index, TCG_DIGEST2 + LOG_WARN("PCR%d algorithm %d unsupported", pcr_index, alg); + } + +- if (pcr && !tpm2_openssl_pcr_extend(alg, pcr, digest->Digest, alg_size)) { ++ if (eventType != EV_NO_ACTION && pcr && ++ !tpm2_openssl_pcr_extend(alg, pcr, digest->Digest, alg_size)) { + LOG_ERR("PCR%d extend failed", pcr_index); + return false; + } +@@ -179,7 +181,8 @@ bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + .data = digests_size, + .digest2_cb = digest2_accumulator_callback, + }; +- ret = foreach_digest2(&ctx, eventhdr->PCRIndex, ++ ret = foreach_digest2(&ctx, eventhdr->EventType, ++ eventhdr->PCRIndex, + eventhdr->Digests, eventhdr->DigestCount, + buf_size - sizeof(*eventhdr)); + if (ret != true) { +@@ -216,7 +219,7 @@ bool parse_sha1_log_event(tpm2_eventlog_context *ctx, TCG_EVENT const *event, si + *event_size = sizeof(*event); + + pcr = ctx->sha1_pcrs[ event->pcrIndex]; +- if (pcr) { ++ if (event->eventType != EV_NO_ACTION && pcr) { + tpm2_openssl_pcr_extend(TPM2_ALG_SHA1, pcr, &event->digest[0], 20); + ctx->sha1_used |= (1 << event->pcrIndex); + } +@@ -451,7 +454,8 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + } + + /* digest callback foreach digest */ +- ret = foreach_digest2(ctx, eventhdr->PCRIndex, eventhdr->Digests, eventhdr->DigestCount, digests_size); ++ ret = foreach_digest2(ctx, eventhdr->EventType, eventhdr->PCRIndex, ++ eventhdr->Digests, eventhdr->DigestCount, digests_size); + if (ret != true) { + return false; + } +diff --git a/lib/tpm2_eventlog.h b/lib/tpm2_eventlog.h +index 2a91ed60..f141e806 100644 +--- a/lib/tpm2_eventlog.h ++++ b/lib/tpm2_eventlog.h +@@ -44,7 +44,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + void *data); + + bool parse_event2body(TCG_EVENT2 const *event, UINT32 type); +-bool foreach_digest2(tpm2_eventlog_context *ctx, unsigned pcr_index, ++bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, + TCG_DIGEST2 const *event_hdr, size_t count, size_t size); + bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + size_t *event_size, size_t *digests_size); +diff --git a/test/unit/test_tpm2_eventlog.c b/test/unit/test_tpm2_eventlog.c +index ebf50e80..e48404d8 100644 +--- a/test/unit/test_tpm2_eventlog.c ++++ b/test/unit/test_tpm2_eventlog.c +@@ -27,7 +27,7 @@ static void test_foreach_digest2_null(void **state){ + (void)state; + tpm2_eventlog_context ctx = {0}; + +- assert_false(foreach_digest2(&ctx, 0, NULL, 0, sizeof(TCG_DIGEST2))); ++ assert_false(foreach_digest2(&ctx, 0, 0, NULL, 0, sizeof(TCG_DIGEST2))); + } + static void test_foreach_digest2_size(void **state) { + +@@ -36,7 +36,7 @@ static void test_foreach_digest2_size(void **state) { + TCG_DIGEST2 *digest = (TCG_DIGEST2*)buf; + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; + +- assert_false(foreach_digest2(&ctx, 0, digest, 1, sizeof(TCG_DIGEST2) - 1)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, sizeof(TCG_DIGEST2) - 1)); + } + static void test_foreach_digest2(void **state) { + +@@ -47,7 +47,7 @@ static void test_foreach_digest2(void **state) { + will_return(foreach_digest2_test_callback, true); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_true(foreach_digest2(&ctx, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); + } + static void test_foreach_digest2_cbnull(void **state){ + +@@ -56,7 +56,7 @@ static void test_foreach_digest2_cbnull(void **state){ + TCG_DIGEST2* digest = (TCG_DIGEST2*)buf; + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); + } + static void test_sha1(void **state){ + +@@ -73,7 +73,7 @@ static void test_sha1(void **state){ + memcpy(digest->Digest, "the magic words are:", TPM2_SHA1_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE)); + assert_memory_equal(ctx.sha1_pcrs[pcr_index], sha1sum, sizeof(sha1sum)); + } + static void test_sha256(void **state){ +@@ -93,7 +93,7 @@ static void test_sha256(void **state){ + memcpy(digest->Digest, "The Magic Words are Squeamish Ossifrage, for RSA-129 (from 1977)", TPM2_SHA256_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE)); + assert_memory_equal(ctx.sha256_pcrs[pcr_index], sha256sum, sizeof(sha256sum)); + } + static void test_foreach_digest2_cbfail(void **state){ +@@ -105,7 +105,7 @@ static void test_foreach_digest2_cbfail(void **state){ + will_return(foreach_digest2_test_callback, false); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_false(foreach_digest2(&ctx, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); + } + static void test_digest2_accumulator_callback(void **state) { + +@@ -292,6 +292,7 @@ static void test_foreach_event2_parse_event2body_fail(void **state){ + + eventhdr->DigestCount = 1; + eventhdr->EventType = EV_EFI_VARIABLE_BOOT; ++ eventhdr->PCRIndex = 0; + digest->AlgorithmId = TPM2_ALG_SHA1; + event->EventSize = 1; + +-- +2.40.1 + diff --git a/SOURCES/0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch b/SOURCES/0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch new file mode 100644 index 0000000..ae7b17e --- /dev/null +++ b/SOURCES/0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch @@ -0,0 +1,52 @@ +From 72b6a5497df8757987dfedd6263346154adb921e Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Mon, 6 Mar 2023 12:16:05 +0100 +Subject: [PATCH 17/17] kdfa.c Fix problem with FORTIFY_SOURCE on Fedora + +The original kdfa implementation did produce an error caused by the flags +-flto -_FORTIFY_SOURCE=3 on Fedora rawhide. +This error can be avoided by switching off the optimization with pragma. +Fixes: #3210. + +Signed-off-by: Juergen Repp +--- + lib/tpm2_kdfa.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/lib/tpm2_kdfa.c b/lib/tpm2_kdfa.c +index 5eb8d558..e97c06f6 100644 +--- a/lib/tpm2_kdfa.c ++++ b/lib/tpm2_kdfa.c +@@ -13,6 +13,15 @@ + #include "tpm2_kdfa.h" + #include "tpm2_openssl.h" + ++/* ++ * Disable optimization because of an error in FORTIFY_SOURCE ++ */ ++ ++#ifdef _FORTIFY_SOURCE ++#pragma GCC push_options ++#pragma GCC optimize ("O0") ++#endif ++ + TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label, + TPM2B *context_u, TPM2B *context_v, UINT16 bits, + TPM2B_MAX_BUFFER *result_key) { +@@ -139,3 +148,13 @@ err: + + return rval; + } ++#ifdef _FORTIFY_SOURCE ++ ++#endif ++ ++#ifdef _FORTIFY_SOURCE ++#pragma GCC pop_options ++#endif ++ ++ ++ +-- +2.40.1 + diff --git a/SOURCES/add_pregenerated_doc.patch b/SOURCES/add_pregenerated_doc.patch new file mode 100644 index 0000000..a5755fb --- /dev/null +++ b/SOURCES/add_pregenerated_doc.patch @@ -0,0 +1,434 @@ +diff --git a/man/man1/tpm2_encodeobject.1 b/man/man1/tpm2_encodeobject.1 +new file mode 100644 +index 00000000..9b616bb0 +--- /dev/null ++++ b/man/man1/tpm2_encodeobject.1 +@@ -0,0 +1,428 @@ ++.\" Automatically generated by Pandoc 2.5 ++.\" ++.TH "tpm2_encodeobject" "1" "" "tpm2\-tools" "General Commands Manual" ++.hy ++.SH NAME ++.PP ++\f[B]tpm2_encodeobject\f[R](1) \- Encode an object into a combined PEM ++format. ++.SH SYNOPSIS ++.PP ++\f[B]tpm2_encodeobject\f[R] [\f[I]OPTIONS\f[R]] ++.SH DESCRIPTION ++.PP ++\f[B]tpm2_encodeobject\f[R](1) \- Encode both the private and public ++portions of an object into a combined PEM format used by ++tpm2\-tss\-engine. ++.PP ++The tool reads private and public portions of an object and encodes it ++into a combined PEM format used by tpm2\-tss\-engine and other ++applications. ++.PP ++\f[B]NOTE\f[R]: Both private and public portions of the tpm key must be ++specified. ++.SH OPTIONS ++.IP \[bu] 2 ++\f[B]\-C\f[R], \f[B]\-\-parent\-context\f[R]=\f[I]OBJECT\f[R]: ++.RS 2 ++.PP ++The parent object. ++.RE ++.IP \[bu] 2 ++\f[B]\-P\f[R], \f[B]\-\-auth\f[R]=\f[I]AUTH\f[R]: ++.RS 2 ++.PP ++The authorization value of the parent object specified by \f[B]\-C\f[R]. ++.RE ++.IP \[bu] 2 ++\f[B]\-u\f[R], \f[B]\-\-public\f[R]=\f[I]FILE\f[R]: ++.RS 2 ++.PP ++A file containing the public portion of the object. ++.RE ++.IP \[bu] 2 ++\f[B]\-r\f[R], \f[B]\-\-private\f[R]=\f[I]FILE\f[R]: ++.RS 2 ++.PP ++A file containing the sensitive portion of the object. ++.RE ++.IP \[bu] 2 ++\f[B]\-p\f[R], \f[B]\-\-key\-auth\f[R]: ++.RS 2 ++.PP ++Indicates if an authorization value is needed for the object specified ++by \f[B]\-r\f[R] and \f[B]\-u\f[R]. ++.RE ++.IP \[bu] 2 ++\f[B]\-o\f[R], \f[B]\-\-output\f[R]=\f[I]FILE\f[R]: ++.RS 2 ++.PP ++The output file path, recording the public portion of the object. ++.RE ++.SS References ++.SH Context Object Format ++.PP ++The type of a context object, whether it is a handle or file name, is ++determined according to the following logic \f[I]in\-order\f[R]: ++.IP \[bu] 2 ++If the argument is a file path, then the file is loaded as a restored ++TPM transient object. ++.IP \[bu] 2 ++If the argument is a \f[I]prefix\f[R] match on one of: ++.RS 2 ++.IP \[bu] 2 ++owner: the owner hierarchy ++.IP \[bu] 2 ++platform: the platform hierarchy ++.IP \[bu] 2 ++endorsement: the endorsement hierarchy ++.IP \[bu] 2 ++lockout: the lockout control persistent object ++.RE ++.IP \[bu] 2 ++If the argument argument can be loaded as a number it will be treat as a ++handle, e.g.\ 0x81010013 and used directly._OBJECT_. ++.SH Authorization Formatting ++.PP ++Authorization for use of an object in TPM2.0 can come in 3 different ++forms: 1. ++Password 2. ++HMAC 3. ++Sessions ++.PP ++\f[B]NOTE:\f[R] \[lq]Authorizations default to the \f[B]EMPTY ++PASSWORD\f[R] when not specified\[rq]. ++.SS Passwords ++.PP ++Passwords are interpreted in the following forms below using prefix ++identifiers. ++.PP ++\f[B]Note\f[R]: By default passwords are assumed to be in the string ++form when they do not have a prefix. ++.SS String ++.PP ++A string password, specified by prefix \[lq]str:\[rq] or it\[cq]s ++absence (raw string without prefix) is not interpreted, and is directly ++used for authorization. ++.SS Examples ++.IP ++.nf ++\f[C] ++foobar ++str:foobar ++\f[R] ++.fi ++.SS Hex\-string ++.PP ++A hex\-string password, specified by prefix \[lq]hex:\[rq] is converted ++from a hexidecimal form into a byte array form, thus allowing passwords ++with non\-printable and/or terminal un\-friendly characters. ++.SS Example ++.IP ++.nf ++\f[C] ++hex:1122334455667788 ++\f[R] ++.fi ++.SS File ++.PP ++A file based password, specified be prefix \[lq]file:\[rq] should be the ++path of a file containing the password to be read by the tool or a ++\[lq]\-\[rq] to use stdin. ++Storing passwords in files prevents information leakage, passwords ++passed as options can be read from the process list or common shell ++history features. ++.SS Examples ++.IP ++.nf ++\f[C] ++# to use stdin and be prompted ++file:\- ++ ++# to use a file from a path ++file:path/to/password/file ++ ++# to echo a password via stdin: ++echo foobar | tpm2_tool \-p file:\- ++ ++# to use a bash here\-string via stdin: ++ ++tpm2_tool \-p file:\- <<< foobar ++\f[R] ++.fi ++.SS Sessions ++.PP ++When using a policy session to authorize the use of an object, prefix ++the option argument with the \f[I]session\f[R] keyword. ++Then indicate a path to a session file that was created with ++tpm2_startauthsession(1). ++Optionally, if the session requires an auth value to be sent with the ++session handle (eg policy password), then append a + and a string as ++described in the \f[B]Passwords\f[R] section. ++.SS Examples ++.PP ++To use a session context file called \f[I]session.ctx\f[R]. ++.IP ++.nf ++\f[C] ++session:session.ctx ++\f[R] ++.fi ++.PP ++To use a session context file called \f[I]session.ctx\f[R] \f[B]AND\f[R] ++send the authvalue mypassword. ++.IP ++.nf ++\f[C] ++session:session.ctx+mypassword ++\f[R] ++.fi ++.PP ++To use a session context file called \f[I]session.ctx\f[R] \f[B]AND\f[R] ++send the \f[I]HEX\f[R] authvalue 0x11223344. ++.IP ++.nf ++\f[C] ++session:session.ctx+hex:11223344 ++\f[R] ++.fi ++.SS PCR Authorizations ++.PP ++You can satisfy a PCR policy using the \[lq]pcr:\[rq] prefix and the PCR ++minilanguage. ++The PCR minilanguage is as follows: ++\f[C]=\f[R] ++.PP ++The PCR spec is documented in in the section \[lq]PCR bank ++specifiers\[rq]. ++.PP ++The \f[C]raw\-pcr\-file\f[R] is an \f[B]optional\f[R] argument that ++contains the output of the raw PCR contents as returned by ++\f[I]tpm2_pcrread(1)\f[R]. ++.PP ++PCR bank specifiers (pcr.md) ++.SS Examples ++.PP ++To satisfy a PCR policy of sha256 on banks 0, 1, 2 and 3 use a specifier ++of: ++.IP ++.nf ++\f[C] ++pcr:sha256:0,1,2,3 ++\f[R] ++.fi ++.PP ++specifying \f[I]AUTH\f[R]. ++.SH COMMON OPTIONS ++.PP ++This collection of options are common to many programs and provide ++information that many users may expect. ++.IP \[bu] 2 ++\f[B]\-h\f[R], \f[B]\-\-help=[man|no\-man]\f[R]: Display the tools ++manpage. ++By default, it attempts to invoke the manpager for the tool, however, on ++failure will output a short tool summary. ++This is the same behavior if the \[lq]man\[rq] option argument is ++specified, however if explicit \[lq]man\[rq] is requested, the tool will ++provide errors from man on stderr. ++If the \[lq]no\-man\[rq] option if specified, or the manpager fails, the ++short options will be output to stdout. ++.RS 2 ++.PP ++To successfully use the manpages feature requires the manpages to be ++installed or on \f[I]MANPATH\f[R], See man(1) for more details. ++.RE ++.IP \[bu] 2 ++\f[B]\-v\f[R], \f[B]\-\-version\f[R]: Display version information for ++this tool, supported tctis and exit. ++.IP \[bu] 2 ++\f[B]\-V\f[R], \f[B]\-\-verbose\f[R]: Increase the information that the ++tool prints to the console during its execution. ++When using this option the file and line number are printed. ++.IP \[bu] 2 ++\f[B]\-Q\f[R], \f[B]\-\-quiet\f[R]: Silence normal tool output to ++stdout. ++.IP \[bu] 2 ++\f[B]\-Z\f[R], \f[B]\-\-enable\-errata\f[R]: Enable the application of ++errata fixups. ++Useful if an errata fixup needs to be applied to commands sent to the ++TPM. ++Defining the environment TPM2TOOLS_ENABLE_ERRATA is equivalent. ++information many users may expect. ++.SH TCTI Configuration ++.PP ++The TCTI or \[lq]Transmission Interface\[rq] is the communication ++mechanism with the TPM. ++TCTIs can be changed for communication with TPMs across different ++mediums. ++.PP ++To control the TCTI, the tools respect: ++.IP "1." 3 ++The command line option \f[B]\-T\f[R] or \f[B]\-\-tcti\f[R] ++.IP "2." 3 ++The environment variable: \f[I]TPM2TOOLS_TCTI\f[R]. ++.PP ++\f[B]Note:\f[R] The command line option always overrides the environment ++variable. ++.PP ++The current known TCTIs are: ++.IP \[bu] 2 ++tabrmd \- The resource manager, called ++tabrmd (https://github.com/tpm2-software/tpm2-abrmd). ++Note that tabrmd and abrmd as a tcti name are synonymous. ++.IP \[bu] 2 ++mssim \- Typically used for communicating to the TPM software simulator. ++.IP \[bu] 2 ++device \- Used when talking directly to a TPM device file. ++.IP \[bu] 2 ++none \- Do not initalize a connection with the TPM. ++Some tools allow for off\-tpm options and thus support not using a TCTI. ++Tools that do not support it will error when attempted to be used ++without a TCTI connection. ++Does not support \f[I]ANY\f[R] options and \f[I]MUST BE\f[R] presented ++as the exact text of \[lq]none\[rq]. ++.PP ++The arguments to either the command line option or the environment ++variable are in the form: ++.PP ++\f[C]:\f[R] ++.PP ++Specifying an empty string for either the \f[C]\f[R] or ++\f[C]\f[R] results in the default being used for ++that portion respectively. ++.SS TCTI Defaults ++.PP ++When a TCTI is not specified, the default TCTI is searched for using ++\f[I]dlopen(3)\f[R] semantics. ++The tools will search for \f[I]tabrmd\f[R], \f[I]device\f[R] and ++\f[I]mssim\f[R] TCTIs \f[B]IN THAT ORDER\f[R] and \f[B]USE THE FIRST ONE ++FOUND\f[R]. ++You can query what TCTI will be chosen as the default by using the ++\f[B]\-v\f[R] option to print the version information. ++The \[lq]default\-tcti\[rq] key\-value pair will indicate which of the ++aforementioned TCTIs is the default. ++.SS Custom TCTIs ++.PP ++Any TCTI that implements the dynamic TCTI interface can be loaded. ++The tools internally use \f[I]dlopen(3)\f[R], and the raw ++\f[I]tcti\-name\f[R] value is used for the lookup. ++Thus, this could be a path to the shared library, or a library name as ++understood by \f[I]dlopen(3)\f[R] semantics. ++.SH TCTI OPTIONS ++.PP ++This collection of options are used to configure the various known TCTI ++modules available: ++.IP \[bu] 2 ++\f[B]device\f[R]: For the device TCTI, the TPM character device file for ++use by the device TCTI can be specified. ++The default is \f[I]/dev/tpm0\f[R]. ++.RS 2 ++.PP ++Example: \f[B]\-T device:/dev/tpm0\f[R] or \f[B]export ++\f[BI]TPM2TOOLS_TCTI\f[B]=\[lq]device:/dev/tpm0\[rq]\f[R] ++.RE ++.IP \[bu] 2 ++\f[B]mssim\f[R]: For the mssim TCTI, the domain name or IP address and ++port number used by the simulator can be specified. ++The default are 127.0.0.1 and 2321. ++.RS 2 ++.PP ++Example: \f[B]\-T mssim:host=localhost,port=2321\f[R] or \f[B]export ++\f[BI]TPM2TOOLS_TCTI\f[B]=\[lq]mssim:host=localhost,port=2321\[rq]\f[R] ++.RE ++.IP \[bu] 2 ++\f[B]abrmd\f[R]: For the abrmd TCTI, the configuration string format is ++a series of simple key value pairs separated by a `,' character. ++Each key and value string are separated by a `=' character. ++.RS 2 ++.IP \[bu] 2 ++TCTI abrmd supports two keys: ++.RS 2 ++.IP "1." 3 ++`bus_name' : The name of the tabrmd service on the bus (a string). ++.IP "2." 3 ++`bus_type' : The type of the dbus instance (a string) limited to ++`session' and `system'. ++.RE ++.PP ++Specify the tabrmd tcti name and a config string of ++\f[C]bus_name=com.example.FooBar\f[R]: ++.IP ++.nf ++\f[C] ++\[rs]\-\-tcti=tabrmd:bus_name=com.example.FooBar ++\f[R] ++.fi ++.PP ++Specify the default (abrmd) tcti and a config string of ++\f[C]bus_type=session\f[R]: ++.IP ++.nf ++\f[C] ++\[rs]\-\-tcti:bus_type=session ++\f[R] ++.fi ++.PP ++\f[B]NOTE\f[R]: abrmd and tabrmd are synonymous. ++the various known TCTI modules. ++.RE ++.SH EXAMPLES ++.SS Setup ++.PP ++To load an object you first must create an object under a primary ++object. ++So the first step is to create the primary object. ++.IP ++.nf ++\f[C] ++tpm2_createprimary \-c primary.ctx ++\f[R] ++.fi ++.PP ++Step 2 is to create an object under the primary object. ++.IP ++.nf ++\f[C] ++tpm2_create \-C primary.ctx \-u key.pub \-r key.priv \-f pem \-o pub.pem ++\f[R] ++.fi ++.PP ++This creates the private and public portions of the TPM object. ++With these object portions, it is now possible to load that object into ++the TPM for subsequent use. ++.SS Encoding an Object into a combined PEM format ++.PP ++The final step, is encoding the public and private portions of the ++object into a PEM format. ++.IP ++.nf ++\f[C] ++tpm2_encodeobject \-C primary.ctx \-u key.pub \-r key.priv \-o priv.pem ++\f[R] ++.fi ++.PP ++The generated \f[C]priv.pem\f[R] can be used together with ++\f[C]pub.pem\f[R] created in the step 2 of Setup section. ++.SH Returns ++.PP ++Tools can return any of the following codes: ++.IP \[bu] 2 ++0 \- Success. ++.IP \[bu] 2 ++1 \- General non\-specific error. ++.IP \[bu] 2 ++2 \- Options handling error. ++.IP \[bu] 2 ++3 \- Authentication error. ++.IP \[bu] 2 ++4 \- TCTI related error. ++.IP \[bu] 2 ++5 \- Non supported scheme. ++Applicable to tpm2_testparams. ++.SH BUGS ++.PP ++Github Issues (https://github.com/tpm2-software/tpm2-tools/issues) ++.SH HELP ++.PP ++See the Mailing ++List (https://lists.linuxfoundation.org/mailman/listinfo/tpm2) diff --git a/SPECS/tpm2-tools.spec b/SPECS/tpm2-tools.spec index ceccd36..837b621 100644 --- a/SPECS/tpm2-tools.spec +++ b/SPECS/tpm2-tools.spec @@ -2,7 +2,7 @@ Name: tpm2-tools Version: 5.2 -Release: 2%{?candidate:.%{candidate}}%{?dist} +Release: 3%{?candidate:.%{candidate}}%{?dist} Summary: A bunch of TPM testing toolS build upon tpm2-tss License: BSD @@ -20,6 +20,24 @@ Patch8: 0006-test-track-expected-YAML-output-for-eventlog.patch Patch9: 0007-tpm2_eventlog_yaml-fix-parsing-for-MokListTrusted.patch Patch10: 0008-tests-add-eventlog-for-parsing-MokListTrusted.patch Patch11: 0009-tpm2_eventlog_yaml-use-defines-for-Unicode-variables.patch +Patch101: 0001-Fix-nv_readpublic.patch +Patch102: 0002-tpm2_encodeobject-New-tool-to-encode-TPM2-object.patch +Patch103: 0003-tools-tpm2_evictconrol-fix-for-call-to-Esys_TR_Close.patch +Patch104: 0004-Fix-argument-parsing-in-tpm2_policylocality.patch +Patch105: 0005-tools-tpm2_tool.c-Fix-an-issue-where-LOG_WARN-is-alw.patch +Patch106: 0006-import-fix-bug-on-using-scheme.patch +Patch107: 0007-tpm2_policyor-fix-unallocated-policy-list.patch +Patch108: 0008-lib-tpm2_alg_util.c-Fix-potential-null-pointer-deref.patch +Patch109: 0009-tss2_provision-fix-usage-of-L-parameter.patch +Patch110: 0010-tpm2_encodeobject-fix-formatting.patch +Patch111: 0011-tpm2_encodeobject-fix-auth-boolean-flag.patch +Patch112: 0012-bugfix-fix-convert-sm2-public-key-in-openssl3.patch +Patch113: 0013-readpublic-fix-reading-and-writing-serialized-trs.patch +Patch114: 0014-fix-wrong-function-name-of-Esys_Load.patch +Patch115: 0015-tpm-errata-switch-to-twos-complement.patch +Patch116: 0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch +Patch117: 0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch +Patch118: add_pregenerated_doc.patch BuildRequires: git BuildRequires: make @@ -71,6 +89,12 @@ autoreconf -i %{_mandir}/man1/tss2_*.1.gz %changelog +* Wed May 24 2023 Štěpán Horáček - 5.2-3 +- Backport fixes. +- Add tpm2_encodeobject tool. + Resolves: rhbz#2160304 + Resolves: rhbz#2047342 + * Wed Oct 19 2022 Štěpán Horáček - 5.2-2 - Fix eventlog output. Resolves: rhbz#2136215