static void compute_key_digest(TPM_REQUEST *req, TPM_DIGEST *digest) { tpm_sha1_ctx_t ctx; TPM_HANDLE h1, h2; TPM_KEY_DATA *k1, *k2; BYTE *ptr; UINT32 len, offset = tpm_get_in_param_offset(req->ordinal); /* handle some exceptions */ if (req->ordinal == TPM_ORD_FlushSpecific) offset = 0; else if (req->ordinal == TPM_ORD_OwnerReadInternalPub) offset = 4; /* compute public key digests */ if (offset == 0) { debug("no handles"); memset(digest, 0, sizeof(TPM_DIGEST)); } else if (offset == 4) { debug("one handle"); ptr = req->param; len = 4; tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h1); k1 = tpm_get_key(h1); if (k1 != NULL && tpm_compute_key_data_digest(k1, digest) == 0) { debug("key found"); /* compute outer hash */ tpm_sha1_init(&ctx); tpm_sha1_update(&ctx, digest->digest, sizeof(digest->digest)); tpm_sha1_final(&ctx, digest->digest); } else { memset(digest, 0, sizeof(TPM_DIGEST)); } } else if (offset == 8) { TPM_DIGEST digest2; debug("two handles"); ptr = req->param; len = 8; tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h1); tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h2); k1 = tpm_get_key(h1); k2 = tpm_get_key(h2); if (k1 != NULL && tpm_compute_key_data_digest(k1, digest) == 0 && k2 != NULL && tpm_compute_key_data_digest(k2, &digest2) == 0) { debug("two keys found"); /* compute outer hash */ tpm_sha1_init(&ctx); tpm_sha1_update(&ctx, digest->digest, sizeof(digest->digest)); tpm_sha1_update(&ctx, digest2.digest, sizeof(digest2.digest)); tpm_sha1_final(&ctx, digest->digest); } else { memset(digest, 0, sizeof(TPM_DIGEST)); } } else { memset(digest, 0, sizeof(TPM_DIGEST)); } }
static TPM_RESULT execute_TPM_FlushSpecific(TPM_REQUEST *req, TPM_RESPONSE *rsp) { BYTE *ptr; UINT32 len; TPM_HANDLE handle; TPM_RESOURCE_TYPE resourceType; /* unmarshal input */ ptr = req->param; len = req->paramSize; if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType) || len != 0) return TPM_BAD_PARAMETER; /* execute command */ return TPM_FlushSpecific(handle, resourceType); }