Analyze the Error Code
The first step when you get an error is decoding the error code. This decoding is described in the “Response Code Details” section of Part 1 of the TPM 2.0 specification. The “Response Code Evaluation” flowchart in that section is particularly helpful.
The first example error involves the TPM2_Startup command. The following code snippet generates an error (this is a slight modification of the TPM2_Startup test described in Chapter 7:
rval = Tss2_Sys_Startup( sysContext, 03 ) ; CheckPassed(rval);
The call to CheckPassed fails because an error code of 0x000001c4 was returned instead of 0 (TPM2_RC_SUCCESS). Following the flowchart mentioned previously, you can decode this error as follows:
Bit 8: 1
Bit 7: 1
Bit 6: 1
These bits indicate that the error code is in bits 5:0 and the parameter number is in bits 11:8. So, parameter #1 is bad, and the specific error is TPM_RC_VALUE from the “TPM_
RC Values” section of Part 1 of the TPM 2.0 specification. The text description for this error is, “value is out of range or isn't correct for the context.” This means parameter #1 was bad for this command. In looking at the description of the TPM2_Startup command, it's easy to see that the only values allowed for this parameter are TPM_SU_CLEAR(0x0000) and TPM_SU_STATE (0x0001). Obviously, using 0x3 for the parameter is the source of our error.
We strongly encourage the use of a tool for decoding e rrors, because hand-decoding errors can become burdensome for repeated debug sessions. Sample output of such a tool looks like this:
>tpm2decoderring /e 1c4
ERROR: PARAM #1, TPM_RC_VALUE: value is out of range or is not correct for the context
Debug Trace Analysis
Quite often, due to lack of TPM knowledge or, in some cases, obscurity of the error, error-code analysis is insufficient. Additionally, if a program was previously working, a comparison to the output from the previously working program can highlight the error much more quickly. For this reason, we highly recommend instrumenting the TPM device driver with code that displays the command bytes sent to the TPM and the response bytes received from the TPM. This feature has saved many weeks of debugging time over the past two years of TPM 2.0 development work.
In the case of the previous program, the trace dump from the command from a good program looks like this:
Cmd sent: TPM2_Startup Locality = 3
80 01 00 00 00 0c 00 00 01 44 00 00
80 01 00 00 00 0a 00 00 00 00
passing case: PASSED!
The trace dump from the bad program, with the differences highlighted, looks like this:
cmd sent: TPM2_Startup Locality = 3
80 01 00 00 00 0c 00 00 01 44 00 03
80 01 00 00 00 0a 00 00 01 c4
passing case: FAILED! TPM Error -TPM Error: 0x1c4
Use of a good compare utility quickly highlights the bad value, 00 03, in the bad command.
One caveat in this method is that much of the TPM output is randomized, and often these randomized outputs are fed back as inputs to other commands. This means these randomized parts of your trace data need to be ignored when you visually compare output. Experience will help you quickly learn which areas to ignore and which differences to focus on. It's not nearly as hard as it sounds.
Another good way to use trace dumps is when comparing multiple traces coming from different layers in the stack. For instance, you might have a trace dump from the ESAPI layer, one from the driver layer, and maybe even one from the TPM simulator. It can be challenging to synchronize these trace dumps. Session nonces, because they are random, unique, and the same no matter where in the stack they appear, can be used to synchronize these trace dumps. Find a nonce being returned in a session in one trace dump, and then search for where that same nonce is returned in the other trace dumps.
-  Experienced programmers will immediately notice the use of a “magic” number in this line of code. There is no constant defined in the TPM specification for a bad parameter to the startup command. Although not generally a good programming practice, in this case hardcoding the number seems better than defining a special value for use here.
-  2In some cases, the error code may indicate a parameter, session, or handle number of 0. This indicates an error with a parameter, session, or handle, but the TPM isn't giving any indication of which one.
-  This is the output from an Intel internal tool. This tool hasn't been released publicly, but development of such a tool for public use is strongly encouraged