aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2023-01-11 13:53:26 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2023-01-12 16:41:35 -0500
commitac3fa839ebb4267c715f49e719ad731f31709677 (patch)
treeb36a98ffa163dbd08acbc0f78db6642e8e380c4b
parentf6d7c7076a0e320d62629d47c6e4c0177fc7d213 (diff)
downloadopenssl_tpm2_engine-ac3fa839ebb4267c715f49e719ad731f31709677.tar.gz
seal_tpm2_data: allow the creation of importable sealed data
In the same way we do with keys, you should be able to use the --import key.pub option to seal data to a known SRK. The SRK should be created with a P-256 elliptic curve template to match the key we usually create as the parent. tsscreateprimary -hi o -ecc nistp256 -st -opem srk.pub Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--seal_tpm2_data.c137
1 files changed, 102 insertions, 35 deletions
diff --git a/seal_tpm2_data.c b/seal_tpm2_data.c
index 6432255..55b8dac 100644
--- a/seal_tpm2_data.c
+++ b/seal_tpm2_data.c
@@ -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 @@ static struct option long_options[] = {
{"policy", 1, 0, 'c'},
{"nomigrate", 0, 0, 'm'},
{"name-scheme", 1, 0, 'n'},
+ {"import", 1, 0, 'i'},
{0, 0, 0, 0}
};
@@ -79,6 +81,8 @@ usage(char *argv0)
"\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-i, --import <pubkey> Create an importable key with the outer\n"
+ " wrapper encrypted to <pubkey>\n"
"\n"
"\n"
"Report bugs to " PACKAGE_BUGREPORT "\n",
@@ -86,6 +90,24 @@ usage(char *argv0)
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 +117,8 @@ int main(int argc, char **argv)
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 +137,17 @@ int main(int argc, char **argv)
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:vdsuni:",
long_options, &option_index);
if (c == -1)
break;
@@ -182,6 +206,9 @@ int main(int argc, char **argv)
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 +235,11 @@ int main(int argc, char **argv)
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 +286,39 @@ int main(int argc, char **argv)
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 +353,37 @@ int main(int argc, char **argv)
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 +402,9 @@ int main(int argc, char **argv)
goto out_flush;
}
+ parent = tpm2_handle_ext(tssContext, parent);
+
+ write_file:
buffer = pubkey;
pubkey_len = 0;
size = sizeof(pubkey);
@@ -349,18 +415,19 @@ int main(int argc, char **argv)
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: