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; }
int main_v1_1( void ) { char *function = "Tspi_PcrComposite_GetPcrValue03"; TSS_HCONTEXT hContext; TSS_HPCRS hPcrComposite; BYTE rgbPcrValueIn[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; BYTE *prgbPcrValueOut; UINT32 ulPcrValueLength; TSS_RESULT result; print_begin_test( function ); // Create Context result = Tspi_Context_Create( &hContext ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_Create", result ); print_error_exit( function, err_string(result) ); exit( result ); } // create object result = Tspi_Context_CreateObject( hContext, TSS_OBJECT_TYPE_PCRS, 0, &hPcrComposite ); if ( result != TSS_SUCCESS ) { print_error( "Tspi_Context_CreateObject (hPcrComposite)", result ); print_error_exit( function, err_string(result) ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( result ); } // get pcr value result = Tspi_PcrComposite_GetPcrValue( hPcrComposite, 0xffff, &ulPcrValueLength, &prgbPcrValueOut ); if ( TSS_ERROR_CODE(result) != TSS_E_BAD_PARAMETER ) { if( !(checkNonAPI(result)) ) { print_error( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } else { print_error_nonapi( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } } else { print_success( function, result ); } result = Tspi_PcrComposite_GetPcrValue( hPcrComposite, 8, NULL, &prgbPcrValueOut ); if ( TSS_ERROR_CODE(result) != TSS_E_BAD_PARAMETER ) { if( (TSS_ERROR_CODE(result) == TSS_E_INVALID_HANDLE) || (TSS_ERROR_CODE(result) == TSS_E_INTERNAL_ERROR) || (result == TSS_SUCCESS) || (TSS_ERROR_CODE(result) == TSS_E_FAIL) || (TSS_ERROR_CODE(result) == TSS_E_NOTIMPL) || (TSS_ERROR_CODE(result) == TSS_E_PS_KEY_NOTFOUND) || (TSS_ERROR_CODE(result) == TSS_E_KEY_ALREADY_REGISTERED) || (TSS_ERROR_CODE(result) == TSS_E_CANCELED) || (TSS_ERROR_CODE(result) == TSS_E_TIMEOUT) || (TSS_ERROR_CODE(result) == TSS_E_OUTOFMEMORY) || (TSS_ERROR_CODE(result) == TSS_E_TPM_UNEXPECTED) || (TSS_ERROR_CODE(result) == TSS_E_COMM_FAILURE) || (TSS_ERROR_CODE(result) == TSS_E_TPM_UNSUPPORTED_FEATURE) ) { print_error( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } else { print_error_nonapi( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } } else { print_success( function, result ); } result = Tspi_PcrComposite_GetPcrValue( hPcrComposite, 20, &ulPcrValueLength, NULL ); if ( TSS_ERROR_CODE(result) != TSS_E_BAD_PARAMETER ) { if( (TSS_ERROR_CODE(result) == TSS_E_INVALID_HANDLE) || (TSS_ERROR_CODE(result) == TSS_E_INTERNAL_ERROR) || (result == TSS_SUCCESS) || (TSS_ERROR_CODE(result) == TSS_E_FAIL) || (TSS_ERROR_CODE(result) == TSS_E_NOTIMPL) || (TSS_ERROR_CODE(result) == TSS_E_PS_KEY_NOTFOUND) || (TSS_ERROR_CODE(result) == TSS_E_KEY_ALREADY_REGISTERED) || (TSS_ERROR_CODE(result) == TSS_E_CANCELED) || (TSS_ERROR_CODE(result) == TSS_E_TIMEOUT) || (TSS_ERROR_CODE(result) == TSS_E_OUTOFMEMORY) || (TSS_ERROR_CODE(result) == TSS_E_TPM_UNEXPECTED) || (TSS_ERROR_CODE(result) == TSS_E_COMM_FAILURE) || (TSS_ERROR_CODE(result) == TSS_E_TPM_UNSUPPORTED_FEATURE) ) { print_error( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } else { print_error_nonapi( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit(result); } } else { print_success( function, result ); print_end_test( function ); Tspi_Context_FreeMemory( hContext, NULL ); Tspi_Context_Close( hContext ); exit( 0 ); } }