Beispiel #1
0
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;
}
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 );
	}

}