aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2019-12-30 18:42:38 -0800
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2020-01-10 12:26:45 -0800
commit5ea29a4dba5083b5383929b895df32c9c7580d71 (patch)
treef37d3264e44d1be866bd3c680652d36cbb2f5f2a
parent48ee8aab42fa4fbfe59a8877527e1d78e562352d (diff)
downloadopenssl_tpm2_engine-5ea29a4dba5083b5383929b895df32c9c7580d71.tar.gz
tpm2-common.c: move several routines into common code
These routines will be used by the seal/unseal command, so make them common to facilitate this. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--create_tpm2_key.c247
-rw-r--r--tpm2-common.c231
-rw-r--r--tpm2-common.h13
3 files changed, 250 insertions, 241 deletions
diff --git a/create_tpm2_key.c b/create_tpm2_key.c
index 5534fe3..11b2086 100644
--- a/create_tpm2_key.c
+++ b/create_tpm2_key.c
@@ -12,14 +12,9 @@
#include <strings.h>
#include <errno.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
#include <arpa/inet.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
@@ -37,10 +32,6 @@
#include "tpm2-asn.h"
#include "tpm2-common.h"
-/* for use as a TPM_RC return type to indicate this is
- * not a TPM error, so don't process the rc as one */
-#define NOT_TPM_ERROR (0xffffffff)
-
#define OPT_DEPRECATED 0x1ff
#define OPT_RESTRICTED 0x1fe
@@ -121,31 +112,6 @@ openssl_print_errors()
ERR_print_errors_fp(stderr);
}
-/* from lib/hexdump.c (Linux kernel) */
-int hex_to_bin(char ch)
-{
- if ((ch >= '0') && (ch <= '9'))
- return ch - '0';
- ch = tolower(ch);
- if ((ch >= 'a') && (ch <= 'f'))
- return ch - 'a' + 10;
- return -1;
-}
-
-int hex2bin(unsigned char *dst, const char *src, size_t count)
-{
- while (count--) {
- int hi = hex_to_bin(*src++);
- int lo = hex_to_bin(*src++);
-
- if ((hi < 0) || (lo < 0))
- return -1;
-
- *dst++ = (hi << 4) | lo;
- }
- return 0;
-}
-
TPM_RC tpm2_ObjectPublic_GetName(TPM2B_NAME *name,
TPMT_PUBLIC *tpmtPublic)
{
@@ -414,167 +380,6 @@ TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
return TPM_RC_ASYMMETRIC;
}
-TPM_RC
-parse_policy_file(const char *policy_file, STACK_OF(TSSOPTPOLICY) *sk,
- char *auth, TPMT_HA *digest)
-{
- struct stat st;
- char *data, *data_ptr;
- unsigned char buf[2048];
- unsigned char *buf_ptr;
- TSSOPTPOLICY *policy = NULL;
- INT32 buf_len;
- TPM_CC code;
- TPM_RC rc = NOT_TPM_ERROR;
- int fd, policy_auth_value = 0;
-
- if (stat(policy_file, &st) == -1) {
- fprintf(stderr, "File %s cannot be accessed\n", policy_file);
- return rc;
- }
-
- fd = open(policy_file, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "File %s cannot be opened\n", policy_file);
- return rc;
- }
-
- data = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- if (!data) {
- fprintf(stderr, "mmap() failed\n");
- goto out;
- }
-
- while ((data_ptr = strsep(&data, "\n"))) {
- TPMT_HA hash_digest;
- unsigned char *hash = (unsigned char *)hash_digest.digest.tssmax;
- INT32 hash_len;
-
- buf_ptr = buf;
- buf_len = strlen(data_ptr) / 2;
- if (buf_len > sizeof(buf)) {
- rc = NOT_TPM_ERROR;
- fprintf(stderr, "line too long\n");
- goto out_munmap;
- }
-
- if (!buf_len)
- break;
-
- rc = hex2bin(buf, data_ptr, buf_len);
- if (rc < 0) {
- rc = NOT_TPM_ERROR;
- fprintf(stderr, "hex2bin() failed\n");
- goto out_munmap;
- }
-
- rc = TPM_CC_Unmarshal(&code, &buf_ptr, &buf_len);
- if (rc) {
- fprintf(stderr, "TPM_CC_Unmarshal() failed\n");
- goto out_munmap;
- }
-
- if (code == TPM_CC_PolicyCounterTimer) {
- /* for a countertimer, the policy is a hash of the hash */
- hash_digest.hashAlg = digest->hashAlg;
- hash_len = TSS_GetDigestSize(digest->hashAlg);
- TSS_Hash_Generate(&hash_digest, buf_len, buf_ptr, 0, NULL);
- hash = hash_digest.digest.tssmax;
- } else {
- hash = buf_ptr;
- hash_len = buf_len;
- }
-
- rc = TSS_Hash_Generate(digest,
- TSS_GetDigestSize(digest->hashAlg),
- (uint8_t *)&digest->digest,
- /* the command code */
- 4, buf_ptr - 4,
- hash_len, hash, 0, NULL);
- if (rc) {
- fprintf(stderr, "TSS_Hash_Generate() failed\n");
- goto out_munmap;
- }
-
- if (code == TPM_CC_PolicyAuthValue)
- policy_auth_value = 1;
-
- policy = TSSOPTPOLICY_new();
- ASN1_INTEGER_set(policy->CommandCode, code);
- ASN1_STRING_set(policy->CommandPolicy, buf_ptr, buf_len);
- sk_TSSOPTPOLICY_push(sk, policy);
- }
-
- if (auth && !policy_auth_value) {
- rc = NOT_TPM_ERROR;
- fprintf(stderr, "PolicyAuthValue command is required\n");
- }
-
-out_munmap:
- munmap(data, st.st_size);
-out:
- close(fd);
- return rc;
-}
-
-int
-openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
- BYTE *privkey, int privkey_len, int empty_auth,
- TPM_HANDLE parent, STACK_OF(TSSOPTPOLICY) *sk,
- int version, TPM2B_ENCRYPTED_SECRET *secret)
-{
- union {
- TSSLOADABLE tssl;
- TSSPRIVKEY tpk;
- } k;
- BIO *outb;
-
- /* clear structure so as not to have to set optional parameters */
- memset(&k, 0, sizeof(k));
- if ((outb = BIO_new_file(file, "w")) == NULL) {
- fprintf(stderr, "Error opening file for write: %s\n", file);
- return 1;
- }
- if (version == 0) {
- k.tssl.type = OBJ_txt2obj(OID_OldloadableKey, 1);
- k.tssl.emptyAuth = empty_auth;
- k.tssl.parent = ASN1_INTEGER_new();
- ASN1_INTEGER_set(k.tssl.parent, parent);
-
- k.tssl.pubkey = ASN1_OCTET_STRING_new();
- ASN1_STRING_set(k.tssl.pubkey, pubkey, pubkey_len);
- k.tssl.privkey = ASN1_OCTET_STRING_new();
- ASN1_STRING_set(k.tssl.privkey, privkey, privkey_len);
- k.tssl.policy = sk;
-
- PEM_write_bio_TSSLOADABLE(outb, &k.tssl);
- } else {
- if (secret) {
- k.tpk.type = OBJ_txt2obj(OID_importableKey, 1);
- k.tpk.secret = ASN1_OCTET_STRING_new();
- ASN1_STRING_set(k.tpk.secret, secret->t.secret,
- secret->t.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);
-
- k.tpk.pubkey = ASN1_OCTET_STRING_new();
- ASN1_STRING_set(k.tpk.pubkey, pubkey, pubkey_len);
- k.tpk.privkey = ASN1_OCTET_STRING_new();
- ASN1_STRING_set(k.tpk.privkey, privkey, privkey_len);
- k.tpk.policy = sk;
-
- PEM_write_bio_TSSPRIVKEY(outb, &k.tpk);
- }
-
- BIO_free(outb);
- return 0;
-}
-
EVP_PKEY *
openssl_read_key(char *filename)
{
@@ -901,44 +706,6 @@ static void list_curves(void)
exit(1);
}
-static TPM_HANDLE get_parent(const char *pstr)
-{
- TPM_HANDLE p;
-
- if (strcmp(pstr, "owner") == 0)
- p = TPM_RH_OWNER;
- else if (strcmp(pstr, "platform") == 0)
- p = TPM_RH_PLATFORM;
- else if (strcmp(pstr, "endorsement") == 0)
- p = TPM_RH_ENDORSEMENT;
- else if (strcmp(pstr, "null") == 0)
- p = TPM_RH_NULL;
- else
- p = strtoul(pstr, NULL, 16);
-
- if (((p & 0xff000000) == 0x40000000) &&
- (p == TPM_RH_OWNER ||
- p == TPM_RH_PLATFORM ||
- p == TPM_RH_ENDORSEMENT ||
- p == TPM_RH_NULL))
- return p;
- else if ((p & 0xff000000) == 0x81000000)
- return p;
-
- return 0;
-}
-
-void free_policy(STACK_OF(TSSOPTPOLICY) *sk)
-{
- TSSOPTPOLICY *policy;
-
- if (sk)
- while ((policy = sk_TSSOPTPOLICY_pop(sk)))
- TSSOPTPOLICY_free(policy);
-
- sk_TSSOPTPOLICY_free(sk);
-}
-
/*
* A restricted key needs a symmetric seed and algorithm so it can
* derive a symmetric encryption key used to protect the sensitive
@@ -1054,7 +821,7 @@ int main(int argc, char **argv)
}
break;
case 'p':
- parent = get_parent(optarg);
+ parent = tpm2_get_parent(optarg);
if (parent == 0) {
fprintf(stderr, "Invalid parent %s\n", optarg);
exit(1);
@@ -1159,7 +926,7 @@ int main(int argc, char **argv)
goto out_err;
}
- rc = parse_policy_file(policyFilename, sk, auth, &digest);
+ rc = tpm2_parse_policy_file(policyFilename, sk, auth, &digest);
if (rc) {
reason = "parse_policy_file";
goto out_free_policy;
@@ -1438,10 +1205,10 @@ int main(int argc, char **argv)
privkey_len = 0;
size = sizeof(privkey);
TSS_TPM2B_PRIVATE_Marshal(priv, &privkey_len, &buffer, &size);
- openssl_write_tpmfile(filename, pubkey, pubkey_len,
- privkey, privkey_len, auth == NULL, parent, sk,
- version, enc_secret);
- free_policy(sk);
+ tpm2_write_tpmfile(filename, pubkey, pubkey_len,
+ privkey, privkey_len, auth == NULL, parent, sk,
+ version, enc_secret);
+ tpm2_free_policy(sk);
exit(0);
@@ -1453,7 +1220,7 @@ int main(int argc, char **argv)
out_free_auth:
free(auth);
out_free_policy:
- free_policy(sk);
+ tpm2_free_policy(sk);
out_err:
if (rc == NOT_TPM_ERROR)
fprintf(stderr, "%s failed\n", reason);
diff --git a/tpm2-common.c b/tpm2-common.c
index 84b9093..c60b151 100644
--- a/tpm2-common.c
+++ b/tpm2-common.c
@@ -7,6 +7,12 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
@@ -23,8 +29,8 @@
#include TSSINCLUDE(tsscryptoh.h)
#include TSSINCLUDE(Unmarshal_fp.h)
-#include "tpm2-common.h"
#include "tpm2-asn.h"
+#include "tpm2-common.h"
struct myTPM2B {
UINT16 s;
@@ -1361,6 +1367,229 @@ void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key)
TSS_Delete(tssContext);
}
+TPM_HANDLE tpm2_get_parent(const char *pstr)
+{
+ TPM_HANDLE p;
+
+ if (strcmp(pstr, "owner") == 0)
+ p = TPM_RH_OWNER;
+ else if (strcmp(pstr, "platform") == 0)
+ p = TPM_RH_PLATFORM;
+ else if (strcmp(pstr, "endorsement") == 0)
+ p = TPM_RH_ENDORSEMENT;
+ else if (strcmp(pstr, "null") == 0)
+ p = TPM_RH_NULL;
+ else
+ p = strtoul(pstr, NULL, 16);
+
+ if (((p & 0xff000000) == 0x40000000) &&
+ (p == TPM_RH_OWNER ||
+ p == TPM_RH_PLATFORM ||
+ p == TPM_RH_ENDORSEMENT ||
+ p == TPM_RH_NULL))
+ return p;
+ else if ((p & 0xff000000) == 0x81000000)
+ return p;
+
+ return 0;
+}
+
+int tpm2_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
+ BYTE *privkey, int privkey_len, int empty_auth,
+ TPM_HANDLE parent, STACK_OF(TSSOPTPOLICY) *sk,
+ int version, TPM2B_ENCRYPTED_SECRET *secret)
+{
+ union {
+ TSSLOADABLE tssl;
+ TSSPRIVKEY tpk;
+ } k;
+ BIO *outb;
+
+ /* clear structure so as not to have to set optional parameters */
+ memset(&k, 0, sizeof(k));
+ if ((outb = BIO_new_file(file, "w")) == NULL) {
+ fprintf(stderr, "Error opening file for write: %s\n", file);
+ return 1;
+ }
+ if (version == 0) {
+ k.tssl.type = OBJ_txt2obj(OID_OldloadableKey, 1);
+ k.tssl.emptyAuth = empty_auth;
+ k.tssl.parent = ASN1_INTEGER_new();
+ ASN1_INTEGER_set(k.tssl.parent, parent);
+
+ k.tssl.pubkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(k.tssl.pubkey, pubkey, pubkey_len);
+ k.tssl.privkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(k.tssl.privkey, privkey, privkey_len);
+ k.tssl.policy = sk;
+
+ PEM_write_bio_TSSLOADABLE(outb, &k.tssl);
+ } else {
+ if (secret) {
+ k.tpk.type = OBJ_txt2obj(OID_importableKey, 1);
+ k.tpk.secret = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(k.tpk.secret, secret->t.secret,
+ secret->t.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);
+
+ k.tpk.pubkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(k.tpk.pubkey, pubkey, pubkey_len);
+ k.tpk.privkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(k.tpk.privkey, privkey, privkey_len);
+ k.tpk.policy = sk;
+
+ PEM_write_bio_TSSPRIVKEY(outb, &k.tpk);
+ }
+
+ BIO_free(outb);
+ return 0;
+}
+
+/* from lib/hexdump.c (Linux kernel) */
+int hex_to_bin(char ch)
+{
+ if ((ch >= '0') && (ch <= '9'))
+ return ch - '0';
+ ch = tolower(ch);
+ if ((ch >= 'a') && (ch <= 'f'))
+ return ch - 'a' + 10;
+ return -1;
+}
+
+int hex2bin(unsigned char *dst, const char *src, size_t count)
+{
+ while (count--) {
+ int hi = hex_to_bin(*src++);
+ int lo = hex_to_bin(*src++);
+
+ if ((hi < 0) || (lo < 0))
+ return -1;
+
+ *dst++ = (hi << 4) | lo;
+ }
+ return 0;
+}
+
+TPM_RC tpm2_parse_policy_file(const char *policy_file,
+ STACK_OF(TSSOPTPOLICY) *sk,
+ char *auth, TPMT_HA *digest)
+{
+ struct stat st;
+ char *data, *data_ptr;
+ unsigned char buf[2048];
+ unsigned char *buf_ptr;
+ TSSOPTPOLICY *policy = NULL;
+ INT32 buf_len;
+ TPM_CC code;
+ TPM_RC rc = NOT_TPM_ERROR;
+ int fd, policy_auth_value = 0;
+
+ if (stat(policy_file, &st) == -1) {
+ fprintf(stderr, "File %s cannot be accessed\n", policy_file);
+ return rc;
+ }
+
+ fd = open(policy_file, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "File %s cannot be opened\n", policy_file);
+ return rc;
+ }
+
+ data = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0);
+ if (!data) {
+ fprintf(stderr, "mmap() failed\n");
+ goto out;
+ }
+
+ while ((data_ptr = strsep(&data, "\n"))) {
+ TPMT_HA hash_digest;
+ unsigned char *hash = (unsigned char *)hash_digest.digest.tssmax;
+ INT32 hash_len;
+
+ buf_ptr = buf;
+ buf_len = strlen(data_ptr) / 2;
+ if (buf_len > sizeof(buf)) {
+ rc = NOT_TPM_ERROR;
+ fprintf(stderr, "line too long\n");
+ goto out_munmap;
+ }
+
+ if (!buf_len)
+ break;
+
+ rc = hex2bin(buf, data_ptr, buf_len);
+ if (rc < 0) {
+ rc = NOT_TPM_ERROR;
+ fprintf(stderr, "hex2bin() failed\n");
+ goto out_munmap;
+ }
+
+ rc = TPM_CC_Unmarshal(&code, &buf_ptr, &buf_len);
+ if (rc) {
+ fprintf(stderr, "TPM_CC_Unmarshal() failed\n");
+ goto out_munmap;
+ }
+
+ if (code == TPM_CC_PolicyCounterTimer) {
+ /* for a countertimer, the policy is a hash of the hash */
+ hash_digest.hashAlg = digest->hashAlg;
+ hash_len = TSS_GetDigestSize(digest->hashAlg);
+ TSS_Hash_Generate(&hash_digest, buf_len, buf_ptr, 0, NULL);
+ hash = hash_digest.digest.tssmax;
+ } else {
+ hash = buf_ptr;
+ hash_len = buf_len;
+ }
+
+ rc = TSS_Hash_Generate(digest,
+ TSS_GetDigestSize(digest->hashAlg),
+ (uint8_t *)&digest->digest,
+ /* the command code */
+ 4, buf_ptr - 4,
+ hash_len, hash, 0, NULL);
+ if (rc) {
+ fprintf(stderr, "TSS_Hash_Generate() failed\n");
+ goto out_munmap;
+ }
+
+ if (code == TPM_CC_PolicyAuthValue)
+ policy_auth_value = 1;
+
+ policy = TSSOPTPOLICY_new();
+ ASN1_INTEGER_set(policy->CommandCode, code);
+ ASN1_STRING_set(policy->CommandPolicy, buf_ptr, buf_len);
+ sk_TSSOPTPOLICY_push(sk, policy);
+ }
+
+ if (auth && !policy_auth_value) {
+ rc = NOT_TPM_ERROR;
+ fprintf(stderr, "PolicyAuthValue command is required\n");
+ }
+
+out_munmap:
+ munmap(data, st.st_size);
+out:
+ close(fd);
+ return rc;
+}
+
+void tpm2_free_policy(STACK_OF(TSSOPTPOLICY) *sk)
+{
+ TSSOPTPOLICY *policy;
+
+ if (sk)
+ while ((policy = sk_TSSOPTPOLICY_pop(sk)))
+ TSSOPTPOLICY_free(policy);
+
+ sk_TSSOPTPOLICY_free(sk);
+}
+
IMPLEMENT_ASN1_FUNCTIONS(TSSOPTPOLICY)
IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE)
IMPLEMENT_ASN1_FUNCTIONS(TSSPRIVKEY)
diff --git a/tpm2-common.h b/tpm2-common.h
index 536cedb..0e5d415 100644
--- a/tpm2-common.h
+++ b/tpm2-common.h
@@ -4,6 +4,10 @@
#define T2_AES_KEY_BITS 128
#define T2_AES_KEY_BYTES (T2_AES_KEY_BITS/8)
+/* for use as a TPM_RC return type to indicate this is
+ * not a TPM error, so don't process the rc as one */
+#define NOT_TPM_ERROR (0xffffffff)
+
struct policy_command {
TPM_CC code;
INT32 size;
@@ -63,4 +67,13 @@ TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key);
void tpm2_delete(struct app_data *app_data);
char *tpm2_get_auth(UI_METHOD *ui, char *input_string, void *cb_data);
+TPM_HANDLE tpm2_get_parent(const char *pstr);
+int tpm2_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
+ BYTE *privkey, int privkey_len, int empty_auth,
+ TPM_HANDLE parent, STACK_OF(TSSOPTPOLICY) *sk,
+ int version, TPM2B_ENCRYPTED_SECRET *secret);
+TPM_RC tpm2_parse_policy_file(const char *policy_file,
+ STACK_OF(TSSOPTPOLICY) *sk,
+ char *auth, TPMT_HA *digest);
+void tpm2_free_policy(STACK_OF(TSSOPTPOLICY) *sk);
#endif