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 2023-02-01 16:39:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openssl_tpm2_engine (Old)
 and      /work/SRC/openSUSE:Factory/.openssl_tpm2_engine.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openssl_tpm2_engine"

Wed Feb  1 16:39:34 2023 rev:10 rq:1062393 version:3.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/openssl_tpm2_engine/openssl_tpm2_engine.changes  
2023-01-14 00:03:44.197892246 +0100
+++ 
/work/SRC/openSUSE:Factory/.openssl_tpm2_engine.new.32243/openssl_tpm2_engine.changes
       2023-02-01 16:49:00.417187926 +0100
@@ -1,0 +2,9 @@
+Tue Jan 31 21:17:40 UTC 2023 - james.bottom...@hansenpartnership.com
+
+- Update to version 3.3.1
+  * fix intermittent EC TPM_RC_KEY return
+  * add import section to man pages
+  * Add importable sealed data
+  * Fix name hash for importable keys and data
+
+-------------------------------------------------------------------

Old:
----
  openssl_tpm2_engine-3.2.1.tar.gz

New:
----
  openssl_tpm2_engine-3.3.1.tar.gz

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

Other differences:
------------------
++++++ openssl_tpm2_engine.spec ++++++
--- /var/tmp/diff_new_pack.D3Iddi/_old  2023-02-01 16:49:00.773190075 +0100
+++ /var/tmp/diff_new_pack.D3Iddi/_new  2023-02-01 16:49:00.781190124 +0100
@@ -18,7 +18,7 @@
 
 
 Name:           openssl_tpm2_engine
-Version:        3.2.1
+Version:        3.3.1
 Release:        0
 Summary:        OpenSSL TPM 2.0 interface engine plugin
 License:        LGPL-2.1-only

++++++ openssl_tpm2_engine-3.2.1.tar.gz -> openssl_tpm2_engine-3.3.1.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/configure.ac 
new/openssl_tpm2_engine-3.3.1/configure.ac
--- old/openssl_tpm2_engine-3.2.1/configure.ac  2023-01-12 21:56:04.000000000 
+0100
+++ new/openssl_tpm2_engine-3.3.1/configure.ac  2023-01-31 17:21:01.000000000 
+0100
@@ -2,7 +2,7 @@
 # configure.in for the OpenSSL TPM engine project
 #
 
-AC_INIT(openssl-tpm2-engine, 3.2.1, <openssl-tpm2-eng...@groups.io>)
+AC_INIT(openssl-tpm2-engine, 3.3.1, <openssl-tpm2-eng...@groups.io>)
 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-3.2.1/create_tpm2_key.1.in 
new/openssl_tpm2_engine-3.3.1/create_tpm2_key.1.in
--- old/openssl_tpm2_engine-3.2.1/create_tpm2_key.1.in  2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/create_tpm2_key.1.in  2023-01-31 
17:21:01.000000000 +0100
@@ -45,6 +45,25 @@
 
  sha512:1,3-5 means PCRs 1,3,4 and 5 in the sha512 bank
 
+[Import]
+
+In some cases, there may be a need to wrap a key without access to the
+TPM it will be use on.  For these cases an importable key may be
+specified with the --import option.  For this to work, you must use a
+public key corresponding exactly to the one the importing TPM will use
+(Note: only Elliptic Curve parents are currently supported).  For
+instance the owner seed elliptic curve storage key may be produced as
+
+tsscreateprimary -hi o -st -ecc nistp256 -opem parent.pub
+
+Then an importable key may be wrapped to the TPM via:
+
+create_tpm2_key --import parent.pub --wrap key.priv key.tpm
+
+Note that certain parameters must be assumed about a parent when it is
+wrapped, like the template (must be standard restricted decryption
+key) and the name hash (must be sha256).
+
 [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-3.2.1/create_tpm2_key.c 
new/openssl_tpm2_engine-3.3.1/create_tpm2_key.c
--- old/openssl_tpm2_engine-3.2.1/create_tpm2_key.c     2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/create_tpm2_key.c     2023-01-31 
17:21:01.000000000 +0100
@@ -204,141 +204,6 @@
        return TPM_RC_SUCCESS;
 }
 
-TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
-                     TPMT_SENSITIVE *s,
-                     TPMT_PUBLIC *pub,
-                     PRIVATE_2B *p,
-                     ENCRYPTED_SECRET_2B *enc_secret)
-{
-       PRIVATE_2B secret, seed;
-       /*  amount of room in the buffer for the integrity TPM2B */
-       const int name_alg_size = TSS_GetDigestSize(pub->nameAlg);
-       const int integrity_skip = name_alg_size + 2;
-       //      BYTE *integrity = p->buffer;
-       BYTE *sensitive = p->buffer + integrity_skip;
-       BYTE *buf;
-       TPM2B *t2b;
-       INT32 size;
-       size_t ssize;
-       UINT16 bsize, written = 0;
-       EVP_PKEY *ephemeral = NULL;
-       EVP_PKEY_CTX *ctx;
-       TPM2B_ECC_POINT pub_pt, ephemeral_pt;
-       EC_KEY *e_parent, *e_ephemeral;
-       const EC_GROUP *group;
-       unsigned char aeskey[T2_AES_KEY_BYTES];
-       /* hmac follows namealg, so set to max size */
-       KEY_2B hmackey;
-       TPMT_HA hmac;
-       NAME_2B name;
-       DIGEST_2B digest;
-       unsigned char null_iv[AES_128_BLOCK_SIZE_BYTES];
-       TPM2B null_2b;
-
-       null_2b.size = 0;
-
-       if (EVP_PKEY_type(EVP_PKEY_id(parent)) != EVP_PKEY_EC) {
-               printf("Can only currently wrap to EC parent\n");
-               return TPM_RC_ASYMMETRIC;
-       }
-
-       e_parent = EVP_PKEY_get1_EC_KEY(parent);
-       group = EC_KEY_get0_group(e_parent);
-
-       /* marshal the sensitive into a TPM2B */
-       t2b = (TPM2B *)sensitive;
-       buf = t2b->buffer;
-       size = sizeof(p->buffer) - integrity_skip;
-       bsize = 0;
-       TSS_TPMT_SENSITIVE_Marshal(s, &bsize, &buf, &size);
-       buf = (BYTE *)&t2b->size;
-       size = 2;
-       TSS_UINT16_Marshal(&bsize, &written, &buf, &size);
-       /* set the total size of the private entity */
-       p->size = bsize + sizeof(UINT16) + integrity_skip;
-
-       /* compute the elliptic curve shared (and encrypted) secret */
-       ctx = EVP_PKEY_CTX_new(parent, NULL);
-       if (!ctx)
-               goto openssl_err;
-       if (EVP_PKEY_keygen_init(ctx) != 1)
-               goto openssl_err;
-       EVP_PKEY_keygen(ctx, &ephemeral);
-       if (!ephemeral)
-               goto openssl_err;
-       /* otherwise the ctx free will free the key */
-#if OPENSSL_VERSION_NUMBER < 0x10100000
-       CRYPTO_add(&ephemeral->references, 1, CRYPTO_LOCK_EVP_PKEY);
-#else
-       EVP_PKEY_up_ref(ephemeral);
-#endif
-       EVP_PKEY_CTX_free(ctx);
-
-       e_ephemeral = EVP_PKEY_get1_EC_KEY(ephemeral);
-
-       /* now begin again with the ephemeral private key because the
-        * context must be initialised with the private key */
-       ctx = EVP_PKEY_CTX_new(ephemeral, NULL);
-       if (!ctx)
-               goto openssl_err;
-       if (EVP_PKEY_derive_init(ctx) != 1)
-               goto openssl_err;
-       if (EVP_PKEY_derive_set_peer(ctx, parent) != 1)
-               goto openssl_err;
-       ssize = sizeof(secret.buffer);
-       if (EVP_PKEY_derive(ctx, secret.buffer, &ssize) != 1)
-               goto openssl_err;
-       secret.size = ssize;
-       EVP_PKEY_CTX_free(ctx);
-
-       tpm2_get_public_point(&pub_pt, group, EC_KEY_get0_public_key(e_parent));
-       tpm2_get_public_point(&ephemeral_pt, group,
-                             EC_KEY_get0_public_key(e_ephemeral));
-       EC_KEY_free(e_parent);
-       EC_KEY_free(e_ephemeral);
-
-       /* now pass the secret through KDFe to get the shared secret
-        * The size is the size of the parent name algorithm which we
-        * assume to be sha256 */
-       TSS_KDFE(seed.buffer, pub->nameAlg, (TPM2B *)&secret, "DUPLICATE",
-                (TPM2B *)&ephemeral_pt.point.x, (TPM2B *)&pub_pt.point.x,
-                SHA256_DIGEST_LENGTH*8);
-       seed.size = SHA256_DIGEST_LENGTH;
-
-       /* and finally through KDFa to get the aes symmetric encryption key */
-       tpm2_ObjectPublic_GetName(&name, pub);
-       TSS_KDFA(aeskey, pub->nameAlg, (TPM2B *)&seed, "STORAGE",
-                (TPM2B *)&name, &null_2b, T2_AES_KEY_BITS);
-       /* and then the outer HMAC key */
-       hmackey.size = name_alg_size;
-       TSS_KDFA(hmackey.buffer, pub->nameAlg, (TPM2B *)&seed, "INTEGRITY",
-                &null_2b, &null_2b, name_alg_size * 8);
-       /* OK the ephermeral public point is now the encrypted secret */
-       size = sizeof(ephemeral_pt);
-       buf = enc_secret->secret;
-       TSS_TPM2B_ECC_POINT_Marshal(&ephemeral_pt, &written,
-                                   &buf, &size);
-       enc_secret->size = written;
-       memset(null_iv, 0, sizeof(null_iv));
-       TSS_AES_EncryptCFB(sensitive, T2_AES_KEY_BITS, aeskey, null_iv,
-                          p->size - integrity_skip, sensitive);
-       hmac.hashAlg = pub->nameAlg;
-       TSS_HMAC_Generate(&hmac, (TPM2B_KEY *)&hmackey,
-                         p->size - integrity_skip, sensitive,
-                         name.size, name.name,
-                         0, NULL);
-       digest.size  = name_alg_size;
-       memcpy(digest.buffer, &hmac.digest, digest.size);
-       size = integrity_skip;
-       buf = p->buffer;
-       TSS_TPM2B_DIGEST_Marshal((TPM2B_DIGEST *)&digest, &written, &buf, 
&size);
-       return TPM_RC_SUCCESS;
-
- openssl_err:
-       ERR_print_errors_fp(stderr);
-       return TPM_RC_ASYMMETRIC;
-}
-
 EVP_PKEY *
 openssl_read_key(char *filename)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/seal_tpm2_data.1.in 
new/openssl_tpm2_engine-3.3.1/seal_tpm2_data.1.in
--- old/openssl_tpm2_engine-3.2.1/seal_tpm2_data.1.in   2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/seal_tpm2_data.1.in   2023-01-31 
17:21:01.000000000 +0100
@@ -21,6 +21,25 @@
 
  sha512:1,3-5 means PCRs 1,3,4 and 5 in the sha512 bank
 
+[Import]
+
+In some cases, there may be a need to wrap a key without access to the
+TPM it will be use on.  For these cases an importable key may be
+specified with the --import option.  For this to work, you must use a
+public key corresponding exactly to the one the importing TPM will use
+(Note: only Elliptic Curve parents are currently supported).  For
+instance the owner seed elliptic curve storage key may be produced as
+
+tsscreateprimary -hi o -st -ecc nistp256 -opem parent.pub
+
+Then a sealed data file may be wrapped to the TPM via:
+
+echo "data" | seal_tpm2_data --import parent.pub seal.tpm
+
+Note that certain parameters must be assumed about a parent when it is
+wrapped, like the template (must be standard restricted decryption
+key) and the name hash (must be sha256).
+
 [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-3.2.1/seal_tpm2_data.c 
new/openssl_tpm2_engine-3.3.1/seal_tpm2_data.c
--- old/openssl_tpm2_engine-3.2.1/seal_tpm2_data.c      2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/seal_tpm2_data.c      2023-01-31 
17:21:01.000000000 +0100
@@ -14,6 +14,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <openssl/rand.h>
 #include <openssl/ui.h>
 
 #include "tpm2-tss.h"
@@ -35,6 +36,7 @@
        {"policy", 1, 0, 'c'},
        {"nomigrate", 0, 0, 'm'},
        {"name-scheme", 1, 0, 'n'},
+       {"import", 1, 0, 'i'},
        {0, 0, 0, 0}
 };
 
@@ -78,7 +80,10 @@
                "                                details about formatting\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                              to authorize unsealing\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"
                "\n"
                "\n"
                "Report bugs to " PACKAGE_BUGREPORT "\n",
@@ -86,6 +91,24 @@
        exit(-1);
 }
 
+void wrap_data(TPMT_SENSITIVE *s, const char *password, void *data,
+              int data_len)
+{
+       memset(s, 0, sizeof(*s));
+
+       s->sensitiveType = TPM_ALG_KEYEDHASH;
+       if (password) {
+               int len = strlen(password);
+
+               memcpy(VAL_2B(s->authValue, buffer), password, len);
+               VAL_2B(s->authValue, size) = len;
+       } else {
+               VAL_2B(s->authValue, size) = 0;
+       }
+       VAL_2B(s->sensitive.bits, size) = data_len;
+       memcpy(VAL_2B(s->sensitive.bits, buffer), data, data_len);
+}
+
 int main(int argc, char **argv)
 {
        int option_index, c;
@@ -95,8 +118,8 @@
        char *filename;
        uint32_t noda = TPMA_OBJECT_NODA, phandle;
        TPM_RC rc;
-       TSS_CONTEXT *tssContext;
-       const char *dir;
+       TSS_CONTEXT *tssContext = NULL;
+       const char *dir = NULL;
        const char *reason = ""; /* gcc 4.8.5 gives spurious uninitialized 
warning without this */
        TPMT_HA digest;
        uint32_t sizeInBytes;
@@ -115,15 +138,17 @@
        int32_t size;
        uint16_t pubkey_len, privkey_len;
        char *parent_str = NULL;
+       char *import = NULL;
        TPML_PCR_SELECTION pcr_lock;
        int has_policy = 0;
        char *signed_policy = NULL;
+       ENCRYPTED_SECRET_2B secret, *enc_secret = NULL;
 
        pcr_lock.count = 0;
 
        while (1) {
                option_index = 0;
-               c = getopt_long(argc, argv, "ak:b:hp:vdsun",
+               c = getopt_long(argc, argv, "ak:b:hp:vdsun:i:",
                                long_options, &option_index);
                if (c == -1)
                        break;
@@ -182,6 +207,9 @@
                case 'x':
                        tpm2_get_pcr_lock(&pcr_lock, optarg);
                        break;
+               case 'i':
+                       import = optarg;
+                       break;
                case OPT_SIGNED_POLICY:
                        signed_policy = optarg;
                        break;
@@ -208,6 +236,11 @@
                exit(1);
        }
 
+       if (pcr_lock.count != 0 && import) {
+               fprintf(stderr, "cannot specify pcr lock and import because 
pcrs may not be correct\n");
+               exit(1);
+       }
+
        if (pcr_lock.count != 0 || policyFilename || signed_policy)
                has_policy = 1;
 
@@ -254,39 +287,39 @@
                        tpm2_add_auth_policy(sk, &digest);
        }
 
-       dir = tpm2_set_unique_tssdir();
-       rc = tpm2_create(&tssContext, dir);
-       if (rc) {
-               reason = "TSS_Create";
-               goto out_rmdir;
-       }
-
-       if (pcr_lock.count != 0) {
-               rc = tpm2_pcr_lock_policy(tssContext, &pcr_lock,
-                                         sk, &digest);
+       if (!import) {
+               dir = tpm2_set_unique_tssdir();
+               rc = tpm2_create(&tssContext, dir);
                if (rc) {
-                       reason = "create pcr policy";
-                       goto out_free_auth;
+                       reason = "TSS_Create";
+                       goto out_rmdir;
                }
-       }
-
-       if (parent_str) {
-               parent = tpm2_get_parent(tssContext, parent_str);
-               if (parent == 0) {
-                       reason = "Invalid parent";
-                       goto out_delete;
+               if (pcr_lock.count != 0) {
+                       rc = tpm2_pcr_lock_policy(tssContext, &pcr_lock,
+                                                 sk, &digest);
+                       if (rc) {
+                               reason = "create pcr policy";
+                               goto out_free_auth;
+                       }
+               }
+               if (parent_str) {
+                       parent = tpm2_get_parent(tssContext, parent_str);
+                       if (parent == 0) {
+                               reason = "Invalid parent";
+                               goto out_delete;
+                       }
                }
-       }
 
-       if (tpm2_handle_mso(tssContext, parent, TPM_HT_PERMANENT)) {
-               rc = tpm2_load_srk(tssContext, &phandle, parent_auth,
-                                  NULL, parent, 1);
-               if (rc) {
+               if (tpm2_handle_mso(tssContext, parent, TPM_HT_PERMANENT)) {
+                       rc = tpm2_load_srk(tssContext, &phandle, parent_auth,
+                                          NULL, parent, 1);
+                       if (rc) {
                                reason = "tpm2_load_srk";
                                goto out_delete;
+                       }
+               } else {
+                       phandle = parent;
                }
-       } else {
-               phandle = parent;
        }
 
        tpm2_public_template_seal(p);
@@ -321,6 +354,37 @@
                        TPMA_OBJECT_FIXEDPARENT |
                        TPMA_OBJECT_FIXEDTPM;
 
+       if (import) {
+               TPMT_SENSITIVE ts;
+               EVP_PKEY *p_pkey = openssl_read_public_key(import);
+
+               wrap_data(&ts, data_auth, VAL_2B(s->data, buffer),
+                         VAL_2B(s->data, size));
+
+               /* random nonce for seed to add entropy to wrapping */
+               VAL_2B(ts.seedValue, size) = TSS_GetDigestSize(name_alg);
+               RAND_bytes(VAL_2B(ts.seedValue, buffer),
+                          VAL_2B(ts.seedValue, size));
+
+               /* fill in the unique area as Hash(seed||key) */
+               digest.hashAlg = name_alg;
+               TSS_Hash_Generate(&digest,
+                                 VAL_2B(ts.seedValue, size),
+                                 VAL_2B(ts.seedValue, buffer),
+                                 VAL_2B(ts.sensitive.bits, size),
+                                 VAL_2B(ts.sensitive.bits, buffer),
+                                 0, NULL);
+               VAL_2B(p->unique.keyedHash, size) = TSS_GetDigestSize(name_alg);
+               memcpy(VAL_2B(p->unique.keyedHash, buffer),
+                      &digest.digest, VAL_2B(p->unique.keyedHash, size));
+
+               outPublic = inPublic;
+               rc = tpm2_outerwrap(p_pkey, &ts, &outPublic.publicArea, 
&outPrivate, &secret);
+               if (rc)
+                       goto out_flush;
+               enc_secret = &secret;
+               goto write_file;
+       }
        /* use salted parameter encryption to hide the key */
        rc = tpm2_get_session_handle(tssContext, &authHandle, phandle,
                                             TPM_SE_HMAC, name_alg);
@@ -339,6 +403,9 @@
                goto out_flush;
        }
 
+       parent = tpm2_handle_ext(tssContext, parent);
+
+ write_file:
        buffer = pubkey;
        pubkey_len = 0;
        size = sizeof(pubkey);
@@ -349,18 +416,19 @@
        size = sizeof(privkey);
        TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)&outPrivate, &privkey_len,
                                  &buffer, &size);
-       parent = tpm2_handle_ext(tssContext, parent);
        tpm2_write_tpmfile(filename, pubkey, pubkey_len,
                           privkey, privkey_len, data_auth == NULL,
-                          parent, sk, 2, NULL);
-
+                          parent, sk, 2, enc_secret);
 
  out_flush:
-       tpm2_flush_srk(tssContext, phandle);
+       if (tssContext)
+               tpm2_flush_srk(tssContext, phandle);
  out_delete:
-       TSS_Delete(tssContext);
+       if (tssContext)
+               TSS_Delete(tssContext);
  out_rmdir:
-       rmdir(dir);
+       if (dir)
+               rmdir(dir);
  out_free_auth:
        free(data_auth);
  out_free_policy:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/tests/check_importable.sh 
new/openssl_tpm2_engine-3.3.1/tests/check_importable.sh
--- old/openssl_tpm2_engine-3.2.1/tests/check_importable.sh     2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/tests/check_importable.sh     2023-01-31 
17:21:01.000000000 +0100
@@ -6,21 +6,32 @@
 prim=$(tsscreateprimary -ecc nistp256 -hi o -opem srk.pub | sed 's/Handle //') 
|| exit 1
 tssflushcontext -ha ${prim} || exit 1
 
-# check an EC key with a cert and password
-openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out 
key.priv || exit 1
-${bindir}/create_tpm2_key --import srk.pub --wrap key.priv -a -k passw0rd 
key.tpm || exit 1
-openssl req -new -x509 -subj '/CN=test/' -key key.tpm -passin pass:passw0rd 
-engine tpm2 -keyform engine -out tmp.crt || exit 1
-openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
+for n in sha1 sha256 sha384; do
+    echo "Checking Name Hash $n"
+    if [ "$n" = "sha256" ]; then
+       POLICYFILE=policies/policy_pcr.txt
+    else
+       POLICYFILE=policies/policy_pcr${n}.txt
+    fi
+    # check an EC key with a cert and password
+    openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out 
key.priv || exit 1
+    ${bindir}/create_tpm2_key --import srk.pub --wrap key.priv -n ${n} -a -k 
passw0rd key.tpm || exit 1
+    openssl req -new -x509 -subj '/CN=test/' -key key.tpm -passin 
pass:passw0rd -engine tpm2 -keyform engine -out tmp.crt || exit 1
+    openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
 
-# Check the loadability of an importable key
-NV=81000201
-${bindir}/load_tpm2_key key.tpm ${NV} || exit 1
-openssl req -new -x509 -subj '/CN=test/' -key //nvkey:${NV} -passin 
pass:passw0rd -engine tpm2 -keyform engine -out tmp.crt || exit 1
-openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
-
-#check an RSA key with a cert and policy
-openssl genrsa 2048 > key.priv || exit 1
-${bindir}/create_tpm2_key --import srk.pub --wrap key.priv -a -k passw0rd -c 
policies/policy_authvalue.txt key.tpm || exit 1
-openssl req -new -x509 -subj '/CN=test/' -key key.tpm -passin pass:passw0rd 
-engine tpm2 -keyform engine -out tmp.crt || exit 1
-openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
+    # Check the loadability of an importable key
+    NV=81000201
+    ${bindir}/load_tpm2_key key.tpm ${NV} || exit 1
+    openssl req -new -x509 -subj '/CN=test/' -key //nvkey:${NV} -passin 
pass:passw0rd -engine tpm2 -keyform engine -out tmp.crt || exit 1
+    openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
+    tssevictcontrol -hi o -ho ${NV} -hp ${NV}
 
+    #check an RSA key with a cert and policy
+    openssl genrsa 2048 > key.priv || exit 1
+    tsspcrreset -ha 16
+    ${bindir}/create_tpm2_key --import srk.pub -n ${n} --wrap key.priv -c 
${POLICYFILE} key.tpm || exit 1
+    openssl req -new -x509 -subj '/CN=test/' -key key.tpm -engine tpm2 
-keyform engine -out tmp.crt && exit 1
+    tsspcrextend -ha 16 -ic aaa
+    openssl req -new -x509 -subj '/CN=test/' -key key.tpm -engine tpm2 
-keyform engine -out tmp.crt || exit 1
+    openssl verify -CAfile tmp.crt -check_ss_sig tmp.crt || exit 1
+done
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/tests/seal_unseal.sh 
new/openssl_tpm2_engine-3.3.1/tests/seal_unseal.sh
--- old/openssl_tpm2_engine-3.2.1/tests/seal_unseal.sh  2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/tests/seal_unseal.sh  2023-01-31 
17:21:01.000000000 +0100
@@ -1,37 +1,65 @@
 #!/bin/bash
-set -x
 
 bindir=${srcdir}/..
 
-##
-# test is
-# 1. Verify that a standard key can't be unsealed
-# 2. seal a phrase
-# 3. recover the same phrase on unseal
-##
-DATA="This is some DATA"
-AUTH="Passw0rd"
-${bindir}/create_tpm2_key key.tpm || exit 1;
-${bindir}/unseal_tpm2_data key.tpm 2> /dev/null && exit 1;
-echo $DATA | ${bindir}/seal_tpm2_data -a -k ${AUTH} seal.tpm || exit 1;
-${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 1;
-
-##
-# Check with policy
-# test is
-# 1. seal with a pcr lock and no auth
-# 2. verify unseal
-# 3. move PCR on and verify no unseal
-# 4. 1-3 with auth and pcr lock
-##
-echo $DATA | ${bindir}/seal_tpm2_data --pcr-lock 2,16 seal.tpm || exit 1;
-${bindir}/unseal_tpm2_data seal.tpm | grep -q "${DATA}" || exit 1;
-tsspcrextend -ha 16 -ic $RANDOM
-${bindir}/unseal_tpm2_data seal.tpm && exit 1
-echo $DATA | ${bindir}/seal_tpm2_data -a -k ${AUTH} --pcr-lock 2,16 seal.tpm 
|| exit 1;
-${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 1;
-tsspcrextend -ha 16 -ic $RANDOM
-${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm && exit 1
+for n in sha1 sha256 sha384; do
+    echo "Checking Name Hash $n"
+    ##
+    # test is
+    # 1. Verify that a standard key can't be unsealed
+    # 2. seal a phrase
+    # 3. recover the same phrase on unseal
+    ##
+    DATA="This is some DATA $n"
+    AUTH="Passw0rd"
+    ${bindir}/create_tpm2_key key.tpm || exit 1;
+    ${bindir}/unseal_tpm2_data key.tpm 2> /dev/null && exit 1;
+    echo $DATA | ${bindir}/seal_tpm2_data -n ${n} -a -k ${AUTH} seal.tpm || 
exit 1;
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 
1;
 
+    ##
+    # Check with policy
+    # test is
+    # 1. seal with a pcr lock and no auth
+    # 2. verify unseal
+    # 3. move PCR on and verify no unseal
+    # 4. 1-3 with auth and pcr lock
+    ##
+    echo $DATA | ${bindir}/seal_tpm2_data -n ${n} --pcr-lock 2,16 seal.tpm || 
exit 1;
+    ${bindir}/unseal_tpm2_data seal.tpm | grep -q "${DATA}" || exit 1;
+    tsspcrextend -ha 16 -ic $RANDOM
+    ${bindir}/unseal_tpm2_data seal.tpm && exit 1
+    echo $DATA | ${bindir}/seal_tpm2_data -a -k ${AUTH} --pcr-lock 2,16 
seal.tpm || exit 1;
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 
1;
+    tsspcrextend -ha 16 -ic $RANDOM
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm && exit 1
+
+    ##
+    # Check importable
+    # test is
+    # 1. create srk.pub as parent for import
+    # 2. seal with password
+    # 3. check unseal
+    # 4. seal with policy
+    # 5. check unseal
+    # 6. update PCR and check unseal failure
+    DATA="Some Different DATA $n"
+    if [ "$n" = "sha256" ]; then
+       POLICYFILE="policies/policy_pcr.txt"
+    else
+       POLICYFILE="policies/policy_pcr${n}.txt"
+    fi
+    prim=$(tsscreateprimary -hi o -st -ecc nistp256 -opem srk.pub | sed 
's/Handle //') || exit 1
+    tssflushcontext -ha $prim
+    TPM_INTERFACE_TYPE= echo $DATA | ${bindir}/seal_tpm2_data -n ${n} -a -k 
${AUTH} --import srk.pub seal.tpm || exit 1;
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 
1;
+    rm seal.tpm
+
+    TPM_INTERFACE_TYPE= echo $DATA | ${bindir}/seal_tpm2_data -n ${n} --import 
srk.pub --policy ${POLICYFILE} seal.tpm || exit 1;
+    tsspcrreset -ha 16
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm && exit 1
+    tsspcrextend -ha 16 -ic aaa
+    ${bindir}/unseal_tpm2_data -k ${AUTH} seal.tpm | grep -q "${DATA}" || exit 
1;
+done
 
 exit 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/tpm2-common.c 
new/openssl_tpm2_engine-3.3.1/tpm2-common.c
--- old/openssl_tpm2_engine-3.2.1/tpm2-common.c 2023-01-12 21:56:04.000000000 
+0100
+++ new/openssl_tpm2_engine-3.3.1/tpm2-common.c 2023-01-31 17:21:01.000000000 
+0100
@@ -1171,6 +1171,17 @@
        return 0;
 }
 
+int tpm2_curve_to_order(TPMI_ECC_CURVE curve)
+{
+       int i;
+
+       for (i = 0; tpm2_supported_curves[i].name != NULL; i++)
+               if (tpm2_supported_curves[i].curve == curve)
+                       return tpm2_supported_curves[i].C[5].s;
+
+       return 0;
+}
+
 TPMI_ECC_CURVE tpm2_nid_to_curve_name(int nid)
 {
        int i;
@@ -1773,7 +1784,7 @@
                }
        }
 
-       if (strcmp(OID_importableKey, oid) == 0) {
+       if (secret) {
                TPM_HANDLE session;
                TPM_HANDLE parentHandle;
                DATA_2B encryptionKey;
@@ -2059,12 +2070,16 @@
                        k.tpk.type = OBJ_txt2obj(OID_sealedData, 1);
                } else if (secret) {
                        k.tpk.type = OBJ_txt2obj(OID_importableKey, 1);
+               } else {
+                       k.tpk.type = OBJ_txt2obj(OID_loadableKey, 1);
+               }
+
+               if (secret) {
                        k.tpk.secret = ASN1_OCTET_STRING_new();
                        ASN1_STRING_set(k.tpk.secret, secret->secret,
                                        secret->size);
-               } else {
-                       k.tpk.type = OBJ_txt2obj(OID_loadableKey, 1);
                }
+
                k.tpk.emptyAuth = empty_auth;
                k.tpk.parent = ASN1_INTEGER_new();
                ASN1_INTEGER_set(k.tpk.parent, parent);
@@ -2691,6 +2706,7 @@
        TPM_RC rc = TPM_RC_CURVE;
        BN_CTX *ctx = NULL;
        BIGNUM *x, *y;
+       int order;
 
        if (curve == TPM_ECC_NONE) {
                fprintf(stderr, "TPM does not support the curve in this EC 
key\n");
@@ -2722,10 +2738,11 @@
                goto err;
        }
 
+       order = tpm2_curve_to_order(curve);
        VAL_2B(pub->unique.ecc.x, size) =
-               BN_bn2bin(x, VAL_2B(pub->unique.ecc.x, buffer));
+               BN_bn2binpad(x, VAL_2B(pub->unique.ecc.x, buffer), order);
        VAL_2B(pub->unique.ecc.y, size) =
-               BN_bn2bin(y, VAL_2B(pub->unique.ecc.y, buffer));
+               BN_bn2binpad(y, VAL_2B(pub->unique.ecc.y, buffer), order);
 
        rc = TPM_RC_SUCCESS;
 
@@ -2795,6 +2812,140 @@
        return TPM_RC_ASYMMETRIC;
 }
 
+TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
+                     TPMT_SENSITIVE *s,
+                     TPMT_PUBLIC *pub,
+                     PRIVATE_2B *p,
+                     ENCRYPTED_SECRET_2B *enc_secret)
+{
+       PRIVATE_2B secret, seed;
+       /*  amount of room in the buffer for the integrity TPM2B */
+       const int integrity_skip = SHA256_DIGEST_LENGTH + 2;
+       //      BYTE *integrity = p->buffer;
+       BYTE *sensitive = p->buffer + integrity_skip;
+       BYTE *buf;
+       TPM2B *t2b;
+       INT32 size;
+       size_t ssize;
+       UINT16 bsize, written = 0;
+       EVP_PKEY *ephemeral = NULL;
+       EVP_PKEY_CTX *ctx;
+       TPM2B_ECC_POINT pub_pt, ephemeral_pt;
+       EC_KEY *e_parent, *e_ephemeral;
+       const EC_GROUP *group;
+       unsigned char aeskey[T2_AES_KEY_BYTES];
+       /* hmac follows namealg, so set to max size */
+       KEY_2B hmackey;
+       TPMT_HA hmac;
+       NAME_2B name;
+       DIGEST_2B digest;
+       unsigned char null_iv[AES_128_BLOCK_SIZE_BYTES];
+       TPM2B null_2b;
+
+       null_2b.size = 0;
+
+       if (EVP_PKEY_type(EVP_PKEY_id(parent)) != EVP_PKEY_EC) {
+               printf("Can only currently wrap to EC parent\n");
+               return TPM_RC_ASYMMETRIC;
+       }
+
+       e_parent = EVP_PKEY_get1_EC_KEY(parent);
+       group = EC_KEY_get0_group(e_parent);
+
+       /* marshal the sensitive into a TPM2B */
+       t2b = (TPM2B *)sensitive;
+       buf = t2b->buffer;
+       size = sizeof(p->buffer) - integrity_skip;
+       bsize = 0;
+       TSS_TPMT_SENSITIVE_Marshal(s, &bsize, &buf, &size);
+       buf = (BYTE *)&t2b->size;
+       size = 2;
+       TSS_UINT16_Marshal(&bsize, &written, &buf, &size);
+       /* set the total size of the private entity */
+       p->size = bsize + sizeof(UINT16) + integrity_skip;
+
+       /* compute the elliptic curve shared (and encrypted) secret */
+       ctx = EVP_PKEY_CTX_new(parent, NULL);
+       if (!ctx)
+               goto openssl_err;
+       if (EVP_PKEY_keygen_init(ctx) != 1)
+               goto openssl_err;
+       EVP_PKEY_keygen(ctx, &ephemeral);
+       if (!ephemeral)
+               goto openssl_err;
+       /* otherwise the ctx free will free the key */
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+       CRYPTO_add(&ephemeral->references, 1, CRYPTO_LOCK_EVP_PKEY);
+#else
+       EVP_PKEY_up_ref(ephemeral);
+#endif
+       EVP_PKEY_CTX_free(ctx);
+
+       e_ephemeral = EVP_PKEY_get1_EC_KEY(ephemeral);
+
+       /* now begin again with the ephemeral private key because the
+        * context must be initialised with the private key */
+       ctx = EVP_PKEY_CTX_new(ephemeral, NULL);
+       if (!ctx)
+               goto openssl_err;
+       if (EVP_PKEY_derive_init(ctx) != 1)
+               goto openssl_err;
+       if (EVP_PKEY_derive_set_peer(ctx, parent) != 1)
+               goto openssl_err;
+       ssize = sizeof(secret.buffer);
+       if (EVP_PKEY_derive(ctx, secret.buffer, &ssize) != 1)
+               goto openssl_err;
+       secret.size = ssize;
+       EVP_PKEY_CTX_free(ctx);
+
+       tpm2_get_public_point(&pub_pt, group, EC_KEY_get0_public_key(e_parent));
+       tpm2_get_public_point(&ephemeral_pt, group,
+                             EC_KEY_get0_public_key(e_ephemeral));
+       EC_KEY_free(e_parent);
+       EC_KEY_free(e_ephemeral);
+
+       /* now pass the secret through KDFe to get the shared secret
+        * The size is the size of the parent name algorithm which we
+        * assume to be sha256 */
+       TSS_KDFE(seed.buffer, TPM_ALG_SHA256, (TPM2B *)&secret, "DUPLICATE",
+                (TPM2B *)&ephemeral_pt.point.x, (TPM2B *)&pub_pt.point.x,
+                SHA256_DIGEST_LENGTH*8);
+       seed.size = SHA256_DIGEST_LENGTH;
+
+       /* and finally through KDFa to get the aes symmetric encryption key */
+       tpm2_ObjectPublic_GetName(&name, pub);
+       TSS_KDFA(aeskey, TPM_ALG_SHA256, (TPM2B *)&seed, "STORAGE",
+                (TPM2B *)&name, &null_2b, T2_AES_KEY_BITS);
+       /* and then the outer HMAC key */
+       hmackey.size = SHA256_DIGEST_LENGTH;
+       TSS_KDFA(hmackey.buffer, TPM_ALG_SHA256, (TPM2B *)&seed, "INTEGRITY",
+                &null_2b, &null_2b, SHA256_DIGEST_LENGTH*8);
+       /* OK the ephermeral public point is now the encrypted secret */
+       size = sizeof(ephemeral_pt);
+       buf = enc_secret->secret;
+       TSS_TPM2B_ECC_POINT_Marshal(&ephemeral_pt, &written,
+                                   &buf, &size);
+       enc_secret->size = written;
+       memset(null_iv, 0, sizeof(null_iv));
+       TSS_AES_EncryptCFB(sensitive, T2_AES_KEY_BITS, aeskey, null_iv,
+                          p->size - integrity_skip, sensitive);
+       hmac.hashAlg = TPM_ALG_SHA256;
+       TSS_HMAC_Generate(&hmac, (TPM2B_KEY *)&hmackey,
+                         p->size - integrity_skip, sensitive,
+                         name.size, name.name,
+                         0, NULL);
+       digest.size  = SHA256_DIGEST_LENGTH;
+       memcpy(digest.buffer, &hmac.digest, digest.size);
+       size = integrity_skip;
+       buf = p->buffer;
+       TSS_TPM2B_DIGEST_Marshal((TPM2B_DIGEST *)&digest, &written, &buf, 
&size);
+       return TPM_RC_SUCCESS;
+
+ openssl_err:
+       ERR_print_errors_fp(stderr);
+       return TPM_RC_ASYMMETRIC;
+}
+
 void
 openssl_print_errors()
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/tpm2-common.h 
new/openssl_tpm2_engine-3.3.1/tpm2-common.h
--- old/openssl_tpm2_engine-3.2.1/tpm2-common.h 2023-01-12 21:56:04.000000000 
+0100
+++ new/openssl_tpm2_engine-3.3.1/tpm2-common.h 2023-01-31 17:21:01.000000000 
+0100
@@ -115,4 +115,9 @@
                              TPMT_HA *digest);
 TPM_RC tpm2_new_signed_policy(char *tpmkey, char *policykey, char *engine,
                              TSSAUTHPOLICY *ap, TPMT_HA *digest);
+TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
+                     TPMT_SENSITIVE *s,
+                     TPMT_PUBLIC *pub,
+                     PRIVATE_2B *p,
+                     ENCRYPTED_SECRET_2B *enc_secret);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl_tpm2_engine-3.2.1/unseal_tpm2_data.c 
new/openssl_tpm2_engine-3.3.1/unseal_tpm2_data.c
--- old/openssl_tpm2_engine-3.2.1/unseal_tpm2_data.c    2023-01-12 
21:56:04.000000000 +0100
+++ new/openssl_tpm2_engine-3.3.1/unseal_tpm2_data.c    2023-01-31 
17:21:01.000000000 +0100
@@ -142,6 +142,8 @@
                goto out_free_app_data;
        }
 
+       name_alg = app_data->name_alg;
+
        itemHandle = rc;
 
        rc = tpm2_get_session_handle(tssContext, &session, parent,

Reply via email to