From: Hal F. <hal...@gm...> - 2009-12-08 18:54:58
|
Hi Hardeep - Actually you mean that you will use the public identity key to *verify the signature* of data in ValidationData. Let me explain this in more detail. I wrote a long message about this a few days ago but I will focus on this one issue. Tspi_TPM_Quote() takes a TSS_VALIDATION structure which has one input buffer and two output buffers. The input buffer is rgbExternalData and is "external data" that you supply to be signed, which should be 20 bytes long. The output buffers are rgbData and rgbValidationData. rgbData is a TPM_QUOTE_INFO struct which gets signed. rgbValidationData is the RSA signature over the rgbData buffer. In addition, the TSS_HPCRS object gets updated on return to hold the PCR values that were signed. So to verify the signature, the first thing you do is to hash the rgbData value, and then use an RSA library to check that rgbValidationData is a valid signature on the rgbData hash, using the public identity key. You can perform this step without hashing any PCRs; it is self-contained based on the return values from the Quote call. But you need to do more, and that is what you are asking about. The next step is that you need to verify that the hash of the PCRs matches the field compositeHash in TPM_QUOTE_INFO. You are asking how to hash the PCRs. What you do is to create a TPM_PCR_COMPOSITE structure holding the PCR values, and hash that. However it has to be formatted in a special way. If you look at tpm.h in the include/tss subdirectory (which also defines TPM_QUOTE_INFO), you will see the following structure definitions: typedef struct tdTPM_PCR_SELECTION /* 1.1b */ { UINT16 sizeOfSelect; SIZEIS(sizeOfSelect) BYTE *pcrSelect; } TPM_PCR_SELECTION; typedef struct tdTPM_PCR_COMPOSITE /* 1.1b */ { TPM_PCR_SELECTION select; UINT32 valueSize; SIZEIS(valueSize) TPM_PCRVALUE *pcrValue; } TPM_PCR_COMPOSITE; The second one, TPM_PCR_COMPOSITE, is what you want to hash, but note that it includes TPM_PCR_SELECTION, the first one. Now you have to format these in a special way. Note the fields pcrSelect and pcrValue - they are pointers. Instead, you need to format them as in-line byte arrays. They are preceded by fields which hold the length in bytes of these arrays. pcrSelect is supposed to be a bit map of which PCRs are being used in the Quote. The LSB of the 1st byte is PCR 0; the MSB of the 1st byte is PCR 7; the LSB of the 2nd byte is PCR 8, and so on. The length should be enough to hold all the PCRs supported by the TPM. Normally that will be 3 bytes with a modern TPM (corresponding to 24 PCRs). Therefore sizeOfSelect should be 3. pcrValue holds the actual PCR values being signed, 20 bytes each, one after another, concatenated. So its length will be 20 times the number of PCRs that are being signed, and that is what should be stored in valueSize. Putting this together, set up a data structure in memory that starts with 2 bytes of sizeOfSelect. This should hold the value 3. NOTE THAT IT IS IN BIG_ENDIAN FORM. The 1st byte is 0 and the 2nd byte is 3. Then comes 3 bytes of the bit map for which PCRs are signed, as I explained earlier. Then comes 4 bytes of valueSize, which again should be 20 times the number of PCRs being signed, AGAIN IN BIG-ENDIAN FORM. Finally come the actual PCR values, 20 bytes each. The total length of this will be 2 + 3 + 4 + 20*nPCRs. Hash this buffer and compare with the compositeHash field of TPM_QUOTE_INFO (ie. rgbData). If they match, you know that these are the set of PCRs which are signed. Now here is a special note, which is how to read the PCR values. Rather than reading them from the TPM, it is better to read them from the HPCRS object that you passed to Tspi_TPM_Quote(). When the PCRs are signed, their values are stored in this object. You can read the signed values using Tspi_PcrComposite_GetPcrValue() on the HPCRS object, for each PCR that was signed. Then these get stored in the data structure I described above. This is a more reliable way to read the correct PCR values. Well, this is probably more complicated than you expected, but that is the general rule when dealing with the TPM. Get used to it! I will be glad to answer more questions if you have them. Hal Finney On Mon, Dec 7, 2009 at 11:10 PM, Hardeep Uppal <har...@cs...> wrote: > Ok. So I can use the public identy key to decrypt data in > ValidationData.rgbValidationData but it will not match the current set of > pcr values that are in the tpm since the signed pcr values were hashed > before getting signed. This means that I need to look up the current pcr > values in the tpm, do SHA-1 hash of each value and then compare that with > the decrypted data in ValidationData.rgbValidationData to check if the pcr > values getting signed are same as the pcr values in the tpm. Does that sound > correct? > > --Hardeep > > On Mon, Dec 7, 2009 at 10:47 PM, adrian golding <adr...@gm...> > wrote: >> >> hi, >> yeah, the ValidationData.rgbValidationData holds the hashed then signed >> pcr values. >> ValidationData.rgbExternalData holds the nonce i think. >> ValidationData.rgbData is another struct that holds things such as >> version, fixed bytes of "QUOT", the nonce (rgbExternalData) and the hash of >> your PCR(s). note that the PCRs contained in the hash is never in plain. >> i think you can just put in some known value as the nonce and create a >> quote to check if the above is correct. hope that helps! =] >> regards - adrian >> >> >> >> On Tue, Dec 8, 2009 at 2:15 PM, Hardeep Uppal <har...@cs...> >> wrote: >>> >>> Hi Adrian, >>> >>> Thanks for the reply. One thing I read on a forum was that the tpm will >>> hash the current pcr values and then sign the hashed pcr value with a key. >>> Is that true? Also which byte array holds the sign pcr values? Can you give >>> me a description of what each byte array means. >>> >>> --Hardeep >>> >>> On Mon, Dec 7, 2009 at 10:02 PM, adrian golding <adr...@gm...> >>> wrote: >>>> >>>> hi, >>>> >>>> typedef struct tdTSS_VALIDATION >>>> { >>>> TSS_VERSION versionInfo; >>>> UINT32 ulExternalDataLength; >>>> #ifdef __midl >>>> [size_is(ulExternalDataLength)] >>>> #endif >>>> BYTE* rgbExternalData; >>>> UINT32 ulDataLength; >>>> #ifdef __midl >>>> [size_is(ulDataLength)] >>>> #endif >>>> BYTE* rgbData; >>>> UINT32 ulValidationDataLength; >>>> #ifdef __midl >>>> [size_is(ulValidationDataLength)] >>>> #endif >>>> BYTE* rgbValidationData; >>>> } TSS_VALIDATION; >>>> >>>> its in ~/src/includes/tss/tss_structs.h >>>> >>>> regards - adrian >>> >> > > > ------------------------------------------------------------------------------ > Return on Information: > Google Enterprise Search pays you back > Get the facts. > http://p.sf.net/sfu/google-dev2dev > > _______________________________________________ > TrouSerS-users mailing list > Tro...@li... > https://lists.sourceforge.net/lists/listinfo/trousers-users > > |