/* * Determine the default path to the persistent storage file and create it if it doesn't exist. */ TSS_RESULT get_user_ps_path(char **file) { TSS_RESULT result; char *file_name = NULL, *home_dir = NULL; struct passwd *pwp; #if (defined (__linux) || defined (linux) || defined(__GLIBC__)) struct passwd pw; #endif struct stat stat_buf; char buf[PASSWD_BUFSIZE]; uid_t euid; int rc; if ((file_name = getenv("TSS_USER_PS_FILE"))) { *file = strdup(file_name); return (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY); } #if (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__)) MUTEX_LOCK(user_ps_path); #endif euid = geteuid(); #if defined (SOLARIS) /* * Solaris keeps user PS in a local directory instead of * in the user's home directory, which may be shared * by multiple systems. * * The directory path on Solaris is /var/tpm/userps/[EUID]/ */ rc = snprintf(buf, sizeof (buf), "%s/%d", TSS_USER_PS_DIR, euid); #else setpwent(); while (1) { #if (defined (__linux) || defined (linux) || defined(__GLIBC__)) rc = getpwent_r(&pw, buf, PASSWD_BUFSIZE, &pwp); if (rc) { LogDebugFn("USER PS: Error getting path to home directory: getpwent_r: %s", strerror(rc)); endpwent(); return TSPERR(TSS_E_INTERNAL_ERROR); } #elif (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__)) if ((pwp = getpwent()) == NULL) { LogDebugFn("USER PS: Error getting path to home directory: getpwent: %s", strerror(rc)); endpwent(); MUTEX_UNLOCK(user_ps_path); return TSPERR(TSS_E_INTERNAL_ERROR); } #endif if (euid == pwp->pw_uid) { home_dir = strdup(pwp->pw_dir); break; } } endpwent(); if (!home_dir) return TSPERR(TSS_E_OUTOFMEMORY); /* Tack on TSS_USER_PS_DIR and see if it exists */ rc = snprintf(buf, sizeof (buf), "%s/%s", home_dir, TSS_USER_PS_DIR); #endif /* SOLARIS */ if (rc == sizeof (buf)) { LogDebugFn("USER PS: Path to file too long! (> %d bytes)", PASSWD_BUFSIZE); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } errno = 0; if ((rc = stat(buf, &stat_buf)) == -1) { if (errno == ENOENT) { errno = 0; /* Create the user's ps directory if it is not there. */ if ((rc = mkdir(buf, 0700)) == -1) { LogDebugFn("USER PS: Error creating dir: %s: %s", buf, strerror(errno)); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } else { LogDebugFn("USER PS: Error stating dir: %s: %s", buf, strerror(errno)); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } /* Directory exists or has been created, return the path to the file */ #if defined (SOLARIS) rc = snprintf(buf, sizeof (buf), "%s/%d/%s", TSS_USER_PS_DIR, euid, TSS_USER_PS_FILE); #else rc = snprintf(buf, sizeof (buf), "%s/%s/%s", home_dir, TSS_USER_PS_DIR, TSS_USER_PS_FILE); #endif if (rc == sizeof (buf)) { LogDebugFn("USER PS: Path to file too long! (> %zd bytes)", sizeof (buf)); } else *file = strdup(buf); result = (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY); done: free(home_dir); return result; }
TSS_RESULT Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID * pUuidData, /* in */ UINT32 * pulKeyHierarchySize, /* out */ TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */ { TSS_RESULT result; TSS_KM_KEYINFO *tcsHier, *tspHier; UINT32 tcsHierSize, tspHierSize; TSS_UUID tcs_uuid; if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if (!obj_is_context(tspContext)) return TSPERR(TSS_E_INVALID_HANDLE); if (pUuidData) { if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, pulKeyHierarchySize, ppKeyHierarchy))) return result; } else if (persistentStorageType == TSS_PS_TYPE_USER) { if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid, &tspHierSize, &tspHier))) return result; if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize, &tcsHier))) { free(tspHier); return result; } result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize, tcsHier, pulKeyHierarchySize, ppKeyHierarchy); free(tcsHier); free(tspHier); } else return TSPERR(TSS_E_BAD_PARAMETER); } else { if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize, &tcsHier))) return result; if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) { free(tcsHier); return result; } result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize, tcsHier, pulKeyHierarchySize, ppKeyHierarchy); free(tcsHier); free(tspHier); } if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { free(*ppKeyHierarchy); *ppKeyHierarchy = NULL; *pulKeyHierarchySize = 0; } return result; }
TSS_RESULT RPC_GetAuditDigestSigned_TP(struct host_table_entry *hte, TCS_KEY_HANDLE keyHandle, /* in */ TSS_BOOL closeAudit, /* in */ TPM_NONCE *antiReplay, /* in */ TPM_AUTH *privAuth, /* in/out */ UINT32 *counterValueSize, /* out */ BYTE **counterValue, /* out */ TPM_DIGEST *auditDigest, /* out */ TPM_DIGEST *ordinalDigest, /* out */ UINT32 *sigSize, /* out */ BYTE **sig) /* out */ { TSS_RESULT result; TPM_AUTH null_auth; int i; initData(&hte->comm, 5); hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGESTSIGNED; LogDebugFn("TCS Context: 0x%x", hte->tcsContext); memset(&null_auth, 0, sizeof(TPM_AUTH)); if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_BOOL, 2, &closeAudit, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_NONCE, 3, antiReplay, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (privAuth) { if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); } else { if (setData(TCSD_PACKET_TYPE_AUTH, 4, &null_auth, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); } result = sendTCSDPacket(hte); if (result == TSS_SUCCESS) result = hte->comm.hdr.u.result; if (result == TSS_SUCCESS) { i = 0; if (privAuth) { if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } if (getData(TCSD_PACKET_TYPE_UINT32, i++, counterValueSize, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } *counterValue = (BYTE *)malloc(*counterValueSize); if (*counterValue == NULL) { LogError("malloc of %u bytes failed.", *counterValueSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *counterValue, *counterValueSize, &hte->comm)) { free(*counterValue); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_DIGEST, i++, auditDigest, 0, &hte->comm)) { free(*counterValue); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_DIGEST, i++, ordinalDigest, 0, &hte->comm)) { free(*counterValue); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { free(*counterValue); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } *sig = (BYTE *)malloc(*sigSize); if (*sig == NULL) { LogError("malloc of %u bytes failed.", *sigSize); free(*counterValue); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { free(*counterValue); free(*sig); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } done: return result; }
/* XXX int set to unsigned int values */ int Trspi_RSA_Encrypt(unsigned char *dataToEncrypt, /* in */ unsigned int dataToEncryptLen, /* in */ unsigned char *encryptedData, /* out */ unsigned int *encryptedDataLen, /* out */ unsigned char *publicKey, unsigned int keysize) { int rv; unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* 65537 hex */ unsigned char oaepPad[] = "TCPA"; int oaepPadLen = 4; RSA *rsa = RSA_new(); BYTE encodedData[256]; int encodedDataLen; if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(publicKey, keysize, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* padding constraint for PKCS#1 OAEP padding */ if ((int)dataToEncryptLen >= (RSA_size(rsa) - ((2 * SHA_DIGEST_LENGTH) + 1))) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } encodedDataLen = MIN(RSA_size(rsa), 256); /* perform our OAEP padding here with custom padding parameter */ rv = RSA_padding_add_PKCS1_OAEP(encodedData, encodedDataLen, dataToEncrypt, dataToEncryptLen, oaepPad, oaepPadLen); if (rv != EVP_SUCCESS) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* call OpenSSL with no additional padding */ rv = RSA_public_encrypt(encodedDataLen, encodedData, encryptedData, rsa, RSA_NO_PADDING); if (rv == -1) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* RSA_public_encrypt returns the size of the encrypted data */ *encryptedDataLen = rv; rv = TSS_SUCCESS; goto out; err: DEBUG_print_openssl_errors(); out: if (rsa) RSA_free(rsa); return rv; }
TSS_RESULT Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_ALGORITHM_ID algID, /* in */ UINT32 ulPublicInfoLength, /* in */ BYTE * rgbPublicInfo, /* in */ TSS_HKEY * phKey) /* out */ { TCPA_ALGORITHM_ID tcsAlgID; UINT32 keyBlobSize; BYTE *keyBlob; TSS_RESULT result; TSS_HKEY keyOutHandle; UINT32 flag = 0; TSS_KEY keyContainer; UINT64 offset; if (phKey == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if (!obj_is_context(tspContext)) return TSPERR(TSS_E_INVALID_HANDLE); switch (algID) { case TSS_ALG_RSA: tcsAlgID = TCPA_ALG_RSA; break; default: LogError("Algorithm ID was not type RSA."); return TSPERR(TSS_E_BAD_PARAMETER); } if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID, ulPublicInfoLength, rgbPublicInfo, &keyBlobSize, &keyBlob))) return result; } else if (persistentStorageType == TSS_PS_TYPE_USER) { return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo, phKey); } else return TSPERR(TSS_E_BAD_PARAMETER); /* need to setup the init flags of the create object based on * the size of the blob's pubkey */ offset = 0; if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) { free(keyBlob); return result; } /* begin setting up the key object */ switch (keyContainer.pubKey.keyLength) { case 16384/8: flag |= TSS_KEY_SIZE_16384; break; case 8192/8: flag |= TSS_KEY_SIZE_8192; break; case 4096/8: flag |= TSS_KEY_SIZE_4096; break; case 2048/8: flag |= TSS_KEY_SIZE_2048; break; case 1024/8: flag |= TSS_KEY_SIZE_1024; break; case 512/8: flag |= TSS_KEY_SIZE_512; break; default: LogError("Key was not a known keylength."); free(keyBlob); free_key_refs(&keyContainer); return TSPERR(TSS_E_INTERNAL_ERROR); } if (keyContainer.keyUsage == TPM_KEY_SIGNING) flag |= TSS_KEY_TYPE_SIGNING; else if (keyContainer.keyUsage == TPM_KEY_STORAGE) flag |= TSS_KEY_TYPE_STORAGE; else if (keyContainer.keyUsage == TPM_KEY_IDENTITY) flag |= TSS_KEY_TYPE_IDENTITY; else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE) flag |= TSS_KEY_TYPE_AUTHCHANGE; else if (keyContainer.keyUsage == TPM_KEY_BIND) flag |= TSS_KEY_TYPE_BIND; else if (keyContainer.keyUsage == TPM_KEY_LEGACY) flag |= TSS_KEY_TYPE_LEGACY; if (keyContainer.authDataUsage == TPM_AUTH_NEVER) flag |= TSS_KEY_NO_AUTHORIZATION; else flag |= TSS_KEY_AUTHORIZATION; if (keyContainer.keyFlags & TPM_MIGRATABLE) flag |= TSS_KEY_MIGRATABLE; else flag |= TSS_KEY_NOT_MIGRATABLE; if (keyContainer.keyFlags & TPM_VOLATILE) flag |= TSS_KEY_VOLATILE; else flag |= TSS_KEY_NON_VOLATILE; #ifdef TSS_BUILD_CMK if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY) flag |= TSS_KEY_CERTIFIED_MIGRATABLE; else flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE; #endif /* Create a new Key Object */ if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) { free(keyBlob); free_key_refs(&keyContainer); return result; } /* Stick the info into this net KeyObject */ if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) { free(keyBlob); free_key_refs(&keyContainer); return result; } free(keyBlob); free_key_refs(&keyContainer); *phKey = keyOutHandle; return TSS_SUCCESS; }
TSS_RESULT authsess_oiap_get(TSS_HOBJECT obj, TPM_COMMAND_CODE ord, TPM_DIGEST *digest, TPM_AUTH *auth) { TSS_RESULT result = TSS_SUCCESS; TSS_BOOL bExpired; UINT32 mode; TPM_SECRET secret; TSS_HCONTEXT tspContext; TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack if (obj_is_tpm(obj)) result = obj_tpm_get_tsp_context(obj, hContext); else if (obj_is_rsakey(obj)) result = obj_rsakey_get_tsp_context(obj, hContext); else if (obj_is_encdata(obj)) result = obj_encdata_get_tsp_context(obj, hContext); else if (obj_is_nvstore(obj)) result = obj_nvstore_get_tsp_context(obj, hContext); else result = TSPERR(TSS_E_INVALID_HANDLE); #if 0 /* This validates that the secret can be used */ if ((result = obj_policy_has_expired(hPolicy, &bExpired))) return result; if (bExpired == TRUE) return TSPERR(TSS_E_INVALID_OBJ_ACCESS); if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) return result; if ((result = obj_policy_get_mode(hPolicy, &mode))) return result; #else if ((result = obj_policy_get_authsess_params())) return result; #endif if ((result = Init_AuthNonce(tspContext, cas, auth))) return result; /* XXX hack for opening a transport session */ if (cas) { OIAP = RPC_OIAP; TerminateHandle = RPC_TerminateHandle; } else { OIAP = TCS_API(tspContext)->OIAP; TerminateHandle = TCS_API(tspContext)->TerminateHandle; } /* added retry logic */ if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) { if (result == TCPA_E_RESOURCES) { int retry = 0; do { /* POSIX sleep time, { secs, nanosecs } */ struct timespec t = { 0, AUTH_RETRY_NANOSECS }; nanosleep(&t, NULL); result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven); } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); } if (result) return result; } switch (mode) { case TSS_SECRET_MODE_CALLBACK: result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, TRUE, ulPendingFn, auth->fContinueAuthSession, 20, auth->NonceEven.nonce, auth->NonceOdd.nonce, NULL, NULL, 20, hashDigest->digest, (BYTE *)&auth->HMAC); break; case TSS_SECRET_MODE_SHA1: case TSS_SECRET_MODE_PLAIN: case TSS_SECRET_MODE_POPUP: if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, &secret))) break; HMAC_Auth(secret.authdata, hashDigest->digest, auth); break; case TSS_SECRET_MODE_NONE: /* fall through */ default: result = TSPERR(TSS_E_POLICY_NO_SECRET); break; } if (result) { TerminateHandle(tspContext, auth->AuthHandle); return result; } return obj_policy_dec_counter(hPolicy); }
TSS_RESULT Trspi_Verify(UINT32 HashType, BYTE *pHash, UINT32 iHashLength, unsigned char *pModulus, int iKeyLength, BYTE *pSignature, UINT32 sig_len) { int rv, nid; unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* The default public exponent for the TPM */ unsigned char buf[256]; RSA *rsa = RSA_new(); if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* We assume we're verifying data from a TPM, so there are only * two options, SHA1 data and PKCSv1.5 encoded signature data. */ switch (HashType) { case TSS_HASH_SHA1: nid = NID_sha1; break; case TSS_HASH_OTHER: nid = NID_undef; break; default: rv = TSPERR(TSS_E_BAD_PARAMETER); goto out; break; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(pModulus, iKeyLength, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* if we don't know the structure of the data we're verifying, do a public decrypt * and compare manually. If we know we're looking for a SHA1 hash, allow OpenSSL * to do the work for us. */ if (nid == NID_undef) { rv = RSA_public_decrypt(sig_len, pSignature, buf, rsa, RSA_PKCS1_PADDING); if ((UINT32)rv != iHashLength) { rv = TSPERR(TSS_E_FAIL); goto out; } else if (memcmp(pHash, buf, iHashLength)) { rv = TSPERR(TSS_E_FAIL); goto out; } } else { if ((rv = RSA_verify(nid, pHash, iHashLength, pSignature, sig_len, rsa)) == 0) { rv = TSPERR(TSS_E_FAIL); goto out; } } rv = TSS_SUCCESS; goto out; err: DEBUG_print_openssl_errors(); out: if (rsa) RSA_free(rsa); return rv; }
TSS_RESULT RPC_ChangeAuth_TP(struct host_table_entry *hte, TCS_KEY_HANDLE parentHandle, /* in */ TCPA_PROTOCOL_ID protocolID, /* in */ TCPA_ENCAUTH *newAuth, /* in */ TCPA_ENTITY_TYPE entityType, /* in */ UINT32 encDataSize, /* in */ BYTE * encData, /* in */ TPM_AUTH * ownerAuth, /* in, out */ TPM_AUTH * entityAuth, /* in, out */ UINT32 * outDataSize, /* out */ BYTE ** outData) /* out */ { TSS_RESULT result; initData(&hte->comm, 9); hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTH; LogDebugFn("TCS Context: 0x%x", hte->tcsContext); if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT16, 2, &protocolID, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, newAuth, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT16, 4, &entityType, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT32, 5, &encDataSize, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_PBYTE, 6, encData, encDataSize, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_AUTH, 8, entityAuth, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); result = sendTCSDPacket(hte); if (result == TSS_SUCCESS) result = hte->comm.hdr.u.result; if (result == TSS_SUCCESS) { if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_AUTH, 1, entityAuth, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_UINT32, 2, outDataSize, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } *outData = (BYTE *) malloc(*outDataSize); if (*outData == NULL) { LogError("malloc of %u bytes failed.", *outDataSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *outData, *outDataSize, &hte->comm)) { free(*outData); result = TSPERR(TSS_E_INTERNAL_ERROR); } } done: return result; }
/* XXX Split into two functions */ TSS_RESULT Tspi_TPM_GetAuditDigest(TSS_HTPM hTpm, /* in */ TSS_HKEY hKey, /* in */ TSS_BOOL closeAudit, /* in */ UINT32* pulAuditDigestSize, /* out */ BYTE** prgbAuditDigest, /* out */ TPM_COUNTER_VALUE* pCounterValue, /* out */ TSS_VALIDATION* pValidationData, /* out */ UINT32* ordSize, /* out */ UINT32** ordList) /* out */ { TSS_HCONTEXT tspContext; UINT32 counterValueSize; BYTE *counterValue = NULL; TPM_DIGEST auditDigest; TSS_RESULT result = TSS_SUCCESS; UINT64 offset; if ((pulAuditDigestSize == NULL) || (prgbAuditDigest == NULL) || (pCounterValue == NULL)) return TSPERR(TSS_E_BAD_PARAMETER); if (hKey == NULL_HKEY) if ((ordSize == NULL) || (ordList == NULL)) return TSPERR(TSS_E_BAD_PARAMETER); if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext))) return result; if (hKey == NULL_HKEY) { UINT32 startOrdinal = 0; TSS_BOOL more; UINT32 tcsOrdSize; UINT32 *tcsOrdList = NULL; UINT32 *pulTemp; *prgbAuditDigest = NULL; *pulAuditDigestSize = 0; *ordList = NULL; *ordSize = 0; do { if ((result = TCS_API(tspContext)->GetAuditDigest(tspContext, startOrdinal, &auditDigest, &counterValueSize, &counterValue, &more, &tcsOrdSize, &tcsOrdList))) goto done1; if ((pulTemp = calloc_tspi(tspContext, (*ordSize + tcsOrdSize) * sizeof(UINT32))) == NULL) { LogError("malloc of %u bytes failed.", *ordSize + tcsOrdSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done1; } if (*ordList) memcpy(pulTemp, *ordList, *ordSize * sizeof(UINT32)); memcpy(pulTemp + *ordSize, tcsOrdList, tcsOrdSize * sizeof(UINT32)); free(tcsOrdList); tcsOrdList = NULL; if (*ordList) free_tspi(tspContext, *ordList); *ordList = pulTemp; *ordSize += tcsOrdSize; if (more == TRUE) { offset = 0; Trspi_UnloadBlob_UINT32(&offset, &startOrdinal, (BYTE *)(*ordList + (*ordSize - 1))); startOrdinal++; free(counterValue); counterValue = NULL; } } while (more == TRUE); *pulAuditDigestSize = sizeof(auditDigest.digest); if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { LogError("malloc of %u bytes failed.", *pulAuditDigestSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done1; } offset = 0; Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); offset = 0; Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); result = TSS_SUCCESS; done1: if (result != TSS_SUCCESS) { if (*prgbAuditDigest) free_tspi(tspContext, *prgbAuditDigest); if (*ordList) free_tspi(tspContext, *ordList); *prgbAuditDigest = NULL; *pulAuditDigestSize = 0; *ordList = NULL; *ordSize = 0; } free(counterValue); free(tcsOrdList); return result; } else { TSS_HPOLICY hPolicy; TSS_BOOL usesAuth; TCS_KEY_HANDLE tcsKeyHandle; TPM_AUTH keyAuth, *pAuth; Trspi_HashCtx hashCtx; TCPA_DIGEST digest; TPM_NONCE antiReplay; TPM_DIGEST auditDigest; TPM_DIGEST ordinalDigest; UINT32 sigSize; BYTE *sig = NULL; TPM_SIGN_INFO signInfo; UINT32 signInfoBlobSize; BYTE *signInfoBlob = NULL; if (pValidationData == NULL) { LogDebug("Internal Verify"); if ((result = get_local_random(tspContext, FALSE, TPM_NONCE_SIZE, (BYTE **)antiReplay.nonce))) return result; } else { LogDebug("External Verify"); if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) return TSPERR(TSS_E_BAD_PARAMETER); if (pValidationData->rgbExternalData == NULL) return TSPERR(TSS_E_BAD_PARAMETER); memcpy(antiReplay.nonce, pValidationData->rgbExternalData, sizeof(antiReplay.nonce)); pValidationData->ulDataLength = 0; pValidationData->rgbData = NULL; pValidationData->ulValidationDataLength = 0; pValidationData->rgbValidationData = NULL; } if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) return result; if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) return result; if (usesAuth) { result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); result |= Trspi_Hash_BOOL(&hashCtx, closeAudit); result |= Trspi_Hash_NONCE(&hashCtx, antiReplay.nonce); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) return result; pAuth = &keyAuth; if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetAuditDigestSigned, hPolicy, FALSE, &digest, pAuth))) return result; } else pAuth = NULL; if ((result = TCS_API(tspContext)->GetAuditDigestSigned(tspContext, tcsKeyHandle, closeAudit, &antiReplay, pAuth, &counterValueSize, &counterValue, &auditDigest, &ordinalDigest, &sigSize, &sig))) return result; memset(&signInfo, 0, sizeof(signInfo)); signInfo.tag = TPM_TAG_SIGNINFO; memcpy(signInfo.fixed, "ADIG", strlen("ADIG")); signInfo.replay = antiReplay; signInfo.dataLen = sizeof(auditDigest.digest) + counterValueSize + sizeof(ordinalDigest.digest); if ((signInfo.data = malloc(signInfo.dataLen)) == NULL) { LogError("malloc of %u bytes failed.", signInfo.dataLen); result = TSPERR(TSS_E_OUTOFMEMORY); goto done2; } offset = 0; Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &auditDigest); Trspi_LoadBlob(&offset, counterValueSize, signInfo.data, counterValue); Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &ordinalDigest); if (usesAuth) { result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, result); result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); result |= Trspi_HashUpdate(&hashCtx, counterValueSize, counterValue); result |= Trspi_Hash_DIGEST(&hashCtx, auditDigest.digest); result |= Trspi_Hash_DIGEST(&hashCtx, ordinalDigest.digest); result |= Trspi_Hash_UINT32(&hashCtx, sigSize); result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) goto done2; if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) goto done2; } offset = 0; Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo); signInfoBlobSize = offset; signInfoBlob = malloc(signInfoBlobSize); if (signInfoBlob == NULL) { LogError("malloc of %u bytes failed.", signInfoBlobSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done2; } offset = 0; Trspi_LoadBlob_SIGN_INFO(&offset, signInfoBlob, &signInfo); if (pValidationData == NULL) { if ((result = Trspi_Hash(TSS_HASH_SHA1, signInfoBlobSize, signInfoBlob, digest.digest))) goto done2; if ((result = __tspi_rsa_verify(hKey, TSS_HASH_SHA1, sizeof(digest.digest), digest.digest, sigSize, sig))) { result = TSPERR(TSS_E_VERIFICATION_FAILED); goto done2; } } else { pValidationData->ulDataLength = signInfoBlobSize; pValidationData->rgbData = calloc_tspi(tspContext, signInfoBlobSize); if (pValidationData->rgbData == NULL) { LogError("malloc of %u bytes failed.", signInfoBlobSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done2; } memcpy(pValidationData->rgbData, signInfoBlob, signInfoBlobSize); pValidationData->ulValidationDataLength = sigSize; pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize); if (pValidationData->rgbValidationData == NULL) { LogError("malloc of %u bytes failed.", sigSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done2; } memcpy(pValidationData->rgbValidationData, sig, sigSize); } *pulAuditDigestSize = sizeof(auditDigest.digest); if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { LogError("malloc of %u bytes failed.", *pulAuditDigestSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done2; } offset = 0; Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); offset = 0; Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); result = TSS_SUCCESS; done2: if (result != TSS_SUCCESS) { if (*prgbAuditDigest) free_tspi(tspContext, *prgbAuditDigest); *prgbAuditDigest = NULL; *pulAuditDigestSize = 0; if (pValidationData != NULL) { if (pValidationData->rgbData) free_tspi(tspContext, pValidationData->rgbData); if (pValidationData->rgbValidationData) free_tspi(tspContext, pValidationData->rgbValidationData); pValidationData->ulDataLength = 0; pValidationData->rgbData = NULL; pValidationData->ulValidationDataLength = 0; pValidationData->rgbValidationData = NULL; } } free(counterValue); free(sig); free(signInfo.data); free(signInfoBlob); return result; } }
TSS_RESULT obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore, TSS_HPCRS hPcrComposite, UINT32 *size, BYTE **data) { struct tsp_object *obj; BYTE pdata[MAX_PUBLIC_DATA_SIZE]; UINT32 dataLen; UINT64 offset; TSS_HCONTEXT tspContext; TSS_RESULT result = TSS_SUCCESS; BYTE* ppbHashData; UINT32 i; BYTE digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, }; UINT32 tmp_locAtRelease; TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR; BYTE tmp_pcr_select[3] = {0, 0, 0}; TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select}; if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); tspContext = obj->tspContext; if (hPcrComposite) { if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) { LogDebug("get_selection error from hReadPcrComposite"); goto out; } /* the index should not >= 24, so the sizeofselect should not be >3*/ if (dataLen - sizeof(UINT16) > 3) { result = TSPERR(TSS_E_BAD_PARAMETER); goto out; } offset = 0; Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect); if (pcrSelect.sizeOfSelect != 0) { if ((result = obj_pcrs_get_digest_at_release(hPcrComposite, &dataLen, &ppbHashData))) { LogDebug("get_composite error from hReadPcrComposite"); goto out; } memcpy(digAtRelease, ppbHashData, dataLen); free_tspi(tspContext, ppbHashData); } else { pcrSelect.sizeOfSelect = 3; pcrSelect.pcrSelect = tmp_pcr_select; } if (pcrSelect.sizeOfSelect < 3) { for (i = 0; i < pcrSelect.sizeOfSelect; i++) { tmp_pcr_select[i] = pcrSelect.pcrSelect[i]; } pcrSelect.sizeOfSelect = 3; pcrSelect.pcrSelect = tmp_pcr_select; } if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease))) goto out; locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK); } *size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN; *data = calloc_tspi(tspContext, *size); if (*data == NULL) { LogError("malloc of %u bytes failed.", *size); result = TSPERR(TSS_E_OUTOFMEMORY); goto out; } offset = 0; Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect); Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data); Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease); out: obj_list_put(&nvstore_list); return result; }
TSS_RESULT Trspi_UnloadBlob_DAA_PK(UINT64 *offset, BYTE *blob, TSS_DAA_PK *pk) { UINT32 i = 0, j; memset(pk, 0, sizeof(TSS_DAA_PK)); Trspi_UnloadBlob_TSS_VERSION(offset, blob, &pk->versionInfo); Trspi_UnloadBlob_UINT32(offset, &pk->modulusLength, blob); if (pk->modulusLength > 0) { if ((pk->modulus = malloc(pk->modulusLength)) == NULL) return TSPERR(TSS_E_OUTOFMEMORY); Trspi_UnloadBlob(offset, pk->modulusLength, blob, pk->modulus); } else { pk->modulus = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalSLength, blob); if (pk->capitalSLength > 0) { if ((pk->capitalS = malloc(pk->capitalSLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalSLength, blob, pk->capitalS); } else { pk->capitalS = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalZLength, blob); if (pk->capitalZLength > 0) { if ((pk->capitalZ = malloc(pk->capitalZLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalZLength, blob, pk->capitalZ); } else { pk->capitalZ = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalR0Length, blob); if (pk->capitalR0Length > 0) { if ((pk->capitalR0 = malloc(pk->capitalR0Length)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalR0Length, blob, pk->capitalR0); } else { pk->capitalR0 = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalR1Length, blob); if (pk->capitalR1Length > 0) { if ((pk->capitalR1 = malloc(pk->capitalR1Length)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalR1Length, blob, pk->capitalR1); } else { pk->capitalR1 = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->gammaLength, blob); if (pk->gammaLength > 0) { if ((pk->gamma = malloc(pk->gammaLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->gammaLength, blob, pk->gamma); } else { pk->gamma = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalGammaLength, blob); if (pk->capitalGammaLength > 0) { if ((pk->capitalGamma = malloc(pk->capitalGammaLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalGammaLength, blob, pk->capitalGamma); } else { pk->capitalGamma = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->rhoLength, blob); if (pk->rhoLength > 0) { if ((pk->rho = malloc(pk->rhoLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->rhoLength, blob, pk->rho); } else { pk->rho = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength, blob); Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength2, blob); if (pk->capitalYLength > 0 && pk->capitalYLength2 > 0) { if ((pk->capitalY = calloc(pk->capitalYLength, sizeof(BYTE *))) == NULL) goto error; for (i = 0; i < pk->capitalYLength; i++) { if ((pk->capitalY[i] = malloc(pk->capitalYLength2)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->capitalYLength2, blob, pk->capitalY[i]); } } else { pk->capitalY = NULL; } Trspi_UnloadBlob_UINT32(offset, &pk->capitalYPlatformLength, blob); Trspi_UnloadBlob_UINT32(offset, &pk->issuerBaseNameLength, blob); if (pk->issuerBaseNameLength > 0) { if ((pk->issuerBaseName = malloc(pk->issuerBaseNameLength)) == NULL) goto error; Trspi_UnloadBlob(offset, pk->issuerBaseNameLength, blob, pk->issuerBaseName); } else { pk->issuerBaseName = NULL; } return TSS_SUCCESS; error: free(pk->modulus); free(pk->capitalS); free(pk->capitalZ); free(pk->capitalR0); free(pk->capitalR1); free(pk->gamma); free(pk->capitalGamma); free(pk->rho); if (pk->capitalY) { for (j = 0; j < i; j++) free(pk->capitalY[j]); free(pk->capitalY); } free(pk->issuerBaseName); memset(pk, 0, sizeof(TSS_DAA_PK)); return TSPERR(TSS_E_OUTOFMEMORY); }
TSS_RESULT obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public) { struct tsp_object *obj; TSS_HCONTEXT hContext; TSS_HTPM hTpm; TSS_RESULT result; struct tr_nvstore_obj *nvstore; UINT32 uiResultLen; BYTE *pResult; UINT32 i; TPM_BOOL defined_index = FALSE; if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); hContext = obj->tspContext; nvstore = (struct tr_nvstore_obj *)obj->data; if ((result = obj_tpm_get(hContext, &hTpm))) goto out; if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, NULL, &uiResultLen, &pResult))) { goto out; } for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { defined_index = TRUE; break; } } free_tspi(hContext, pResult); if (!defined_index) { result = TSPERR(TPM_E_BADINDEX); goto out; } if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX, sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)), &uiResultLen, &pResult))) { LogDebug("get the index capability error"); goto out; } if (uiResultLen > *size) { free_tspi(hContext, pResult); result = TSPERR(TSS_E_INTERNAL_ERROR); goto out; } *size = uiResultLen; memcpy(nv_data_public, pResult, uiResultLen); free_tspi(hContext, pResult); out: obj_list_put(&nvstore_list); return result; }
TSS_RESULT psfile_get_registered_keys2(int fd, TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO2 **keys) { TSS_RESULT result; struct key_disk_cache *cache_entries; UINT32 cache_size, i, j; TSS_KM_KEYINFO2 *keyinfos = NULL; TSS_UUID *find_uuid; if ((result = psfile_get_all_cache_entries(fd, &cache_size, &cache_entries))) return result; if (cache_size == 0) { if (uuid) return TSPERR(TSS_E_PS_KEY_NOTFOUND); else { *size = 0; *keys = NULL; return TSS_SUCCESS; } } if (uuid) { find_uuid = uuid; j = 0; restart_search: /* Search for the requested UUID. When found, allocate new space for it, copy * it in, then change the uuid to be searched for it its parent and start over. */ for (i = 0; i < cache_size; i++) { /*Return 0 if normal finish*/ if (!memcmp(&cache_entries[i].uuid, find_uuid, sizeof(TSS_UUID))) { if (!(keyinfos = realloc(keyinfos, (j+1) * sizeof(TSS_KM_KEYINFO2)))) { free(cache_entries); free(keyinfos); return TSPERR(TSS_E_OUTOFMEMORY); } /* Here the key UUID is found and needs to be copied for the array*/ /* Initializes the keyinfos with 0's*/ memset(&keyinfos[j], 0, sizeof(TSS_KM_KEYINFO2)); if ((result = copy_key_info2(fd, &keyinfos[j], &cache_entries[i]))) { free(cache_entries); free(keyinfos); return result; } find_uuid = &keyinfos[j].parentKeyUUID; j++; goto restart_search; } } /* Searching for keys in the user PS will always lead us up to some key in the * system PS. Return that key's uuid so that the upper layers can call down to TCS * to search for it. */ memcpy(tcs_uuid, find_uuid, sizeof(TSS_UUID)); *size = j; } else { if ((keyinfos = calloc(cache_size, sizeof(TSS_KM_KEYINFO2))) == NULL) { LogDebug("malloc of %zu bytes failed.", cache_size * sizeof(TSS_KM_KEYINFO2)); free(cache_entries); return TSPERR(TSS_E_OUTOFMEMORY); } for (i = 0; i < cache_size; i++) { if ((result = copy_key_info2(fd, &keyinfos[i], &cache_entries[i]))) { free(cache_entries); free(keyinfos); return result; } } *size = cache_size; } free(cache_entries); *keys = keyinfos; return TSS_SUCCESS; }
TSS_RESULT psfile_get_all_cache_entries(int fd, UINT32 *size, struct key_disk_cache **c) { UINT32 i, num_keys = psfile_get_num_keys(fd); int offset; TSS_RESULT result; struct key_disk_cache *tmp = NULL; if (num_keys == 0) { *size = 0; *c = NULL; return TSS_SUCCESS; } /* make sure the file pointer is where we expect, just after the number * of keys on disk at the head of the file */ offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET); if (offset == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } if ((tmp = malloc(num_keys * sizeof(struct key_disk_cache))) == NULL) { LogDebug("malloc of %zu bytes failed.", num_keys * sizeof(struct key_disk_cache)); return TSPERR(TSS_E_OUTOFMEMORY); } for (i = 0; i < num_keys; i++) { offset = lseek(fd, 0, SEEK_CUR); if (offset == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); result = TSPERR(TSS_E_INTERNAL_ERROR); goto err_exit; } tmp[i].offset = offset; /* read UUID */ if ((result = read_data(fd, &tmp[i].uuid, sizeof(TSS_UUID)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } /* read parent UUID */ if ((result = read_data(fd, &tmp[i].parent_uuid, sizeof(TSS_UUID)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } /* pub data size */ if ((result = read_data(fd, &tmp[i].pub_data_size, sizeof(UINT16)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } tmp[i].pub_data_size = LE_16(tmp[i].pub_data_size); DBG_ASSERT(tmp[i].pub_data_size <= 2048); /* blob size */ if ((result = read_data(fd, &tmp[i].blob_size, sizeof(UINT16)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } tmp[i].blob_size = LE_16(tmp[i].blob_size); DBG_ASSERT(tmp[i].blob_size <= 4096); /* vendor data size */ if ((result = read_data(fd, &tmp[i].vendor_data_size, sizeof(UINT32)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } tmp[i].vendor_data_size = LE_32(tmp[i].vendor_data_size); /* cache flags */ if ((result = read_data(fd, &tmp[i].flags, sizeof(UINT16)))) { LogDebug("%s", __FUNCTION__); goto err_exit; } tmp[i].flags = LE_16(tmp[i].flags); /* fast forward over the pub key */ offset = lseek(fd, tmp[i].pub_data_size, SEEK_CUR); if (offset == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); result = TSPERR(TSS_E_INTERNAL_ERROR); goto err_exit; } /* fast forward over the blob */ offset = lseek(fd, tmp[i].blob_size, SEEK_CUR); if (offset == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); result = TSPERR(TSS_E_INTERNAL_ERROR); goto err_exit; } /* ignore vendor data for user ps */ } *size = num_keys; *c = tmp; return TSS_SUCCESS; err_exit: free(tmp); return result; }
TSS_RESULT secret_PerformAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn, TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20], TPM_AUTH *auth, BYTE *hashDigest, TCPA_NONCE *nonceEvenOSAP) { TSS_RESULT result; UINT32 keyMode, usageMode, migMode = 0; if ((result = obj_policy_get_mode(hPolicy, &keyMode))) return result; if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) return result; if (hMigPolicy) { if ((result = obj_policy_get_mode(hMigPolicy, &migMode))) return result; } /* --- If any of them is a callback */ if (keyMode == TSS_SECRET_MODE_CALLBACK || usageMode == TSS_SECRET_MODE_CALLBACK || (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { /* --- And they're not all callback */ if (keyMode != TSS_SECRET_MODE_CALLBACK || usageMode != TSS_SECRET_MODE_CALLBACK || (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) return TSPERR(TSS_E_BAD_PARAMETER); } if (keyMode == TSS_SECRET_MODE_CALLBACK) { if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, TRUE, ulPendingFn, auth->fContinueAuthSession, 20, auth->NonceEven.nonce, NULL, nonceEvenOSAP->nonce, auth->NonceOdd.nonce, 20, hashDigest, (BYTE *)&auth->HMAC))) return result; } else { HMAC_Auth(sharedSecret, hashDigest, auth); } if ((result = obj_policy_dec_counter(hPolicy))) return result; if ((result = obj_policy_dec_counter(hUsagePolicy))) return result; if (hMigPolicy) { if ((result = obj_policy_dec_counter(hMigPolicy))) return result; } return TSS_SUCCESS; }
TSS_RESULT obj_pcrs_set_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 size, BYTE *value) { struct tsp_object *obj; struct tr_pcrs_obj *pcrs; TSS_RESULT result = TSS_SUCCESS; TPM_PCR_SELECTION *select; TPM_COMPOSITE_HASH *compHash; UINT16 bytes_to_hold = (idx / 8) + 1; if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); pcrs = (struct tr_pcrs_obj *)obj->data; switch(pcrs->type) { case TSS_PCRS_STRUCT_INFO: bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold; select = &pcrs->info.info11.pcrSelection; compHash = &pcrs->info.info11.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_SHORT: bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; select = &pcrs->info.infoshort.pcrSelection; compHash = &pcrs->info.infoshort.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_LONG: bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; select = &pcrs->info.infolong.releasePCRSelection; compHash = &pcrs->info.infolong.digestAtRelease; break; default: LogDebugFn("Undefined type of PCRs object"); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; break; } /* allocate the selection structure */ if (select->pcrSelect == NULL) { if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } select->sizeOfSelect = bytes_to_hold; memset(select->pcrSelect, 0, bytes_to_hold); /* allocate the pcr array */ if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } } else if (select->sizeOfSelect < bytes_to_hold) { if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } /* set the newly allocated bytes to 0 */ memset(&select->pcrSelect[select->sizeOfSelect], 0, bytes_to_hold - select->sizeOfSelect); select->sizeOfSelect = bytes_to_hold; /* realloc the pcrs array */ if ((pcrs->pcrs = realloc(pcrs->pcrs, bytes_to_hold * 8 * sizeof(TPM_PCRVALUE))) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } } /* set the bit in the selection structure */ select->pcrSelect[idx / 8] |= (1 << (idx % 8)); /* set the value in the pcrs array */ memcpy(&(pcrs->pcrs[idx]), value, size); result = pcrs_calc_composite(select, pcrs->pcrs, compHash); done: obj_list_put(&pcrs_list); return result; }
TSS_RESULT OSAP_Calc(TSS_HCONTEXT tspContext, UINT16 EntityType, UINT32 EntityValue, BYTE * authSecret, BYTE * usageSecret, BYTE * migSecret, TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, BYTE * sharedSecret, TPM_AUTH * auth) { TSS_RESULT rc; TCPA_NONCE nonceEvenOSAP; UINT64 offset; BYTE hmacBlob[0x200]; BYTE hashBlob[0x200]; BYTE xorUsageAuth[20]; BYTE xorMigAuth[20]; UINT32 i; if ((rc = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), (BYTE **)auth->NonceOdd.nonce))) { LogError("Failed creating random nonce"); return TSPERR(TSS_E_INTERNAL_ERROR); } auth->fContinueAuthSession = 0x00; if ((rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, &auth->NonceOdd, &auth->AuthHandle, &auth->NonceEven, &nonceEvenOSAP))) { if (rc == TCPA_E_RESOURCES) { int retry = 0; do { /* POSIX sleep time, { secs, nanosecs } */ struct timespec t = { 0, AUTH_RETRY_NANOSECS }; nanosleep(&t, NULL); rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, &auth->NonceOdd, &auth->AuthHandle, &auth->NonceEven, &nonceEvenOSAP); } while (rc == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); } if (rc) return rc; } offset = 0; Trspi_LoadBlob(&offset, 20, hmacBlob, nonceEvenOSAP.nonce); Trspi_LoadBlob(&offset, 20, hmacBlob, auth->NonceOdd.nonce); Trspi_HMAC(TSS_HASH_SHA1, 20, authSecret, offset, hmacBlob, sharedSecret); offset = 0; Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceEven.nonce); if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorUsageAuth))) return rc; offset = 0; Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceOdd.nonce); if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorMigAuth))) return rc; for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) encAuthUsage->authdata[i] = usageSecret[i] ^ xorUsageAuth[i]; for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) encAuthMig->authdata[i] = migSecret[i] ^ xorMigAuth[i]; return TSS_SUCCESS; }
TSS_RESULT obj_pcrs_select_index_ex(TSS_HPCRS hPcrs, UINT32 dir, UINT32 idx) { struct tsp_object *obj; struct tr_pcrs_obj *pcrs; TSS_RESULT result = TSS_SUCCESS; TPM_PCR_SELECTION *select; UINT16 bytes_to_hold = (idx / 8) + 1; if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); pcrs = (struct tr_pcrs_obj *)obj->data; switch(pcrs->type) { case TSS_PCRS_STRUCT_INFO: result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); goto done; case TSS_PCRS_STRUCT_INFO_SHORT: if (dir == TSS_PCRS_DIRECTION_CREATION) { result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); goto done; } bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; select = &pcrs->info.infoshort.pcrSelection; break; case TSS_PCRS_STRUCT_INFO_LONG: bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; if (dir == TSS_PCRS_DIRECTION_CREATION) select = &pcrs->info.infolong.creationPCRSelection; else select = &pcrs->info.infolong.releasePCRSelection; break; default: LogDebugFn("Undefined type of PCRs object"); result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; break; } /* allocate the selection structure */ if (select->pcrSelect == NULL) { if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } select->sizeOfSelect = bytes_to_hold; memset(select->pcrSelect, 0, bytes_to_hold); /* alloc the pcrs array */ if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } } else if (select->sizeOfSelect < bytes_to_hold) { if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } /* set the newly allocated bytes to 0 */ memset(&select->pcrSelect[select->sizeOfSelect], 0, bytes_to_hold - select->sizeOfSelect); select->sizeOfSelect = bytes_to_hold; /* realloc the pcrs array */ if ((pcrs->pcrs = realloc(pcrs->pcrs, bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } } /* set the bit in the selection structure */ select->pcrSelect[idx / 8] |= (1 << (idx % 8)); done: obj_list_put(&pcrs_list); return result; }
/* Create an OSAP session. @requirements is used in different ways depending on the command to * indicate whether we should require a policy or auth value */ TSS_RESULT authsess_xsap_init(TSS_HCONTEXT tspContext, TSS_HOBJECT obj_parent, TSS_HOBJECT obj_child, TSS_BOOL requirements, TPM_COMMAND_CODE command, TPM_ENTITY_TYPE entity_type, struct authsess **xsess) { TSS_RESULT result; TSS_BOOL authdatausage = FALSE, req_auth = TRUE, get_child_auth = TRUE, secret_set = FALSE; BYTE hmacBlob[2 * sizeof(TPM_DIGEST)]; UINT64 offset; TSS_BOOL new_secret = TR_SECRET_CTX_NOT_NEW; struct authsess *sess; if ((sess = calloc(1, sizeof(struct authsess))) == NULL) { LogError("malloc of %zd bytes failed", sizeof(struct authsess)); return TSPERR(TSS_E_OUTOFMEMORY); } switch (command) { /* Parent is Key for the cases below */ case TPM_ORD_Delegate_CreateKeyDelegation: case TPM_ORD_CreateWrapKey: case TPM_ORD_CMK_CreateKey: case TPM_ORD_Seal: case TPM_ORD_Sealx: case TPM_ORD_Unseal: case TPM_ORD_ChangeAuth: if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, &sess->hUsageParent, NULL))) goto error; break; /* Parent is TPM for the cases below */ case TPM_ORD_Delegate_CreateOwnerDelegation: req_auth = FALSE; /* fall through */ case TPM_ORD_MakeIdentity: case TPM_ORD_NV_DefineSpace: if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, &sess->hUsageParent))) goto error; break; case TPM_ORD_ChangeAuthOwner: /* Special case, ChangeAuthOwner is used to change Owner and SRK auth */ if (obj_is_rsakey(obj_parent)) { if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, &sess->hUsageParent, NULL))) goto error; } else { if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, &sess->hUsageParent))) goto error; } break; default: result = TSPERR(TSS_E_INTERNAL_ERROR); goto error; } if (requirements && !sess->hUsageParent) { result = TSPERR(TSS_E_TSP_AUTHREQUIRED); goto error; } if (sess->hUsageParent) { /* These are trousers callback functions which will be used to process the auth * session. If the policy type is callback for hUsageParent, they will be * overwritten by the application defined callback functions in the policy */ sess->cb_xor.callback = authsess_callback_xor; sess->cb_xor.appData = (PVOID)sess; sess->cb_hmac.callback = authsess_callback_hmac; sess->cb_hmac.appData = (PVOID)sess; /* XXX the parent object doesn't always hold the callbacks */ if ((result = obj_policy_get_xsap_params(sess->hUsageParent, command, &sess->entity_type, &sess->entityValueSize, &sess->entityValue, sess->parentSecret.authdata, &sess->cb_xor, &sess->cb_hmac, NULL, &sess->parentMode, new_secret))) goto error; } else sess->parentMode = TSS_SECRET_MODE_NONE; switch (command) { /* Child is a Key object */ case TPM_ORD_CreateWrapKey: case TPM_ORD_CMK_CreateKey: if ((result = obj_rsakey_get_policies(obj_child, &sess->hUsageChild, &sess->hMigChild, &authdatausage))) goto error; if (authdatausage && !sess->hUsageChild) { result = TSPERR(TSS_E_TSP_AUTHREQUIRED); goto error; } if (obj_rsakey_is_migratable(obj_child)) { if (!sess->hMigChild) { result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY); goto error; } if ((result = obj_policy_get_xsap_params(sess->hMigChild, 0, NULL, NULL, NULL, sess->encAuthMig.authdata, NULL, NULL, NULL, &sess->mMode, new_secret))) goto error; } if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) goto error; break; /* Child is an Encdata object */ case TPM_ORD_Unseal: #ifdef TSS_BUILD_SEALX case TPM_ORD_Sealx: /* These may be overwritten down below, when obj_policy_get_xsap_params is called * on the child usage policy */ sess->cb_sealx.callback = sealx_mask_cb; sess->cb_sealx.appData = (PVOID)sess; /* fall through */ #endif case TPM_ORD_Seal: if ((result = obj_encdata_get_policy(obj_child, TSS_POLICY_USAGE, &sess->hUsageChild))) goto error; if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) goto error; break; #ifdef TSS_BUILD_NV /* Child is an NV object */ case TPM_ORD_NV_DefineSpace: /* The requirements variable tells us whether nv object auth is required */ req_auth = requirements; if (req_auth) { if (sess->parentMode == TSS_SECRET_MODE_NONE) { result = TSPERR(TSS_E_TSP_AUTHREQUIRED); goto error; } if ((result = obj_nvstore_get_policy(obj_child, TSS_POLICY_USAGE, &sess->hUsageChild))) goto error; /* According to the spec, we must fall back on the TSP context's policy for * auth if none is set in the NV object */ if (!sess->hUsageChild) { if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &sess->hUsageChild))) goto error; } if ((result = obj_policy_is_secret_set(sess->hUsageChild, &secret_set))) goto error; if (!secret_set) { result = TSPERR(TSS_E_TSP_AUTHREQUIRED); goto error; } } else { /* In this case, the TPM is owned, but we're creating a no-auth NV area */ get_child_auth = FALSE; } break; #endif /* Child is a Key object */ case TPM_ORD_MakeIdentity: if ((result = obj_rsakey_get_policy(obj_child, TSS_POLICY_USAGE, &sess->hUsageChild, NULL))) goto error; break; /* Child is a Policy object */ case TPM_ORD_Delegate_CreateKeyDelegation: case TPM_ORD_ChangeAuth: if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) goto error; /* fall through */ case TPM_ORD_Delegate_CreateOwnerDelegation: case TPM_ORD_ChangeAuthOwner: sess->hUsageChild = obj_child; new_secret = TR_SECRET_CTX_NEW; break; default: result = TSPERR(TSS_E_INTERNAL_ERROR); goto error; } /* If req_auth is FALSE here, we don't actually need to set up an auth session, so returning * is OK. At this point, authsess->pAuth is NULL, so the TCS API will not get any * authdata. */ if (req_auth == FALSE && sess->parentMode == TSS_SECRET_MODE_NONE) goto done; if (get_child_auth) { if ((result = obj_policy_get_xsap_params(sess->hUsageChild, 0, 0, NULL, NULL, sess->encAuthUse.authdata, NULL, NULL, &sess->cb_sealx, &sess->uMode, new_secret))) goto error; } if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), (BYTE **)sess->nonceOddxSAP.nonce))) goto error; sess->obj_child = obj_child; sess->tspContext = tspContext; sess->pAuth = &sess->auth; sess->command = command; #ifdef TSS_BUILD_DELEGATION /* if entityValue is set, we have a custom entity, i.e. delegation blob or row */ if (sess->entityValue) { /* DSAP's entity type was pulled from the policy in the authsess_xsap_init call * above */ if ((result = authsess_do_dsap(sess))) goto error; } #endif if (!sess->entityValue) { sess->entity_type = entity_type; if ((result = authsess_do_osap(sess))) goto error; } if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), (BYTE **)sess->auth.NonceOdd.nonce))) goto error; /* We have both OSAP nonces, so calculate the shared secret if we're responsible for it */ if (sess->parentMode != TSS_SECRET_MODE_CALLBACK) { offset = 0; Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceEvenxSAP.nonce); Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceOddxSAP.nonce); if ((result = Trspi_HMAC(TSS_HASH_SHA1, sizeof(TPM_ENCAUTH), sess->parentSecret.authdata, offset, hmacBlob, sess->sharedSecret.digest))) goto error; } /* XXX What does a PurposeSecret of TRUE mean here? */ if ((result = ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HOBJECT, TSS_FLAG, UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, BYTE *))sess->cb_xor.callback)(sess->cb_xor.appData, sess->hUsageParent, sess->hUsageChild, TRUE, sizeof(TPM_DIGEST), sess->auth.NonceEven.nonce, sess->auth.NonceOdd.nonce, sess->nonceEvenxSAP.nonce, sess->nonceOddxSAP.nonce, sizeof(TPM_ENCAUTH), sess->encAuthUse.authdata, sess->encAuthMig.authdata))) return result; done: *xsess = sess; return TSS_SUCCESS; error: free(sess); return result; }
TSS_RESULT obj_pcrs_create_info_long(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info) { struct tsp_object *obj; struct tr_pcrs_obj *pcrs; TSS_RESULT result = TSS_SUCCESS; TPM_PCR_INFO_LONG infolong; BYTE dummyBits[3] = { 0, 0, 0 }; TPM_PCR_SELECTION dummySelection = { 3, dummyBits }; UINT64 offset; UINT32 ret_size; BYTE *ret; if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); pcrs = (struct tr_pcrs_obj *)obj->data; /* Set everything that is not assigned to be all zeroes */ memset(&infolong, 0, sizeof(infolong)); infolong.tag = TPM_TAG_PCR_INFO_LONG; /* localityAtCreation and creationPCRSelection certainly do not need to be set here, but * some chips such as Winbond do not ignore them on input, so we must give them dummy * "good" values */ infolong.localityAtCreation = TPM_LOC_ZERO; infolong.creationPCRSelection = dummySelection; switch (pcrs->type) { case TSS_PCRS_STRUCT_INFO: infolong.localityAtRelease = TSS_LOCALITY_ALL; infolong.releasePCRSelection = pcrs->info.info11.pcrSelection; infolong.digestAtRelease = pcrs->info.info11.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_LONG: infolong.localityAtRelease = pcrs->info.infolong.localityAtRelease; infolong.releasePCRSelection = pcrs->info.infolong.releasePCRSelection; infolong.digestAtRelease = pcrs->info.infolong.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_SHORT: infolong.localityAtRelease = pcrs->info.infoshort.localityAtRelease; infolong.releasePCRSelection = pcrs->info.infoshort.pcrSelection; infolong.digestAtRelease = pcrs->info.infoshort.digestAtRelease; break; default: result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } offset = 0; Trspi_LoadBlob_PCR_INFO_LONG(&offset, NULL, &infolong); ret_size = offset; if ((ret = calloc(1, ret_size)) == NULL) { result = TSPERR(TSS_E_OUTOFMEMORY); LogDebug("malloc of %u bytes failed.", ret_size); goto done; } offset = 0; Trspi_LoadBlob_PCR_INFO_LONG(&offset, ret, &infolong); *info = ret; *size = ret_size; done: obj_list_put(&pcrs_list); return result; }
int Trspi_RSA_Public_Encrypt(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen, unsigned char *pubkey, unsigned int pubsize, unsigned int e, int padding) { int rv, e_size = 3; unsigned char exp[] = { 0x01, 0x00, 0x01 }; RSA *rsa = RSA_new(); if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } switch (e) { case 0: /* fall through */ case 65537: break; case 17: exp[0] = 17; e_size = 1; break; case 3: exp[0] = 3; e_size = 1; break; default: rv = TSPERR(TSS_E_INTERNAL_ERROR); goto out; break; } switch (padding) { case TR_RSA_PKCS1_OAEP_PADDING: padding = RSA_PKCS1_OAEP_PADDING; break; case TR_RSA_PKCS1_PADDING: padding = RSA_PKCS1_PADDING; break; case TR_RSA_NO_PADDING: padding = RSA_NO_PADDING; break; default: rv = TSPERR(TSS_E_INTERNAL_ERROR); goto out; break; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(pubkey, pubsize, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, e_size, rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } rv = RSA_public_encrypt(inlen, in, out, rsa, padding); if (rv == -1) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* RSA_public_encrypt returns the size of the encrypted data */ *outlen = rv; rv = TSS_SUCCESS; goto out; err: DEBUG_print_openssl_errors(); out: if (rsa) RSA_free(rsa); return rv; }
TSS_RESULT obj_pcrs_create_info_short(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info) { struct tsp_object *obj; struct tr_pcrs_obj *pcrs; TSS_RESULT result = TSS_SUCCESS; TPM_PCR_INFO_SHORT infoshort; BYTE select[] = { 0, 0, 0 }; UINT64 offset; UINT32 ret_size; BYTE *ret; /* Set everything that is not assigned to be all zeroes */ memset(&infoshort, 0, sizeof(infoshort)); if (hPcrs != NULL_HPCRS) { if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) return TSPERR(TSS_E_INVALID_HANDLE); pcrs = (struct tr_pcrs_obj *)obj->data; switch (pcrs->type) { case TSS_PCRS_STRUCT_INFO: infoshort.pcrSelection = pcrs->info.info11.pcrSelection; infoshort.localityAtRelease = TSS_LOCALITY_ALL; infoshort.digestAtRelease = pcrs->info.info11.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_LONG: infoshort.pcrSelection = pcrs->info.infolong.releasePCRSelection; infoshort.localityAtRelease = pcrs->info.infolong.localityAtRelease; infoshort.digestAtRelease = pcrs->info.infolong.digestAtRelease; break; case TSS_PCRS_STRUCT_INFO_SHORT: infoshort = pcrs->info.infoshort; break; default: result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } else { infoshort.pcrSelection.sizeOfSelect = sizeof(select); infoshort.pcrSelection.pcrSelect = select; infoshort.localityAtRelease = TSS_LOCALITY_ALL; } offset = 0; Trspi_LoadBlob_PCR_INFO_SHORT(&offset, NULL, &infoshort); ret_size = offset; if ((ret = calloc(1, ret_size)) == NULL) { result = TSPERR(TSS_E_OUTOFMEMORY); LogDebug("malloc of %u bytes failed.", ret_size); goto done; } offset = 0; Trspi_LoadBlob_PCR_INFO_SHORT(&offset, ret, &infoshort); *info = ret; *size = ret_size; done: if (hPcrs != NULL_HPCRS) obj_list_put(&pcrs_list); return result; }
VOID DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipState, INT *pUncalX, INT *pUncalY) { static int PrevX=0; static int PrevY=0; int TmpX = 0; int TmpY = 0; //TSPMSG((_T("[TSP] ++DdsiTouchPanelGetPoint()\r\n"))); if (g_pVIC1Reg->VICRAWINTR & (1<<(PHYIRQ_PENDN-VIC1_BIT_OFFSET))) // gIntrTouch Interrupt Case { //TSPMSG((_T("[TSP] gIntrTouch(PHYIRQ_PENDN) Case\r\n"))); *pTipState = TouchSampleValidFlag; if ((g_pADCReg->ADCDAT0 & D_UPDOWN_UP) || (g_pADCReg->ADCDAT1 & D_UPDOWN_UP)) { //TSPMSG((_T("[TSP] Pen Up\r\n"))); g_bTSP_DownFlag = FALSE; g_pADCReg->ADCTSC = ADCTSC_WAIT_PENDOWN; *pUncalX = PrevX; *pUncalY = PrevY; TSP_SampleStop(); } else { //TSPMSG((_T("[TSP] Pen Down\r\n"))); g_bTSP_DownFlag = TRUE; g_pADCReg->ADCTSC = ADCTSC_WAIT_PENUP; *pTipState |= TouchSampleIgnore; *pUncalX = PrevX; *pUncalY = PrevY; *pTipState |= TouchSampleDownFlag; TSP_SampleStart(); } g_pADCReg->ADCCLRWK = CLEAR_ADCWK_INT; InterruptDone(gIntrTouch); // Not handled in MDD } else// if (g_pVIC0Reg->VICRAWINTR & (1<<(PHYIRQ_TIMER3))) // gIntrTouchTimer Interrupt Case { //TSPMSG((_T("[TSP] gIntrTouchChanged(PHYIRQ_TIMER3) Case\r\n"))); // Check for Pen-Up case on the event of timer3 interrupt if ((g_pADCReg->ADCDAT0 & D_UPDOWN_UP) || (g_pADCReg->ADCDAT1 & D_UPDOWN_UP)) { //TSPMSG((_T("[TSP] Pen Up +\r\n"))); g_bTSP_DownFlag = FALSE; g_pADCReg->ADCTSC = ADCTSC_WAIT_PENDOWN; *pUncalX = PrevX; *pUncalY = PrevY; *pTipState = TouchSampleValidFlag; TSP_SampleStop(); } else if (g_bTSP_DownFlag) { if (TSP_GetXY(&TmpX, &TmpY) == TRUE) { //TSP_TransXY(&TmpX, &TmpY); if(Touch_Pen_Filtering(&TmpX, &TmpY)) { *pTipState = TouchSampleValidFlag | TouchSampleDownFlag; *pTipState &= ~TouchSampleIgnore; } else // Invalid touch pen { *pTipState = TouchSampleValidFlag; *pTipState |= TouchSampleIgnore; } *pUncalX = PrevX = TmpX; *pUncalY = PrevY = TmpY; g_pADCReg->ADCTSC = ADCTSC_WAIT_PENUP; //TSPMSG((_T("[TSP] UncalX = %d, UncalY = %d\r\n"), *pUncalX,*pUncalY)); } else { *pTipState = TouchSampleIgnore; } } else { TSPERR((_T("[TSP] Unknown State\r\n"))); *pTipState = TouchSampleIgnore; TSP_SampleStop(); } // timer3 interrupt status clear //g_pPWMReg->TINT_CSTAT |= (1<<8); // Do not use OR/AND operation on TINTC_CSTAT g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_PENDING_CLEAR; InterruptDone(gIntrTouchChanged); // Not Handled in MDD } //TSPMSG((_T("[TSP] --DdsiTouchPanelGetPoint()\r\n"))); }
TSS_RESULT Tspi_Data_Unseal(TSS_HENCDATA hEncData, /* in */ TSS_HKEY hKey, /* in */ UINT32 * pulUnsealedDataLength,/* out */ BYTE ** prgbUnsealedData) /* out */ { UINT64 offset; TPM_AUTH privAuth2; TPM_DIGEST digest; TPM_NONCE authLastNonceEven; TSS_RESULT result; TSS_HPOLICY hPolicy, hEncPolicy; TCS_KEY_HANDLE tcsKeyHandle; TSS_HCONTEXT tspContext; UINT32 ulDataLen, unSealedDataLen; BYTE *data = NULL, *unSealedData = NULL, *maskedData; UINT16 mask; Trspi_HashCtx hashCtx; struct authsess *xsap = NULL; if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext))) return result; if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL))) return result; if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy))) return result; if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data))) return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ? TSPERR(TSS_E_ENC_NO_DATA) : result; offset = 0; Trspi_UnloadBlob_UINT16(&offset, &mask, data); if (mask == TPM_TAG_STORED_DATA12) { /* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero * then we must unmask the unsealed data after it returns from the TCS */ Trspi_UnloadBlob_UINT16(&offset, &mask, data); } else mask = 0; if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) goto error; if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED, TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap))) goto error; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal); result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) goto error; if ((result = authsess_xsap_hmac(xsap, &digest))) goto error; if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest, &privAuth2))) goto error; if (mask) { /* save off last nonce even to pass to sealx callback */ memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE)); } if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data, xsap->pAuth, &privAuth2, &unSealedDataLen, &unSealedData))) goto error; result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal); result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen); result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { free(unSealedData); goto error; } if ((result = authsess_xsap_verify(xsap, &digest))) { free(unSealedData); goto error; } if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) { free(unSealedData); goto error; } /* If the data is masked, use the callback set up in authsess_xsap_init */ if (mask) { maskedData = unSealedData; if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) { free(maskedData); LogError("malloc of %u bytes failed", unSealedDataLen); result = TSPERR(TSS_E_OUTOFMEMORY); goto error; } /* XXX pass in out saved-off authLastNonceEven. This conflicts with the * description of the rgbNonceEven parameter in the spec, but without it, its not * possible to compute the MGF1 key */ if ((result = ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData, xsap->cb_sealx.alg, sizeof(TPM_NONCE), authLastNonceEven.nonce, xsap->auth.NonceOdd.nonce, xsap->nonceEvenxSAP.nonce, xsap->nonceOddxSAP.nonce, unSealedDataLen, maskedData, unSealedData))) { free(maskedData); goto error; } free(maskedData); } else { if ((result = __tspi_add_mem_entry(tspContext, unSealedData))) goto error; } *pulUnsealedDataLength = unSealedDataLen; *prgbUnsealedData = unSealedData; error: authsess_free(xsap); if (data) free_tspi(tspContext, data); return result; }
TSS_RESULT Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID uuidData, /* in */ TSS_HKEY * phKey) /* out */ { TSS_RESULT result; TSS_UUID parentUUID; UINT32 keyBlobSize, parentPSType; BYTE *keyBlob = NULL; TCS_KEY_HANDLE tcsKeyHandle; TSS_HKEY parentTspHandle; TCS_LOADKEY_INFO info; UINT32 ulPubKeyLength; BYTE *rgbPubKey; if (phKey == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((!obj_is_context(tspContext))) return TSPERR(TSS_E_INVALID_HANDLE); /* This key is in the System Persistant storage */ if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { #if 1 memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { TSS_HKEY keyHandle; TSS_HPOLICY hPolicy; /* load failed, due to some key in the chain needing auth * which doesn't yet exist at the TCS level. However, the * auth may already be set in policies at the TSP level. * To find out, get the key handle of the key requiring * auth. First, look at the list of keys in memory. */ if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { /* If that failed, look on disk, in User PS. */ if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, &keyHandle)) return result; } if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, &hPolicy, NULL)) return result; if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE, &info.paramDigest, &info.authData)) return result; if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle))) return result; } else if (result) return result; /*check if provided UUID has an owner evict key UUID prefix */ if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) { if ((result = obj_rsakey_add(tspContext, TSS_RSAKEY_FLAG_OWNEREVICT, phKey))) return result; if ((result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle))) return result; //The cached public key portion of the owner evict key is used //further by TPM_KEY_CONTROLOWNER command for sanity check if ((result = Tspi_Key_GetPubKey(*phKey, &ulPubKeyLength, &rgbPubKey))) return result; result = obj_rsakey_set_pubkey(*phKey, FALSE, rgbPubKey); free(rgbPubKey); if (result != TSS_SUCCESS) return result; } else { if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, &keyBlob))) return result; if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { free (keyBlob); return result; } result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); free (keyBlob); } #else if ((result = load_from_system_ps(tspContext, &uuidData, phKey))) return result; #endif } else if (persistentStorageType == TSS_PS_TYPE_USER) { if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID))) return result; /* If the parent is not in memory, recursively call ourselves on it */ if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) { if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType))) return result; if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType, parentUUID, &parentTspHandle))) return result; } if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) return result; /* The parent is loaded and we have the parent key handle, so call the TCS to * actually load the child. */ return Tspi_Key_LoadKey(*phKey, parentTspHandle); } else { return TSPERR(TSS_E_BAD_PARAMETER); } return TSS_SUCCESS; }
TSS_RESULT Tspi_Data_Seal(TSS_HENCDATA hEncData, /* in */ TSS_HKEY hEncKey, /* in */ UINT32 ulDataLength, /* in */ BYTE * rgbDataToSeal, /* in */ TSS_HPCRS hPcrComposite) /* in */ { TPM_DIGEST digest; TSS_RESULT result; TSS_HPOLICY hPolicy, hEncPolicy; BYTE *encData = NULL; BYTE *pcrData = NULL; UINT32 encDataSize; UINT32 pcrDataSize; UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT; UINT32 sealOrdinal = TPM_ORD_Seal; TCS_KEY_HANDLE tcsKeyHandle; TSS_HCONTEXT tspContext; Trspi_HashCtx hashCtx; BYTE *sealData = NULL; struct authsess *xsap = NULL; #ifdef TSS_BUILD_SEALX UINT32 protectMode; #endif if (rgbDataToSeal == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext))) return result; if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE, &hPolicy, NULL))) return result; if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy))) return result; if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle))) return result; #ifdef TSS_BUILD_SEALX /* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute to determine the seal function to invoke */ if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode))) return result; if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) { sealOrdinal = TPM_ORD_Seal; pcrInfoType = 0; } else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) { sealOrdinal = TPM_ORD_Sealx; pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG; } else return TSPERR(TSS_E_INTERNAL_ERROR); #endif /* If PCR's are of interest */ pcrDataSize = 0; if (hPcrComposite) { if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize, &pcrData))) return result; } if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED, sealOrdinal, TPM_ET_KEYHANDLE, &xsap))) goto error; #ifdef TSS_BUILD_SEALX if (sealOrdinal == TPM_ORD_Seal) sealData = rgbDataToSeal; else { if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) { LogError("malloc of %u bytes failed", ulDataLength); result = TSPERR(TSS_E_OUTOFMEMORY); goto error; } if ((result = ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData, xsap->cb_sealx.alg, sizeof(TPM_NONCE), xsap->auth.NonceEven.nonce, xsap->auth.NonceOdd.nonce, xsap->nonceEvenxSAP.nonce, xsap->nonceOddxSAP.nonce, ulDataLength, rgbDataToSeal, sealData))) goto error; } #else sealData = rgbDataToSeal; #endif result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal); result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize); result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData); result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength); result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { goto error; } if ((result = authsess_xsap_hmac(xsap, &digest))) goto error; #ifdef TSS_BUILD_SEALX if (sealOrdinal == TPM_ORD_Seal) { if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse, pcrDataSize, pcrData, ulDataLength, sealData, xsap->pAuth, &encDataSize, &encData))) { goto error; } } else if (sealOrdinal == TPM_ORD_Sealx) { if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse, pcrDataSize, pcrData, ulDataLength, sealData, xsap->pAuth, &encDataSize, &encData))) { goto error; } } else { result = TSPERR(TSS_E_INTERNAL_ERROR); goto error; } #else if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse, pcrDataSize, pcrData, ulDataLength, sealData, xsap->pAuth, &encDataSize, &encData))) goto error; #endif result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); result |= Trspi_Hash_UINT32(&hashCtx, result); result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal); result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData); if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) goto error; if ((result = authsess_xsap_verify(xsap, &digest))) goto error; /* Need to set the object with the blob and the pcr's */ if ((result = obj_encdata_set_data(hEncData, encDataSize, encData))) goto error; if (pcrDataSize) result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData); error: authsess_free(xsap); free(encData); free(pcrData); if (sealData != rgbDataToSeal) free(sealData); return result; }
TSS_RESULT Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext, /* in */ TSS_FLAG persistentStorageType, /* in */ TSS_UUID * pUuidData, /* in */ UINT32 * pulKeyHierarchySize, /* out */ TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */ { TSS_RESULT result; TSS_KM_KEYINFO2 *tcsHier, *tspHier; UINT32 tcsHierSize, tspHierSize; TSS_UUID tcs_uuid; /* If out parameters are NULL, return error */ if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) return TSPERR(TSS_E_BAD_PARAMETER); if (!obj_is_context(tspContext)) return TSPERR(TSS_E_INVALID_HANDLE); if (pUuidData) { /* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of * TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key * hierarchy regarding that key. The first array entry is the key addressed by the * given UUID followed by its parent key up to and including the root key. */ if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, pulKeyHierarchySize, ppKeyHierarchy))) return result; } else if (persistentStorageType == TSS_PS_TYPE_USER) { if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize, &tspHier))) return result; /* The tcs_uuid returned by ps_get_registered_key2 will always be a parent * of some key into the system ps of a user key into the user ps. This key * needs to be searched for in the system ps to be merged */ if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize, &tcsHier))) { free(tspHier); return result; } result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize, tcsHier, pulKeyHierarchySize, ppKeyHierarchy); free(tcsHier); free(tspHier); } else return TSPERR(TSS_E_BAD_PARAMETER); } else { /* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures * contains data reflecting the entire key hierarchy starting with root key. The * array will include keys from both the user and the system TSS key store. The * persistentStorageType field will be ignored. */ if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize, &tcsHier))) return result; if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) { free(tcsHier); return result; } result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize, tcsHier, pulKeyHierarchySize, ppKeyHierarchy); free(tcsHier); free(tspHier); } if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { free(*ppKeyHierarchy); *ppKeyHierarchy = NULL; *pulKeyHierarchySize = 0; } return result; }
TSS_RESULT secret_PerformXOR_OSAP(TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, TSS_HPOLICY hMigrationPolicy, TSS_HOBJECT hOSAPObject, UINT16 osapType, UINT32 osapData, TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, BYTE *sharedSecret, TPM_AUTH * auth, TCPA_NONCE * nonceEvenOSAP) { TSS_BOOL bExpired; TCPA_SECRET keySecret; TCPA_SECRET usageSecret; TCPA_SECRET migSecret = { { 0, } }; UINT32 keyMode, usageMode, migMode = 0; TSS_RESULT result; TSS_HCONTEXT tspContext; if ((result = obj_policy_has_expired(hPolicy, &bExpired))) return result; if (bExpired == TRUE) return TSPERR(TSS_E_INVALID_OBJ_ACCESS); if ((result = obj_policy_has_expired(hUsagePolicy, &bExpired))) return result; if (bExpired == TRUE) return TSPERR(TSS_E_INVALID_OBJ_ACCESS); if (hMigrationPolicy) { if ((result = obj_policy_has_expired(hMigrationPolicy, &bExpired))) return result; if (bExpired == TRUE) return TSPERR(TSS_E_INVALID_OBJ_ACCESS); if ((result = obj_policy_get_mode(hMigrationPolicy, &migMode))) return result; } if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) return result; if ((result = obj_policy_get_mode(hPolicy, &keyMode))) return result; if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) return result; if (keyMode == TSS_SECRET_MODE_CALLBACK || usageMode == TSS_SECRET_MODE_CALLBACK || (hMigrationPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { if (keyMode != TSS_SECRET_MODE_CALLBACK || usageMode != TSS_SECRET_MODE_CALLBACK || (hMigrationPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) return TSPERR(TSS_E_BAD_PARAMETER); } if (keyMode != TSS_SECRET_MODE_CALLBACK) { if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, &keySecret))) return result; if ((result = obj_policy_get_secret(hUsagePolicy, TR_SECRET_CTX_NEW, &usageSecret))) return result; if (hMigrationPolicy) { if ((result = obj_policy_get_secret(hMigrationPolicy, TR_SECRET_CTX_NEW, &migSecret))) return result; } if ((result = OSAP_Calc(tspContext, osapType, osapData, keySecret.authdata, usageSecret.authdata, migSecret.authdata, encAuthUsage, encAuthMig, sharedSecret, auth))) return result; } else { /* If the secret mode is NONE here, we don't return an error. This is * because there are commands such as CreateKey, which require an auth * session even when creating no-auth keys. A secret of all 0's will be * used in this case. */ if ((result = TCS_API(tspContext)->OSAP(tspContext, osapType, osapData, &auth->NonceOdd, &auth->AuthHandle, &auth->NonceEven, nonceEvenOSAP))) return result; if ((result = obj_policy_do_xor(hPolicy, hOSAPObject, hPolicy, TRUE, 20, auth->NonceEven.nonce, NULL, nonceEvenOSAP->nonce, auth->NonceOdd.nonce, 20, encAuthUsage->authdata, encAuthMig->authdata))) { TCS_API(tspContext)->TerminateHandle(tspContext, auth->AuthHandle); return result; } } return TSS_SUCCESS; }
TSS_RESULT RPC_GetAuditDigest_TP(struct host_table_entry *hte, UINT32 startOrdinal, /* in */ TPM_DIGEST *auditDigest, /* out */ UINT32 *counterValueSize, /* out */ BYTE **counterValue, /* out */ TSS_BOOL *more, /* out */ UINT32 *ordSize, /* out */ UINT32 **ordList) /* out */ { TSS_RESULT result; initData(&hte->comm, 2); hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGEST; LogDebugFn("TCS Context: 0x%x", hte->tcsContext); if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); if (setData(TCSD_PACKET_TYPE_UINT32, 1, &startOrdinal, 0, &hte->comm)) return TSPERR(TSS_E_INTERNAL_ERROR); result = sendTCSDPacket(hte); if (result == TSS_SUCCESS) result = hte->comm.hdr.u.result; if (result == TSS_SUCCESS) { if (getData(TCSD_PACKET_TYPE_DIGEST, 0, auditDigest, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_UINT32, 1, counterValueSize, 0, &hte->comm)) { result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } *counterValue = (BYTE *)malloc(*counterValueSize); if (*counterValue == NULL) { LogError("malloc of %u bytes failed.", *counterValueSize); result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *counterValue, *counterValueSize, &hte->comm)) { free(*counterValue); *counterValue = NULL; result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_BOOL, 3, more, 0, &hte->comm)) { free(*counterValue); *counterValue = NULL; result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } if (getData(TCSD_PACKET_TYPE_UINT32, 4, ordSize, 0, &hte->comm)) { free(*counterValue); *counterValue = NULL; result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } *ordList = (UINT32 *)malloc(*ordSize * sizeof(UINT32)); if (*ordList == NULL) { LogError("malloc of %u bytes failed.", *ordSize); free(*counterValue); *counterValue = NULL; result = TSPERR(TSS_E_OUTOFMEMORY); goto done; } if (getData(TCSD_PACKET_TYPE_PBYTE, 5, *ordList, *ordSize * sizeof(UINT32), &hte->comm)) { free(*counterValue); *counterValue = NULL; free(*ordList); *ordList = NULL; result = TSPERR(TSS_E_INTERNAL_ERROR); goto done; } } done: return result; }
TSS_RESULT psfile_remove_key(int fd, TSS_UUID *uuid) { TSS_RESULT result; UINT32 head_offset = 0, tail_offset; int rc, size = 0; struct key_disk_cache c; BYTE buf[4096]; if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &c))) return result; /* head_offset is the offset the beginning of the key */ head_offset = TSSPS_UUID_OFFSET(&c); /* tail_offset is the offset the beginning of the next key */ tail_offset = TSSPS_VENDOR_DATA_OFFSET(&c) + c.vendor_data_size; rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* read in from tail, write out to head to fill the gap */ while ((rc = read(fd, buf, sizeof(buf))) > 0) { size = rc; tail_offset += size; /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* write the data */ if ((result = write_data(fd, (void *)buf, size))) { LogDebug("%s", __FUNCTION__); return result; } head_offset += size; /* set the file pointer to where we want to read in the next * loop */ rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } } if (rc < 0) { LogDebug("read: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* head_offset now contains a pointer to where we want to truncate the * file. Zero out the old tail end of the file and truncate it. */ memset(buf, 0, sizeof(buf)); /* Zero out the old tail end of the file */ if ((result = write_data(fd, (void *)buf, tail_offset - head_offset))) { LogDebug("%s", __FUNCTION__); return result; } if ((rc = ftruncate(fd, head_offset)) < 0) { LogDebug("ftruncate: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* we succeeded in removing a key from the disk. Decrement the number * of keys in the file */ if ((result = psfile_change_num_keys(fd, TSS_PSFILE_DECREMENT_NUM_KEYS))) return result; return TSS_SUCCESS; }