Search code examples
tpmtrusted-computing

Why do I get nonstandard responses from the TPM Through TBS?


I have a C++ program to do a basic TPM_GetCapabilities Through TPM Base Services and the Windows 7 SDK.

I've setup the program below

int _tmain(int argc, _TCHAR* argv[])
{       
    TBS_CONTEXT_PARAMS    pContextParams;
    TBS_HCONTEXT        hContext;
    TBS_RESULT            rv;
    pContextParams.version = TBS_CONTEXT_VERSION_ONE;
    rv = Tbsi_Context_Create(&pContextParams, &hContext);
    printf("\n1 RESULT : %x  STATUS : %x", rv, hContext);   
    BYTE data[200] =   
       {0,0xc1,     /* TPM_TAG_RQU_COMMAND */
        0,0,0,18,  /* blob length, bytes */
        0,0,0,0x65, /* TPM_ORD_GetCapability */
        0,0,0,0x06,   /* TPM_CAP_VERSION */
        0,0,0,0}; /* 0 bytes subcap */


    BYTE buf[4000];
    UINT32 len = 4000;    

    rv = Tbsip_Submit_Command(hContext,0,TBS_COMMAND_PRIORITY_NORMAL,data,18,buf,&len); 
    //CAPABILITY_RETURN* retVal = new CAPABILITY_RETURN(buf);
    //printf("\n2 Response Tag: %x Output Bytes: %x",tag,);
    printf("\n2 RESULT : %x  STATUS : %x\n", rv, hContext);
    printBuf(buf,len);  
    rv = Tbsip_Context_Close(hContext);
    printf("\n3 RESULT : %x  STATUS : %x", rv, hContext);

My Return Buffer looks like:

00:C4:00:00:00:12:00:00:00:00:00:00:00:04:01:01:00:00

According to this doc, Section 7.1 TPM_GetCapability I should get the following: enter image description here

Looking at my output buffer, I am getting TPM_TAG_RSP_COMMAND,a value of 18 for my paramSize, 0 for my TPM_RESULT, 0x...04 for ordinal (Not sure what this is supposed to mean.) then 1,1,0,0 for my final bits. I'm at a loss as to how to decipher this.


Solution

  • The answer to your question:

    You don't get a nonstandard response.

    1. The response is perfectly fine, there is nothing nonstandard in it. It looks exactly like it is defined in the spec.
    2. The response' content resp you get is also what is to be expected. A Standard conform TPM has to answer with 01 01 00 00 when asked for TPM_CAP_VERSION.

    Why?

    First of all: The line stating TPM_COMMAND_CODE ordinal is not part of the response. It has no PARAM # and no PARAM SZ. It is only relevant for calculating the HMAC of the response.

    So the response is the following:

    00 C4          tag
    00 00 00 12    paramSize
    00 00 00 00    returnCode
    00 00 00 04    respSize
    01 01 00 00    resp
    

    You asked for the capability TPM_CAP_VERSION. Here is what the spec says:

    Value:             0x00000006
    Capability Name:   TPM_CAP_VERSION
    Sub cap:           Ignored
    
    TPM_STRUCT_VER structure.
    The major and minor version MUST indicate 1.1.
    The firmware revision MUST indicate 0.0.
    
    The use of this value is deprecated, new software SHOULD
    use TPM_CAP_VERSION_VAL to obtain version and revision information
    regarding the TPM.
    

    So when you decode resp, which is a TPM_STRUCT_VER, you get the following:

    typedef struct tdTPM_STRUCT_VER {
        BYTE major;      // ==> 1
        BYTE minor;      // ==> 1
        BYTE revMajor;   // ==> 0
        BYTE revMinor;   // ==> 0
    } TPM_STRUCT_VER;
    

    So 1.1 and 0.0, exactly according to specification.