From 56d1d5c1ab21c11cf9a91aa3aaccace1465d3346 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Mon, 20 Mar 2023 18:49:56 +0200 Subject: [PATCH 01/10] attrs: synchronize CKA_TPM2_* in C and Python This makes it easier to add new vendor attributes without accidentally reusing the same constant value and making implementations incompatible. Signed-off-by: Sergii Dmytruk --- tools/tpm2_pkcs11/pkcs11t.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tpm2_pkcs11/pkcs11t.py b/tools/tpm2_pkcs11/pkcs11t.py index 36598933..44850d08 100644 --- a/tools/tpm2_pkcs11/pkcs11t.py +++ b/tools/tpm2_pkcs11/pkcs11t.py @@ -110,6 +110,7 @@ CKA_TPM2_OBJAUTH_ENC=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x1 CKA_TPM2_PUB_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x2 CKA_TPM2_PRIV_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x3 +CKA_TPM2_ENC_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x4 CKC_X_509 = 0 From 81bb0f0ad395a2c78a7ec72b49e93a1edab6e6fa Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Mon, 20 Mar 2023 18:53:47 +0200 Subject: [PATCH 02/10] attrs: add CKA_TPM2_POLICY_JSON To be used as a storage of TPM policy in JSON formed understood by tpm2-tss libpolicy library. Signed-off-by: Sergii Dmytruk --- src/lib/attrs.c | 1 + src/lib/attrs.h | 1 + tools/tpm2_pkcs11/pkcs11t.py | 1 + 3 files changed, 3 insertions(+) diff --git a/src/lib/attrs.c b/src/lib/attrs.c index 0c81e6a4..2ddcd1b1 100644 --- a/src/lib/attrs.c +++ b/src/lib/attrs.c @@ -171,6 +171,7 @@ static attr_handler2 attr_handlers[] = { ADD_ATTR_HANDLER(CKA_TPM2_PUB_BLOB, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_PRIV_BLOB, TYPE_BYTE_HEX_STR), ADD_ATTR_HANDLER(CKA_TPM2_ENC_BLOB, TYPE_BYTE_HEX_STR), + ADD_ATTR_HANDLER(CKA_TPM2_POLICY_JSON, TYPE_BYTE_HEX_STR), }; static attr_handler2 default_handler = { .memtype = 0, .name="UNKNOWN" }; diff --git a/src/lib/attrs.h b/src/lib/attrs.h index c0c542c5..7cf4e1aa 100644 --- a/src/lib/attrs.h +++ b/src/lib/attrs.h @@ -15,6 +15,7 @@ #define CKA_TPM2_PUB_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x2UL) #define CKA_TPM2_PRIV_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x3UL) #define CKA_TPM2_ENC_BLOB (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x4UL) +#define CKA_TPM2_POLICY_JSON (CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x5UL) /* Invalid values for error detection */ #define CK_OBJECT_CLASS_BAD (~(CK_OBJECT_CLASS)0) diff --git a/tools/tpm2_pkcs11/pkcs11t.py b/tools/tpm2_pkcs11/pkcs11t.py index 44850d08..a06cf90e 100644 --- a/tools/tpm2_pkcs11/pkcs11t.py +++ b/tools/tpm2_pkcs11/pkcs11t.py @@ -111,6 +111,7 @@ CKA_TPM2_PUB_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x2 CKA_TPM2_PRIV_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x3 CKA_TPM2_ENC_BLOB=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x4 +CKA_TPM2_POLICY_JSON=CKA_VENDOR_DEFINED|CKA_VENDOR_TPM2_DEFINED|0x5 CKC_X_509 = 0 From edaa1d97e8498894df3569cf3f67bb40183a659c Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 21 Mar 2023 18:36:44 +0200 Subject: [PATCH 03/10] tpm2_ptool: add objpol command for object policies Policies are expected to be specified in JSON format. The command allows reading, writing or deleting policy set on an object. Signed-off-by: Sergii Dmytruk --- tools/tpm2_pkcs11/commandlets_keys.py | 62 +++++++++++++++++++++++++++ tools/tpm2_pkcs11/utils.py | 7 +++ 2 files changed, 69 insertions(+) diff --git a/tools/tpm2_pkcs11/commandlets_keys.py b/tools/tpm2_pkcs11/commandlets_keys.py index 86d1ed8b..afd05fee 100644 --- a/tools/tpm2_pkcs11/commandlets_keys.py +++ b/tools/tpm2_pkcs11/commandlets_keys.py @@ -28,6 +28,7 @@ from .utils import dump_blobs from .utils import dump_tsspem from .utils import dump_pubpem +from .utils import validate_policy from .tpm2 import Tpm2 @@ -551,6 +552,67 @@ def __call__(self, args): ObjDel.delete(path, args['id']) +@commandlet("objpol") +class ObjPol(Command): + ''' + Gets/sets/removes object's policy. + ''' + + @classmethod + def objpol(cls, path, tid, policy, delete): + + with Db(path) as db: + obj = db.getobject(tid) + if obj is None: + sys.exit('Not found, object with id: {}'.format(tid)) + s = obj['attrs'] + obj_attrs = yaml.safe_load(s) + + # print policy when neither --policy nor --delete is specified + if policy is None and not delete: + if CKA_TPM2_POLICY_JSON not in obj_attrs: + sys.exit('The object has no policy set') + + x = obj_attrs[CKA_TPM2_POLICY_JSON] + print(binascii.unhexlify(x).decode()) + sys.exit() + + if delete: + # remove the policy even if it's wasn't yet set + obj_attrs.pop(CKA_TPM2_POLICY_JSON, None) + else: + # set policy if --policy is a well-formed JSON + validate_policy(policy) + obj_attrs[CKA_TPM2_POLICY_JSON] = binascii.hexlify(policy.encode()).decode() + + with Db(path) as db: + db.updatetertiary(obj['id'], obj_attrs) + + # adhere to an interface + def generate_options(self, group_parser): + + group_parser.add_argument( + '--id', + help='The id of the object to use.\n', required=True) + group_parser.add_argument( + '--policy', + help='New policy value as JSON.\n') + group_parser.add_argument( + '--delete', + action='store_true', + help='Removes policy if the object has it.\n') + + def __call__(self, args): + + path = args['path'] + policy = args['policy'] + delete = args['delete'] + + if policy and delete: + sys.exit("Cannot specify --policy with --delete") + + ObjPol.objpol(path, args['id'], policy, delete) + @commandlet("link") class LinkCommand(NewKeyCommandBase): ''' diff --git a/tools/tpm2_pkcs11/utils.py b/tools/tpm2_pkcs11/utils.py index ded80335..fb6bfeef 100644 --- a/tools/tpm2_pkcs11/utils.py +++ b/tools/tpm2_pkcs11/utils.py @@ -2,6 +2,7 @@ import binascii import hashlib import io +import json import os import argparse import sys @@ -555,3 +556,9 @@ def dump_pubpem(db, obj, pin, is_sopin, output_prefix): with open(output_prefix + ".pem", "wb") as f: f.write(pub_blob.to_pem()) +def validate_policy(policy): + try: + # discarding result as this is just a JSON sanity check + json.loads(policy) + except json.JSONDecodeError: + sys.exit('Object policy must be a valid JSON') From d98b691d60452f16c2d318ae997eee1aaafdb6ce Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 21 Mar 2023 21:24:15 +0200 Subject: [PATCH 04/10] tpm2_ptool: add --policy to addkey/import/link To specify the policy right on creation. Signed-off-by: Sergii Dmytruk --- tools/tpm2_pkcs11/commandlets_keys.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/tpm2_pkcs11/commandlets_keys.py b/tools/tpm2_pkcs11/commandlets_keys.py index afd05fee..e43b2e6d 100644 --- a/tools/tpm2_pkcs11/commandlets_keys.py +++ b/tools/tpm2_pkcs11/commandlets_keys.py @@ -59,6 +59,9 @@ def generate_options(self, group_parser): '--hierarchy-auth', help='The hierarchyauth, required for transient pobjects.\n', default='') + group_parser.add_argument( + '--policy', + help='Policy to apply on using the key (in JSON format).\n') pinopts = group_parser.add_mutually_exclusive_group() pinopts.add_argument('--sopin', help='The Administrator pin.\n'), pinopts.add_argument('--userpin', help='The User pin.\n'), @@ -174,6 +177,7 @@ def __call__(self, args): key_label = args['key_label'] tid = args['id'] hierarchyauth = args['hierarchy_auth'] + policy = args['policy'] passin = args['passin'] if 'passin' in args else None privkey = None @@ -206,6 +210,9 @@ def __call__(self, args): # handle options that can add additional attributes always_auth = args['attr_always_authenticate'] priv_attrs = {CKA_ALWAYS_AUTHENTICATE : always_auth} + if policy is not None: + validate_policy(policy) + priv_attrs[CKA_TPM2_POLICY_JSON] = binascii.hexlify(policy.encode()).decode() override_keylen = getattr(self, '_override_keylen', None) From fc5a4112398237dd8bc23a8193f4202fe5102d00 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 28 Mar 2023 18:57:58 +0300 Subject: [PATCH 05/10] build: support linking against tss2-policy It was added in tpm2-tss v4.0 and functionality that requires it will be no-op when it's not there or --without-policy is specified during configuration step. Signed-off-by: Sergii Dmytruk --- Makefile.am | 6 ++++-- configure.ac | 23 +++++++++++++++++++++++ docs/BUILDING.md | 2 +- lib/tpm2-pkcs11.pc.in | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9fa6cd0f..c1ecb866 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,11 +5,13 @@ ACLOCAL_AMFLAGS = -I m4 --install AM_CFLAGS = $(INCLUDE_DIRS) $(EXTRA_CFLAGS) $(CODE_COVERAGE_CFLAGS) \ $(TSS2_ESYS_CFLAGS) $(TSS2_MU_CFLAGS) $(TSS2_TCTILDR_CFLAGS) \ $(TSS2_RC_CFLAGS) $(SQLITE3_CFLAGS) $(PTHREAD_CFLAGS) \ - $(CRYPTO_CFLAGS) $(YAML_CFLAGS) $(TSS2_FAPI_CFLAGS) + $(CRYPTO_CFLAGS) $(YAML_CFLAGS) $(TSS2_FAPI_CFLAGS) \ + $(TSS2_POLICY_CFLAGS) AM_LDFLAGS = $(EXTRA_LDFLAGS) $(CODE_COVERAGE_LIBS) $(TSS2_ESYS_LIBS) \ $(TSS2_MU_LIBS) $(TSS2_TCTILDR_LIBS) $(TSS2_RC_LIBS) \ - $(SQLITE3_LIBS) $(PTHREAD_LIBS) $(CRYPTO_LIBS) $(YAML_LIBS) $(TSS2_FAPI_LIBS) + $(SQLITE3_LIBS) $(PTHREAD_LIBS) $(CRYPTO_LIBS) $(YAML_LIBS) \ + $(TSS2_FAPI_LIBS) $(TSS2_POLICY_LIBS) check-programs: $(check_PROGRAMS) diff --git a/configure.ac b/configure.ac index 771004b8..756884f0 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,29 @@ PKG_CHECK_MODULES([TSS2_MU], [tss2-mu]) PKG_CHECK_MODULES([TSS2_TCTILDR], [tss2-tctildr]) PKG_CHECK_MODULES([TSS2_RC], [tss2-rc]) +AC_ARG_WITH( + [policy], + [AS_HELP_STRING([--with-policy], + [enable or disable policy support. Default is "auto" to autodetect])], + [enable_policy=$withval], + [enable_policy=auto]) + +AC_DEFUN([do_policy_configure], [ + # tss2-policy was added in tpm2-tss v4.0 + AS_IF([test "x$enable_policy" = "xauto"], + [ PKG_CHECK_MODULES([TSS2_POLICY], [tss2-policy], [have_policy=1], [have_policy=0]) ], + [ PKG_CHECK_MODULES([TSS2_POLICY], [tss2-policy], [have_policy=1]) ] + ) +]) + +AS_IF([test "x$enable_policy" != "xno"], + [do_policy_configure]) + +AS_IF([test "$have_policy" = "1"], [ + AC_DEFINE([HAVE_POLICY], [1], [Should respect policies and libpolicy is found.]) + AC_SUBST(TSS2_POLICY_DEP, [tss2-policy]) +]) + # Macro that checks for existence of a python module AC_DEFUN([AC_PYTHON_MODULE], [AC_MSG_CHECKING([for module $2 in python]) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 5c725d29..bc68dd16 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -12,7 +12,7 @@ The project depends on: 1. [gcc](https://www.gnu.org/software/gcc/) 2. [clang](https://clang.llvm.org/) 4. [SQLite3](https://www.sqlite.org/) -5. [tpm2-tss](https://github.com/tpm2-software/tpm2-tss): **Requires >= 2.0, recommended >= 2.3.0** +5. [tpm2-tss](https://github.com/tpm2-software/tpm2-tss): **Requires >= 2.0, recommended >= 4.0.1** 6. A Resource Manager, one of: - [tpm2-abrmd](https://github.com/tpm2-software/tpm2-abrmd): **Requires version >= 2.1.0** - Linux kernel version >= 4.12 for `/dev/tpmrm[0-9]+` nodes. diff --git a/lib/tpm2-pkcs11.pc.in b/lib/tpm2-pkcs11.pc.in index 34bc26dc..b75cfc55 100644 --- a/lib/tpm2-pkcs11.pc.in +++ b/lib/tpm2-pkcs11.pc.in @@ -4,7 +4,7 @@ Name: tpm2-pkcs11 Description: TPM2 PKCS#11 library URL: https://github.com/tpm2-software/tpm2-pkcs11 Version: @VERSION@ -Requires.private: tss2-esys tss2-mu sqlite3 libcrypto +Requires.private: @TSS2_POLICY_DEP@ tss2-esys tss2-mu sqlite3 libcrypto Cflags: @PTHREAD_CFLAGS@ Libs: -L${p11_module_path} -ltpm2_pkcs11 Libs.private: @PTHREAD_LIBS@ From 21a21e7541b878ad599a28e77e5dac6031ce8e08 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 28 Mar 2023 19:54:57 +0300 Subject: [PATCH 06/10] sign: enforce PCR policy on signing if present If tpm2-pkcs11 was built without tss2-policy, policy is ignored (a warning is logged about it). This might work for other kinds of policies if they don't require any callbacks for calculation or execution of a policy. Signed-off-by: Sergii Dmytruk --- src/lib/sign.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/tpm.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/tpm.h | 8 ++++++++ 3 files changed, 105 insertions(+) diff --git a/src/lib/sign.c b/src/lib/sign.c index 20494eaf..59584701 100644 --- a/src/lib/sign.c +++ b/src/lib/sign.c @@ -9,6 +9,11 @@ #include #include +#ifdef HAVE_POLICY +#include +#include +#endif + #include "attrs.h" #include "backend.h" #include "checks.h" @@ -149,6 +154,42 @@ static CK_RV update_pss_sig_state(token *tok, tobject *tobj) { return rv; } +static CK_RV policy_is_satisfied(tpm_ctx *tctx, tobject *tobj, uint32_t handle) { + + CK_ATTRIBUTE_PTR policy_attr = attr_get_attribute_by_type(tobj->attrs, CKA_TPM2_POLICY_JSON); + if (!policy_attr) { + /* nonexistent policy is always satisfied */ + return CKR_OK; + } + +#ifndef HAVE_POLICY + UNUSED(tctx); + UNUSED(handle); + /* the policy is considered to be satisfied, but will warn about it */ + LOGW("Found a policy, but support for enforcing it wasn't compiled in"); + return CKR_OK; +#else + TSS2_RC rc; + + TSS2_POLICY_CTX *policy_ctx = NULL; + rc = Tss2_PolicyInit(policy_attr->pValue, TPM2_ALG_SHA256, &policy_ctx); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Tss2_PolicyInit: %s:", Tss2_RC_Decode(rc)); + return CKR_GENERAL_ERROR; + } + + CK_RV rv = tpm2_execute_policy(tctx, policy_ctx, handle); + if (rv != CKR_OK) { + LOGE("Could not execute policy."); + Tss2_PolicyFinalize(&policy_ctx); + return CKR_GENERAL_ERROR; + } + + Tss2_PolicyFinalize(&policy_ctx); + return CKR_OK; +#endif +} + static CK_RV common_init(operation op, session_ctx *ctx, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { check_pointer(mechanism); @@ -211,6 +252,13 @@ static CK_RV common_init(operation op, session_ctx *ctx, CK_MECHANISM_PTR mechan return rv; } + if (op == operation_sign) { + rv = policy_is_satisfied(tok->tctx, tobj, tok->pobject.handle); + if (rv != CKR_OK) { + return rv; + } + } + tpm_op_data *tpm_opdata = NULL; if (op == operation_sign || is_hmac) { diff --git a/src/lib/tpm.c b/src/lib/tpm.c index 16466240..d093b653 100644 --- a/src/lib/tpm.c +++ b/src/lib/tpm.c @@ -24,6 +24,9 @@ #include #include #include +#ifdef HAVE_POLICY +#include +#endif #include "attrs.h" #include "checks.h" @@ -4008,6 +4011,52 @@ CK_RV tpm2_getmechanisms(tpm_ctx *ctx, CK_MECHANISM_TYPE *mechanism_list, CK_ULO return rv; } +#ifdef HAVE_POLICY +CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t handle) +{ + + check_pointer(ctx); + check_pointer(policy_ctx); + check_num(handle); + + TPMT_SYM_DEF symmetric = { + .algorithm = TPM2_ALG_AES, + .keyBits = { .aes = 128 }, + .mode = { .aes = TPM2_ALG_CFB } + }; + + TSS2_RC rc; + + /* XXX should we cache the session or running multiple policies is unlikely? */ + ESYS_TR policy_session = ESYS_TR_NONE; + rc = Esys_StartAuthSession(ctx->esys_ctx, + handle, + handle, + ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, + NULL, + TPM2_SE_POLICY, &symmetric, TPM2_ALG_SHA256, + &policy_session); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Esys_StartAuthSession: %s", Tss2_RC_Decode(rc)); + return CKR_GENERAL_ERROR; + } + + TSS2_RC result = Tss2_PolicyExecute(policy_ctx, ctx->esys_ctx, policy_session); + if (result != TSS2_RC_SUCCESS) { + LOGE("Tss2_PolicyExecute: %s:", Tss2_RC_Decode(result)); + /* continue and stop the session */ + } + + rc = Esys_FlushContext(ctx->esys_ctx, policy_session); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Esys_FlushContext: %s", Tss2_RC_Decode(rc)); + return CKR_GENERAL_ERROR; + } + + return result; +} +#endif + void tpm_init(void) { /* pass nothing to do */ } diff --git a/src/lib/tpm.h b/src/lib/tpm.h index 24246082..339f44be 100644 --- a/src/lib/tpm.h +++ b/src/lib/tpm.h @@ -7,6 +7,9 @@ #include #include +#ifdef HAVE_POLICY +#include +#endif #include "attrs.h" #include "debug.h" @@ -189,6 +192,11 @@ CK_RV tpm2_generate_key( CK_RV tpm2_getmechanisms(tpm_ctx *ctx, CK_MECHANISM_TYPE *mechanism_list, CK_ULONG_PTR count); +/* the function can't be defined without the library because of TSS2_POLICY_CTX type */ +#ifdef HAVE_POLICY +CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t handle); +#endif + CK_RV tpm_get_existing_primary(tpm_ctx *tpm, uint32_t *primary_handle, twist *primary_blob); CK_RV tpm_create_persistent_primary(tpm_ctx *tpm, uint32_t *primary_handle, twist *primary_blob); From 6483606624a21e68ba74c39928c7f812864819ff Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 28 Mar 2023 21:12:35 +0300 Subject: [PATCH 07/10] sign: remove extra space before one #include Signed-off-by: Sergii Dmytruk --- src/lib/sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/sign.c b/src/lib/sign.c index 59584701..bd91a886 100644 --- a/src/lib/sign.c +++ b/src/lib/sign.c @@ -7,7 +7,7 @@ #include #include #include - #include +#include #ifdef HAVE_POLICY #include From 0e228704207ea343c16dd7b7ad80ca3f1fc381c6 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 28 Mar 2023 21:13:45 +0300 Subject: [PATCH 08/10] tpm2_ptool: fix description of "export --id" It said "add" instead of "export". Signed-off-by: Sergii Dmytruk --- tools/tpm2_pkcs11/commandlets_keys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tpm2_pkcs11/commandlets_keys.py b/tools/tpm2_pkcs11/commandlets_keys.py index e43b2e6d..40cafea5 100644 --- a/tools/tpm2_pkcs11/commandlets_keys.py +++ b/tools/tpm2_pkcs11/commandlets_keys.py @@ -828,7 +828,7 @@ def export(db, tid, pin, is_so_pin, hierarchyauth, format, output_prefix): def generate_options(self, group_parser): group_parser.add_argument( - '--id', help='The id of the object to add (mutually exclusive with --label and --key-label).\n', + '--id', help='The id of the object to export (mutually exclusive with --label and --key-label).\n', type=int) group_parser.add_argument( From 03e9dd3f2828d1eb654e7add70fdd556e7a37c2a Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 28 Mar 2023 21:15:39 +0300 Subject: [PATCH 09/10] ci: fix --disable/enable-fapi in docker.run It's --with/without-fapi (or --with-fapi=yes/no). Signed-off-by: Sergii Dmytruk --- .ci/docker.run | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/docker.run b/.ci/docker.run index 54335c8b..4c625115 100755 --- a/.ci/docker.run +++ b/.ci/docker.run @@ -64,7 +64,7 @@ fi # avoid error checking or cause make distcheck to fail. So run a # pure check with gcc before adding those flags. if [[ "$CC" != clang* ]]; then - ./configure --enable-esapi-session-manage-flags --disable-fapi --enable-unit --enable-integration + ./configure --enable-esapi-session-manage-flags --without-fapi --enable-unit --enable-integration make distcheck TESTS= make distclean fi @@ -84,7 +84,7 @@ if [[ "$CC" != clang* ]]; then # rebuild after running scan-build. fi -../configure --enable-unit --enable-integration --enable-esapi-session-manage-flags --enable-fapi $config_flags +../configure --enable-unit --enable-integration --enable-esapi-session-manage-flags --with-fapi $config_flags make -j$(nproc) make -j check From bccb70707c2a9565140c5a316b619f25a72c71fe Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Fri, 31 Mar 2023 00:37:46 +0300 Subject: [PATCH 10/10] tpm: setup "get pcr" callback on policy execution It's a calculation callback, but not yet calculated policy is automatically calculated before execution. Signed-off-by: Sergii Dmytruk --- src/lib/tpm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/lib/tpm.c b/src/lib/tpm.c index d093b653..e8900ea9 100644 --- a/src/lib/tpm.c +++ b/src/lib/tpm.c @@ -4012,6 +4012,55 @@ CK_RV tpm2_getmechanisms(tpm_ctx *ctx, CK_MECHANISM_TYPE *mechanism_list, CK_ULO } #ifdef HAVE_POLICY +static TSS2_RC tpm2_policy_get_pcr(TSS2_POLICY_PCR_SELECTION *selection, + TPML_PCR_SELECTION *out_selection, + TPML_DIGEST *out_digest, + void *userdata) +{ + + TPML_PCR_SELECTION in_pcr_selection = {0}; + if (selection->type == TSS2_POLICY_PCR_SELECTOR_PCR_SELECTION) { + in_pcr_selection = selection->selections.pcr_selection; + } else { + in_pcr_selection.count = 1; + + TPMS_PCR_SELECTION *pcr_bank = &in_pcr_selection.pcrSelections[0]; + TPMS_PCR_SELECT *pcr_select = &selection->selections.pcr_select; + + pcr_bank->hash = TPM2_ALG_SHA256; + pcr_bank->sizeofSelect = pcr_select->sizeofSelect; + memcpy(pcr_bank->pcrSelect, pcr_select->pcrSelect, pcr_bank->sizeofSelect); + } + + ESYS_CONTEXT *esys_ctx = userdata; + + UINT32 pcr_update_counter; + TPML_PCR_SELECTION *pcr_selection = NULL; + TPML_DIGEST *pcr_values = NULL; + + TSS2_RC rc = Esys_PCR_Read(esys_ctx, + ESYS_TR_NONE, + ESYS_TR_NONE, + ESYS_TR_NONE, + &in_pcr_selection, + &pcr_update_counter, + &pcr_selection, + &pcr_values); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Esys_PCR_Read: %s:", Tss2_RC_Decode(rc)); + free(pcr_selection); + free(pcr_values); + return rc; + } + + *out_selection = *pcr_selection; + *out_digest = *pcr_values; + + free(pcr_selection); + free(pcr_values); + return TSS2_RC_SUCCESS; +} + CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t handle) { @@ -4025,8 +4074,18 @@ CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t ha .mode = { .aes = TPM2_ALG_CFB } }; + TSS2_POLICY_CALC_CALLBACKS calc_callbacks = {0}; + calc_callbacks.cbpcr = &tpm2_policy_get_pcr; + calc_callbacks.cbpcr_userdata = ctx->esys_ctx; + TSS2_RC rc; + rc = Tss2_PolicySetCalcCallbacks(policy_ctx, &calc_callbacks); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Tss2_PolicySetCalcCallbacks: %s:", Tss2_RC_Decode(rc)); + return CKR_GENERAL_ERROR; + } + /* XXX should we cache the session or running multiple policies is unlikely? */ ESYS_TR policy_session = ESYS_TR_NONE; rc = Esys_StartAuthSession(ctx->esys_ctx,