Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openssl_tpm2_engine for 
openSUSE:Factory checked in at 2024-01-03 12:30:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openssl_tpm2_engine (Old)
 and      /work/SRC/openSUSE:Factory/.openssl_tpm2_engine.new.28375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openssl_tpm2_engine"

Wed Jan  3 12:30:40 2024 rev:15 rq:1136249 version:4.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/openssl_tpm2_engine/openssl_tpm2_engine.changes  
2023-12-05 17:03:26.945662632 +0100
+++ 
/work/SRC/openSUSE:Factory/.openssl_tpm2_engine.new.28375/openssl_tpm2_engine.changes
       2024-01-03 12:31:20.057387821 +0100
@@ -1,0 +2,12 @@
+Tue Jan  1 16:07:25 UTC 2024 - [email protected]
+
+- Update to version 4.1.1
+  * fix 32 bit build
+
+-------------------------------------------------------------------
+Mon Dec 31 03:55:34 UTC 2023 - [email protected]
+
+- Update to version 4.1.0
+  * implement tpm2_PolicySecret
+
+-------------------------------------------------------------------

Old:
----
  openssl_tpm2_engine-4.0.2.tar.gz

New:
----
  openssl_tpm2_engine-4.1.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openssl_tpm2_engine.spec ++++++
--- /var/tmp/diff_new_pack.P6UOqr/_old  2024-01-03 12:31:20.621408449 +0100
+++ /var/tmp/diff_new_pack.P6UOqr/_new  2024-01-03 12:31:20.621408449 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package openssl_tpm2_engine
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 # Copyright (c) 2017 [email protected]
 #
 # All modifications and additions to the file contributed by third parties
@@ -18,7 +18,7 @@
 
 
 Name:           openssl_tpm2_engine
-Version:        4.0.2
+Version:        4.1.1
 Release:        0
 Summary:        OpenSSL TPM 2.0 interface engine plugin
 License:        LGPL-2.1-only

++++++ openssl_tpm2_engine-4.0.2.tar.gz -> openssl_tpm2_engine-4.1.1.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/configure.ac 
new/openssl_tpm2_engine-4.1.1/configure.ac
--- old/openssl_tpm2_engine-4.0.2/configure.ac  2023-12-05 04:47:13.000000000 
+0100
+++ new/openssl_tpm2_engine-4.1.1/configure.ac  2024-01-02 16:52:46.000000000 
+0100
@@ -2,7 +2,7 @@
 # configure.in for the OpenSSL TPM engine project
 #
 
-AC_INIT(openssl-tpm2-engine, 4.0.2, <[email protected]>)
+AC_INIT(openssl-tpm2-engine, 4.1.1, <[email protected]>)
 AM_INIT_AUTOMAKE([foreign 1.6.3])
 AC_CANONICAL_HOST
 AM_CONDITIONAL(NATIVE_BUILD, test "x$cross_compiling" = "xno")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/doc/draft-bottomley-tpm2-keys.xml 
new/openssl_tpm2_engine-4.1.1/doc/draft-bottomley-tpm2-keys.xml
--- old/openssl_tpm2_engine-4.0.2/doc/draft-bottomley-tpm2-keys.xml     
2023-12-05 04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/doc/draft-bottomley-tpm2-keys.xml     
2024-01-02 16:52:46.000000000 +0100
@@ -23,7 +23,7 @@
         <email>[email protected]</email>
       </address>
     </author>
-    <date month="June" year="2023"/>
+    <date month="December" year="2023"/>
     <area>Security</area>
     <keyword>I-D</keyword>
     <keyword>Internet-Draft</keyword>
@@ -277,7 +277,7 @@
            This is a binary string representing a fully marshalled,
            TPM ordered, command body for the TPM policy command.
            Therefore to send the command, the implementation simply
-           marshalls the command code and appends this octet string
+           marshals the command code and appends this octet string
            as the body.
          </t>
          <t>
@@ -330,6 +330,25 @@
            policySignature.
          </t>
        </section>
+       <section title="TPM2_PolicySecret">
+         <t>
+           According to <xref target="TPM2.0"/> the body of this
+           command consists of the handle of the authorizing object,
+           TPM2B_NONCE nonceTPM, TPM2B_DIGEST cpHashA, TPM2B_NONCE
+           policyRef and INT32 expiration.  However, the policyHash
+           only uses policyRef and the name of the authorizing
+           object.  Since the usual authorizing object for
+           TPM2_PolicySecret is a permanent handle or NV Index, and
+           those are hard to find by name, the handle is also given
+           as an optional hint in addition to the name.
+         </t>
+         <t>
+           The format of CommandPolicy for TPM2_PolicySecret MUST be
+           TPM_HANDLE objectHandleHint, TPM2B_NAME objectName,
+           TPM2B_DIGEST policyRef.  Where objectHandleHint MAY be
+           zero to indicate no hint.
+         </t>
+       </section>
       </section>
       <section title="Policy Implementation Considerations">
        <t>
@@ -364,16 +383,25 @@
        <section title="Authorization Policy">
          <t>
            When Authorization (Passing in a password) is required,
-           the emptyAuth parameter MUST be absent or set to false
-           and additionally the TPM_CC_PolicyAuthValue MUST be
-           specified as the command code for one entry in the
-           TPMPolicy sequence.  However, the implementation MAY
-           choose to execute either TPM2_PolicyPassword for TPM_RS_PW
-           or TPM2_PolicyAuthValue for HMAC based authorization
-           depending on whether the command being authorized is using
-           sessions or not.  If the policy does not require an
-           authorization then the emptyAuth parameter MUST be set to
-           true.
+           the emptyAuth parameter MUST be absent or set to false and
+           additionally TPM_CC_PolicyAuthValue or TPM_CC_PolicySecret
+           MUST be specified as the command code for one entry in the
+           TPMPolicy sequence.  However, when TPM2_PolicyAuthValue is
+           specified, the implementation MAY choose to execute either
+           TPM2_PolicyPassword for TPM_RS_PW or TPM2_PolicyAuthValue
+           for HMAC based authorization depending on whether the
+           command being authorized is using sessions or not.  If the
+           policy does not require an authorization then the
+           emptyAuth parameter MUST be set to true.
+         </t>
+         <t>
+           Implementations should bear in mind that most crypto
+           systems with key management expect to consume only one
+           password per key, so implementations SHOULD avoid policy
+           chains which would require more than one password as would
+           happen when TPM2_PolicySecret and TPM2_PolicyAuthValue
+           both appear in the same policy chain.  Implementations MAY
+           detect and emit an error in this case.
          </t>
        </section>
       </section>
@@ -520,6 +548,25 @@
            the TPM clock.
          </t>
        </section>
+       <section title="Policy Signing Keys and policyRef values">
+         <t>
+           There is a high likelihood that a consumer would use the
+           same policy signing key for multiple TPM objects with
+           signed policy.  This gives rise to the risk that a
+           malicious user could extract signed policy meant for key1
+           and use it instead with key2 (policy swapping).  To
+           mitigate this risk, the implementation SHOULD place a high
+           entropy nonce in policyRef to ensure that each key has a
+           different policyRef which prevents this policy swapping.
+         </t>
+         <t>
+           The TCG specifies that policyRef could have an
+           implementation defined meaning in which case
+           implementations MAY use implementation meaningful values
+           instead of nonces for policyRef but SHOULD take other
+           measures to prevent policy swapping.
+         </t>
+       </section>
       </section>
     </section>
     <section anchor="implementation" title="Implementation Considerations">
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/engine/e_tpm2.c 
new/openssl_tpm2_engine-4.1.1/src/engine/e_tpm2.c
--- old/openssl_tpm2_engine-4.0.2/src/engine/e_tpm2.c   2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/engine/e_tpm2.c   2024-01-02 
16:52:46.000000000 +0100
@@ -177,7 +177,8 @@
 
                rc = tpm2_get_bound_handle(tssContext, &session, key, NULL);
                if (rc == TPM_RC_SUCCESS) {
-                       rc = tpm2_ReadPublic(tssContext, key, NULL, session);
+                       rc = tpm2_ReadPublic(tssContext, key, NULL, session,
+                                            NULL);
                        if (rc)
                                tpm2_flush_handle(tssContext, session);
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/include/ibm-tss.h 
new/openssl_tpm2_engine-4.1.1/src/include/ibm-tss.h
--- old/openssl_tpm2_engine-4.0.2/src/include/ibm-tss.h 2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/include/ibm-tss.h 2024-01-02 
16:52:46.000000000 +0100
@@ -163,7 +163,7 @@
 
 static inline TPM_RC
 tpm2_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE objectHandle,
-               TPMT_PUBLIC *pub, TPM_HANDLE auth)
+               TPMT_PUBLIC *pub, TPM_HANDLE auth, NAME_2B *name)
 {
        ReadPublic_In rin;
        ReadPublic_Out rout;
@@ -190,6 +190,35 @@
 
        if (pub)
                *pub = rout.outPublic.publicArea;
+       if (name)
+               *name = rout.name.t;
+
+       return rc;
+}
+
+static inline TPM_RC
+tpm2_NV_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE nvIndex,
+                  NAME_2B *nvName)
+{
+       TPM_RC rc;
+       NV_ReadPublic_In in;
+       NV_ReadPublic_Out out;
+
+       in.nvIndex = nvIndex;
+       rc = TSS_Execute (tssContext,
+                         (RESPONSE_PARAMETERS *)&out,
+                         (COMMAND_PARAMETERS *)&in,
+                         NULL,
+                         TPM_CC_NV_ReadPublic,
+                         TPM_RH_NULL, NULL, 0);
+
+       if (rc) {
+               tpm2_error(rc, "TPM2_NV_ReadPublic");
+               return rc;
+       }
+
+       if (nvName)
+               *nvName = out.nvName.t;
 
        return rc;
 }
@@ -379,7 +408,7 @@
                 * access to the public part.  It does this by keeping
                 * key files, but request the public part just to make
                 * sure*/
-               tpm2_ReadPublic(tssContext, tpmKey,  NULL, TPM_RH_NULL);
+               tpm2_ReadPublic(tssContext, tpmKey,  NULL, TPM_RH_NULL, NULL);
                /* don't care what rout returns, the purpose of the
                 * operation was to get the public key parameters into
                 * the tss so it can construct the salt */
@@ -584,6 +613,87 @@
 
        return rc;
 }
+
+static inline TPM_RC
+tpm2_PolicyLocality(TSS_CONTEXT *tssContext, TPM_HANDLE policySession,
+                   UINT8 locality)
+{
+       PolicyLocality_In in;
+       TPM_RC rc;
+
+       in.policySession = policySession;
+       in.locality.val = locality;
+
+       rc = TSS_Execute(tssContext,
+                        NULL,
+                        (COMMAND_PARAMETERS *)&in,
+                        NULL,
+                        TPM_CC_PolicyLocality,
+                        TPM_RH_NULL, NULL, 0);
+
+       return rc;
+}
+
+static inline TPM_RC
+tpm2_PolicySecret(TSS_CONTEXT *tssContext, TPM_HANDLE authHandle,
+                 TPM_HANDLE policySession, DIGEST_2B *policyRef,
+                 const char *authVal)
+{
+       PolicySecret_In in;
+       PolicySecret_Out out;
+       TPM_RC rc;
+       TPMT_SYM_DEF symmetric;
+       TPM_HANDLE authSession;
+
+       /*
+        * Simple use case: we take a bound session inside this
+        * function because we know the auth and we have an object
+        * handle.  In theory the caller should pass in the session,
+        * but all current callers would flush the handle immediately
+        * after so it simplifies the API to do the session setup and
+        * teardown inside this call.
+        */
+
+       symmetric.algorithm = TPM_ALG_AES;
+       symmetric.keyBits.aes = 128;
+       symmetric.mode.aes = TPM_ALG_CFB;
+
+       /* need public area pulled in for nonce computation */
+       if ((authHandle >> 24) == TPM_HT_NV_INDEX)
+               tpm2_NV_ReadPublic(tssContext, authHandle, NULL);
+       else
+               tpm2_ReadPublic(tssContext, authHandle, NULL, TPM_RH_NULL, 
NULL);
+
+       rc = tpm2_StartAuthSession(tssContext, TPM_RH_NULL, authHandle,
+                                  TPM_SE_HMAC, &symmetric, TPM_ALG_SHA256,
+                                  &authSession, authVal);
+       if (rc)
+               return rc;
+
+       in.authHandle = authHandle;
+       in.policySession = policySession;
+       in.nonceTPM.b.size = 0;
+       in.cpHashA.b.size = 0;
+
+       in.policyRef.t = *policyRef;
+       in.expiration = 0;
+
+       rc = TSS_Execute(tssContext,
+                        (RESPONSE_PARAMETERS *)&out,
+                        (COMMAND_PARAMETERS *)&in,
+                        NULL,
+                        TPM_CC_PolicySecret,
+                        authSession, authVal, 0,
+                        TPM_RH_NULL, NULL, 0);
+
+       if (rc) {
+               tpm2_FlushContext(tssContext, authSession);
+               tpm2_error(rc, "TPM2_PolicySecret");
+               return rc;
+       }
+
+       return rc;
+}
 
 static inline TPM_RC
 tpm2_PolicyGetDigest(TSS_CONTEXT *tssContext, TPM_HANDLE policySession,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/include/intel-tss.h 
new/openssl_tpm2_engine-4.1.1/src/include/intel-tss.h
--- old/openssl_tpm2_engine-4.0.2/src/include/intel-tss.h       2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/include/intel-tss.h       2024-01-02 
16:52:46.000000000 +0100
@@ -70,6 +70,8 @@
 #define TPM_CC_PolicyAuthValue TPM2_CC_PolicyAuthValue
 #define TPM_CC_PolicyCounterTimer      TPM2_CC_PolicyCounterTimer
 #define TPM_CC_PolicyAuthorize TPM2_CC_PolicyAuthorize
+#define TPM_CC_PolicyLocality  TPM2_CC_PolicyLocality
+#define TPM_CC_PolicySecret    TPM2_CC_PolicySecret
 
 #define TPM_ST_HASHCHECK       TPM2_ST_HASHCHECK
 
@@ -78,6 +80,8 @@
 #define TPM_RH_ENDORSEMENT     ESYS_TR_RH_ENDORSEMENT
 #define TPM_RH_NULL            ESYS_TR_NONE
 
+#define TPM_HT_NV_INDEX                TPM2_HT_NV_INDEX
+#define TPM_HT_POLICY_SESSION  TPM2_HT_POLICY_SESSION
 #define TPM_HT_PERMANENT       TPM2_HT_PERMANENT
 #define TPM_HT_TRANSIENT       TPM2_HT_TRANSIENT
 #define TPM_HT_PERSISTENT      TPM2_HT_PERSISTENT
@@ -178,10 +182,12 @@
 }
 
 TSS_CONVERT_MARSHAL(TPMT_PUBLIC, )
+TSS_CONVERT_MARSHAL(UINT8, *)
 TSS_CONVERT_MARSHAL(UINT16, *)
 TSS_CONVERT_MARSHAL(TPMT_SENSITIVE, )
 TSS_CONVERT_MARSHAL(TPM2B_ECC_POINT, )
 TSS_CONVERT_MARSHAL(TPM2B_DIGEST, )
+TSS_CONVERT_MARSHAL(TPM2B_NAME, )
 TSS_CONVERT_MARSHAL(TPM2B_PUBLIC, )
 TSS_CONVERT_MARSHAL(TPM2B_PRIVATE, )
 TSS_CONVERT_MARSHAL(TPML_PCR_SELECTION, )
@@ -196,6 +202,7 @@
 TSS_CONVERT_UNMARSHAL(UINT16, )
 TSS_CONVERT_UNMARSHAL(UINT32, )
 TSS_CONVERT_UNMARSHAL(TPM2B_DIGEST, )
+TSS_CONVERT_UNMARSHAL(TPM2B_NAME, )
 TSS_CONVERT_UNMARSHAL(TPMT_SIGNATURE, X)
 
 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
@@ -796,27 +803,50 @@
 
 static inline TPM_RC
 tpm2_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE objectHandle,
-               TPMT_PUBLIC *pub, TPM_HANDLE auth)
+               TPMT_PUBLIC *pub, TPM_HANDLE auth, NAME_2B *name)
 {
        TPM2B_PUBLIC *out;
+       NAME_2B *out_name;
        TPM_RC rc;
 
        if (auth != TPM_RH_NULL)
                intel_sess_helper(tssContext, auth, TPMA_SESSION_ENCRYPT);
 
        rc = Esys_ReadPublic(tssContext, objectHandle, auth, ESYS_TR_NONE,
-                            ESYS_TR_NONE, &out, NULL, NULL);
+                            ESYS_TR_NONE, &out, &out_name, NULL);
        if (rc)
                return rc;
 
        if (pub)
                *pub = out->publicArea;
+       if (name)
+               *name = *out_name;
        free(out);
 
        return rc;
 }
 
 static inline TPM_RC
+tpm2_NV_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE nvIndex,
+                  NAME_2B *nvName)
+{
+       TPM_RC rc;
+       NAME_2B *name;
+
+       rc = Esys_NV_ReadPublic(tssContext, nvIndex, ESYS_TR_NONE, ESYS_TR_NONE,
+                               ESYS_TR_NONE, NULL, &name);
+
+       if (rc)
+               return rc;
+
+       if (nvName)
+               *nvName = *name;
+       free(name);
+
+       return rc;
+}
+
+static inline TPM_RC
 tpm2_RSA_Decrypt(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
                 PUBLIC_KEY_RSA_2B *cipherText, TPMT_RSA_DECRYPT *inScheme,
                 PUBLIC_KEY_RSA_2B *message,
@@ -1045,6 +1075,58 @@
 }
 
 static inline TPM_RC
+tpm2_PolicyLocality(TSS_CONTEXT *tssContext, TPM_HANDLE policySession,
+                   UINT8 locality)
+{
+       return Esys_PolicyLocality(tssContext, policySession,
+                                  ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
+                                  locality);
+}
+
+static inline TPM_RC
+tpm2_PolicySecret(TSS_CONTEXT *tssContext, TPM_HANDLE authHandle,
+                 TPM_HANDLE policySession, DIGEST_2B *policyRef,
+                 const char *authVal)
+{
+       TPM_RC rc;
+       TPM_HANDLE authSession;
+       TPMT_SYM_DEF symmetric;
+
+       /*
+        * Simple use case: we take a bound session inside this
+        * function because we know the auth and we have an object
+        * handle.  In theory the caller should pass in the session,
+        * but all current callers would flush the handle immediately
+        * after so it simplifies the API to do the session setup and
+        * teardown inside this call.
+        */
+
+       symmetric.algorithm = TPM_ALG_AES;
+       symmetric.keyBits.aes = 128;
+       symmetric.mode.aes = TPM_ALG_CFB;
+
+
+       rc = tpm2_StartAuthSession(tssContext, TPM_RH_NULL, authHandle,
+                                  TPM_SE_HMAC, &symmetric, TPM_ALG_SHA256,
+                                  &authSession, authVal);
+       if (rc)
+               return rc;
+
+       intel_auth_helper(tssContext, authHandle, authVal);
+       intel_sess_helper(tssContext, authSession, 0);
+
+       rc = Esys_PolicySecret(tssContext, authHandle, policySession,
+                              authSession, ESYS_TR_NONE, ESYS_TR_NONE,
+                              NULL /* nonceTPM */, NULL /* cpHashA */,
+                              policyRef, 0, NULL, NULL);
+
+       if (rc)
+               tpm2_FlushContext(tssContext, authSession);
+
+       return rc;
+}
+
+static inline TPM_RC
 tpm2_PolicyGetDigest(TSS_CONTEXT *tssContext, TPM_HANDLE policySession,
                     DIGEST_2B *digest)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/include/tpm2-common.h 
new/openssl_tpm2_engine-4.1.1/src/include/tpm2-common.h
--- old/openssl_tpm2_engine-4.0.2/src/include/tpm2-common.h     2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/include/tpm2-common.h     2024-01-02 
16:52:46.000000000 +0100
@@ -62,7 +62,7 @@
                               TPM_HANDLE salt_key, TPM_SE sessionType,
                               TPM_ALG_ID name_alg);
 TPM_RC tpm2_init_session(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
-                        const struct app_data *app_data, TPM_ALG_ID name_alg);
+                        const struct app_data *app_data, const char **auth);
 TPM_RC tpm2_get_bound_handle(TSS_CONTEXT *tssContext, TPM_HANDLE *handle,
                             TPM_HANDLE bind, const char *auth);
 TPMI_ECC_CURVE tpm2_curve_name_to_TPMI(const char *name);
@@ -104,6 +104,8 @@
                            STACK_OF(TSSOPTPOLICY) *sk,
                            TPMT_HA *digest);
 void tpm2_add_auth_policy(STACK_OF(TSSOPTPOLICY) *sk, TPMT_HA *digest);
+void tpm2_add_locality(STACK_OF(TSSOPTPOLICY) *sk, UINT8 locality,
+                      TPMT_HA *digest);
 EVP_PKEY *openssl_read_public_key(char *filename);
 void tpm2_public_template_rsa(TPMT_PUBLIC *pub);
 void tpm2_public_template_ecc(TPMT_PUBLIC *pub, TPMI_ECC_CURVE curve);
@@ -115,7 +117,9 @@
 TPM_RC tpm2_add_signed_policy(STACK_OF(TSSOPTPOLICY) *sk, char *key_file,
                              TPMT_HA *digest);
 TPM_RC tpm2_new_signed_policy(char *tpmkey, char *policykey, char *engine,
-                             TSSAUTHPOLICY *ap, TPMT_HA *digest);
+                             TSSAUTHPOLICY *ap, TPMT_HA *digest, int 
need_auth);
+TPM_RC tpm2_add_policy_secret(TSS_CONTEXT *tssContext, STACK_OF(TSSOPTPOLICY) 
*sk,
+                             TPM_HANDLE handle, TPMT_HA *digest);
 TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
                      TPMT_SENSITIVE *s,
                      TPMT_PUBLIC *pub,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/libcommon/tpm2-common.c 
new/openssl_tpm2_engine-4.1.1/src/libcommon/tpm2-common.c
--- old/openssl_tpm2_engine-4.0.2/src/libcommon/tpm2-common.c   2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/libcommon/tpm2-common.c   2024-01-02 
16:52:46.000000000 +0100
@@ -475,6 +475,7 @@
        PUBLIC_KEY_RSA_2B message;
        TPM_HANDLE authHandle;
        TPM_SE sessionType;
+       const char *auth;
 
        keyHandle = tpm2_load_key(&tssContext, ad, srk_auth, NULL);
 
@@ -505,15 +506,12 @@
        if (rc)
                goto out;
 
-       if (sessionType == TPM_SE_POLICY) {
-               rc = tpm2_init_session(tssContext, authHandle,
-                                      ad, ad->Public.publicArea.nameAlg);
-               if (rc)
-                       goto out;
-       }
+       rc = tpm2_init_session(tssContext, authHandle, ad, &auth);
+       if (rc)
+               goto out;
 
        rc = tpm2_RSA_Decrypt(tssContext, keyHandle, cipherText, &inScheme,
-                             &message, authHandle, ad->auth, protection);
+                             &message, authHandle, auth, protection);
 
        if (rc) {
                tpm2_error(rc, "TPM2_RSA_Decrypt");
@@ -543,6 +541,7 @@
        TPM_SE sessionType;
        ECDSA_SIG *sig;
        BIGNUM *r, *s;
+       const char *auth;
        int len = 
tpm2_curve_to_order(ad->Public.publicArea.parameters.eccDetail.curveID);
 
        /* so we give it a digest equal to the key length, except if that
@@ -590,15 +589,12 @@
        if (rc)
                goto out;
 
-       if (sessionType == TPM_SE_POLICY) {
-               rc = tpm2_init_session(tssContext, authHandle,
-                                      ad, ad->Public.publicArea.nameAlg);
-               if (rc)
-                       goto out;
-       }
+       rc = tpm2_init_session(tssContext, authHandle, ad, &auth);
+       if (rc)
+               goto out;
 
        rc = tpm2_Sign(tssContext, keyHandle, &digest, &inScheme, &signature,
-                      authHandle, ad->auth);
+                      authHandle, auth);
        if (rc) {
                tpm2_error(rc, "TPM2_Sign");
                tpm2_flush_handle(tssContext, authHandle);
@@ -638,6 +634,7 @@
        TPM_SE sessionType;
        size_t len;
        int ret;
+       const char *auth;
 
        keyHandle = tpm2_load_key(&tssContext, ad, srk_auth, NULL);
        if (keyHandle == 0) {
@@ -654,12 +651,9 @@
        if (rc)
                goto out;
 
-       if (sessionType == TPM_SE_POLICY) {
-               rc = tpm2_init_session(tssContext, authHandle,
-                                      ad, ad->Public.publicArea.nameAlg);
-               if (rc)
-                       goto out;
-       }
+       rc = tpm2_init_session(tssContext, authHandle, ad, &auth);
+       if (rc)
+               goto out;
 
        rc = tpm2_ECDH_ZGen(tssContext, keyHandle, inPoint, &outPoint,
                            authHandle, ad->auth);
@@ -984,7 +978,16 @@
 TPM_RC tpm2_readpublic(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
                       TPMT_PUBLIC *pub)
 {
-       return tpm2_ReadPublic(tssContext, handle, pub, TPM_RH_NULL);
+       return tpm2_ReadPublic(tssContext, handle, pub, TPM_RH_NULL, NULL);
+}
+
+static TPM_RC tpm2_readname(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
+                           NAME_2B *name)
+{
+       if (tpm2_handle_mso(tssContext, handle, TPM_HT_NV_INDEX))
+               return tpm2_NV_ReadPublic(tssContext, handle, name);
+       else
+               return tpm2_ReadPublic(tssContext, handle, NULL, TPM_RH_NULL, 
name);
 }
 
 TPM_RC tpm2_get_bound_handle(TSS_CONTEXT *tssContext, TPM_HANDLE *handle,
@@ -1034,7 +1037,8 @@
 
 static TPM_RC tpm2_try_policy(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
                              int num_commands, struct policy_command *commands,
-                             TPM_ALG_ID name_alg, const char *prefix)
+                             TPM_ALG_ID name_alg, const char *prefix,
+                             const struct app_data *ad, const char **auth)
 {
        INT32 size;
        BYTE *policy;
@@ -1173,6 +1177,41 @@
 
                        break;
                }
+               case TPM_CC_PolicyLocality:
+                       rc = tpm2_PolicyLocality(tssContext, handle, policy[0]);
+                       if (rc)
+                               sprintf(reason, "Locality Check 0x%x failed",
+                                       policy[0]);
+                       break;
+
+               case TPM_CC_PolicySecret: {
+                       NAME_2B name;
+                       DIGEST_2B policyRef;
+                       TPM_HANDLE authHandle;
+
+                       rc = UINT32_Unmarshal(&authHandle, &policy, &size);
+                       if (rc)
+                               goto unmarshal_failure;
+                       rc = TPM2B_NAME_Unmarshal((TPM2B_NAME *)&name, &policy, 
&size);
+                       if (rc)
+                               goto unmarshal_failure;
+                       rc = TPM2B_DIGEST_Unmarshal((TPM2B_DIGEST *)&policyRef, 
&policy, &size);
+                       if (rc)
+                               goto unmarshal_failure;
+
+                       authHandle = tpm2_handle_int(tssContext, authHandle);
+                       rc = tpm2_PolicySecret(tssContext, authHandle,
+                                              handle, &policyRef, *auth);
+
+                       /*
+                        * we consumed auth above, so make sure it
+                        * doesn't get reused in the actual command
+                        */
+                       *auth = NULL;
+                       tpm2_rm_keyfile(ad->dir, authHandle);
+                       break;
+               }
+
                default:
                        fprintf(stderr, "%sUnsupported policy command %d\n",
                                prefix, commands[i].code);
@@ -1210,12 +1249,18 @@
 }
 
 TPM_RC tpm2_init_session(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
-                        const struct app_data *app_data, TPM_ALG_ID name_alg)
+                        const struct app_data *app_data, const char **auth)
 {
        int num_commands;
        struct policy_command *commands;
        char prefix[128];
        TPM_RC rc;
+       TPM_ALG_ID name_alg = app_data->Public.publicArea.nameAlg;
+
+       *auth = app_data->auth;
+
+       if (!tpm2_handle_mso(tssContext, handle, TPM_HT_POLICY_SESSION))
+               return TPM_RC_SUCCESS;
 
        if (app_data->pols == NULL)
                return TPM_RC_SUCCESS;
@@ -1244,7 +1289,8 @@
                        rc = tpm2_try_policy(tssContext, handle,
                                             pols->num_commands,
                                             pols->commands,
-                                            name_alg, prefix);
+                                            name_alg, prefix,
+                                            app_data, auth);
                        if (rc == TPM_RC_SUCCESS)
                                break;
                }
@@ -1255,7 +1301,7 @@
        }
 
        rc = tpm2_try_policy(tssContext, handle, num_commands, commands,
-                            name_alg, "");
+                            name_alg, "", app_data, auth);
  out:
        if (rc != TPM_RC_SUCCESS)
                tpm2_flush_handle(tssContext, handle);
@@ -1436,6 +1482,10 @@
        unlink(keyfile);
        snprintf(keyfile, sizeof(keyfile), "%s/hp%08x.bin", dir, key);
        unlink(keyfile);
+       if ((key >> 24) == TPM_HT_NV_INDEX) {
+               snprintf(keyfile, sizeof(keyfile), "%s/nvp%08x.bin", dir, key);
+               unlink(keyfile);
+       }
 }
 
 void tpm2_rm_tssdir(const char *dir)
@@ -2433,7 +2483,7 @@
 }
 
 TPM_RC tpm2_new_signed_policy(char *tpmkey, char *policykey, char *engine,
-                             TSSAUTHPOLICY *ap, TPMT_HA *digest)
+                             TSSAUTHPOLICY *ap, TPMT_HA *digest, int need_auth)
 {
        BIO *bf;
        TSSPRIVKEY *tpk;
@@ -2460,6 +2510,10 @@
                goto err_free_tpmkey;
        }
 
+       /* remove the emptyAuth attribut if set and we need authorization */
+       if (tpk->emptyAuth != -1 && need_auth)
+               tpk->emptyAuth = -1;
+
        policy = sk_TSSOPTPOLICY_value(tpk->policy, 0);
        if (ASN1_INTEGER_get(policy->CommandCode) != TPM_CC_PolicyAuthorize) {
                fprintf(stderr, "TPM Key has no signed policy\n");
@@ -2598,13 +2652,13 @@
 
        if (sep)
                *sep = '\0';
-       from = to = strtol(str, &endptr, 10);
+       from = to = strtoul(str, &endptr, 10);
        if (*endptr != '\0' || from < 0 || from >= MAX_TPM_PCRS)
                goto err;
 
        if (sep) {
                str = sep + 1;
-               to = strtol(str, &endptr, 10);
+               to = strtoul(str, &endptr, 10);
 
                if (*endptr != '\0' || to < 0 || to >= MAX_TPM_PCRS)
                        goto err;
@@ -2760,6 +2814,30 @@
                          written, buf, 0, NULL);
 }
 
+void tpm2_add_locality(STACK_OF(TSSOPTPOLICY) *sk, UINT8 locality,
+                      TPMT_HA *digest)
+{
+       TSSOPTPOLICY *policy = TSSOPTPOLICY_new();
+       BYTE buf[5];
+       BYTE *buffer = buf;
+       UINT16 written = 0;
+       INT32 size = sizeof(buf);
+       const TPM_CC cc = TPM_CC_PolicyLocality;
+
+       TSS_TPM_CC_Marshal(&cc, &written, &buffer, &size);
+       TSS_UINT8_Marshal(&locality, &written, &buffer, &size);
+
+       ASN1_INTEGER_set(policy->CommandCode, cc);
+       ASN1_STRING_set(policy->CommandPolicy, buf + 4, written - 4);
+
+       sk_TSSOPTPOLICY_push(sk, policy);
+
+       TSS_Hash_Generate(digest,
+                         TSS_GetDigestSize(digest->hashAlg),
+                         (uint8_t *)&digest->digest,
+                         written, buf, 0, NULL);
+}
+
 TPM_RC tpm2_add_signed_policy(STACK_OF(TSSOPTPOLICY) *sk, char *key_file,
                              TPMT_HA *digest)
 {
@@ -2825,6 +2903,50 @@
 
        return TPM_RC_SUCCESS;
 }
+
+TPM_RC
+tpm2_add_policy_secret(TSS_CONTEXT *tssContext, STACK_OF(TSSOPTPOLICY) *sk,
+                      TPM_HANDLE handle, TPMT_HA *digest)
+{
+       TSSOPTPOLICY *policy;
+       BYTE buf[1024];
+       BYTE *buffer = buf;
+       UINT16 written = 0;
+       INT32 size = sizeof(buf);
+       const TPM_CC cc = TPM_CC_PolicySecret;
+       NAME_2B name;
+       DIGEST_2B policyRef = {0};
+       TPM_RC rc;
+       TPM_HANDLE intHandle = tpm2_handle_int(tssContext, handle);
+
+       rc = tpm2_readname(tssContext, intHandle, &name);
+       if (rc)
+               return rc;
+       policy = TSSOPTPOLICY_new();
+       TSS_TPM_CC_Marshal(&cc, &written, &buffer, &size);
+       TSS_UINT32_Marshal(&handle, &written, &buffer, &size);
+       TSS_TPM2B_NAME_Marshal((TPM2B_NAME *)&name, &written, &buffer, &size);
+       TSS_TPM2B_DIGEST_Marshal((TPM2B_DIGEST *)&policyRef, &written, &buffer, 
&size);
+
+       ASN1_INTEGER_set(policy->CommandCode, cc);
+       ASN1_STRING_set(policy->CommandPolicy, buf + 4, written - 4);
+       sk_TSSOPTPOLICY_push(sk, policy);
+
+       TSS_Hash_Generate(digest,
+                         TSS_GetDigestSize(digest->hashAlg),
+                         (uint8_t *)&digest->digest,
+                         4, buf, /* CC */
+                         name.size, name.name, /* name */
+                         0, NULL);
+       TSS_Hash_Generate(digest,
+                         TSS_GetDigestSize(digest->hashAlg),
+                         (uint8_t *)&digest->digest, /* intermediate digest */
+                         policyRef.size, policyRef.buffer,
+                         0, NULL);
+
+
+       return TPM_RC_SUCCESS;
+}
 
 EVP_PKEY *
 openssl_read_public_key(char *filename)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/provider/store.c 
new/openssl_tpm2_engine-4.1.1/src/provider/store.c
--- old/openssl_tpm2_engine-4.0.2/src/provider/store.c  2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/provider/store.c  2024-01-02 
16:52:46.000000000 +0100
@@ -85,7 +85,8 @@
 
                        rc = tpm2_get_bound_handle(tssContext, &session, key, 
NULL);
                        if (rc == TPM_RC_SUCCESS) {
-                               rc = tpm2_ReadPublic(tssContext, key, NULL, 
session);
+                               rc = tpm2_ReadPublic(tssContext, key, NULL,
+                                                    session, NULL);
                                if (rc)
                                        tpm2_flush_handle(tssContext, session);
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/create_tpm2_key.1.in 
new/openssl_tpm2_engine-4.1.1/src/tools/create_tpm2_key.1.in
--- old/openssl_tpm2_engine-4.0.2/src/tools/create_tpm2_key.1.in        
2023-12-05 04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/create_tpm2_key.1.in        
2024-01-02 16:52:46.000000000 +0100
@@ -64,6 +64,18 @@
 wrapped, like the template (must be standard restricted decryption
 key) and the name hash (must be sha256).
 
+[Secrets in Other Objects]
+
+When the option --secrets <handle> is used, it creates a key whose
+authorization password is conditioned on the password of a different
+object identified by <handle>.  Usually this is a permanent NV index,
+but could be any object.  The design of this policy is to allow the
+password to be changed without updating the key (simply by changing
+the authorization of the other object).  Because OpenSSL can only
+request a single password, keys with a --secret policy may not
+additionally have an --auth option to also require passing in the
+password embedded in the key.
+
 [Signed Policies]
 
 When the option --signed-policy <key> is used, it creates a key whose
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/create_tpm2_key.c 
new/openssl_tpm2_engine-4.1.1/src/tools/create_tpm2_key.c
--- old/openssl_tpm2_engine-4.0.2/src/tools/create_tpm2_key.c   2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/create_tpm2_key.c   2024-01-02 
16:52:46.000000000 +0100
@@ -29,6 +29,8 @@
 #define OPT_DEPRECATED 0x1ff
 #define OPT_RESTRICTED 0x1fe
 #define OPT_SIGNED_POLICY 0x1fd
+#define OPT_LOCALITY 0x1fc
+#define OPT_SECRET 0x1fb
 
 static struct option long_options[] = {
        {"auth", 0, 0, 'a'},
@@ -39,6 +41,7 @@
        {"parent-handle", 1, 0, 'p'},
        {"pcr-lock", 1, 0, 'x'},
        {"signed-policy", 1, 0, OPT_SIGNED_POLICY },
+       {"locality", 1, 0, OPT_LOCALITY },
        {"wrap", 1, 0, 'w'},
        {"version", 0, 0, 'v'},
        {"password", 1, 0, 'k'},
@@ -49,6 +52,7 @@
        {"key-policy", 1, 0, 'c'},
        {"import", 1, 0, 'i'},
        {"restricted", 0, 0, OPT_RESTRICTED },
+       {"secret", 1, 0, OPT_SECRET },
        /*
         * The option --deprecated allows us to create old format keys
         * for the purposes of testing.  It should never be used in
@@ -98,9 +102,14 @@
                "\t-x, --pcr-lock <pcrs>         Lock the created key to the 
specified PCRs\n"
                "                                By current value.  See PCR 
VALUES for\n"
                "                                details about formatting\n"
+               "\t--locality <loc>              Can only be used in a set of 
localities\n"
+               "                                described by the <loc> 
bitmap\n"
                "\t--signed-policy <key>         Add a signed policy directive 
that allows\n"
                "\t                              policies signed by the 
specified public <key>\n"
                "\t                              to authorize use of the key\n"
+               "\t--secret <handle>             Tie authorization of the key 
to the\n"
+               "\t                              Authorization of a different 
object\n"
+               "\t                              Identified by <handle>.\n"
                "\n"
                "Report bugs to " PACKAGE_BUGREPORT "\n",
                argv0);
@@ -448,7 +457,7 @@
        int option_index, c;
        const char *reason;
        TSS_CONTEXT *tssContext = NULL;
-       TPM_HANDLE parent = TPM_RH_OWNER, phandle;
+       TPM_HANDLE parent = TPM_RH_OWNER, phandle, secret_handle = 0;
        TPM_RC rc;
        BYTE pubkey[sizeof(TPM2B_PUBLIC)],privkey[sizeof(TPM2B_PRIVATE)], 
*buffer;
        uint16_t pubkey_len, privkey_len;
@@ -478,7 +487,8 @@
        int restricted = 0;
        char *parent_str = NULL;
        TPML_PCR_SELECTION pcr_lock = { 0 };
-       int has_policy = 0;
+       int has_policy = 0, has_locality = 0;
+       UINT8 locality = 0;
 
        OpenSSL_add_all_digests();
        /* may be needed to decrypt the key */
@@ -573,6 +583,14 @@
                        case OPT_SIGNED_POLICY:
                                signed_policy = optarg;
                                break;
+                       case OPT_LOCALITY:
+                               has_locality = 1;
+                               locality = strtoul(optarg, NULL, 0);
+                               break;
+                       case OPT_SECRET:
+                               secret_handle = strtoul(optarg, NULL, 0);
+                               has_policy = 1;
+                               break;
                        default:
                                printf("Unknown option '%c'\n", c);
                                usage(argv[0]);
@@ -627,7 +645,13 @@
                exit(1);
        }
 
-       if (pcr_lock.count != 0 || policyFilename || signed_policy)
+       if (has_locality && locality == 0) {
+               fprintf(stderr, "zero is an illegal locality bitmap\n");
+               exit(1);
+       }
+
+       if (pcr_lock.count != 0 || policyFilename || signed_policy ||
+           has_locality)
                has_policy = 1;
 
        digest.hashAlg = name_alg;
@@ -671,6 +695,9 @@
                        tpm2_add_auth_policy(sk, &digest);
        }
 
+       if (has_locality)
+               tpm2_add_locality(sk, locality, &digest);
+
        if (import) {
                EVP_PKEY *p_pkey = openssl_read_public_key(import);
                EVP_PKEY *pkey = openssl_read_key(wrap);
@@ -762,6 +789,9 @@
                }
        }
 
+       if (secret_handle)
+               tpm2_add_policy_secret(tssContext, sk, secret_handle, &digest);
+
        if (parent_str) {
                parent = tpm2_get_parent(tssContext, parent_str);
                if (parent == 0) {
@@ -947,7 +977,8 @@
        size = sizeof(privkey);
        TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)priv, &privkey_len, &buffer, 
&size);
        tpm2_write_tpmfile(filename, pubkey, pubkey_len,
-                          privkey, privkey_len, auth == NULL, parent, sk,
+                          privkey, privkey_len,
+                          auth == NULL && secret_handle == 0, parent, sk,
                           version, enc_secret);
        tpm2_free_policy(sk);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/seal_tpm2_data.1.in 
new/openssl_tpm2_engine-4.1.1/src/tools/seal_tpm2_data.1.in
--- old/openssl_tpm2_engine-4.0.2/src/tools/seal_tpm2_data.1.in 2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/seal_tpm2_data.1.in 2024-01-02 
16:52:46.000000000 +0100
@@ -40,6 +40,18 @@
 wrapped, like the template (must be standard restricted decryption
 key) and the name hash (must be sha256).
 
+[Secrets in Other Objects]
+
+When the option --secrets <handle> is used, it creates a sealed blob
+whose authorization password is conditioned on the password of a
+different object identified by <handle>.  Usually this is a permanent
+NV index, but could be any object.  The design of this policy is to
+allow the password to be changed without updating the sealed blob
+(simply by changing the authorization of the other object).  Because
+most unseal applications can only request a single password, blobs
+with a --secret policy may not additionally have an --auth option to
+also require passing in the password embedded in the blob.
+
 [Signed Policies]
 
 When the option --signed-policy <key> is used, it creates a sealed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/src/tools/seal_tpm2_data.c 
new/openssl_tpm2_engine-4.1.1/src/tools/seal_tpm2_data.c
--- old/openssl_tpm2_engine-4.0.2/src/tools/seal_tpm2_data.c    2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/seal_tpm2_data.c    2024-01-02 
16:52:46.000000000 +0100
@@ -22,6 +22,8 @@
 #include "tpm2-common.h"
 
 #define OPT_SIGNED_POLICY 0x1fd
+#define OPT_LOCALITY 0x1fc
+#define OPT_SECRET 0x1fb
 
 static struct option long_options[] = {
        {"auth", 0, 0, 'a'},
@@ -29,7 +31,9 @@
        {"help", 0, 0, 'h'},
        {"parent-handle", 1, 0, 'p'},
        {"pcr-lock", 1, 0, 'x'},
+       {"locality", 1, 0, OPT_LOCALITY },
        {"signed-policy", 1, 0, OPT_SIGNED_POLICY },
+       {"secret", 1, 0, OPT_SECRET },
        {"version", 0, 0, 'v'},
        {"password", 1, 0, 'k'},
        {"da", 0, 0, 'd'},
@@ -78,9 +82,14 @@
                "\t-x, --pcr-lock <pcrs>         Lock the created key to the 
specified PCRs\n"
                "                                By current value.  See PCR 
VALUES for\n"
                "                                details about formatting\n"
+               "\t--locality <loc>              Can only be unsealed in a set 
of localities\n"
+               "                                described by the <loc> 
bitmap\n"
                "\t--signed-policy <key>         Add a signed policy directive 
that allows\n"
                "\t                              policies signed by the 
specified public <key>\n"
                "\t                              to authorize unsealing\n"
+               "\t--secret <handle>             Tie authorization of the key 
to the\n"
+               "\t                              Authorization of a different 
object\n"
+               "\t                              Identified by <handle>.\n"
                "\t-i, --import <pubkey>         Create an importable key with 
the outer\n"
                "                                wrapper encrypted to 
<pubkey>\n"
                "\t-c, --policy                  Specify a policy for unsealing 
the data\n"
@@ -123,7 +132,7 @@
        const char *reason = ""; /* gcc 4.8.5 gives spurious uninitialized 
warning without this */
        TPMT_HA digest;
        uint32_t sizeInBytes;
-       TPM_HANDLE authHandle;
+       TPM_HANDLE authHandle, secret_handle = 0;
        STACK_OF(TSSOPTPOLICY) *sk = NULL;
        TPM2B_SENSITIVE_CREATE inSensitive;
        TPM2B_PUBLIC inPublic;
@@ -143,6 +152,7 @@
        int has_policy = 0;
        char *signed_policy = NULL;
        ENCRYPTED_SECRET_2B secret, *enc_secret = NULL;
+       int has_locality = 0, locality = 0;
 
        pcr_lock.count = 0;
 
@@ -213,6 +223,14 @@
                case OPT_SIGNED_POLICY:
                        signed_policy = optarg;
                        break;
+               case OPT_LOCALITY:
+                       has_locality = 1;
+                       locality = strtoul(optarg, NULL, 0);
+                       break;
+               case OPT_SECRET:
+                       has_policy = 1;
+                       secret_handle = strtoul(optarg, NULL, 0);
+                       break;
                default:
                        printf("Unknown option '%c'\n", c);
                        usage(argv[0]);
@@ -241,7 +259,13 @@
                exit(1);
        }
 
-       if (pcr_lock.count != 0 || policyFilename || signed_policy)
+       if (has_locality && locality == 0) {
+               fprintf(stderr, "zero is an illegal locality bitmap\n");
+               exit(1);
+       }
+
+       if (pcr_lock.count != 0 || policyFilename || signed_policy ||
+           has_locality)
                has_policy = 1;
 
        digest.hashAlg = name_alg;
@@ -322,6 +346,12 @@
                }
        }
 
+       if (has_locality)
+               tpm2_add_locality(sk, locality, &digest);
+
+       if (secret_handle)
+               tpm2_add_policy_secret(tssContext, sk, secret_handle, &digest);
+
        tpm2_public_template_seal(p);
 
        if (has_policy) {
@@ -427,7 +457,8 @@
        TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)&outPrivate, &privkey_len,
                                  &buffer, &size);
        tpm2_write_tpmfile(filename, pubkey, pubkey_len,
-                          privkey, privkey_len, data_auth == NULL,
+                          privkey, privkey_len,
+                          data_auth == NULL && secret_handle == 0,
                           parent, sk, 2, enc_secret);
 
  out_flush:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/signed_tpm2_policy.1.in 
new/openssl_tpm2_engine-4.1.1/src/tools/signed_tpm2_policy.1.in
--- old/openssl_tpm2_engine-4.0.2/src/tools/signed_tpm2_policy.1.in     
2023-12-05 04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/signed_tpm2_policy.1.in     
2024-01-02 16:52:46.000000000 +0100
@@ -22,6 +22,18 @@
 
  sha512:1,3-5 means PCRs 1,3,4 and 5 in the sha512 bank
 
+[Secrets in Other Objects]
+
+When the option --secrets <handle> is used, it creates a key whose
+authorization password is conditioned on the password of a different
+object identified by <handle>.  Usually this is a permanent NV index,
+but could be any object.  The design of this policy is to allow the
+password to be changed without updating the key (simply by changing
+the authorization of the other object).  Because OpenSSL can only
+request a single password, keys with a --secret policy may not
+additionally have an --auth option to also require passing in the
+password embedded in the key.
+
 [examples]
 
 list all signed policies:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/signed_tpm2_policy.c 
new/openssl_tpm2_engine-4.1.1/src/tools/signed_tpm2_policy.c
--- old/openssl_tpm2_engine-4.0.2/src/tools/signed_tpm2_policy.c        
2023-12-05 04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/signed_tpm2_policy.c        
2024-01-02 16:52:46.000000000 +0100
@@ -27,12 +27,16 @@
 #include "tpm2-common.h"
 
 #define OPT_SIGNED_POLICY 0x1fd
+#define OPT_LOCALITY 0x1fc
+#define OPT_SECRET 0x1fb
 
 static struct option long_options[] = {
        {"auth", 0, 0, 'a'},
        {"help", 0, 0, 'h'},
        {"pcr-lock", 1, 0, 'x'},
+       {"locality", 1, 0, OPT_LOCALITY },
        {"signed-policy", 1, 0, OPT_SIGNED_POLICY },
+       {"secret", 1, 0, OPT_SECRET},
        {"version", 0, 0, 'v'},
        {"key-policy", 1, 0, 'c'},
        {"engine", 1, 0, 'e'},
@@ -53,10 +57,14 @@
                "\t-x, --pcr-lock <pcrs>         Lock the created key to the 
specified PCRs\n"
                "                                By current value.  See PCR 
VALUES for\n"
                "                                details about formatting\n"
-               "\n"
+               "\t--locality <loc>              Can only be used in a set of 
localities\n"
+               "                                described by the <loc> 
bitmap\n"
                "\t--signed-policy <key>         Add a signed policy directive 
that allows\n"
                "\t                              policies signed by the 
specified public <key>\n"
                "\t                              to authorize use of the key\n"
+               "\t--secret <handle>             Tie authorization of the key 
to the\n"
+               "\t                              Authorization of a different 
object\n"
+               "\t                              Identified by <handle>.\n"
                "\t-n, --policy-name <name>      Optional name to annotate the 
policy with\n"
                "\n"
                "Report bugs to " PACKAGE_BUGREPORT "\n",
@@ -110,6 +118,9 @@
        TPMT_HA digest;
        int size;
        TPML_PCR_SELECTION pcr_lock = { 0 };
+       int has_locality = 0;
+       int locality = 0;
+       int secret_handle = 0;
        STACK_OF(TSSAUTHPOLICY) *sk;
        enum cmd {
                CMD_ADD = 0,
@@ -177,6 +188,13 @@
                        case OPT_SIGNED_POLICY:
                                signed_policy = optarg;
                                break;
+                       case OPT_LOCALITY:
+                               has_locality = 1;
+                               locality = strtoul(optarg, NULL, 0);
+                               break;
+                       case OPT_SECRET:
+                               secret_handle = strtoul(optarg, NULL, 0);
+                               break;
                        default:
                                printf("Unknown option '%c'\n", c);
                                usage(argv0);
@@ -190,6 +208,11 @@
                usage(argv0);
        }
 
+       if (has_locality && locality == 0) {
+               fprintf(stderr, "zero is an illegal locality bitmap\n");
+               exit(1);
+       }
+
        switch(cmd) {
        case CMD_ADD:
                filename = argv[argc - 2];
@@ -254,8 +277,34 @@
                        }
                }
 
+               if (has_locality)
+                       tpm2_add_locality(ap->policy, locality, &digest);
+
+               if (secret_handle) {
+                       TSS_CONTEXT *tssContext = NULL;
+                       const char *dir;
+
+                       dir = tpm2_set_unique_tssdir();
+                       rc = tpm2_create(&tssContext, dir);
+                       if (rc) {
+                               reason = "TSS_Create";
+                               goto out_free_policy;
+                       }
+
+                       rc = tpm2_add_policy_secret(tssContext, ap->policy,
+                                                   secret_handle, &digest);
+                       TSS_Delete(tssContext);
+                       tpm2_rm_tssdir(dir);
+                       if (rc) {
+                               reason = "create object authorization policy";
+                               goto out_free_policy;
+                       }
+               }
+
+
                rc = tpm2_new_signed_policy(filename, policy_signing_key,
-                                           engine, ap, &digest);
+                                           engine, ap, &digest,
+                                           auth || secret_handle);
                if (rc == 0)
                        exit(0);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/src/tools/unseal_tpm2_data.c 
new/openssl_tpm2_engine-4.1.1/src/tools/unseal_tpm2_data.c
--- old/openssl_tpm2_engine-4.0.2/src/tools/unseal_tpm2_data.c  2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/src/tools/unseal_tpm2_data.c  2024-01-02 
16:52:46.000000000 +0100
@@ -73,6 +73,7 @@
        uint32_t parent, session;
        UI_METHOD *ui = UI_create_method("unseal");
        struct app_data *app_data;
+       const char *auth;
 
        while (1) {
                option_index = 0;
@@ -156,17 +157,13 @@
                goto out_flush_data;
        }
 
-       if (app_data->req_policy_session) {
-               rc = tpm2_init_session(tssContext, session,
-                                      app_data, name_alg);
-               if (rc) {
-                       reason = "tpm2_init_session";
-                       goto out_flush_session;
-               }
+       rc = tpm2_init_session(tssContext, session, app_data, &auth);
+       if (rc) {
+               reason = "tpm2_init_session";
+               goto out_flush_session;
        }
 
-       rc = tpm2_Unseal(tssContext, itemHandle, &outData, session,
-                        app_data->auth);
+       rc = tpm2_Unseal(tssContext, itemHandle, &outData, session, auth);
 
        if (rc) {
                reason = "TPM2_Unseal";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/tests/check_locality.sh 
new/openssl_tpm2_engine-4.1.1/tests/check_locality.sh
--- old/openssl_tpm2_engine-4.0.2/tests/check_locality.sh       1970-01-01 
01:00:00.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/tests/check_locality.sh       2024-01-02 
16:52:46.000000000 +0100
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -x
+##
+# The TPM emulators always run in locality 0, so the only tests
+# we can do is create a key including and excluding locality zero
+# and check that one loads and the other doesn't
+##
+LOCALITY_01234=0x1f
+LOCALITY_1234=0x1e
+echo "This is a message" > plain.txt
+DATA="Test some data"
+
+${bindir}/create_tpm2_key --ecc prime256v1 --locality ${LOCALITY_01234} 
key.tpm || exit 1
+openssl pkeyutl -sign $ENGINE $KEYFORM -inkey key.tpm -in plain.txt -out 
tmp.msg|| exit 1
+echo "${DATA}"|${bindir}/seal_tpm2_data --locality ${LOCALITY_01234} key.tpm
+${bindir}/unseal_tpm2_data key.tpm|grep -q "${DATA}" || exit 1
+
+${bindir}/create_tpm2_key --ecc prime256v1 --locality ${LOCALITY_1234} key.tpm 
|| exit 1
+openssl pkeyutl -sign $ENGINE $KEYFORM -inkey key.tpm -in plain.txt -out 
tmp.msg&& exit 1
+echo "${DATA}"|${bindir}/seal_tpm2_data --locality ${LOCALITY_1234} key.tpm
+${bindir}/unseal_tpm2_data key.tpm && exit 1
+
+exit 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openssl_tpm2_engine-4.0.2/tests/check_secret_policies.sh 
new/openssl_tpm2_engine-4.1.1/tests/check_secret_policies.sh
--- old/openssl_tpm2_engine-4.0.2/tests/check_secret_policies.sh        
1970-01-01 01:00:00.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/tests/check_secret_policies.sh        
2024-01-02 16:52:46.000000000 +0100
@@ -0,0 +1,49 @@
+#!/bin/bash
+set -x
+
+##
+# First create a NV object and a permanent key with a known authorization
+##
+PASSWORD="RNDPWD${RANDOM}"
+NVINDEX=0x01000002
+NVKEY=0x81005555
+DATA="Some Random Data ${RANDOM}"
+tssnvdefinespace -hi o -ha ${NVINDEX} -pwdn ${PASSWORD} || exit 1
+# note index is not initialized (but shouldn't need to be)
+key=$(tsscreateprimary -hi o -st -ecc nistp256 -pwdk ${PASSWORD}|sed 's/Handle 
//') && \
+tssevictcontrol -hi o -ho ${key} -hp ${NVKEY} && \
+tssflushcontext -ha ${key}
+# create a policy key
+openssl genpkey -out policy.key -algorithm EC -pkeyopt 
ec_paramgen_curve:prime256v1 || exit 1
+openssl pkey -in policy.key -pubout -out policy.pub
+
+##
+# Tests for each index, create an ordinary key a sealed object and a
+# signed policy key each with --secret and then verify they fail with
+# no password and accept the object password
+##
+for index in ${NVINDEX} ${NVKEY}; do
+
+    ${bindir}/create_tpm2_key --secret ${index} key.tpm || exit 1
+    echo ${DATA}|${bindir}/seal_tpm2_data --secret ${index} seal.tpm || exit 1
+    echo ${DATA} > plain.txt
+    openssl pkey $ENGINE $INFORM -in key.tpm -passin pass:" " -pubout -out 
key.pub || exit 1
+    ${bindir}/create_tpm2_key --signed-policy policy.pub skey.tpm
+    ${bindir}/signed_tpm2_policy add --policy-name "secret" --secret ${index} 
skey.tpm policy.key || exit 1
+    openssl pkey $ENGINE $INFORM -in skey.tpm -passin pass:" " -pubout -out 
skey.pub || exit 1
+
+    # Verify use without password fails
+
+    openssl pkeyutl -sign -passin pass:" " -in plain.txt $ENGINE $KEYFORM 
-inkey key.tpm -out tmp.msg && exit 1
+    ${bindir}/unseal_tpm2_data seal.tpm -k " " && exit 1
+    openssl pkeyutl -sign -passin pass:" " -in plain.txt $ENGINE $KEYFORM 
-inkey skey.tpm -out tmp.msg && exit 1
+
+    # verify use with object password works
+    openssl pkeyutl -sign -passin pass:${PASSWORD} -in plain.txt $ENGINE 
$KEYFORM -inkey key.tpm -out tmp.msg && \
+       openssl pkeyutl -verify -in plain.txt -sigfile tmp.msg -inkey key.pub 
-pubin || exit 1
+    ${bindir}/unseal_tpm2_data seal.tpm -k ${PASSWORD}| grep -q "${DATA}" || 
exit 1
+    openssl pkeyutl -sign -passin pass:${PASSWORD} -in plain.txt $ENGINE 
$KEYFORM -inkey skey.tpm -out tmp.msg && \
+       openssl pkeyutl -verify -in plain.txt -sigfile tmp.msg -inkey skey.pub 
-pubin || exit 1
+done
+
+exit 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/tests/engine/Makefile.am 
new/openssl_tpm2_engine-4.1.1/tests/engine/Makefile.am
--- old/openssl_tpm2_engine-4.0.2/tests/engine/Makefile.am      2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/tests/engine/Makefile.am      2024-01-02 
16:52:46.000000000 +0100
@@ -27,6 +27,8 @@
        ../restricted_parent.sh \
        ../seal_unseal.sh \
        ../check_signed_policies.sh \
+       ../check_locality.sh \
+       ../check_secret_policies.sh \
        ../dynamic_engine.sh \
        ../stop_sw_tpm.sh
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-4.0.2/tests/provider/Makefile.am 
new/openssl_tpm2_engine-4.1.1/tests/provider/Makefile.am
--- old/openssl_tpm2_engine-4.0.2/tests/provider/Makefile.am    2023-12-05 
04:47:13.000000000 +0100
+++ new/openssl_tpm2_engine-4.1.1/tests/provider/Makefile.am    2024-01-02 
16:52:46.000000000 +0100
@@ -29,6 +29,8 @@
        ../restricted_parent.sh \
        ../seal_unseal.sh \
        ../check_signed_policies.sh \
+       ../check_locality.sh \
+       ../check_secret_policies.sh \
        ../stop_sw_tpm.sh
 
 fail_connect.sh: tpm_server_found

Reply via email to