| /* Software-based Trusted Platform Module (TPM) Emulator |
| * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net> |
| * |
| * This module is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published |
| * by the Free Software Foundation; either version 2 of the License, |
| * or (at your option) any later version. |
| * |
| * This module is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * $Id: tpm_cmd_handler.c 377 2010-02-16 14:52:57Z mast $ |
| */ |
| |
| #include "tpm_marshalling.h" |
| #include "tpm_commands.h" |
| #include "crypto/sha1.h" |
| #include "crypto/hmac.h" |
| #include "tpm_data.h" |
| #include "tpm_handles.h" |
| |
| #ifdef MTM_EMULATOR |
| #include "mtm/mtm_commands.h" |
| #endif |
| |
| UINT32 tpm_get_in_param_offset(TPM_COMMAND_CODE ordinal) |
| { |
| switch (ordinal) { |
| case TPM_ORD_ActivateIdentity: |
| case TPM_ORD_ChangeAuth: |
| case TPM_ORD_ChangeAuthAsymStart: |
| case TPM_ORD_CMK_ConvertMigration: |
| case TPM_ORD_CMK_CreateBlob: |
| case TPM_ORD_CMK_CreateKey: |
| case TPM_ORD_ConvertMigrationBlob: |
| case TPM_ORD_CreateMigrationBlob: |
| case TPM_ORD_CreateWrapKey: |
| case TPM_ORD_Delegate_CreateKeyDelegation: |
| case TPM_ORD_DSAP: |
| case TPM_ORD_EstablishTransport: |
| case TPM_ORD_EvictKey: |
| case TPM_ORD_FlushSpecific: |
| case TPM_ORD_GetAuditDigestSigned: |
| case TPM_ORD_GetPubKey: |
| case TPM_ORD_KeyControlOwner: |
| case TPM_ORD_LoadKey: |
| case TPM_ORD_LoadKey2: |
| case TPM_ORD_Quote: |
| case TPM_ORD_Quote2: |
| case TPM_ORD_ReleaseTransportSigned: |
| case TPM_ORD_SaveKeyContext: |
| case TPM_ORD_Seal: |
| case TPM_ORD_Sealx: |
| case TPM_ORD_SetRedirection: |
| case TPM_ORD_Sign: |
| case TPM_ORD_TickStampBlob: |
| case TPM_ORD_UnBind: |
| case TPM_ORD_Unseal: |
| case TPM_ORD_DAA_Join: |
| case TPM_ORD_DAA_Sign: |
| return 4; |
| |
| case TPM_ORD_CertifyKey: |
| case TPM_ORD_CertifyKey2: |
| case TPM_ORD_ChangeAuthAsymFinish: |
| return 8; |
| |
| case TPM_ORD_OSAP: |
| return 26; |
| |
| default: |
| return 0; |
| } |
| } |
| |
| UINT32 tpm_get_out_param_offset(TPM_COMMAND_CODE ordinal) |
| { |
| switch (ordinal) { |
| |
| case TPM_ORD_EstablishTransport: |
| case TPM_ORD_LoadKey2: |
| return 4; |
| |
| case TPM_ORD_OIAP: |
| return 24; |
| |
| case TPM_ORD_OSAP: |
| return 44; |
| |
| default: |
| return 0; |
| } |
| } |
| |
| void tpm_compute_in_param_digest(TPM_REQUEST *req) |
| { |
| tpm_sha1_ctx_t sha1; |
| UINT32 offset = tpm_get_in_param_offset(req->ordinal); |
| |
| /* compute SHA1 hash */ |
| if (offset <= req->paramSize) { |
| tpm_sha1_init(&sha1); |
| tpm_sha1_update_be32(&sha1, req->ordinal); |
| /* skip all handles at the beginning */ |
| tpm_sha1_update(&sha1, req->param + offset, req->paramSize - offset); |
| tpm_sha1_final(&sha1, req->auth1.digest); |
| memcpy(req->auth2.digest, req->auth1.digest, sizeof(req->auth1.digest)); |
| } |
| } |
| |
| void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp) |
| { |
| tpm_sha1_ctx_t sha1; |
| UINT32 offset = tpm_get_out_param_offset(ordinal); |
| |
| /* compute SHA1 hash */ |
| tpm_sha1_init(&sha1); |
| tpm_sha1_update_be32(&sha1, rsp->result); |
| tpm_sha1_update_be32(&sha1, ordinal); |
| tpm_sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset); |
| tpm_sha1_final(&sha1, rsp->auth1->digest); |
| if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest, |
| rsp->auth1->digest, sizeof(rsp->auth1->digest)); |
| } |
| |
| static TPM_RESULT execute_TPM_Startup(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_STARTUP_TYPE startupType; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_STARTUP_TYPE(&ptr, &len, &startupType) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_Startup(startupType); |
| } |
| |
| static TPM_RESULT execute_TPM_SaveState(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_SaveState(); |
| } |
| |
| static TPM_RESULT execute_TPM_SelfTestFull(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_SelfTestFull(); |
| } |
| |
| static TPM_RESULT execute_TPM_ContinueSelfTest(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_ContinueSelfTest(); |
| } |
| |
| static TPM_RESULT execute_TPM_GetTestResult(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* execute command */ |
| res = TPM_GetTestResult(&outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SetOwnerInstall(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL state; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &state) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetOwnerInstall(state); |
| } |
| |
| static TPM_RESULT execute_TPM_OwnerSetDisable(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL disableState; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &disableState) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_OwnerSetDisable(disableState, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_PhysicalEnable(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_PhysicalEnable(); |
| } |
| |
| static TPM_RESULT execute_TPM_PhysicalDisable(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_PhysicalDisable(); |
| } |
| |
| static TPM_RESULT execute_TPM_PhysicalSetDeactivated(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL state; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &state) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_PhysicalSetDeactivated(state); |
| } |
| |
| static TPM_RESULT execute_TPM_SetTempDeactivated(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_SetTempDeactivated(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_SetOperatorAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_SECRET operatorAuth; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_SECRET(&ptr, &len, &operatorAuth) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetOperatorAuth(&operatorAuth); |
| } |
| |
| static TPM_RESULT execute_TPM_TakeOwnership(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PROTOCOL_ID protocolID; |
| UINT32 encOwnerAuthSize; |
| BYTE *encOwnerAuth; |
| UINT32 encSrkAuthSize; |
| BYTE *encSrkAuth; |
| TPM_KEY srkParams; |
| TPM_KEY srkPub; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encOwnerAuthSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encOwnerAuth, encOwnerAuthSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encSrkAuthSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encSrkAuth, encSrkAuthSize) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &srkParams) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_TakeOwnership(protocolID, encOwnerAuthSize, encOwnerAuth, |
| encSrkAuthSize, encSrkAuth, &srkParams, &req->auth1, &srkPub); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_KEY(srkPub); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY(&ptr, &len, &srkPub)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_KEY(srkPub); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_OwnerClear(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_OwnerClear(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_ForceClear(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_ForceClear(); |
| } |
| |
| static TPM_RESULT execute_TPM_DisableOwnerClear(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_DisableOwnerClear(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_DisableForceClear(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_DisableForceClear(); |
| } |
| |
| static TPM_RESULT execute_TSC_PhysicalPresence(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PHYSICAL_PRESENCE physicalPresence; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PHYSICAL_PRESENCE(&ptr, &len, &physicalPresence) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TSC_PhysicalPresence(physicalPresence); |
| } |
| |
| static TPM_RESULT execute_TSC_ResetEstablishmentBit(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TSC_ResetEstablishmentBit(); |
| } |
| |
| static TPM_RESULT execute_TPM_GetCapability(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_CAPABILITY_AREA capArea; |
| UINT32 subCapSize; |
| BYTE *subCap; |
| UINT32 respSize; |
| BYTE *resp = NULL; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea) |
| || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| #ifdef MTM_EMULATOR |
| res = MTM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp); |
| #else |
| res = TPM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp); |
| #endif |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + respSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, respSize) |
| || tpm_marshal_BLOB(&ptr, &len, resp, respSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(resp); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SetCapability(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_CAPABILITY_AREA capArea; |
| UINT32 subCapSize, setValueSize; |
| BYTE *subCap, *setValue; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea) |
| || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &setValueSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &setValue, setValueSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetCapability(capArea, subCapSize, subCap, setValueSize, setValue, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_GetCapabilityOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 non_volatile_flags, volatile_flags; |
| TPM_VERSION version; |
| BYTE *resp = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| res = TPM_GetCapabilityOwner(&req->auth1, &version, &non_volatile_flags, &volatile_flags); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 12; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_VERSION(&ptr, &len, &version) |
| || tpm_marshal_UINT32(&ptr, &len, non_volatile_flags) |
| || tpm_marshal_UINT32(&ptr, &len, volatile_flags)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(resp); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_GetAuditDigest(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 startOrdinal; |
| TPM_COUNTER_VALUE counterValue; |
| TPM_DIGEST auditDigest; |
| BOOL more; |
| UINT32 ordSize; |
| UINT32 *ordList = NULL; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &startOrdinal) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_GetAuditDigest(startOrdinal, &counterValue, &auditDigest, &more, &ordSize, &ordList); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 10 + 20 + 1 + 4 + ordSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &auditDigest) |
| || tpm_marshal_BOOL(&ptr, &len, more) |
| || tpm_marshal_UINT32(&ptr, &len, ordSize) |
| || tpm_marshal_UINT32_ARRAY(&ptr, &len, ordList, ordSize/4)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(ordList); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_GetAuditDigestSigned(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| BOOL closeAudit; |
| TPM_NONCE antiReplay; |
| TPM_COUNTER_VALUE counterValue; |
| TPM_DIGEST auditDigest; |
| TPM_DIGEST ordinalDigest; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_BOOL(&ptr, &len, &closeAudit) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_GetAuditDigestSigned(keyHandle, closeAudit, &antiReplay, &req->auth1, |
| &counterValue, &auditDigest, &ordinalDigest, &sigSize, &sig); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 10 + 20 + 20 + 4 + sigSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &auditDigest) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &ordinalDigest) |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SetOrdinalAuditStatus(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_COMMAND_CODE ordinalToAudit; |
| BOOL auditState; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_COMMAND_CODE(&ptr, &len, &ordinalToAudit) |
| || tpm_unmarshal_BOOL(&ptr, &len, &auditState) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetOrdinalAuditStatus(ordinalToAudit, auditState, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_FieldUpgrade(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_FieldUpgrade(); |
| } |
| |
| static TPM_RESULT execute_TPM_SetRedirection(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_REDIR_COMMAND redirCmd; |
| UINT32 inputDataSize; |
| BYTE *inputData; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_REDIR_COMMAND(&ptr, &len, &redirCmd) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inputDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData, inputDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetRedirection(keyHandle, redirCmd, inputDataSize, inputData, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_ResetLockValue(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_ResetLockValue(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_Seal(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_ENCAUTH encAuth; |
| UINT32 pcrInfoSize; |
| TPM_PCR_INFO pcrInfo; |
| UINT32 inDataSize; |
| BYTE *inData; |
| TPM_STORED_DATA sealedData; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth) |
| || tpm_unmarshal_UINT32(&ptr, &len, &pcrInfoSize) |
| || (pcrInfoSize > 0 |
| && tpm_unmarshal_TPM_PCR_INFO(&ptr, &len, &pcrInfo)) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Seal(keyHandle, &encAuth, pcrInfoSize, &pcrInfo, inDataSize, inData, |
| &req->auth1, &sealedData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_STORED_DATA(sealedData); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_STORED_DATA(&ptr, &len, &sealedData)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_STORED_DATA(sealedData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Unseal(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_STORED_DATA inData; |
| UINT32 sealedDataSize; |
| BYTE *secret = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_STORED_DATA(&ptr, &len, &inData) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Unseal(parentHandle, &inData, &req->auth1, &req->auth2, &sealedDataSize, &secret); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + sealedDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, sealedDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, secret, sealedDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(secret); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_UnBind(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| UINT32 inDataSize; |
| BYTE *inData; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_UnBind(keyHandle, inDataSize, inData, &req->auth1, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateWrapKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_ENCAUTH dataUsageAuth; |
| TPM_ENCAUTH dataMigrationAuth; |
| TPM_KEY keyInfo; |
| TPM_KEY wrappedKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataUsageAuth) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataMigrationAuth) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &keyInfo) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateWrapKey(parentHandle, &dataUsageAuth, &dataMigrationAuth, |
| &keyInfo, &req->auth1, &wrappedKey); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_KEY(wrappedKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY(&ptr, &len, &wrappedKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_KEY(wrappedKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_KEY inKey; |
| TPM_KEY_HANDLE inkeyHandle; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &inKey) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadKey(parentHandle, &inKey, &req->auth1, &inkeyHandle); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, inkeyHandle)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadKey2(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_KEY inKey; |
| TPM_KEY_HANDLE inkeyHandle; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &inKey) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadKey2(parentHandle, &inKey, &req->auth1, &inkeyHandle); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, inkeyHandle)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_GetPubKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_PUBKEY pubKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_GetPubKey(keyHandle, &req->auth1, &pubKey); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(pubKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(pubKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Sealx(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_ENCAUTH encAuth; |
| UINT32 pcrInfoSize; |
| TPM_PCR_INFO pcrInfo; |
| UINT32 inDataSize; |
| BYTE *inData; |
| TPM_STORED_DATA sealedData; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth) |
| || tpm_unmarshal_UINT32(&ptr, &len, &pcrInfoSize) |
| || (pcrInfoSize > 0 |
| && tpm_unmarshal_TPM_PCR_INFO(&ptr, &len, &pcrInfo)) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Sealx(keyHandle, &encAuth, pcrInfoSize, &pcrInfo, inDataSize, inData, |
| &req->auth1, &sealedData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_STORED_DATA(sealedData); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_STORED_DATA(&ptr, &len, &sealedData)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_STORED_DATA(sealedData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateMigrationBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_MIGRATE_SCHEME migrationType; |
| TPM_MIGRATIONKEYAUTH migrationKeyAuth; |
| UINT32 encDataSize; |
| BYTE *encData; |
| UINT32 randomSize; |
| BYTE *random = NULL; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrationType) |
| || tpm_unmarshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &migrationKeyAuth) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateMigrationBlob(parentHandle, migrationType, &migrationKeyAuth, encDataSize, |
| encData, &req->auth1, &req->auth2, &randomSize, &random, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + randomSize + 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, randomSize) |
| || tpm_marshal_BLOB(&ptr, &len, random, randomSize) |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(random); |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ConvertMigrationBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| UINT32 inDataSize; |
| BYTE *inData; |
| UINT32 randomSize; |
| BYTE *random; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &randomSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ConvertMigrationBlob(parentHandle, inDataSize, inData, randomSize, |
| random, &req->auth1, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_AuthorizeMigrationKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_MIGRATE_SCHEME migrateScheme; |
| TPM_PUBKEY migrationKey; |
| TPM_MIGRATIONKEYAUTH outData; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrateScheme) |
| || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &migrationKey) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_AuthorizeMigrationKey(migrateScheme, &migrationKey, &req->auth1, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_MIGRATIONKEYAUTH(outData); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &outData)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_MIGRATIONKEYAUTH(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_MigrateKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE maKeyHandle; |
| TPM_PUBKEY pubKey; |
| UINT32 inDataSize; |
| BYTE *inData; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &maKeyHandle) |
| || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_MigrateKey(maKeyHandle, &pubKey, inDataSize, inData, |
| &req->auth1, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_SetRestrictions(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_CMK_DELEGATE restriction; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_CMK_DELEGATE(&ptr, &len, &restriction) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_CMK_SetRestrictions(restriction, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_ApproveMA(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_DIGEST migrationAuthorityDigest; |
| TPM_HMAC outData; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationAuthorityDigest) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CMK_ApproveMA(&migrationAuthorityDigest, &req->auth1, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_HMAC(&ptr, &len, &outData)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_CreateKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_ENCAUTH dataUsageAuth; |
| TPM_KEY keyInfo; |
| TPM_HMAC migrationAuthorityApproval; |
| TPM_DIGEST migrationAuthorityDigest; |
| TPM_KEY wrappedKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataUsageAuth) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &keyInfo) |
| || tpm_unmarshal_TPM_HMAC(&ptr, &len, &migrationAuthorityApproval) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationAuthorityDigest) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CMK_CreateKey(parentHandle, &dataUsageAuth, &keyInfo, &migrationAuthorityApproval, |
| &migrationAuthorityDigest, &req->auth1, &req->auth2, &wrappedKey); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_KEY(wrappedKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY(&ptr, &len, &wrappedKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_KEY(wrappedKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_CreateTicket(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PUBKEY verificationKey; |
| TPM_DIGEST signedData; |
| UINT32 signatureValueSize; |
| BYTE *signatureValue; |
| TPM_DIGEST sigTicket; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &verificationKey) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &signedData) |
| || tpm_unmarshal_UINT32(&ptr, &len, &signatureValueSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &signatureValue, signatureValueSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CMK_CreateTicket(&verificationKey, &signedData, signatureValueSize, |
| signatureValue, &req->auth1, &sigTicket); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &sigTicket)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_CreateBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_MIGRATE_SCHEME migrationType; |
| TPM_MIGRATIONKEYAUTH migrationKeyAuth; |
| TPM_DIGEST pubSourceKeyDigest; |
| UINT32 msaListSize; |
| TPM_MSA_COMPOSITE msaList; |
| UINT32 restrictTicketSize; |
| TPM_CMK_AUTH restrictTicket; |
| UINT32 sigTicketSize; |
| TPM_HMAC sigTicket; |
| UINT32 encDataSize; |
| BYTE *encData; |
| UINT32 randomSize; |
| BYTE *random = NULL; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrationType) |
| || tpm_unmarshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &migrationKeyAuth) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &pubSourceKeyDigest) |
| || tpm_unmarshal_UINT32(&ptr, &len, &msaListSize) |
| || tpm_unmarshal_TPM_MSA_COMPOSITE(&ptr, &len, &msaList) |
| || tpm_unmarshal_UINT32(&ptr, &len, &restrictTicketSize) |
| || (restrictTicketSize > 0 |
| && tpm_unmarshal_TPM_CMK_AUTH(&ptr, &len, &restrictTicket)) |
| || tpm_unmarshal_UINT32(&ptr, &len, &sigTicketSize) |
| || (sigTicketSize > 0 |
| && tpm_unmarshal_TPM_HMAC(&ptr, &len, &sigTicket)) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CMK_CreateBlob(parentHandle, migrationType, &migrationKeyAuth, |
| &pubSourceKeyDigest, &msaList, |
| restrictTicketSize > 0 ? &restrictTicket : NULL, |
| sigTicketSize > 0 ? &sigTicket : NULL, |
| encDataSize, encData, &req->auth1, &randomSize, &random, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + randomSize + 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, randomSize) |
| || tpm_marshal_BLOB(&ptr, &len, random, randomSize) |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(random); |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CMK_ConvertMigration(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_CMK_AUTH restrictTicket; |
| TPM_HMAC sigTicket; |
| TPM_KEY migratedKey; |
| UINT32 msaListSize; |
| TPM_MSA_COMPOSITE msaList; |
| UINT32 randomSize; |
| BYTE *random; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_CMK_AUTH(&ptr, &len, &restrictTicket) |
| || tpm_unmarshal_TPM_HMAC(&ptr, &len, &sigTicket) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &migratedKey) |
| || tpm_unmarshal_UINT32(&ptr, &len, &msaListSize) |
| || tpm_unmarshal_TPM_MSA_COMPOSITE(&ptr, &len, &msaList) |
| || tpm_unmarshal_UINT32(&ptr, &len, &randomSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CMK_ConvertMigration(parentHandle, &restrictTicket, &sigTicket, |
| &migratedKey, &msaList, randomSize, random, &req->auth1, &outDataSize, |
| &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateMaintenanceArchive(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL generateRandom; |
| UINT32 randomSize; |
| BYTE *random = NULL; |
| UINT32 archiveSize; |
| BYTE *archive = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &generateRandom) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateMaintenanceArchive(generateRandom, &req->auth1, &randomSize, |
| &random, &archiveSize, &archive); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + randomSize + 4 + archiveSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, randomSize) |
| || tpm_marshal_BLOB(&ptr, &len, random, randomSize) |
| || tpm_marshal_UINT32(&ptr, &len, archiveSize) |
| || tpm_marshal_BLOB(&ptr, &len, archive, archiveSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(random); |
| tpm_free(archive); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadMaintenanceArchive(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 archiveSize; |
| BYTE *archive; |
| UINT32 sigSize; |
| BYTE *sig; |
| UINT32 randomSize; |
| BYTE *random; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &archiveSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &archive, archiveSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &sigSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &sig, sigSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &randomSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_LoadMaintenanceArchive(archiveSize, archive, sigSize, sig, |
| randomSize, random, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_KillMaintenanceFeature(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_KillMaintenanceFeature(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_LoadManuMaintPub(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE antiReplay; |
| TPM_PUBKEY pubKey; |
| TPM_DIGEST checksum; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadManuMaintPub(&antiReplay, &pubKey, &checksum); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ReadManuMaintPub(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE antiReplay; |
| TPM_DIGEST checksum; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ReadManuMaintPub(&antiReplay, &checksum); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SHA1Start(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 maxNumBytes; |
| TPM_RESULT res; |
| /* execute command */ |
| res = TPM_SHA1Start(&maxNumBytes); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, maxNumBytes)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SHA1Update(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 numBytes; |
| BYTE *hashData; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &numBytes) |
| || tpm_unmarshal_BLOB(&ptr, &len, &hashData, numBytes) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SHA1Update(numBytes, hashData); |
| } |
| |
| static TPM_RESULT execute_TPM_SHA1Complete(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 hashDataSize; |
| BYTE *hashData; |
| TPM_DIGEST hashValue; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &hashDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &hashData, hashDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_SHA1Complete(hashDataSize, hashData, &hashValue); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &hashValue)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SHA1CompleteExtend(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PCRINDEX pcrNum; |
| UINT32 hashDataSize; |
| BYTE *hashData; |
| TPM_DIGEST hashValue; |
| TPM_PCRVALUE outDigest; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum) |
| || tpm_unmarshal_UINT32(&ptr, &len, &hashDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &hashData, hashDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_SHA1CompleteExtend(pcrNum, hashDataSize, hashData, &hashValue, &outDigest); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &hashValue) |
| || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Sign(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| UINT32 areaToSignSize; |
| BYTE *areaToSign; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_UINT32(&ptr, &len, &areaToSignSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &areaToSign, areaToSignSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Sign(keyHandle, areaToSignSize, areaToSign, &req->auth1, &sigSize, &sig); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + sigSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_GetRandom(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 bytesRequested; |
| UINT32 randomBytesSize; |
| BYTE *randomBytes = NULL; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &bytesRequested) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_GetRandom(bytesRequested, &randomBytesSize, &randomBytes); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + randomBytesSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, randomBytesSize) |
| || tpm_marshal_BLOB(&ptr, &len, randomBytes, randomBytesSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(randomBytes); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_StirRandom(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 dataSize; |
| BYTE *inData; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &dataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inData, dataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_StirRandom(dataSize, inData); |
| } |
| |
| static TPM_RESULT execute_TPM_CertifyKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE certHandle; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_NONCE antiReplay; |
| TPM_CERTIFY_INFO certifyInfo; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &certHandle) |
| || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CertifyKey(certHandle, keyHandle, &antiReplay, &req->auth1, |
| &req->auth2, &certifyInfo, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_CERTIFY_INFO(certifyInfo) + 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo) |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_CERTIFY_INFO(certifyInfo); |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CertifyKey2(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE certHandle; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_DIGEST migrationPubDigest; |
| TPM_NONCE antiReplay; |
| TPM_CERTIFY_INFO certifyInfo; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &certHandle) |
| || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationPubDigest) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CertifyKey2(certHandle, keyHandle, &migrationPubDigest, &antiReplay, |
| &req->auth1, &req->auth2, &certifyInfo, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_CERTIFY_INFO(certifyInfo) + 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo) |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_CERTIFY_INFO(certifyInfo); |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateEndorsementKeyPair(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE antiReplay; |
| TPM_KEY_PARMS keyInfo; |
| TPM_PUBKEY pubEndorsementKey; |
| TPM_DIGEST Checksum; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &keyInfo) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateEndorsementKeyPair(&antiReplay, &keyInfo, &pubEndorsementKey, &Checksum); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &Checksum)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(pubEndorsementKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateRevocableEK(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE antiReplay; |
| TPM_KEY_PARMS keyInfo; |
| BOOL generateReset; |
| TPM_NONCE inputEKreset; |
| TPM_PUBKEY pubEndorsementKey; |
| TPM_DIGEST Checksum; |
| TPM_NONCE outputEKreset; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &keyInfo) |
| || tpm_unmarshal_BOOL(&ptr, &len, &generateReset) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &inputEKreset) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateRevocableEK(&antiReplay, &keyInfo, generateReset, |
| &inputEKreset, &pubEndorsementKey, &Checksum, &outputEKreset); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &Checksum) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &outputEKreset)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(pubEndorsementKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_RevokeTrust(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE EKReset; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &EKReset) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_RevokeTrust(&EKReset); |
| } |
| |
| static TPM_RESULT execute_TPM_ReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NONCE antiReplay; |
| TPM_PUBKEY pubEndorsementKey; |
| TPM_DIGEST checksum; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ReadPubek(&antiReplay, &pubEndorsementKey, &checksum); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(pubEndorsementKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_DisablePubekRead(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| return TPM_DisablePubekRead(&req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_OwnerReadInternalPub(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_PUBKEY publicPortion; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_OwnerReadInternalPub(keyHandle, &req->auth1, &publicPortion); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(publicPortion); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &publicPortion)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(publicPortion); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_MakeIdentity(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_ENCAUTH identityAuth; |
| TPM_CHOSENID_HASH labelPrivCADigest; |
| TPM_KEY idKeyParams; |
| TPM_KEY idKey; |
| UINT32 identityBindingSize; |
| BYTE *identityBinding = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &identityAuth) |
| || tpm_unmarshal_TPM_CHOSENID_HASH(&ptr, &len, &labelPrivCADigest) |
| || tpm_unmarshal_TPM_KEY(&ptr, &len, &idKeyParams) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_MakeIdentity(&identityAuth, &labelPrivCADigest, &idKeyParams, |
| &req->auth1, &req->auth2, &idKey, &identityBindingSize, &identityBinding); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_KEY(idKey) + 4 + identityBindingSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY(&ptr, &len, &idKey) |
| || tpm_marshal_UINT32(&ptr, &len, identityBindingSize) |
| || tpm_marshal_BLOB(&ptr, &len, identityBinding, identityBindingSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_KEY(idKey); |
| tpm_free(identityBinding); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ActivateIdentity(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE idKeyHandle; |
| UINT32 blobSize; |
| BYTE *blob; |
| TPM_SYMMETRIC_KEY symmetricKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &idKeyHandle) |
| || tpm_unmarshal_UINT32(&ptr, &len, &blobSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &blob, blobSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* allocate memory for the symmetricKey data */ |
| symmetricKey.size = blobSize; |
| symmetricKey.data = tpm_malloc(blobSize); |
| if (symmetricKey.data == NULL) |
| return TPM_NOSPACE; |
| /* execute command */ |
| res = TPM_ActivateIdentity(idKeyHandle, blobSize, blob, &req->auth1, |
| &req->auth2, &symmetricKey); |
| if (res != TPM_SUCCESS) { |
| free_TPM_SYMMETRIC_KEY(symmetricKey); |
| return res; |
| } |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_SYMMETRIC_KEY(symmetricKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL) |
| res = TPM_NOSPACE; |
| else if (tpm_marshal_TPM_SYMMETRIC_KEY(&ptr, &len, &symmetricKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_SYMMETRIC_KEY(symmetricKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Extend(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PCRINDEX pcrNum; |
| TPM_DIGEST inDigest; |
| TPM_PCRVALUE outDigest; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &inDigest) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| #ifdef MTM_EMULATOR |
| res = MTM_Extend(pcrNum, &inDigest, &outDigest); |
| #else |
| res = TPM_Extend(pcrNum, &inDigest, &outDigest); |
| #endif |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_PCRRead(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PCRINDEX pcrIndex; |
| TPM_PCRVALUE outDigest; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrIndex) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_PCRRead(pcrIndex, &outDigest); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Quote(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_NONCE extrnalData; |
| TPM_PCR_SELECTION targetPCR; |
| TPM_PCR_COMPOSITE pcrData; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &extrnalData) |
| || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Quote(keyHandle, &extrnalData, &targetPCR, &req->auth1, &pcrData, &sigSize, &sig); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PCR_COMPOSITE(pcrData) + 4 + sigSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PCR_COMPOSITE(&ptr, &len, &pcrData) |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_PCR_Reset(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PCR_SELECTION pcrSelection; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &pcrSelection) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| #ifdef MTM_EMULATOR |
| return MTM_PCR_Reset(&pcrSelection); |
| #else |
| return TPM_PCR_Reset(&pcrSelection); |
| #endif |
| } |
| |
| static TPM_RESULT execute_TPM_Quote2(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_NONCE externalData; |
| TPM_PCR_SELECTION targetPCR; |
| BOOL addVersion; |
| TPM_PCR_INFO_SHORT pcrData; |
| UINT32 versionInfoSize; |
| TPM_CAP_VERSION_INFO versionInfo; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &externalData) |
| || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR) |
| || tpm_unmarshal_BOOL(&ptr, &len, &addVersion) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Quote2(keyHandle, &externalData, &targetPCR, addVersion, |
| &req->auth1, &pcrData, &versionInfoSize, &versionInfo, &sigSize, &sig); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PCR_INFO_SHORT(pcrData) + 4 |
| + versionInfoSize + 4 + sigSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PCR_INFO_SHORT(&ptr, &len, &pcrData) |
| || tpm_marshal_UINT32(&ptr, &len, versionInfoSize) |
| || ((addVersion == TRUE) |
| && tpm_marshal_TPM_CAP_VERSION_INFO(&ptr, &len, &versionInfo)) |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ChangeAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_PROTOCOL_ID protocolID; |
| TPM_ENCAUTH newAuth; |
| TPM_ENTITY_TYPE entityType; |
| UINT32 encDataSize; |
| BYTE *encData; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &newAuth) |
| || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ChangeAuth(parentHandle, protocolID, &newAuth, entityType, encDataSize, |
| encData, &req->auth1, &req->auth2, &outDataSize, &outData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ChangeAuthOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PROTOCOL_ID protocolID; |
| TPM_ENCAUTH newAuth; |
| TPM_ENTITY_TYPE entityType; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &newAuth) |
| || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_ChangeAuthOwner(protocolID, &newAuth, entityType, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_OIAP(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_AUTHHANDLE authHandle; |
| TPM_NONCE nonceEven; |
| TPM_RESULT res; |
| /* execute command */ |
| res = TPM_OIAP(&authHandle, &nonceEven); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_OSAP(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_ENTITY_TYPE entityType; |
| UINT32 entityValue; |
| TPM_NONCE nonceOddOSAP; |
| TPM_AUTHHANDLE authHandle; |
| TPM_NONCE nonceEven; |
| TPM_NONCE nonceEvenOSAP; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || tpm_unmarshal_UINT32(&ptr, &len, &entityValue) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonceOddOSAP) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_OSAP(entityType, entityValue, &nonceOddOSAP, &authHandle, |
| &nonceEven, &nonceEvenOSAP); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + 20 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEvenOSAP)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_DSAP(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_ENTITY_TYPE entityType; |
| TPM_KEY_HANDLE keyHandle; |
| UINT32 entityValueSize; |
| BYTE *entityValue; |
| TPM_NONCE nonceOddDSAP; |
| TPM_AUTHHANDLE authHandle; |
| TPM_NONCE nonceEven; |
| TPM_NONCE nonceEvenDSAP; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonceOddDSAP) |
| || tpm_unmarshal_UINT32(&ptr, &len, &entityValueSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &entityValue, entityValueSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_DSAP(entityType, keyHandle, &nonceOddDSAP, entityValueSize, |
| entityValue, &authHandle, &nonceEven, &nonceEvenDSAP); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + 20 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEvenDSAP)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SetOwnerPointer(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_ENTITY_TYPE entityType; |
| UINT32 entityValue; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || tpm_unmarshal_UINT32(&ptr, &len, &entityValue) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_SetOwnerPointer(entityType, entityValue); |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_Manage(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_FAMILY_ID familyID; |
| TPM_FAMILY_OPERATION opFlag; |
| UINT32 opDataSize; |
| BYTE *opData; |
| UINT32 retDataSize; |
| BYTE *retData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_FAMILY_ID(&ptr, &len, &familyID) |
| || tpm_unmarshal_TPM_FAMILY_OPERATION(&ptr, &len, &opFlag) |
| || tpm_unmarshal_UINT32(&ptr, &len, &opDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &opData, opDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Delegate_Manage(familyID, opFlag, opDataSize, opData, |
| &req->auth1, &retDataSize, &retData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + retDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, retDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, retData, retDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(retData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_CreateKeyDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_DELEGATE_PUBLIC publicInfo; |
| TPM_ENCAUTH delAuth; |
| UINT32 blobSize; |
| TPM_DELEGATE_KEY_BLOB blob; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_DELEGATE_PUBLIC(&ptr, &len, &publicInfo) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &delAuth) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Delegate_CreateKeyDelegation(keyHandle, &publicInfo, &delAuth, |
| &req->auth1, &blob); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| blobSize = sizeof_TPM_DELEGATE_KEY_BLOB(blob); |
| rsp->paramSize = len = 4 + blobSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, blobSize) |
| || tpm_marshal_TPM_DELEGATE_KEY_BLOB(&ptr, &len, &blob)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_DELEGATE_KEY_BLOB(blob); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_CreateOwnerDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL increment; |
| TPM_DELEGATE_PUBLIC publicInfo; |
| TPM_ENCAUTH delAuth; |
| UINT32 blobSize; |
| TPM_DELEGATE_OWNER_BLOB blob; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &increment) |
| || tpm_unmarshal_TPM_DELEGATE_PUBLIC(&ptr, &len, &publicInfo) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &delAuth) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Delegate_CreateOwnerDelegation(increment, &publicInfo, &delAuth, |
| &req->auth1, &blob); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| blobSize = sizeof_TPM_DELEGATE_OWNER_BLOB(blob); |
| rsp->paramSize = len = 4 + blobSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, blobSize) |
| || tpm_marshal_TPM_DELEGATE_OWNER_BLOB(&ptr, &len, &blob)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_DELEGATE_OWNER_BLOB(blob); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_LoadOwnerDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_DELEGATE_INDEX index; |
| UINT32 blobSize; |
| TPM_DELEGATE_OWNER_BLOB blob; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_DELEGATE_INDEX(&ptr, &len, &index) |
| || tpm_unmarshal_UINT32(&ptr, &len, &blobSize) |
| || tpm_unmarshal_TPM_DELEGATE_OWNER_BLOB(&ptr, &len, &blob) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_Delegate_LoadOwnerDelegation(index, &blob, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_ReadTable(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 familyTableSize; |
| BYTE *familyTable = NULL; |
| UINT32 delegateTableSize; |
| BYTE *delegateTable = NULL; |
| TPM_RESULT res; |
| /* execute command */ |
| res = TPM_Delegate_ReadTable(&familyTableSize, &familyTable, &delegateTableSize, &delegateTable); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + familyTableSize + 4 + delegateTableSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, familyTableSize) |
| || tpm_marshal_BLOB(&ptr, &len, familyTable, familyTableSize) |
| || tpm_marshal_UINT32(&ptr, &len, delegateTableSize) |
| || tpm_marshal_BLOB(&ptr, &len, delegateTable, delegateTableSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(familyTable); |
| tpm_free(delegateTable); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_UpdateVerification(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 inputSize; |
| BYTE *inputData; |
| UINT32 outputSize; |
| BYTE *outputData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &inputSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData, inputSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_Delegate_UpdateVerification(inputSize, inputData, |
| &req->auth1, &outputSize, &outputData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outputSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outputSize) |
| || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outputData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Delegate_VerifyDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 delegateSize; |
| BYTE *delegation; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &delegateSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &delegation, delegateSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_Delegate_VerifyDelegation(delegateSize, delegation); |
| } |
| |
| static TPM_RESULT execute_TPM_NV_DefineSpace(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NV_DATA_PUBLIC pubInfo; |
| TPM_ENCAUTH encAuth; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NV_DATA_PUBLIC(&ptr, &len, &pubInfo) |
| || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_NV_DefineSpace(&pubInfo, &encAuth, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_NV_WriteValue(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NV_INDEX nvIndex; |
| UINT32 offset; |
| UINT32 dataSize; |
| BYTE *data; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex) |
| || tpm_unmarshal_UINT32(&ptr, &len, &offset) |
| || tpm_unmarshal_UINT32(&ptr, &len, &dataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &data, dataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_NV_WriteValue(nvIndex, offset, dataSize, data, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_NV_WriteValueAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NV_INDEX nvIndex; |
| UINT32 offset; |
| UINT32 dataSize; |
| BYTE *data; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex) |
| || tpm_unmarshal_UINT32(&ptr, &len, &offset) |
| || tpm_unmarshal_UINT32(&ptr, &len, &dataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &data, dataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_NV_WriteValueAuth(nvIndex, offset, dataSize, data, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_NV_ReadValue(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NV_INDEX nvIndex; |
| UINT32 offset; |
| UINT32 inDataSize; |
| UINT32 outDataSize; |
| BYTE *data = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex) |
| || tpm_unmarshal_UINT32(&ptr, &len, &offset) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_NV_ReadValue(nvIndex, offset, inDataSize, &req->auth1, &outDataSize, &data); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, data, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(data); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_NV_ReadValueAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_NV_INDEX nvIndex; |
| UINT32 offset; |
| UINT32 inDataSize; |
| UINT32 outDataSize; |
| BYTE *data = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex) |
| || tpm_unmarshal_UINT32(&ptr, &len, &offset) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_NV_ReadValueAuth(nvIndex, offset, inDataSize, &req->auth1, &outDataSize, &data); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, data, outDataSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(data); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_KeyControlOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_PUBKEY pubKey; |
| UINT32 bitName; |
| BOOL bitValue; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey) |
| || tpm_unmarshal_UINT32(&ptr, &len, &bitName) |
| || tpm_unmarshal_BOOL(&ptr, &len, &bitValue) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_KeyControlOwner(keyHandle, pubKey, bitName, bitValue, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_SaveContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_HANDLE handle; |
| TPM_RESOURCE_TYPE resourceType; |
| BYTE label[16]; |
| UINT32 contextSize; |
| TPM_CONTEXT_BLOB contextBlob; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) |
| || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType) |
| || tpm_unmarshal_BYTE_ARRAY(&ptr, &len, label, 16) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_SaveContext(handle, resourceType, label, &contextSize, &contextBlob); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + contextSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, contextSize) |
| || tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_CONTEXT_BLOB(contextBlob); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| BOOL keepHandle; |
| TPM_HANDLE hintHandle; |
| UINT32 contextSize; |
| TPM_CONTEXT_BLOB contextBlob; |
| TPM_HANDLE handle; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_BOOL(&ptr, &len, &keepHandle) |
| || tpm_unmarshal_TPM_HANDLE(&ptr, &len, &hintHandle) |
| || tpm_unmarshal_UINT32(&ptr, &len, &contextSize) |
| || tpm_unmarshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadContext(keepHandle, hintHandle, contextSize, &contextBlob, &handle); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_HANDLE(&ptr, &len, handle)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| 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 */ |
| #ifdef MTM_EMULATOR |
| return MTM_FlushSpecific(handle, resourceType); |
| #else |
| return TPM_FlushSpecific(handle, resourceType); |
| #endif |
| } |
| |
| static TPM_RESULT execute_TPM_GetTicks(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_CURRENT_TICKS currentTime; |
| TPM_RESULT res; |
| /* execute command */ |
| res = TPM_GetTicks(¤tTime); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 32; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, ¤tTime)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_TickStampBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_NONCE antiReplay; |
| TPM_DIGEST digestToStamp; |
| TPM_CURRENT_TICKS currentTicks; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &digestToStamp) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_TickStampBlob(keyHandle, &antiReplay, &digestToStamp, &req->auth1, |
| ¤tTicks, &sigSize, &sig); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 32 + 4 + sigSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, ¤tTicks) |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_EstablishTransport(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE encHandle; |
| TPM_TRANSPORT_PUBLIC transPublic; |
| UINT32 secretSize; |
| BYTE *secret; |
| TPM_TRANSHANDLE transHandle; |
| TPM_MODIFIER_INDICATOR locality; |
| TPM_CURRENT_TICKS currentTicks; |
| TPM_NONCE transNonce; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &encHandle) |
| || tpm_unmarshal_TPM_TRANSPORT_PUBLIC(&ptr, &len, &transPublic) |
| || tpm_unmarshal_UINT32(&ptr, &len, &secretSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &secret, secretSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_EstablishTransport(encHandle, &transPublic, secretSize, secret, |
| &req->auth1, &transHandle, &locality, ¤tTicks, &transNonce); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + 4 + 32 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_TRANSHANDLE(&ptr, &len, transHandle) |
| || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, locality) |
| || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, ¤tTicks) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &transNonce)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ExecuteTransport(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 inWrappedCmdSize; |
| BYTE *inWrappedCmd; |
| UINT64 currentTicks; |
| TPM_MODIFIER_INDICATOR locality; |
| UINT32 outWrappedCmdSize; |
| BYTE *outWrappedCmd = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &inWrappedCmdSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inWrappedCmd, inWrappedCmdSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ExecuteTransport(inWrappedCmdSize, inWrappedCmd, &req->auth1, |
| ¤tTicks, &locality, &outWrappedCmdSize, &outWrappedCmd); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 8 + 4 + 4 + outWrappedCmdSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT64(&ptr, &len, currentTicks) |
| || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, locality) |
| || tpm_marshal_UINT32(&ptr, &len, outWrappedCmdSize) |
| || tpm_marshal_BLOB(&ptr, &len, outWrappedCmd, outWrappedCmdSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outWrappedCmd); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ReleaseTransportSigned(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE key; |
| TPM_NONCE antiReplay; |
| TPM_MODIFIER_INDICATOR locality; |
| TPM_CURRENT_TICKS currentTicks; |
| UINT32 signSize; |
| BYTE *signature = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &key) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ReleaseTransportSigned(key, &antiReplay, &req->auth1, &req->auth2, |
| &locality, ¤tTicks, &signSize, &signature); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + 32 + 4 + signSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, locality) |
| || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, ¤tTicks) |
| || tpm_marshal_UINT32(&ptr, &len, signSize) |
| || tpm_marshal_BLOB(&ptr, &len, signature, signSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(signature); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_CreateCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_ENCAUTH authData; |
| BYTE label[4]; |
| TPM_COUNT_ID countID; |
| TPM_COUNTER_VALUE counterValue; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &authData) |
| || tpm_unmarshal_BYTE_ARRAY(&ptr, &len, label, 4) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_CreateCounter(&authData, label, &req->auth1, &countID, &counterValue); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + sizeof_TPM_COUNTER_VALUE(counterValue); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_COUNT_ID(&ptr, &len, countID) |
| || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_IncrementCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_COUNT_ID countID; |
| TPM_COUNTER_VALUE count; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_IncrementCounter(countID, &req->auth1, &count); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 10; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &count)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ReadCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_COUNT_ID countID; |
| TPM_COUNTER_VALUE count; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ReadCounter(countID, &count); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 10; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &count)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ReleaseCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_COUNT_ID countID; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| #ifdef MTM_EMULATOR |
| return MTM_ReleaseCounter(countID, &req->auth1); |
| #else |
| return TPM_ReleaseCounter(countID, &req->auth1); |
| #endif |
| } |
| |
| static TPM_RESULT execute_TPM_ReleaseCounterOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_COUNT_ID countID; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| #ifdef MTM_EMULATOR |
| return MTM_ReleaseCounterOwner(countID, &req->auth1); |
| #else |
| return TPM_ReleaseCounterOwner(countID, &req->auth1); |
| #endif |
| } |
| |
| static TPM_RESULT execute_TPM_DAA_Join(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_HANDLE handle; |
| BYTE stage; |
| UINT32 inputSize0; |
| BYTE *inputData0; |
| UINT32 inputSize1; |
| BYTE *inputData1; |
| TPM_COMMAND_CODE ordinal; |
| UINT32 outputSize; |
| BYTE *outputData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) |
| || tpm_unmarshal_BYTE(&ptr, &len, &stage) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inputSize0) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData0, inputSize0) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inputSize1) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData1, inputSize1) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_DAA_Join(handle, stage, inputSize0, inputData0, inputSize1, |
| inputData1, &req->auth1, &ordinal, &outputSize, &outputData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outputSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outputSize) |
| || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outputData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_DAA_Sign(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_HANDLE handle; |
| BYTE stage; |
| UINT32 inputSize0; |
| BYTE *inputData0; |
| UINT32 inputSize1; |
| BYTE *inputData1; |
| TPM_COMMAND_CODE ordinal; |
| UINT32 outputSize; |
| BYTE *outputData = NULL; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) |
| || tpm_unmarshal_BYTE(&ptr, &len, &stage) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inputSize0) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData0, inputSize0) |
| || tpm_unmarshal_UINT32(&ptr, &len, &inputSize1) |
| || tpm_unmarshal_BLOB(&ptr, &len, &inputData1, inputSize1) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_DAA_Sign(handle, stage, inputSize0, inputData0, inputSize1, |
| inputData1, &req->auth1, &ordinal, &outputSize, &outputData); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outputSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outputSize) |
| || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outputData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_EvictKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE evictHandle; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &evictHandle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_EvictKey(evictHandle); |
| } |
| |
| static TPM_RESULT execute_TPM_Terminate_Handle(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_AUTHHANDLE handle; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_AUTHHANDLE(&ptr, &len, &handle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_Terminate_Handle(handle); |
| } |
| |
| static TPM_RESULT execute_TPM_SaveKeyContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE keyHandle; |
| UINT32 keyContextSize; |
| BYTE *keyContextBlob = NULL; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_SaveKeyContext(keyHandle, &keyContextSize, &keyContextBlob); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + keyContextSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, keyContextSize) |
| || tpm_marshal_BLOB(&ptr, &len, keyContextBlob, keyContextSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(keyContextBlob); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadKeyContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 keyContextSize; |
| BYTE *keyContextBlob; |
| TPM_KEY_HANDLE keyHandle; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &keyContextSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &keyContextBlob, keyContextSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadKeyContext(keyContextSize, keyContextBlob, &keyHandle); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, keyHandle)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_SaveAuthContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_AUTHHANDLE authandle; |
| UINT32 authContextSize; |
| BYTE *authContextBlob = NULL; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_AUTHHANDLE(&ptr, &len, &authandle) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_SaveAuthContext(authandle, &authContextSize, &authContextBlob); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + authContextSize; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, authContextSize) |
| || tpm_marshal_BLOB(&ptr, &len, authContextBlob, authContextSize)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(authContextBlob); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_LoadAuthContext(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| UINT32 authContextSize; |
| BYTE *authContextBlob; |
| TPM_KEY_HANDLE authHandle; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_UINT32(&ptr, &len, &authContextSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &authContextBlob, authContextSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_LoadAuthContext(authContextSize, authContextBlob, &authHandle); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, authHandle)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_DirWriteAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_DIRINDEX dirIndex; |
| TPM_DIRVALUE newContents; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_DIRINDEX(&ptr, &len, &dirIndex) |
| || tpm_unmarshal_TPM_DIRVALUE(&ptr, &len, &newContents) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| return TPM_DirWriteAuth(dirIndex, &newContents, &req->auth1); |
| } |
| |
| static TPM_RESULT execute_TPM_DirRead(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_DIRINDEX dirIndex; |
| TPM_DIRVALUE dirContents; |
| TPM_RESULT res; |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_DIRINDEX(&ptr, &len, &dirIndex) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_DirRead(dirIndex, &dirContents); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_DIRVALUE(&ptr, &len, &dirContents)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ChangeAuthAsymStart(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE idHandle; |
| TPM_NONCE antiReplay; |
| TPM_KEY_PARMS inTempKey; |
| TPM_CERTIFY_INFO certifyInfo; |
| UINT32 sigSize; |
| BYTE *sig = NULL; |
| TPM_KEY_HANDLE ephHandle; |
| TPM_KEY outTempKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &idHandle) |
| || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay) |
| || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &inTempKey) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ChangeAuthAsymStart(idHandle, &antiReplay, &inTempKey, &req->auth1, |
| &certifyInfo, &sigSize, &sig, &ephHandle, &outTempKey); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 95 + 4 + sigSize + 4 + sizeof_TPM_KEY(outTempKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo) |
| || tpm_marshal_UINT32(&ptr, &len, sigSize) |
| || tpm_marshal_BLOB(&ptr, &len, sig, sigSize) |
| || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, ephHandle) |
| || tpm_marshal_TPM_KEY(&ptr, &len, &outTempKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(sig); |
| free_TPM_KEY(outTempKey); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_ChangeAuthAsymFinish(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_KEY_HANDLE parentHandle; |
| TPM_KEY_HANDLE ephHandle; |
| TPM_ENTITY_TYPE entityType; |
| TPM_HMAC newAuthLink; |
| UINT32 newAuthSize; |
| BYTE *encNewAuth; |
| UINT32 encDataSize; |
| BYTE *encData; |
| UINT32 outDataSize; |
| BYTE *outData = NULL; |
| TPM_NONCE saltNonce; |
| TPM_DIGEST changeProof; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* unmarshal input */ |
| ptr = req->param; |
| len = req->paramSize; |
| if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle) |
| || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &ephHandle) |
| || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType) |
| || tpm_unmarshal_TPM_HMAC(&ptr, &len, &newAuthLink) |
| || tpm_unmarshal_UINT32(&ptr, &len, &newAuthSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encNewAuth, newAuthSize) |
| || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize) |
| || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize) |
| || len != 0) return TPM_BAD_PARAMETER; |
| /* execute command */ |
| res = TPM_ChangeAuthAsymFinish(parentHandle, ephHandle, entityType, |
| &newAuthLink, newAuthSize, encNewAuth, encDataSize, encData, &req->auth1, |
| &outDataSize, &outData, &saltNonce, &changeProof); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = 4 + outDataSize + 20 + 20; |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_UINT32(&ptr, &len, outDataSize) |
| || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize) |
| || tpm_marshal_TPM_NONCE(&ptr, &len, &saltNonce) |
| || tpm_marshal_TPM_DIGEST(&ptr, &len, &changeProof)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| tpm_free(outData); |
| return res; |
| } |
| |
| static TPM_RESULT execute_TPM_Reset(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| /* execute command */ |
| return TPM_Reset(); |
| } |
| |
| static TPM_RESULT execute_TPM_OwnerReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| BYTE *ptr; |
| UINT32 len; |
| TPM_PUBKEY pubEndorsementKey; |
| TPM_RESULT res; |
| /* compute parameter digest */ |
| tpm_compute_in_param_digest(req); |
| /* execute command */ |
| res = TPM_OwnerReadPubek(&req->auth1, &pubEndorsementKey); |
| if (res != TPM_SUCCESS) return res; |
| /* marshal output */ |
| rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey); |
| rsp->param = ptr = tpm_malloc(len); |
| if (ptr == NULL |
| || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey)) { |
| tpm_free(rsp->param); |
| res = TPM_FAIL; |
| } |
| free_TPM_PUBKEY(pubEndorsementKey); |
| return res; |
| } |
| |
| static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp) |
| { |
| tpm_hmac_ctx_t hmac; |
| |
| /* compute parameter digest */ |
| if (ordinal != TPM_ORD_ExecuteTransport) |
| tpm_compute_out_param_digest(ordinal, rsp); |
| /* compute authorization values */ |
| switch (rsp->tag) { |
| case TPM_TAG_RSP_AUTH2_COMMAND: |
| tpm_hmac_init(&hmac, *rsp->auth2->secret, sizeof(*rsp->auth2->secret)); |
| tpm_hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest)); |
| tpm_hmac_update(&hmac, rsp->auth2->nonceEven.nonce, |
| sizeof(rsp->auth2->nonceEven.nonce)); |
| tpm_hmac_update(&hmac, rsp->auth2->nonceOdd.nonce, |
| sizeof(rsp->auth2->nonceOdd.nonce)); |
| tpm_hmac_update(&hmac, (BYTE*)&rsp->auth2->continueAuthSession, 1); |
| tpm_hmac_final(&hmac, rsp->auth2->auth); |
| case TPM_TAG_RSP_AUTH1_COMMAND: |
| tpm_hmac_init(&hmac, *rsp->auth1->secret, sizeof(*rsp->auth1->secret)); |
| tpm_hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest)); |
| tpm_hmac_update(&hmac, rsp->auth1->nonceEven.nonce, |
| sizeof(rsp->auth1->nonceEven.nonce)); |
| tpm_hmac_update(&hmac, rsp->auth1->nonceOdd.nonce, |
| sizeof(rsp->auth1->nonceOdd.nonce)); |
| tpm_hmac_update(&hmac, (BYTE*)&rsp->auth1->continueAuthSession, 1); |
| tpm_hmac_final(&hmac, rsp->auth1->auth); |
| break; |
| } |
| } |
| |
| static void tpm_setup_error_response(TPM_RESULT res, TPM_RESPONSE *rsp) |
| { |
| rsp->tag = TPM_TAG_RSP_COMMAND; |
| rsp->size = 10; |
| rsp->result = res; |
| rsp->param = NULL; |
| rsp->paramSize = 0; |
| } |
| |
| static TPM_RESULT tpm_check_status_and_mode(TPM_REQUEST *req) |
| { |
| /* verify that self-test succeeded */ |
| if (!tpmData.permanent.flags.selfTestSucceeded) return TPM_FAILEDSELFTEST; |
| /* initialisation must be finished before we execute any command */ |
| if (tpmData.stany.flags.postInitialise) return TPM_INVALID_POSTINIT; |
| /* if the TPM is deactivated only a subset of all commands can be performed */ |
| if ((tpmData.permanent.flags.deactivated || tpmData.stclear.flags.deactivated) |
| && req->ordinal != TPM_ORD_Reset |
| && req->ordinal != TPM_ORD_Init |
| && req->ordinal != TPM_ORD_Startup |
| && req->ordinal != TPM_ORD_SaveState |
| && req->ordinal != TPM_ORD_SHA1Start |
| && req->ordinal != TPM_ORD_SHA1Update |
| && req->ordinal != TPM_ORD_SHA1Complete |
| && req->ordinal != TPM_ORD_SHA1CompleteExtend |
| && req->ordinal != TPM_ORD_OIAP |
| && req->ordinal != TPM_ORD_OSAP |
| && req->ordinal != TPM_ORD_DSAP |
| && req->ordinal != TPM_ORD_GetCapability |
| && req->ordinal != TPM_ORD_SetCapability |
| && req->ordinal != TPM_ORD_TakeOwnership |
| && req->ordinal != TPM_ORD_OwnerSetDisable |
| && req->ordinal != TPM_ORD_PhysicalDisable |
| && req->ordinal != TPM_ORD_PhysicalEnable |
| && req->ordinal != TPM_ORD_PhysicalSetDeactivated |
| && req->ordinal != TPM_ORD_ContinueSelfTest |
| && req->ordinal != TPM_ORD_SelfTestFull |
| && req->ordinal != TPM_ORD_GetTestResult |
| && req->ordinal != TPM_ORD_FlushSpecific |
| && req->ordinal != TPM_ORD_Terminate_Handle |
| && req->ordinal != TPM_ORD_Extend |
| && req->ordinal != TPM_ORD_PCR_Reset |
| && req->ordinal != TPM_ORD_NV_DefineSpace |
| && req->ordinal != TPM_ORD_NV_ReadValue |
| && req->ordinal != TPM_ORD_NV_WriteValue |
| && req->ordinal != TSC_ORD_PhysicalPresence |
| && req->ordinal != TSC_ORD_ResetEstablishmentBit |
| ) return TPM_DEACTIVATED; |
| /* if the TPM is disabled only a subset of all commands can be performed */ |
| if (tpmData.permanent.flags.disable |
| && req->ordinal != TPM_ORD_Reset |
| && req->ordinal != TPM_ORD_Init |
| && req->ordinal != TPM_ORD_Startup |
| && req->ordinal != TPM_ORD_SaveState |
| && req->ordinal != TPM_ORD_SHA1Start |
| && req->ordinal != TPM_ORD_SHA1Update |
| && req->ordinal != TPM_ORD_SHA1Complete |
| && req->ordinal != TPM_ORD_SHA1CompleteExtend |
| && req->ordinal != TPM_ORD_OIAP |
| && req->ordinal != TPM_ORD_OSAP |
| && req->ordinal != TPM_ORD_DSAP |
| && req->ordinal != TPM_ORD_GetCapability |
| && req->ordinal != TPM_ORD_SetCapability |
| && req->ordinal != TPM_ORD_OwnerSetDisable |
| && req->ordinal != TPM_ORD_PhysicalEnable |
| && req->ordinal != TPM_ORD_ContinueSelfTest |
| && req->ordinal != TPM_ORD_SelfTestFull |
| && req->ordinal != TPM_ORD_GetTestResult |
| && req->ordinal != TPM_ORD_FlushSpecific |
| && req->ordinal != TPM_ORD_Terminate_Handle |
| && req->ordinal != TPM_ORD_Extend |
| && req->ordinal != TPM_ORD_PCR_Reset |
| && req->ordinal != TPM_ORD_NV_DefineSpace |
| && req->ordinal != TPM_ORD_NV_ReadValue |
| && req->ordinal != TPM_ORD_NV_WriteValue |
| && req->ordinal != TSC_ORD_PhysicalPresence |
| && req->ordinal != TSC_ORD_ResetEstablishmentBit |
| ) return TPM_DISABLED; |
| return TPM_SUCCESS; |
| } |
| |
| void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
| { |
| TPM_RESULT res; |
| |
| /* setup authorisation as well as response tag and size */ |
| memset(rsp, 0, sizeof(*rsp)); |
| switch (req->tag) { |
| case TPM_TAG_RQU_AUTH2_COMMAND: |
| debug("[TPM_TAG_RQU_AUTH2_COMMAND]"); |
| rsp->tag = TPM_TAG_RSP_AUTH2_COMMAND; |
| rsp->size = 10 + 2 * 41; |
| rsp->auth1 = &req->auth1; |
| rsp->auth2 = &req->auth2; |
| break; |
| |
| case TPM_TAG_RQU_AUTH1_COMMAND: |
| debug("[TPM_TAG_RQU_AUTH1_COMMAND]"); |
| rsp->tag = TPM_TAG_RSP_AUTH1_COMMAND; |
| rsp->size = 10 + 41; |
| rsp->auth1 = &req->auth1; |
| break; |
| |
| case TPM_TAG_RQU_COMMAND: |
| debug("[TPM_TAG_RQU_COMMAND]"); |
| rsp->tag = TPM_TAG_RSP_COMMAND; |
| rsp->size = 10; |
| break; |
| |
| default: |
| info("The tag value sent to for a command (0x%02x) is invalid", req->tag); |
| tpm_setup_error_response(TPM_BADTAG, rsp); |
| return; |
| } |
| |
| /* check whether the command is allowed in the current mode of the TPM */ |
| res = tpm_check_status_and_mode(req); |
| if (res != TPM_SUCCESS) { |
| info("tpm_check_status_and_mode(0x%02x) failed: (0x%02x) %s", |
| req->ordinal, res, tpm_error_to_string(res)); |
| tpm_setup_error_response(res, rsp); |
| return; |
| } |
| |
| /* handle command ordinal */ |
| switch (req->ordinal) { |
| case TPM_ORD_Startup: |
| debug("[TPM_ORD_Startup]"); |
| res = execute_TPM_Startup(req, rsp); |
| break; |
| |
| case TPM_ORD_SaveState: |
| debug("[TPM_ORD_SaveState]"); |
| res = execute_TPM_SaveState(req, rsp); |
| break; |
| |
| case TPM_ORD_SelfTestFull: |
| debug("[TPM_ORD_SelfTestFull]"); |
| res = execute_TPM_SelfTestFull(req, rsp); |
| break; |
| |
| case TPM_ORD_ContinueSelfTest: |
| debug("[TPM_ORD_ContinueSelfTest]"); |
| res = execute_TPM_ContinueSelfTest(req, rsp); |
| break; |
| |
| case TPM_ORD_GetTestResult: |
| debug("[TPM_ORD_GetTestResult]"); |
| res = execute_TPM_GetTestResult(req, rsp); |
| break; |
| |
| case TPM_ORD_SetOwnerInstall: |
| debug("[TPM_ORD_SetOwnerInstall]"); |
| res = execute_TPM_SetOwnerInstall(req, rsp); |
| break; |
| |
| case TPM_ORD_OwnerSetDisable: |
| debug("[TPM_ORD_OwnerSetDisable]"); |
| res = execute_TPM_OwnerSetDisable(req, rsp); |
| break; |
| |
| case TPM_ORD_PhysicalEnable: |
| debug("[TPM_ORD_PhysicalEnable]"); |
| res = execute_TPM_PhysicalEnable(req, rsp); |
| break; |
| |
| case TPM_ORD_PhysicalDisable: |
| debug("[TPM_ORD_PhysicalDisable]"); |
| res = execute_TPM_PhysicalDisable(req, rsp); |
| break; |
| |
| case TPM_ORD_PhysicalSetDeactivated: |
| debug("[TPM_ORD_PhysicalSetDeactivated]"); |
| res = execute_TPM_PhysicalSetDeactivated(req, rsp); |
| break; |
| |
| case TPM_ORD_SetTempDeactivated: |
| debug("[TPM_ORD_SetTempDeactivated]"); |
| res = execute_TPM_SetTempDeactivated(req, rsp); |
| break; |
| |
| case TPM_ORD_SetOperatorAuth: |
| debug("[TPM_ORD_SetOperatorAuth]"); |
| res = execute_TPM_SetOperatorAuth(req, rsp); |
| break; |
| |
| case TPM_ORD_TakeOwnership: |
| debug("[TPM_ORD_TakeOwnership]"); |
| res = execute_TPM_TakeOwnership(req, rsp); |
| break; |
| |
| case TPM_ORD_OwnerClear: |
| debug("[TPM_ORD_OwnerClear]"); |
| res = execute_TPM_OwnerClear(req, rsp); |
| break; |
| |
| case TPM_ORD_ForceClear: |
| debug("[TPM_ORD_ForceClear]"); |
| res = execute_TPM_ForceClear(req, rsp); |
| break; |
| |
| case TPM_ORD_DisableOwnerClear: |
| debug("[TPM_ORD_DisableOwnerClear]"); |
| res = execute_TPM_DisableOwnerClear(req, rsp); |
| break; |
| |
| case TPM_ORD_DisableForceClear: |
| debug("[TPM_ORD_DisableForceClear]"); |
| res = execute_TPM_DisableForceClear(req, rsp); |
| break; |
| |
| case TSC_ORD_PhysicalPresence: |
| res = execute_TSC_PhysicalPresence(req, rsp); |
| break; |
| |
| case TSC_ORD_ResetEstablishmentBit: |
| res = execute_TSC_ResetEstablishmentBit(req, rsp); |
| break; |
| |
| case TPM_ORD_GetCapability: |
| debug("[TPM_ORD_GetCapability]"); |
| res = execute_TPM_GetCapability(req, rsp); |
| break; |
| |
| case TPM_ORD_SetCapability: |
| debug("[TPM_ORD_SetCapability]"); |
| res = execute_TPM_SetCapability(req, rsp); |
| break; |
| |
| case TPM_ORD_GetCapabilityOwner: |
| debug("[TPM_ORD_GetCapabilityOwner]"); |
| res = execute_TPM_GetCapabilityOwner(req, rsp); |
| break; |
| |
| case TPM_ORD_GetAuditDigest: |
| debug("[TPM_ORD_GetAuditDigest]"); |
| res = execute_TPM_GetAuditDigest(req, rsp); |
| break; |
| |
| case TPM_ORD_GetAuditDigestSigned: |
| debug("[TPM_ORD_GetAuditDigestSigned]"); |
| res = execute_TPM_GetAuditDigestSigned(req, rsp); |
| break; |
| |
| case TPM_ORD_SetOrdinalAuditStatus: |
| debug("[TPM_ORD_SetOrdinalAuditStatus]"); |
| res = execute_TPM_SetOrdinalAuditStatus(req, rsp); |
| break; |
| |
| case TPM_ORD_FieldUpgrade: |
| debug("[TPM_ORD_FieldUpgrade]"); |
| res = execute_TPM_FieldUpgrade(req, rsp); |
| break; |
| |
| case TPM_ORD_SetRedirection: |
| debug("[TPM_ORD_SetRedirection]"); |
| res = execute_TPM_SetRedirection(req, rsp); |
| break; |
| |
| case TPM_ORD_ResetLockValue: |
| debug("[TPM_ORD_ResetLockValue]"); |
| res = execute_TPM_ResetLockValue(req, rsp); |
| break; |
| |
| case TPM_ORD_Seal: |
| debug("[TPM_ORD_Seal]"); |
| res = execute_TPM_Seal(req, rsp); |
| break; |
| |
| case TPM_ORD_Unseal: |
| debug("[TPM_ORD_Unseal]"); |
| res = execute_TPM_Unseal(req, rsp); |
| break; |
| |
| case TPM_ORD_UnBind: |
| debug("[TPM_ORD_UnBind]"); |
| res = execute_TPM_UnBind(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateWrapKey: |
| debug("[TPM_ORD_CreateWrapKey]"); |
| res = execute_TPM_CreateWrapKey(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadKey: |
| debug("[TPM_ORD_LoadKey]"); |
| res = execute_TPM_LoadKey(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadKey2: |
| debug("[TPM_ORD_LoadKey2]"); |
| res = execute_TPM_LoadKey2(req, rsp); |
| break; |
| |
| case TPM_ORD_GetPubKey: |
| debug("[TPM_ORD_GetPubKey]"); |
| res = execute_TPM_GetPubKey(req, rsp); |
| break; |
| |
| case TPM_ORD_Sealx: |
| debug("[TPM_ORD_Sealx]"); |
| res = execute_TPM_Sealx(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateMigrationBlob: |
| debug("[TPM_ORD_CreateMigrationBlob]"); |
| res = execute_TPM_CreateMigrationBlob(req, rsp); |
| break; |
| |
| case TPM_ORD_ConvertMigrationBlob: |
| debug("[TPM_ORD_ConvertMigrationBlob]"); |
| res = execute_TPM_ConvertMigrationBlob(req, rsp); |
| break; |
| |
| case TPM_ORD_AuthorizeMigrationKey: |
| debug("[TPM_ORD_AuthorizeMigrationKey]"); |
| res = execute_TPM_AuthorizeMigrationKey(req, rsp); |
| break; |
| |
| case TPM_ORD_MigrateKey: |
| debug("[TPM_ORD_MigrateKey]"); |
| res = execute_TPM_MigrateKey(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_SetRestrictions: |
| debug("[TPM_ORD_CMK_SetRestrictions]"); |
| res = execute_TPM_CMK_SetRestrictions(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_ApproveMA: |
| debug("[TPM_ORD_CMK_ApproveMA]"); |
| res = execute_TPM_CMK_ApproveMA(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_CreateKey: |
| debug("[TPM_ORD_CMK_CreateKey]"); |
| res = execute_TPM_CMK_CreateKey(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_CreateTicket: |
| debug("[TPM_ORD_CMK_CreateTicket]"); |
| res = execute_TPM_CMK_CreateTicket(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_CreateBlob: |
| debug("[TPM_ORD_CMK_CreateBlob]"); |
| res = execute_TPM_CMK_CreateBlob(req, rsp); |
| break; |
| |
| case TPM_ORD_CMK_ConvertMigration: |
| debug("[TPM_ORD_CMK_ConvertMigration]"); |
| res = execute_TPM_CMK_ConvertMigration(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateMaintenanceArchive: |
| debug("[TPM_ORD_CreateMaintenanceArchive]"); |
| res = execute_TPM_CreateMaintenanceArchive(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadMaintenanceArchive: |
| debug("[TPM_ORD_LoadMaintenanceArchive]"); |
| res = execute_TPM_LoadMaintenanceArchive(req, rsp); |
| break; |
| |
| case TPM_ORD_KillMaintenanceFeature: |
| debug("[TPM_ORD_KillMaintenanceFeature]"); |
| res = execute_TPM_KillMaintenanceFeature(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadManuMaintPub: |
| debug("[TPM_ORD_LoadManuMaintPub]"); |
| res = execute_TPM_LoadManuMaintPub(req, rsp); |
| break; |
| |
| case TPM_ORD_ReadManuMaintPub: |
| debug("[TPM_ORD_ReadManuMaintPub]"); |
| res = execute_TPM_ReadManuMaintPub(req, rsp); |
| break; |
| |
| case TPM_ORD_SHA1Start: |
| debug("[TPM_ORD_SHA1Start]"); |
| res = execute_TPM_SHA1Start(req, rsp); |
| break; |
| |
| case TPM_ORD_SHA1Update: |
| debug("[TPM_ORD_SHA1Update]"); |
| res = execute_TPM_SHA1Update(req, rsp); |
| break; |
| |
| case TPM_ORD_SHA1Complete: |
| debug("[TPM_ORD_SHA1Complete]"); |
| res = execute_TPM_SHA1Complete(req, rsp); |
| break; |
| |
| case TPM_ORD_SHA1CompleteExtend: |
| debug("[TPM_ORD_SHA1CompleteExtend]"); |
| res = execute_TPM_SHA1CompleteExtend(req, rsp); |
| break; |
| |
| case TPM_ORD_Sign: |
| debug("[TPM_ORD_Sign]"); |
| res = execute_TPM_Sign(req, rsp); |
| break; |
| |
| case TPM_ORD_GetRandom: |
| debug("[TPM_ORD_GetRandom]"); |
| res = execute_TPM_GetRandom(req, rsp); |
| break; |
| |
| case TPM_ORD_StirRandom: |
| debug("[TPM_ORD_StirRandom]"); |
| res = execute_TPM_StirRandom(req, rsp); |
| break; |
| |
| case TPM_ORD_CertifyKey: |
| debug("[TPM_ORD_CertifyKey]"); |
| res = execute_TPM_CertifyKey(req, rsp); |
| break; |
| |
| case TPM_ORD_CertifyKey2: |
| debug("[TPM_ORD_CertifyKey2]"); |
| res = execute_TPM_CertifyKey2(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateEndorsementKeyPair: |
| debug("[TPM_ORD_CreateEndorsementKeyPair]"); |
| res = execute_TPM_CreateEndorsementKeyPair(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateRevocableEK: |
| debug("[TPM_ORD_CreateRevocableEK]"); |
| res = execute_TPM_CreateRevocableEK(req, rsp); |
| break; |
| |
| case TPM_ORD_RevokeTrust: |
| debug("[TPM_ORD_RevokeTrust]"); |
| res = execute_TPM_RevokeTrust(req, rsp); |
| break; |
| |
| case TPM_ORD_ReadPubek: |
| debug("[TPM_ORD_ReadPubek]"); |
| res = execute_TPM_ReadPubek(req, rsp); |
| break; |
| |
| case TPM_ORD_DisablePubekRead: |
| debug("[TPM_ORD_DisablePubekRead]"); |
| res = execute_TPM_DisablePubekRead(req, rsp); |
| break; |
| |
| case TPM_ORD_OwnerReadInternalPub: |
| debug("[TPM_ORD_OwnerReadInternalPub]"); |
| res = execute_TPM_OwnerReadInternalPub(req, rsp); |
| break; |
| |
| case TPM_ORD_MakeIdentity: |
| debug("[TPM_ORD_MakeIdentity]"); |
| res = execute_TPM_MakeIdentity(req, rsp); |
| break; |
| |
| case TPM_ORD_ActivateIdentity: |
| debug("[TPM_ORD_ActivateIdentity]"); |
| res = execute_TPM_ActivateIdentity(req, rsp); |
| break; |
| |
| case TPM_ORD_Extend: |
| debug("[TPM_ORD_Extend]"); |
| res = execute_TPM_Extend(req, rsp); |
| break; |
| |
| case TPM_ORD_PCRRead: |
| debug("[TPM_ORD_PCRRead]"); |
| res = execute_TPM_PCRRead(req, rsp); |
| break; |
| |
| case TPM_ORD_Quote: |
| debug("[TPM_ORD_Quote]"); |
| res = execute_TPM_Quote(req, rsp); |
| break; |
| |
| case TPM_ORD_PCR_Reset: |
| debug("[TPM_ORD_PCR_Reset]"); |
| res = execute_TPM_PCR_Reset(req, rsp); |
| break; |
| |
| case TPM_ORD_Quote2: |
| debug("[TPM_ORD_Quote2]"); |
| res = execute_TPM_Quote2(req, rsp); |
| break; |
| |
| case TPM_ORD_ChangeAuth: |
| debug("[TPM_ORD_ChangeAuth]"); |
| res = execute_TPM_ChangeAuth(req, rsp); |
| break; |
| |
| case TPM_ORD_ChangeAuthOwner: |
| debug("[TPM_ORD_ChangeAuthOwner]"); |
| res = execute_TPM_ChangeAuthOwner(req, rsp); |
| break; |
| |
| case TPM_ORD_OIAP: |
| debug("[TPM_ORD_OIAP]"); |
| res = execute_TPM_OIAP(req, rsp); |
| break; |
| |
| case TPM_ORD_OSAP: |
| debug("[TPM_ORD_OSAP]"); |
| res = execute_TPM_OSAP(req, rsp); |
| break; |
| |
| case TPM_ORD_DSAP: |
| debug("[TPM_ORD_DSAP]"); |
| res = execute_TPM_DSAP(req, rsp); |
| break; |
| |
| case TPM_ORD_SetOwnerPointer: |
| debug("[TPM_ORD_SetOwnerPointer]"); |
| res = execute_TPM_SetOwnerPointer(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_Manage: |
| debug("[TPM_ORD_Delegate_Manage]"); |
| res = execute_TPM_Delegate_Manage(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_CreateKeyDelegation: |
| debug("[TPM_ORD_Delegate_CreateKeyDelegation]"); |
| res = execute_TPM_Delegate_CreateKeyDelegation(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_CreateOwnerDelegation: |
| debug("[TPM_ORD_Delegate_CreateOwnerDelegation]"); |
| res = execute_TPM_Delegate_CreateOwnerDelegation(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_LoadOwnerDelegation: |
| debug("[TPM_ORD_Delegate_LoadOwnerDelegation]"); |
| res = execute_TPM_Delegate_LoadOwnerDelegation(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_ReadTable: |
| debug("[TPM_ORD_Delegate_ReadTable]"); |
| res = execute_TPM_Delegate_ReadTable(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_UpdateVerification: |
| debug("[TPM_ORD_Delegate_UpdateVerification]"); |
| res = execute_TPM_Delegate_UpdateVerification(req, rsp); |
| break; |
| |
| case TPM_ORD_Delegate_VerifyDelegation: |
| debug("[TPM_ORD_Delegate_VerifyDelegation]"); |
| res = execute_TPM_Delegate_VerifyDelegation(req, rsp); |
| break; |
| |
| case TPM_ORD_NV_DefineSpace: |
| debug("[TPM_ORD_NV_DefineSpace]"); |
| res = execute_TPM_NV_DefineSpace(req, rsp); |
| break; |
| |
| case TPM_ORD_NV_WriteValue: |
| debug("[TPM_ORD_NV_WriteValue]"); |
| res = execute_TPM_NV_WriteValue(req, rsp); |
| break; |
| |
| case TPM_ORD_NV_WriteValueAuth: |
| debug("[TPM_ORD_NV_WriteValueAuth]"); |
| res = execute_TPM_NV_WriteValueAuth(req, rsp); |
| break; |
| |
| case TPM_ORD_NV_ReadValue: |
| debug("[TPM_ORD_NV_ReadValue]"); |
| res = execute_TPM_NV_ReadValue(req, rsp); |
| break; |
| |
| case TPM_ORD_NV_ReadValueAuth: |
| debug("[TPM_ORD_NV_ReadValueAuth]"); |
| res = execute_TPM_NV_ReadValueAuth(req, rsp); |
| break; |
| |
| case TPM_ORD_KeyControlOwner: |
| debug("[TPM_ORD_KeyControlOwner]"); |
| res = execute_TPM_KeyControlOwner(req, rsp); |
| break; |
| |
| case TPM_ORD_SaveContext: |
| debug("[TPM_ORD_SaveContext]"); |
| res = execute_TPM_SaveContext(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadContext: |
| debug("[TPM_ORD_LoadContext]"); |
| res = execute_TPM_LoadContext(req, rsp); |
| break; |
| |
| case TPM_ORD_FlushSpecific: |
| debug("[TPM_ORD_FlushSpecific]"); |
| res = execute_TPM_FlushSpecific(req, rsp); |
| break; |
| |
| case TPM_ORD_GetTicks: |
| debug("[TPM_ORD_GetTicks]"); |
| res = execute_TPM_GetTicks(req, rsp); |
| break; |
| |
| case TPM_ORD_TickStampBlob: |
| debug("[TPM_ORD_TickStampBlob]"); |
| res = execute_TPM_TickStampBlob(req, rsp); |
| break; |
| |
| case TPM_ORD_EstablishTransport: |
| debug("[TPM_ORD_EstablishTransport]"); |
| res = execute_TPM_EstablishTransport(req, rsp); |
| break; |
| |
| case TPM_ORD_ExecuteTransport: |
| debug("[TPM_ORD_ExecuteTransport]"); |
| res = execute_TPM_ExecuteTransport(req, rsp); |
| break; |
| |
| case TPM_ORD_ReleaseTransportSigned: |
| debug("[TPM_ORD_ReleaseTransportSigned]"); |
| res = execute_TPM_ReleaseTransportSigned(req, rsp); |
| break; |
| |
| case TPM_ORD_CreateCounter: |
| debug("[TPM_ORD_CreateCounter]"); |
| res = execute_TPM_CreateCounter(req, rsp); |
| break; |
| |
| case TPM_ORD_IncrementCounter: |
| debug("[TPM_ORD_IncrementCounter]"); |
| res = execute_TPM_IncrementCounter(req, rsp); |
| break; |
| |
| case TPM_ORD_ReadCounter: |
| debug("[TPM_ORD_ReadCounter]"); |
| res = execute_TPM_ReadCounter(req, rsp); |
| break; |
| |
| case TPM_ORD_ReleaseCounter: |
| debug("[TPM_ORD_ReleaseCounter]"); |
| res = execute_TPM_ReleaseCounter(req, rsp); |
| break; |
| |
| case TPM_ORD_ReleaseCounterOwner: |
| debug("[TPM_ORD_ReleaseCounterOwner]"); |
| res = execute_TPM_ReleaseCounterOwner(req, rsp); |
| break; |
| |
| case TPM_ORD_DAA_Join: |
| debug("[TPM_ORD_DAA_Join]"); |
| res = execute_TPM_DAA_Join(req, rsp); |
| break; |
| |
| case TPM_ORD_DAA_Sign: |
| debug("[TPM_ORD_DAA_Sign]"); |
| res = execute_TPM_DAA_Sign(req, rsp); |
| break; |
| |
| case TPM_ORD_EvictKey: |
| debug("[TPM_ORD_EvictKey]"); |
| res = execute_TPM_EvictKey(req, rsp); |
| break; |
| |
| case TPM_ORD_Terminate_Handle: |
| debug("[TPM_ORD_Terminate_Handle]"); |
| res = execute_TPM_Terminate_Handle(req, rsp); |
| break; |
| |
| case TPM_ORD_SaveKeyContext: |
| debug("[TPM_ORD_SaveKeyContext]"); |
| res = execute_TPM_SaveKeyContext(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadKeyContext: |
| debug("[TPM_ORD_LoadKeyContext]"); |
| res = execute_TPM_LoadKeyContext(req, rsp); |
| break; |
| |
| case TPM_ORD_SaveAuthContext: |
| debug("[TPM_ORD_SaveAuthContext]"); |
| res = execute_TPM_SaveAuthContext(req, rsp); |
| break; |
| |
| case TPM_ORD_LoadAuthContext: |
| debug("[TPM_ORD_LoadAuthContext]"); |
| res = execute_TPM_LoadAuthContext(req, rsp); |
| break; |
| |
| case TPM_ORD_DirWriteAuth: |
| debug("[TPM_ORD_DirWriteAuth]"); |
| res = execute_TPM_DirWriteAuth(req, rsp); |
| break; |
| |
| case TPM_ORD_DirRead: |
| debug("[TPM_ORD_DirRead]"); |
| res = execute_TPM_DirRead(req, rsp); |
| break; |
| |
| case TPM_ORD_ChangeAuthAsymStart: |
| debug("[TPM_ORD_ChangeAuthAsymStart]"); |
| res = execute_TPM_ChangeAuthAsymStart(req, rsp); |
| break; |
| |
| case TPM_ORD_ChangeAuthAsymFinish: |
| debug("[TPM_ORD_ChangeAuthAsymFinish]"); |
| res = execute_TPM_ChangeAuthAsymFinish(req, rsp); |
| break; |
| |
| case TPM_ORD_Reset: |
| debug("[TPM_ORD_Reset]"); |
| res = execute_TPM_Reset(req, rsp); |
| break; |
| |
| case TPM_ORD_OwnerReadPubek: |
| debug("[TPM_ORD_OwnerReadPubek]"); |
| res = execute_TPM_OwnerReadPubek(req, rsp); |
| break; |
| |
| default: |
| #ifdef MTM_EMULATOR |
| res = mtm_execute_command(req, rsp); |
| if (res != TPM_BAD_ORDINAL) break; |
| #endif |
| info("The ordinal (0x%02x) was unknown or inconsistent", req->ordinal); |
| tpm_setup_error_response(TPM_BAD_ORDINAL, rsp); |
| return; |
| } |
| |
| /* setup response */ |
| if (res != TPM_SUCCESS) { |
| info("TPM command failed: (0x%02x) %s", res, tpm_error_to_string(res)); |
| tpm_setup_error_response(res, rsp); |
| if (!(res & TPM_NON_FATAL)) { |
| if (rsp->auth1 != NULL) rsp->auth1->continueAuthSession = FALSE; |
| if (rsp->auth2 != NULL) rsp->auth2->continueAuthSession = FALSE; |
| } |
| } else { |
| info("TPM command succeeded"); |
| rsp->size += rsp->paramSize; |
| if (rsp->tag != TPM_TAG_RSP_COMMAND) tpm_setup_rsp_auth(req->ordinal, rsp); |
| if (tpmConf & TPM_CONF_STRONG_PERSISTENCE) { |
| if (tpm_store_permanent_data() != 0) { |
| error("tpm_store_permanent_data() failed"); |
| } |
| } |
| } |
| /* terminate authorization sessions if necessary */ |
| if (rsp->auth1 != NULL && !rsp->auth1->continueAuthSession) |
| TPM_FlushSpecific(rsp->auth1->authHandle, HANDLE_TO_RT(rsp->auth1->authHandle)); |
| if (rsp->auth2 != NULL && !rsp->auth2->continueAuthSession) |
| TPM_FlushSpecific(rsp->auth2->authHandle, TPM_RT_AUTH); |
| /* if transportExclusive is set, only the execution of TPM_ExecuteTransport |
| and TPM_ReleaseTransportSigned is allowed */ |
| if (tpmData.stany.flags.transportExclusive |
| && req->ordinal != TPM_ORD_ExecuteTransport |
| && req->ordinal != TPM_ORD_ReleaseTransportSigned) { |
| TPM_FlushSpecific(tpmData.stany.data.transExclusive, TPM_RT_TRANS); |
| tpmData.stany.flags.transportExclusive = FALSE; |
| } |
| } |
| |
| void tpm_emulator_init(uint32_t startup, uint32_t conf) |
| { |
| debug("tpm_emulator_init(%d, 0x%08x)", startup, conf); |
| tpmConf = conf; |
| #ifdef MTM_EMULATOR |
| info("MTM support enabled"); |
| #endif |
| /* try to restore data, if it fails use default values */ |
| if (tpm_restore_permanent_data() != 0) tpm_init_data(); |
| TPM_Init(startup); |
| } |
| |
| void tpm_emulator_shutdown() |
| { |
| debug("tpm_emulator_shutdown()"); |
| if (TPM_SaveState() != TPM_SUCCESS) { |
| error("TPM_SaveState() failed"); |
| } |
| tpm_release_data(); |
| } |
| |
| int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size) |
| { |
| TPM_REQUEST req; |
| TPM_RESPONSE rsp; |
| BYTE *ptr; |
| UINT32 len; |
| BOOL free_out; |
| |
| debug("tpm_handle_command()"); |
| |
| /* we need the whole packet at once, otherwise unmarshalling will fail */ |
| if (tpm_unmarshal_TPM_REQUEST((uint8_t**)&in, &in_size, &req) != 0) { |
| error("tpm_unmarshal_TPM_REQUEST() failed"); |
| return -1; |
| } |
| |
| /* update timing ticks */ |
| tpm_update_ticks(); |
| |
| /* audit request */ |
| tpm_audit_request(req.ordinal, &req); |
| |
| /* execute command */ |
| tpm_execute_command(&req, &rsp); |
| |
| /* audit response */ |
| tpm_audit_response(req.ordinal, &rsp); |
| |
| /* init output and marshal response */ |
| if (*out != NULL) { |
| if (*out_size < rsp.size) { |
| error("output buffer to small (%d/%d)", *out_size, rsp.size); |
| tpm_free(rsp.param); |
| return -1; |
| } |
| *out_size = len = rsp.size; |
| ptr = *out; |
| free_out = FALSE; |
| } else { |
| *out_size = len = rsp.size; |
| *out = ptr = tpm_malloc(len); |
| if (ptr == NULL) { |
| error("tpm_malloc() failed"); |
| tpm_free(rsp.param); |
| return -1; |
| } |
| free_out = TRUE; |
| } |
| if (tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp) != 0) { |
| error("tpm_marshal_TPM_RESPONSE() failed"); |
| if (free_out) tpm_free(*out); |
| tpm_free(rsp.param); |
| return -1; |
| } |
| tpm_free(rsp.param); |
| return 0; |
| } |
| |