示例#1
0
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 );
}
示例#7
0
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;
}
示例#8
0
文件: xenquote.c 项目: banne01/xentpm
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(&quote_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;
}