int get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap, UINT32 subcap, void *buf, size_t bufsize) { TSS_RESULT ret; UINT32 datalen; BYTE *data; ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap), (BYTE *)&subcap, &datalen, &data); if (ret) { print_error(ret, gettext("Get TPM capability")); return (ERR_FAIL); } if (datalen > bufsize) { (void) fprintf(stderr, gettext("Capability 0x%x returned %u bytes " "(expected %u)\n"), cap, datalen, bufsize); return (ERR_FAIL); } bcopy(data, buf, datalen); ret = Tspi_Context_FreeMemory(hContext, data); if (ret) { print_error(ret, gettext("Free capability buffer")); return (ERR_FAIL); } return (0); }
int main_v1_2( char version ) { char *function = "Tspi_TPM_GetCapability16"; UINT32 pulRespDataLength; BYTE *pRetData; UINT32 subCap, subCapLength, numPcrs; TSS_HCONTEXT hContext; TSS_HTPM hTPM; TSS_RESULT result; UINT32 exitCode; print_begin_test( function ); // Create Context result = Tspi_Context_Create( &hContext ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Create", result ); exit( result ); } // Connect to Context result = Tspi_Context_Connect( hContext, get_server(GLOBALSERVER) ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Connect", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } // Retrieve TPM object of context result = Tspi_Context_GetTpmObject( hContext, &hTPM ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_GetTpmObject", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } subCap = TSS_TPMCAP_PROP_TRANSESSIONS; subCapLength = sizeof(UINT32); result = Tspi_TPM_GetCapability( hTPM, TSS_TPMCAP_PROPERTY, subCapLength, (BYTE *)&subCap, &pulRespDataLength, &pRetData ); if ( result != TSS_SUCCESS ) { if( !(checkNonAPI(result)) ) { print_error( function, result ); exitCode = 1; } else { print_error_nonapi( function, result ); exitCode = 1; } } else { print_success( function, result ); exitCode = 0; if (pulRespDataLength == sizeof(UINT32)) fprintf(stderr, "\tThere are %u available transport sessions in this TPM\n\n", *(UINT32 *)pRetData ); } print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( exitCode ); }
int main_v1_2(char version) { char *function = "Tspi_TPM_GetCapability-trans01"; UINT32 pulRespDataLength; BYTE *pNumPCRs; UINT32 subCap, subCapLength, numPcrs; TSS_HCONTEXT hContext; TSS_HTPM hTPM; TSS_RESULT result; TSS_HKEY hSRK, hSigningKey, hWrappingKey; print_begin_test( function ); result = connect_load_all(&hContext, &hSRK, &hTPM); if ( result != TSS_SUCCESS ) { print_error( "connect_load_all", (result) ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, &hSigningKey); if (result != TSS_SUCCESS) { print_error("Testsuite_Transport_Init", result); Tspi_Context_Close(hContext); exit(result); } subCap = TSS_TPMCAP_PROP_PCR; subCapLength = sizeof(UINT32); result = Tspi_TPM_GetCapability( hTPM, TSS_TPMCAP_PROPERTY, subCapLength, (BYTE *)&subCap, &pulRespDataLength, &pNumPCRs ); if (result != TSS_SUCCESS) { print_error("Tspi_TPM_GetCapability", result); Tspi_Context_Close(hContext); exit(result); } result = Testsuite_Transport_Final(hContext, hSigningKey); if ( result != TSS_SUCCESS ) { if( !(checkNonAPI(result)) ) { print_error( function, result ); } else { print_error_nonapi( function, result ); } } else { print_success( function, result ); } fprintf(stderr, "\tThere are %u PCRs supported by this TPM\n", *(UINT32 *)pNumPCRs ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); }
int main(int argc, char **argv) { TSS_HKEY hKey, hSRK; TSS_HCONTEXT hContext; TSS_HTPM hTPM; TSS_RESULT result; TSS_HPOLICY hPolicy; TSS_HPCRS hPcrs; UINT32 ulPcrValueLength, subCap, subCapLength; UINT32 pulRespDataLength, numPcrs; BYTE *pNumPcrs, *rgbPcrValue, *uuidString, *pcrsSelectedValues[24]; int i, c, *pcrsSelected = NULL, numPcrsSelected = 0; TSS_UUID *uuid; BYTE wellknown[] = TSS_WELL_KNOWN_SECRET; while (1) { c = getopt(argc, argv, "p:"); if (c == -1) break; switch (c) { case 'p': numPcrsSelected++; pcrsSelected = realloc(pcrsSelected, (sizeof(int) * numPcrsSelected)); if (pcrsSelected == NULL) { PRINT_ERR("Malloc of %zd bytes failed.", (sizeof(int) * numPcrsSelected)); return -1; } pcrsSelected[numPcrsSelected - 1] = atoi(optarg); break; default: usage(argv[0]); break; } } if (numPcrsSelected == 0) printf("Warning: Key will not be bound to any PCR's!\n"); if (numPcrsSelected > 24) { PRINT_ERR("Too many PCRs selected! Exiting."); return -EINVAL; } result = Tspi_Context_Create(&hContext); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_Create", result); return result; } result = Tspi_Context_Connect(hContext, NULL); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_Connect", result); Tspi_Context_Close(hContext); return result; } result = Tspi_Context_GetTpmObject(hContext, &hTPM); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_GetTpmObject", result); Tspi_Context_Close(hContext); return result; } subCap = TSS_TPMCAP_PROP_PCR; subCapLength = sizeof(UINT32); result = Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_PROPERTY, subCapLength, (BYTE *)&subCap, &pulRespDataLength, &pNumPcrs ); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_TPM_GetCapability", result); Tspi_Context_Close(hContext); return result; } numPcrs = *(UINT32 *)pNumPcrs; for (i = 0; i < (int)numPcrsSelected; i++) { if (pcrsSelected[i] > (int)numPcrs) { fprintf(stderr, "%d: invalid PCR register. PCRs range " "from 0 - %u\n", pcrsSelected[i], numPcrs); return -1; } } result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS, 0, &hPcrs); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_CreateObject", result); return result; } for (i = 0; i < numPcrsSelected; i++) { result = Tspi_TPM_PcrRead(hTPM, pcrsSelected[i], &ulPcrValueLength, &rgbPcrValue); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_TPM_PcrRead", result); Tspi_Context_Close(hContext); return result; } result = Tspi_PcrComposite_SetPcrValue(hPcrs, pcrsSelected[i], ulPcrValueLength, rgbPcrValue); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_PcrComposite_SetPcrValue", result ); Tspi_Context_Close( hContext ); return result; } pcrsSelectedValues[i] = rgbPcrValue; } result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_LoadKeyByUUID", result); Tspi_Context_Close(hContext); return result; } result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hPolicy); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_GetPolicyObject", result); Tspi_Context_Close(hContext); return result; } result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, sizeof(wellknown), wellknown); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_GetPolicyObject", result); Tspi_Context_Close(hContext); return result; } result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, (TSS_KEY_TYPE_STORAGE | TSS_KEY_SIZE_2048 | TSS_KEY_VOLATILE | TSS_KEY_NO_AUTHORIZATION | TSS_KEY_NOT_MIGRATABLE), &hKey); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_CreateObject", result); Tspi_Context_Close(hContext); return result; } result = Tspi_Key_CreateKey(hKey, hSRK, hPcrs); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Key_CreateKey", result); Tspi_Context_Close(hContext); return result; } result = Tspi_TPM_GetRandom(hTPM, (UINT32)16, (BYTE **)&uuid); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_TPM_GetRandom", result); Tspi_Context_Close(hContext); return result; } result = Tspi_Context_RegisterKey(hContext, hKey, TSS_PS_TYPE_USER, *uuid, TSS_PS_TYPE_SYSTEM, SRK_UUID); if (result != TSS_SUCCESS) { PRINT_TSS_ERR("Tspi_Context_RegisterKey", result); Tspi_Context_Close(hContext); return result; } printf("Success: Key created bound to:\n"); for (i = 0; i < numPcrsSelected; i++) { uuidString = (unsigned char *) util_bytes_to_string((char *) pcrsSelectedValues[i], 20); if (uuidString == NULL) { PRINT_ERR("malloc of 41 bytes failed"); Tspi_Context_Close(hContext); return result; } printf("PCR %d: %s\n", pcrsSelected[i], uuidString); free(uuidString); Tspi_Context_FreeMemory(hContext, pcrsSelectedValues[i]); } uuidString = (BYTE *)util_bytes_to_string((char *)uuid, 16); if (uuidString == NULL) { PRINT_ERR("malloc of 33 bytes failed"); Tspi_Context_Close(hContext); return result; } printf("And registered in persistent storage with UUID " "(tspi_uuid parameter): %s\n", uuidString); Tspi_Context_FreeMemory(hContext, (BYTE *)uuid); free(uuidString); Tspi_Context_Close(hContext); return 0; }
int main_v1_1( void ) { char *function = "Tspi_TPM_GetCapability02"; UINT32 pulRespDataLength; BYTE *pNumPCRs; UINT32 subCap; UINT32 subCapLength, exitCode = 0; TSS_HCONTEXT hContext; TSS_HTPM hTPM; TSS_RESULT result; print_begin_test( function ); // Create Context result = Tspi_Context_Create( &hContext ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Create", result ); exit( result ); } // Connect to Context result = Tspi_Context_Connect( hContext, get_server(GLOBALSERVER) ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Connect", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } // Retrieve TPM object of context result = Tspi_Context_GetTpmObject( hContext, &hTPM ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_GetTpmObject", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } subCap = TSS_TPMCAP_PROP_PCR; subCapLength = sizeof(UINT32); //Get random number result = Tspi_TPM_GetCapability( hTPM, TSS_TPMCAP_PROPERTY, subCapLength, (BYTE *)&subCap, NULL, &pNumPCRs ); if ( TSS_ERROR_CODE(result) != TSS_E_BAD_PARAMETER ) { if( !(checkNonAPI(result)) ) { print_error( function, result ); } else { print_error_nonapi( function, result ); } exitCode = result; } else { print_success( function, result ); } print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( exitCode ); }
int main_v1_1( void ) { char *function = "Tspi_TPM_GetCapability01"; UINT32 pulRespDataLength; BYTE *pNumPCRs; UINT32 subCap, subCapLength, numPcrs; TSS_HCONTEXT hContext; TSS_HTPM hTPM; TSS_RESULT result; print_begin_test( function ); // Create Context result = Tspi_Context_Create( &hContext ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Create", result ); exit( result ); } // Connect to Context result = Tspi_Context_Connect( hContext, get_server(GLOBALSERVER) ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Connect", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } // Retrieve TPM object of context result = Tspi_Context_GetTpmObject( hContext, &hTPM ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_GetTpmObject", result ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } subCap = TSS_TPMCAP_PROP_PCR; subCapLength = sizeof(UINT32); result = Tspi_TPM_GetCapability( hTPM, TSS_TPMCAP_PROPERTY, subCapLength, (BYTE *)&subCap, &pulRespDataLength, &pNumPCRs ); if ( result != TSS_SUCCESS ) { if( !(checkNonAPI(result)) ) { print_error( function, result ); } else { print_error_nonapi( function, result ); } } else { print_success( function, result ); } fprintf(stderr, "\tThere are %u PCRs supported by this TPM\n", *(UINT32 *)pNumPCRs ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); }
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; }
int tpm_quote(char * b64_nonce) { TSS_HCONTEXT tpm_context; TSS_HTPM tpm_handle; TSS_HKEY srk_handle; TSS_HKEY aik_handle; TSS_HPOLICY srk_policy; TSS_HPOLICY tpm_policy; TSS_HPCRS pcr_handle; TSS_VALIDATION valid; /* quote validation structure */ UINT32 pcr_property; UINT32 max_pcr; BYTE* pcr_mask ; UINT32 mask_size; BYTE* quote_buf; UINT32 quote_buf_len; BYTE* marker; BYTE* api_buf; UINT32 api_buf_len; BYTE nonce_hash[SHA_DIGEST_LENGTH]; int i; int result; int alloc_size; syslog(LOG_ERR, "Request for TPM quote generation for nonce %s \n", b64_nonce); result = take_ownership(); if (result) { syslog(LOG_ERR, "tpm_quote Error 0x%X taking ownership of TPM.\n", result); goto out; } if ((result = tpm_create_context(&tpm_context, &tpm_handle, &srk_handle, &tpm_policy, &srk_policy)) != TSS_SUCCESS) { syslog(LOG_ERR, "Error in aik context for generating aik_pem"); goto out; } if ((result = get_nonce_sha1(b64_nonce, nonce_hash, tpm_context)) != TSS_SUCCESS) { syslog(LOG_ERR, "Unable to b64 decode nonce \n"); goto free_context; } if ((result = load_aik_tpm(tpm_context, srk_handle, &aik_handle)) != TSS_SUCCESS) { syslog(LOG_ERR, "xenquote Unable to load citrix aik"); goto free_context; } /* Create PCR list to be quoted * We will quote all the PCR's */ pcr_property = TSS_TPMCAP_PROP_PCR; if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY, sizeof(pcr_property), (BYTE *)&pcr_property, &api_buf_len, &api_buf)) != TSS_SUCCESS) { syslog(LOG_ERR, "Tspi_TPM_GetCapability failed with 0x%X %s", result, Trspi_Error_String(result)); goto free_context; } max_pcr = *(UINT32 *)api_buf; Tspi_Context_FreeMemory(tpm_context, api_buf); mask_size = ROUNDUP_BYTE(max_pcr); /* number of bytes for PCR MASK */ if ((result = Tspi_Context_CreateObject(tpm_context, TSS_OBJECT_TYPE_PCRS, TSS_PCRS_STRUCT_INFO, &pcr_handle)) != TSS_SUCCESS) { syslog(LOG_ERR, "Tspi_Context_CreateObject(PCR) failed with 0x%X %s", result, Trspi_Error_String(result)); goto free_context; } /* Allocate buffer for SelectMASK + Quotedata * Also select all the availble PCRS * //return to caller following buffer * 1)uit16 PCRSelectMAskSize //2 byets * 2)BYTE* PCRSelectMask // which pcrs selected (all) * 3)uint32 QuoteSize // Quotes * 4)BYTE *Quote (PCR Quote readable in Text) */ alloc_size = sizeof(UINT16) + mask_size + sizeof(UINT32) + PCR_QUOTE_LEN * max_pcr; quote_buf = (BYTE*)malloc(alloc_size); if (!quote_buf) { syslog(LOG_ERR, "Unable to allocate memory %d , %s and %d \n", alloc_size, __FILE__, __LINE__); result = XENTPM_E_INTERNAL; goto free_quote; } *(UINT16 *)quote_buf = htons(mask_size); /* set num of PCRS */ pcr_mask = quote_buf + sizeof(UINT16); /* mask init */ memset(pcr_mask, 0, mask_size); for (i = 0;i < max_pcr; i++) { result = Tspi_PcrComposite_SelectPcrIndex(pcr_handle, i); if (result != TSS_SUCCESS) { syslog(LOG_ERR, "Tspi_PcrComposite_SelectPcrIndex failed with 0x%X %s", result, Trspi_Error_String(result)); goto free_quote; } SET_BIT(pcr_mask, i); } /* Create TSS_VALIDATION struct for Quote typedef struct tdTSS_VALIDATION { TSS_VERSION versionInfo; UINT32 ulExternalDataLength; //nonce len BYTE* rgbExternalData; // nonce data UINT32 ulDataLength; //sizeof quote_info BYTE* rgbData; //tpm_quote_info UINT32 ulValidationDataLength; BYTE* rgbValidationData; // signature of the quote_info_structure } TSS_VALIDATION; */ /* TPM_QUOTE_INFO structure IDL Definition typedef struct tdTPM_QUOTE_INFO { TPM_STRUCT_VER version; BYTE fixed[4]; TPM_COMPOSITE_HASH digestValue; // sha1 of pcr_maskSize,pcr_mask,quotelen,quoteData TPM_NONCE externalData, } TPM_QUOTE_INFO; Following details from TPM SPEC 1.2 TPM_STRUCT_VER version This MUST be 1.1.0.0 BYTE fixed This SHALL always be the string ‘QUOT’ TPM_COMPOSITE_HASH digestValue This SHALL be the result of i the composite hash algorithm using the current values of the requested PCR indices. TPM_NONCE externalData 160 bits of externally supplied data */ valid.ulExternalDataLength = sizeof(nonce_hash); valid.rgbExternalData = nonce_hash; /* Perform Quote */ result = Tspi_TPM_Quote(tpm_handle, aik_handle, pcr_handle, &valid); if (result != TSS_SUCCESS) { syslog(LOG_ERR, "Tspi_TPM_Quote failed with 0x%X %s", result, Trspi_Error_String(result)); goto free_quote; } /* Fill in the PCR buffer */ marker = quote_buf + sizeof(UINT16) + mask_size; /* no of PCRs */ *(UINT32 *)marker = htonl(PCR_QUOTE_LEN*max_pcr); /* set the quote size */ marker += sizeof(UINT32); for (i = 0;i < max_pcr; i++) { result = Tspi_PcrComposite_GetPcrValue(pcr_handle, i, &api_buf_len, &api_buf); if (result != TSS_SUCCESS) { syslog(LOG_ERR, "Tspi_PcrComposite_GetPcrValue failed with 0x%X %s", result, Trspi_Error_String(result)); goto free_quote; } memcpy (marker, api_buf, api_buf_len); /* individual PCR quote*/ marker += api_buf_len; } /* Appned on the rgbValidationData (quote info singature) * onto the end of the quote buffer */ quote_buf_len = marker - quote_buf; alloc_size = quote_buf_len + valid.ulValidationDataLength; quote_buf = realloc(quote_buf, alloc_size); if (!quote_buf) { syslog(LOG_ERR, "Unable to realloc memory for size %d at %s and %d \n", alloc_size, __FILE__, __LINE__); result = XENTPM_E_INTERNAL; goto free_context; } memcpy("e_buf[quote_buf_len], valid.rgbValidationData, valid.ulValidationDataLength); quote_buf_len += valid.ulValidationDataLength; if ((result = print_base64(quote_buf, quote_buf_len)) != 0) { syslog(LOG_ERR, "Error in converting B64 %s and %d ", __FILE__, __LINE__); result = XENTPM_E_INTERNAL; goto free_quote; } syslog(LOG_INFO, "Generate TPM Quote Success!\n"); free_quote: free(quote_buf); free_context: Tspi_Context_CloseObject(tpm_context, srk_policy); tpm_free_context(tpm_context, tpm_policy); out: return result; }