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_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 = malloc(len); if (ptr == NULL || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle) || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven)) { free(rsp->param); res = TPM_FAIL; } return res; }
TPM_RESULT TPM_EstablishTransport(TPM_KEY_HANDLE encHandle, TPM_TRANSPORT_PUBLIC *transPublic, UINT32 secretSize, BYTE *secret, TPM_AUTH *auth1, TPM_TRANSHANDLE *transHandle, TPM_MODIFIER_INDICATOR *locality, TPM_CURRENT_TICKS *currentTicks, TPM_NONCE *transNonceEven) { TPM_RESULT res; TPM_KEY_DATA *key; TPM_TRANSPORT_AUTH trans_auth; TPM_SESSION_DATA *session; info("TPM_EstablishTransport()"); /* setup authorization data */ if (encHandle == TPM_KH_TRANSPORT) { if (auth1->authHandle != TPM_INVALID_HANDLE) return TPM_BADTAG; if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) return TPM_BAD_SCHEME; if (secretSize != 20) return TPM_BAD_PARAM_SIZE; memcpy(trans_auth.authData, secret, 20); } else { /* get key and verify its usage */ key = tpm_get_key(encHandle); if (key == NULL) return TPM_INVALID_KEYHANDLE; if (key->keyUsage != TPM_KEY_STORAGE && key->keyUsage != TPM_KEY_LEGACY) return TPM_INVALID_KEYUSAGE; /* verify authorization */ if (key->authDataUsage != TPM_AUTH_NEVER) { res = tpm_verify_auth(auth1, key->usageAuth, encHandle); if (res != TPM_SUCCESS) return res; if (decrypt_transport_auth(key, secret, secretSize, &trans_auth)) return TPM_DECRYPT_ERROR; } } /* check whether the transport has to be encrypted */ if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) { if (tpmData.permanent.flags.FIPS && transPublic->algID == TPM_ALG_MGF1) return TPM_INAPPROPRIATE_ENC; /* until now, only MGF1 is supported */ if (transPublic->algID != TPM_ALG_MGF1) return TPM_BAD_KEY_PROPERTY; } /* initialize transport session */ tpm_get_random_bytes(transNonceEven->nonce, sizeof(transNonceEven->nonce)); *transHandle = tpm_get_free_session(TPM_ST_TRANSPORT); session = tpm_get_transport(*transHandle); if (session == NULL) return TPM_RESOURCES; session->transInternal.transHandle = *transHandle; memset(&session->transInternal.transDigest, 0, sizeof(TPM_DIGEST)); memcpy(&session->transInternal.transPublic, transPublic, sizeof_TPM_TRANSPORT_PUBLIC((*transPublic))); memcpy(&session->transInternal.transNonceEven, transNonceEven, sizeof(TPM_NONCE)); memcpy(&session->nonceEven, transNonceEven, sizeof(TPM_NONCE)); memcpy(&session->transInternal.authData, trans_auth.authData, sizeof(TPM_AUTHDATA)); *locality = tpmData.stany.flags.localityModifier; memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS)); /* perform transport logging */ if (transPublic->transAttributes & TPM_TRANSPORT_LOG) { tpm_sha1_ctx_t sha1; BYTE *ptr, buf[4 + 4 + 4 + sizeof_TPM_CURRENT_TICKS(x) + 20]; UINT32 len; /* log input */ memset(buf, 0, sizeof(buf)); transport_log_in(auth1->digest, buf, &session->transInternal.transDigest); /* compute digest of output parameters and log output */ ptr = buf; len = sizeof(buf); tpm_marshal_UINT32(&ptr, &len, TPM_SUCCESS); tpm_marshal_TPM_COMMAND_CODE(&ptr, &len, TPM_ORD_EstablishTransport); tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, *locality); tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, currentTicks); tpm_marshal_TPM_NONCE(&ptr, &len, transNonceEven); tpm_sha1_init(&sha1); tpm_sha1_update(&sha1, buf, sizeof(buf)); tpm_sha1_final(&sha1, buf); transport_log_out(buf, &session->transInternal.transDigest); } /* check whether this is a exclusive transport session */ if (transPublic->transAttributes & TPM_TRANSPORT_EXCLUSIVE) { tpmData.stany.flags.transportExclusive = TRUE; tpmData.stany.data.transExclusive = *transHandle; } auth1->continueAuthSession = FALSE; return TPM_SUCCESS; }