static TPM_RESULT execute_MTM_InstallRIM(TPM_REQUEST *req, TPM_RESPONSE *rsp) { BYTE *ptr; UINT32 len; UINT32 rimCertSize; TPM_RIM_CERTIFICATE rimCertIn; TPM_RIM_CERTIFICATE rimCertOut; 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, &rimCertSize) || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertIn) || len != 0) return TPM_BAD_PARAMETER; /* execute command */ res = MTM_InstallRIM(&rimCertIn, &req->auth1, &rimCertOut); if (res != TPM_SUCCESS) return res; /* marshal output */ rsp->paramSize = len = 4 + sizeof_TPM_RIM_CERTIFICATE(rimCertOut); rsp->param = ptr = tpm_malloc(len); if (ptr == NULL || tpm_marshal_UINT32(&ptr, &len, sizeof_TPM_RIM_CERTIFICATE(rimCertOut)) || tpm_marshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertOut)) { tpm_free(rsp->param); res = TPM_FAIL; } free_TPM_RIM_CERTIFICATE(rimCertOut); 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 = ExtendBuf; if (ptr == NULL || tpm_marshal_UINT32(&ptr, &len, outDataSize) || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) { free(rsp->param); res = TPM_FAIL; } free(outData); 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 = 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)) { free(rsp->param); res = TPM_FAIL; } return res; }
static TPM_RESULT execute_MTM_LoadVerificationKey(TPM_REQUEST *req, TPM_RESPONSE *rsp) { BYTE *ptr; UINT32 len; TPM_VERIFICATION_KEY_HANDLE parentKey; UINT32 verificationKeySize; TPM_VERIFICATION_KEY verificationKey; TPM_VERIFICATION_KEY_HANDLE verificationKeyHandle; BYTE loadMethod; TPM_RESULT res; /* compute parameter digest */ tpm_compute_in_param_digest(req); /* unmarshal input */ ptr = req->param; len = req->paramSize; if (tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &parentKey) || tpm_unmarshal_UINT32(&ptr, &len, &verificationKeySize) || tpm_unmarshal_TPM_VERIFICATION_KEY(&ptr, &len, &verificationKey) || len != 0) return TPM_BAD_PARAMETER; /* execute command */ res = MTM_LoadVerificationKey(parentKey, &verificationKey, &req->auth1, &verificationKeyHandle, &loadMethod); if (res != TPM_SUCCESS) return res; /* marshal output */ rsp->paramSize = len = 4 + 1; rsp->param = ptr = tpm_malloc(len); if (ptr == NULL || tpm_marshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, verificationKeyHandle) || tpm_marshal_BYTE(&ptr, &len, loadMethod)) { tpm_free(rsp->param); res = TPM_FAIL; } return res; }
static TPM_RESULT execute_MTM_VerifyRIMCertAndExtend(TPM_REQUEST *req, TPM_RESPONSE *rsp) { BYTE *ptr; UINT32 len; UINT32 rimCertSize; TPM_RIM_CERTIFICATE rimCert; TPM_VERIFICATION_KEY_HANDLE rimKey; TPM_PCRVALUE outDigest; 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, &rimCertSize) || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert) || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey) || len != 0) return TPM_BAD_PARAMETER; /* execute command */ res = MTM_VerifyRIMCertAndExtend(&rimCert, rimKey, &outDigest); /* 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_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 = malloc(len); if (ptr == NULL || tpm_marshal_TPM_KEY(&ptr, &len, &srkPub)) { free(rsp->param); res = TPM_FAIL; } free_TPM_KEY(srkPub); return res; }
int check_ordinal(tpmcmd_t* tpmcmd) { TPM_COMMAND_CODE ord; UINT32 len = 4; BYTE* ptr; unsigned int i; if(tpmcmd->req_len < 10) { return true; } ptr = tpmcmd->req + 6; tpm_unmarshal_UINT32(&ptr, &len, &ord); for(i = 0; i < n_badords; ++i) { if(ord == badords[i]) { error("Disabled command ordinal (%" PRIu32") requested!\n"); return false; } } return true; }
TPM_RESULT cap_flag(UINT32 subCapSize, BYTE *subCap, UINT32 *respSize, BYTE **resp) { UINT32 type, len; BYTE *ptr; if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &type)) return TPM_BAD_MODE; switch (type) { case TPM_CAP_FLAG_PERMANENT: debug("[TPM_CAP_FLAG_PERMANENT"); *respSize = len = sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags); *resp = ptr = tpm_malloc(len); if (tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)) { tpm_free(*resp); return TPM_FAIL; } return TPM_SUCCESS; case TPM_CAP_FLAG_VOLATILE: debug("[TPM_CAP_FLAG_VOLATILE]"); *respSize = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags); *resp = ptr = tpm_malloc(len); if (tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)) { tpm_free(*resp); return TPM_FAIL; } return TPM_SUCCESS; /* removed since v1.2 rev 94 case TPM_CAP_FLAG_STANY: debug("[TPM_CAP_FLAG_STANY]"); *respSize = len = sizeof_TPM_STANY_FLAGS(tpmData.stany.flags); *resp = ptr = tpm_malloc(len); if (tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)) { tpm_free(*resp); return TPM_FAIL; } */ return TPM_SUCCESS; default: return TPM_BAD_MODE; } }
static TPM_RESULT execute_MTM_IncrementBootstrapCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp) { BYTE *ptr; UINT32 len; UINT32 rimCertSize; TPM_RIM_CERTIFICATE rimCert; TPM_VERIFICATION_KEY_HANDLE rimKey; 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, &rimCertSize) || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert) || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey) || len != 0) return TPM_BAD_PARAMETER; /* execute command */ res = MTM_IncrementBootstrapCounter(&rimCert, rimKey); /* marshal output */ rsp->paramSize = len = 0; rsp->param = ptr = NULL; return res; }
static TPM_RESULT cap_property(UINT32 subCapSize, BYTE *subCap, UINT32 *respSize, BYTE **resp) { UINT32 i, j, property; if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &property)) return TPM_BAD_MODE; switch (property) { case TPM_CAP_PROP_PCR: debug("[TPM_CAP_PROP_PCR]"); return return_UINT32(respSize, resp, TPM_NUM_PCR); case TPM_CAP_PROP_DIR: debug("[TPM_CAP_PROP_DIR]"); return return_UINT32(respSize, resp, 1); case TPM_CAP_PROP_MANUFACTURER: debug("[TPM_CAP_PROP_MANUFACTURER]"); return return_UINT32(respSize, resp, TPM_MANUFACTURER); case TPM_CAP_PROP_KEYS: debug("[TPM_CAP_PROP_KEYS]"); for (i = 0, j = TPM_MAX_KEYS; i < TPM_MAX_KEYS; i++) if (tpmData.permanent.data.keys[i].valid) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_MIN_COUNTER: debug("[TPM_CAP_PROP_MIN_COUNTER]"); return return_UINT32(respSize, resp, 1); case TPM_CAP_PROP_AUTHSESS: debug("[TPM_CAP_PROP_AUTHSESS]"); for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++) if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_TRANSESS: debug("[TPM_CAP_PROP_TRANSESS]"); for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++) if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_COUNTERS: debug("[TPM_CAP_PROP_COUNTERS]"); for (i = 0, j = TPM_MAX_COUNTERS; i < TPM_MAX_COUNTERS; i++) if (tpmData.permanent.data.counters[i].valid) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_MAX_AUTHSESS: debug("[TPM_CAP_PROP_MAX_AUTHSESS]"); return return_UINT32(respSize, resp, TPM_MAX_SESSIONS); case TPM_CAP_PROP_MAX_TRANSESS: debug("[TPM_CAP_PROP_MAX_TRANSESS]"); return return_UINT32(respSize, resp, TPM_MAX_SESSIONS); case TPM_CAP_PROP_MAX_COUNTERS: debug("[TPM_CAP_PROP_MAX_COUNTERS]"); return return_UINT32(respSize, resp, TPM_MAX_COUNTERS); case TPM_CAP_PROP_MAX_KEYS: debug("[TPM_CAP_PROP_MAX_KEYS]"); return return_UINT32(respSize, resp, TPM_MAX_KEYS); case TPM_CAP_PROP_OWNER: debug("[TPM_CAP_PROP_OWNER]"); return return_BOOL(respSize, resp, tpmData.permanent.flags.owned); case TPM_CAP_PROP_CONTEXT: debug("[TPM_CAP_PROP_CONTEXT]"); for (i = 0, j = 0; i < TPM_MAX_SESSION_LIST; i++) if (tpmData.stany.data.contextList[i] == 0) j++; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_MAX_CONTEXT: debug("[TPM_CAP_PROP_MAX_CONTEXT]"); return return_UINT32(respSize, resp, TPM_MAX_SESSION_LIST); case TPM_CAP_PROP_FAMILYROWS: debug("[TPM_CAP_PROP_FAMILYROWS]"); /* TODO: TPM_CAP_PROP_FAMILYROWS */ return TPM_FAIL; case TPM_CAP_PROP_TIS_TIMEOUT: debug("[TPM_CAP_PROP_TIS_TIMEOUT]"); /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */ UINT32 len = *respSize = 16; BYTE *ptr = *resp = tpm_malloc(*respSize); if (ptr == NULL || tpm_marshal_UINT32(&ptr, &len, 200000) || tpm_marshal_UINT32(&ptr, &len, 200000) || tpm_marshal_UINT32(&ptr, &len, 200000) || tpm_marshal_UINT32(&ptr, &len, 200000)) { tpm_free(*resp); return TPM_FAIL; } return TPM_SUCCESS; case TPM_CAP_PROP_STARTUP_EFFECT: debug("[TPM_CAP_PROP_STARTUP_EFFECT]"); /* TODO: TPM_CAP_PROP_STARTUP_EFFECT */ return TPM_FAIL; case TPM_CAP_PROP_DELEGATE_ROW: debug("[TPM_CAP_PROP_DELEGATE_ROW]"); /* TODO: TPM_CAP_PROP_DELEGATE_ROW */ return TPM_FAIL; case TPM_CAP_PROP_DAA_MAX: debug("[TPM_CAP_PROP_DAA_MAX]"); return return_UINT32(respSize, resp, TPM_MAX_SESSIONS_DAA); case TPM_CAP_PROP_SESSION_DAA: debug("[TPM_CAP_PROP_SESSION_DAA]"); for (i = 0, j = TPM_MAX_SESSIONS_DAA; i < TPM_MAX_SESSIONS_DAA; i++) if (tpmData.stany.data.sessionsDAA[i].type != TPM_ST_INVALID) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_CONTEXT_DIST: debug("[TPM_CAP_PROP_CONTEXT_DIST]"); /* TODO: TPM_CAP_PROP_CONTEXT_DIST */ return TPM_FAIL; case TPM_CAP_PROP_DAA_INTERRUPT: debug("[TPM_CAP_PROP_DAA_INTERRUPT]"); /* A value of TRUE indicates that the TPM will accept ANY command * while executing a DAA Join or Sign. A value of FALSE indicates * that the TPM will invalidate the DAA Join or Sign upon the * receipt of any command other than the next join/sign in the * session or a TPM_SaveContext. */ return return_BOOL(respSize, resp, TRUE); case TPM_CAP_PROP_SESSIONS: debug("[TPM_CAP_PROP_SESSIONS]"); for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++) if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--; return return_UINT32(respSize, resp, j); case TPM_CAP_PROP_MAX_SESSIONS: debug("[TPM_CAP_PROP_MAX_SESSIONS]"); return return_UINT32(respSize, resp, TPM_MAX_SESSIONS); case TPM_CAP_PROP_CMK_RESTRICTION: debug("[TPM_CAP_PROP_CMK_RESTRICTION]"); /* TODO: TPM_CAP_PROP_CMK_RESTRICTION */ return TPM_FAIL; case TPM_CAP_PROP_DURATION: debug("[TPM_CAP_PROP_DURATION]"); /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */ BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0}; *respSize = 16; *resp = tpm_malloc(*respSize); memcpy(*resp,dur,16); return TPM_FAIL; case TPM_CAP_PROP_ACTIVE_COUNTER: debug("[TPM_CAP_PROP_ACTIVE_COUNTER]"); /* TODO: TPM_CAP_PROP_ACTIVE_COUNTER */ return TPM_FAIL; case TPM_CAP_PROP_MAX_NV_AVAILABLE: debug("[TPM_CAP_PROP_MAX_NV_AVAILABLE]"); /* TODO: TPM_CAP_PROP_MAX_NV_AVAILABLE */ return TPM_FAIL; case TPM_CAP_PROP_INPUT_BUFFER: debug("[TPM_CAP_PROP_INPUT_BUFFER]"); /* TODO: TPM_CAP_PROP_INPUT_BUFFER */ return TPM_FAIL; default: return TPM_BAD_MODE; } }
static TPM_RESULT cap_handle(UINT32 subCapSize, BYTE *subCap, UINT32 *respSize, BYTE **resp) { UINT32 i, len, type; BYTE *ptr; /* maximum of { TPM_MAX_KEYS, TPM_MAX_SESSIONS } */ UINT32 list_size = (TPM_MAX_KEYS > TPM_MAX_SESSIONS) ? TPM_MAX_KEYS : TPM_MAX_SESSIONS; UINT32 handles[list_size]; TPM_KEY_HANDLE_LIST list = { 0, handles }; if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &type)) return TPM_BAD_MODE; switch (type) { case TPM_RT_KEY: debug("[TPM_RT_KEY]"); for (i = 0; i < TPM_MAX_KEYS; i++) if (tpmData.permanent.data.keys[i].valid) { list.loaded++; list.handle[i] = INDEX_TO_KEY_HANDLE(i); } break; case TPM_RT_AUTH: debug("[TPM_RT_AUTH]"); for (i = 0; i < TPM_MAX_SESSIONS; i++) if (tpmData.stany.data.sessions[i].type == TPM_ST_OIAP || tpmData.stany.data.sessions[i].type == TPM_ST_OSAP) { list.loaded++; list.handle[i] = INDEX_TO_AUTH_HANDLE(i); } break; case TPM_RT_TRANS: debug("[TPM_RT_TRANS]"); for (i = 0; i < TPM_MAX_SESSIONS; i++) if (tpmData.stany.data.sessions[i].type == TPM_ST_TRANSPORT) { list.loaded++; list.handle[i] = INDEX_TO_TRANS_HANDLE(i); } break; /* removed since v1.2 rev 94 case TPM_RT_DELEGATE: debug("[TPM_RT_DELEGATE]"); break; */ case TPM_RT_COUNTER: debug("[TPM_RT_COUNTER]"); for (i = 0; i < TPM_MAX_COUNTERS; i++) if (tpmData.permanent.data.counters[i].valid) { list.loaded++; list.handle[i] = INDEX_TO_COUNTER_HANDLE(i); } break; case TPM_RT_CONTEXT: /* TODO: implement TPM_CAP_HANDLE for TPM_RT_CONTEXT */ default: return TPM_BAD_MODE; } /* marshal handle list */ len = *respSize = 2 + list.loaded * 4; ptr = *resp = tpm_malloc(len); if (ptr == NULL || tpm_marshal_TPM_KEY_HANDLE_LIST(&ptr, &len, &list)) { tpm_free(*resp); return TPM_FAIL; } return TPM_SUCCESS; }