Skip to content

Commit

Permalink
tpm2_getmanufec: fix TPM2B_PUBLIC tss disk serialization
Browse files Browse the repository at this point in the history
The TPM2B_PUBLIC struct was incorectly being dumped to
disk without considering endiness and padding. Correct this
by using the libmarshal routines.

Changes -O to be existing EKpub vs -f as just an output
for a generated EK pub. The whole -f as in in-out
paramter was confusing.

Signed-off-by: William Roberts <william.c.roberts@intel.com>
  • Loading branch information
William Roberts committed Nov 28, 2017
1 parent 49e0562 commit ee0c477
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 72 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,8 @@
## Changelog

### next
* tpm2_getmanufec: -O as a flag for -f has changed. -O is for existing EK public structure
and -f is only for generated EK public output.
* tpm2_nvlist: output in yaml format.
* tpm2_makecredential format changes to the -o output file.
* tpm2-quote: -o option removed.
Expand Down
6 changes: 3 additions & 3 deletions man/tpm2_getmanufec.1.md
Expand Up @@ -42,13 +42,13 @@ server.
an algorithm argument.

* **-f**, **--output**=_FILE_:
specifies the file used to save the public portion of EK.
Specifies the file used to save the public portion of EK.

* **-N**, **--non-persistent**:
specifies to readout the EK public without making it persistent.

* **-O**, **--offline**:
specifies that the file specifier from **-f** is an EK retrieved from offline
* **-O**, **--offline**=_FILE_:
Specifies the file that contains an EK retrieved from offline
platform that needs to be provisioned.

* **-E**, **--ec-cert**=_EC\_CERT\_FILE_:
Expand Down
27 changes: 13 additions & 14 deletions test/system/test_tpm2_getmanufec.sh
Expand Up @@ -47,23 +47,22 @@ onerror() {
}
trap onerror ERR

echo "3a01000001000b00b20003002000837197674484b3f81a90cc8d46a5d724fd52\
d76e06520b64f2a1da1b331469aa000000000000000000000000000000000000\
0000000000000000000000000000000006008000430010000000000000080000\
000000000001c320e2f244a8601aacf3e01d26c665249935562de1da197e9e7f\
076c469613cfb653e98ec2c386fc1d133f2c8c6cc338b732f0b208bd838a877a\
3e5bbc3e1d4084e835c7c8906a1c05b4d2d30fdbebc1dbad950fa6b165bd4b6a\
864603146164c0c4f59d489011ef1f928deea6e90061f3d375e5646273151ef6\
22252098be1a4ab01dc0a12227c609fdaceb115af408d4693a6f49919774695b\
0c12bc18a1ff7120a7337b2fb5f1951d8bb7f094d5b554c11c9523b30729fe64\
787d0a13b9e630488dab4dfd86634a5270ec72fcc5a44dc679a8f32938dd8197\
e29dae839f5b4ca0f5de27c9522c23c54e1c2ce57859525118bd4470b18180ee\
f78ae4267bcd0000" | xxd -r -p > test_ek.pub
echo "013a0001000b000300b20020837197674484b3f81a90cc8d46a5d724fd52
d76e06520b64f2a1da1b331469aa00060080004300100800000000000100
c320e2f244a8601aacf3e01d26c665249935562de1da197e9e7f076c4696
13cfb653e98ec2c386fc1d133f2c8c6cc338b732f0b208bd838a877a3e5b
bc3e1d4084e835c7c8906a1c05b4d2d30fdbebc1dbad950fa6b165bd4b6a
864603146164c0c4f59d489011ef1f928deea6e90061f3d375e564627315
1ef622252098be1a4ab01dc0a12227c609fdaceb115af408d4693a6f4991
9774695b0c12bc18a1ff7120a7337b2fb5f1951d8bb7f094d5b554c11c95
23b30729fe64787d0a13b9e630488dab4dfd86634a5270ec72fcc5a44dc6
79a8f32938dd8197e29dae839f5b4ca0f5de27c9522c23c54e1c2ce57859
525118bd4470b18180eef78ae4267bcd" | xxd -r -p > test_ek.pub

tpm2_getmanufec -g rsa -O -N -U -E ECcert.bin -f test_ek.pub https://ekop.intel.com/ekcertservice/
tpm2_getmanufec -g rsa -O test_ek.pub -N -U -E ECcert.bin https://ekop.intel.com/ekcertservice/

# Test that stdoutput is the same
tpm2_getmanufec -g rsa -O -N -U -f test_ek.pub https://ekop.intel.com/ekcertservice/ > ECcert2.bin
tpm2_getmanufec -g rsa -N -U -O test_ek.pub https://ekop.intel.com/ekcertservice/ > ECcert2.bin

# stdout file should match -E file.
cmp ECcert.bin ECcert2.bin
Expand Down
94 changes: 39 additions & 55 deletions tools/tpm2_getmanufec.c
Expand Up @@ -68,8 +68,9 @@ struct tpm_getmanufec_ctx {
char *ek_server_addr;
unsigned int non_persistent_read;
unsigned int SSL_NO_VERIFY;
unsigned int offline_prov;
char *ek_path;
bool verbose;
TPM2B_PUBLIC outPublic;
};

static tpm_getmanufec_ctx ctx = {
Expand Down Expand Up @@ -157,7 +158,6 @@ int createEKHandle(TSS2_SYS_CONTEXT *sapi_context)

TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name);

TPM2B_PUBLIC outPublic = TPM2B_EMPTY_INIT;
TPM2B_CREATION_DATA creationData = TPM2B_EMPTY_INIT;
TPM2B_DIGEST creationHash = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
TPMT_TK_CREATION creationTicket = TPMT_TK_CREATION_EMPTY_INIT;
Expand Down Expand Up @@ -186,7 +186,7 @@ int createEKHandle(TSS2_SYS_CONTEXT *sapi_context)

rval = TSS2_RETRY_EXP(Tss2_Sys_CreatePrimary(sapi_context, TPM_RH_ENDORSEMENT, &sessionsData,
&inSensitive, &inPublic, &outsideInfo,
&creationPCR, &handle2048ek, &outPublic,
&creationPCR, &handle2048ek, &ctx.outPublic,
&creationData, &creationHash, &creationTicket,
&name, &sessionsDataOut));
if (rval != TPM_RC_SUCCESS ) {
Expand Down Expand Up @@ -222,68 +222,49 @@ int createEKHandle(TSS2_SYS_CONTEXT *sapi_context)

LOG_INFO("Flush transient EK succ.");

/* TODO this serialization is not correct */
if (!files_save_bytes_to_file(ctx.output_file, (UINT8 *)&outPublic, sizeof(outPublic))) {
LOG_ERR("Failed to save EK pub key into file(%s)", ctx.output_file);
return 1;
}

return 0;
return files_save_public(&ctx.outPublic, ctx.output_file) != true;
}

unsigned char *HashEKPublicKey(void)
{
unsigned char *hash = NULL;
FILE *fp = NULL;

unsigned char EKpubKey[259];
static unsigned char *HashEKPublicKey(void) {

LOG_INFO("Calculating the SHA256 hash of the Endorsement Public Key");

fp = fopen(ctx.output_file, "rb");
if (!fp) {
LOG_ERR("Could not open file: \"%s\"", ctx.output_file);
unsigned char *hash = (unsigned char*)malloc(SHA256_DIGEST_LENGTH);
if (!hash) {
LOG_ERR ("OOM");
return NULL;
}

int rc = fseek(fp, 0x66, 0);
if (rc < 0) {
LOG_ERR("Could not perform fseek: %s", strerror(errno));
goto out;
}

size_t read = fread(EKpubKey, 1, 256, fp);
if (read != 256) {
LOG_ERR ("Could not read whole file.");
goto out;
}

hash = (unsigned char*)malloc(SHA256_DIGEST_LENGTH);
if (hash == NULL) {
LOG_ERR ("OOM");
goto out;
}

EKpubKey[256] = 0x01;
EKpubKey[257] = 0x00;
EKpubKey[258] = 0x01; //Exponent
SHA256_CTX sha256;
int is_success = SHA256_Init(&sha256);
if (!is_success) {
LOG_ERR ("SHA256_Init failed");
goto hash_out;
goto err;
}

is_success = SHA256_Update(&sha256, EKpubKey, sizeof(EKpubKey));
is_success = SHA256_Update(&sha256, ctx.outPublic.t.publicArea.unique.rsa.t.buffer,
ctx.outPublic.t.publicArea.unique.rsa.t.size);
if (!is_success) {
LOG_ERR ("SHA256_Update failed");
goto hash_out;
goto err;
}

/* TODO what do these magic bytes line up to? */
BYTE buf[3] = {
0x1,
0x00,
0x01 //Exponent
};

is_success = SHA256_Update(&sha256, buf, sizeof(buf));
if (!is_success) {
LOG_ERR ("SHA256_Update failed");
goto err;
}

is_success = SHA256_Final(hash, &sha256);
if (!is_success) {
LOG_ERR ("SHA256_Final failed");
goto hash_out;
goto err;
}

if (ctx.verbose) {
Expand All @@ -293,14 +274,11 @@ unsigned char *HashEKPublicKey(void)
}
printf("\n");
}
goto out;

hash_out:
free(hash);
hash = NULL;
out:
fclose(fp);
return hash;
err:
free(hash);
return NULL;
}

char *Base64Encode(const unsigned char* buffer)
Expand Down Expand Up @@ -508,7 +486,7 @@ static bool on_option(char key, char *value) {
ctx.non_persistent_read = 1;
break;
case 'O':
ctx.offline_prov = 1;
ctx.ek_path = value;
break;
case 'U':
ctx.SSL_NO_VERIFY = 1;
Expand Down Expand Up @@ -554,13 +532,13 @@ bool tpm2_tool_onstart(tpm2_options **opts) {
{ "alg" , 1, NULL, 'g' },
{ "output" , 1, NULL, 'f' },
{ "non-persistent", 0, NULL, 'N' },
{ "offline" , 0, NULL, 'O' },
{ "offline" , 1, NULL, 'O' },
{ "ec-cert" , 1, NULL, 'E' },
{ "SSL-NO-VERIFY" , 0, NULL, 'U' },
{"input-session-handle",1,NULL,'S'},
};

*opts = tpm2_options_new("e:o:H:P:g:f:NOE:S:i:U", ARRAY_LEN(topts), topts,
*opts = tpm2_options_new("e:o:H:P:g:f:NO:E:S:i:U", ARRAY_LEN(topts), topts,
on_option, on_args);

return *opts != NULL;
Expand All @@ -587,8 +565,14 @@ int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {
}
}

if (!ctx.offline_prov) {
if (!ctx.ek_path) {
return_val = createEKHandle(sapi_context);
} else {
bool res = files_load_public(ctx.ek_path, &ctx.outPublic);
if (!res) {
LOG_ERR("Could not load exiting EK public from file");
return 1;
}
}

provisioning_return_val = TPMinitialProvisioning();
Expand Down

0 comments on commit ee0c477

Please sign in to comment.