1 // This file was extracted from the TCG Published
2 // Trusted Platform Module Library
3 // Part 3: Commands
4 // Family "2.0"
5 // Level 00 Revision 01.16
6 // October 30, 2014
7 
8 #include "InternalRoutines.h"
9 #include "PCR_Extend_fp.h"
10 //
11 //
12 //     Error Returns                     Meaning
13 //
14 //     TPM_RC_LOCALITY                   current command locality is not allowed to extend the PCR
15 //                                       referenced by pcrHandle
16 //
17 TPM_RC
TPM2_PCR_Extend(PCR_Extend_In * in)18 TPM2_PCR_Extend(
19    PCR_Extend_In     *in                 // IN: input parameter list
20    )
21 {
22    TPM_RC                  result;
23    UINT32                  i;
24 
25 // Input Validation
26 
27    //   NOTE: This function assumes that the unmarshaling function for 'digests' will
28    //   have validated that all of the indicated hash algorithms are valid. If the
29    //   hash algorithms are correct, the unmarshaling code will unmarshal a digest
30    //   of the size indicated by the hash algorithm. If the overall size is not
31    //   consistent, the unmarshaling code will run out of input data or have input
32    //   data left over. In either case, it will cause an unmarshaling error and this
33    //   function will not be called.
34 
35    // For NULL handle, do nothing and return success
36    if(in->pcrHandle == TPM_RH_NULL)
37        return TPM_RC_SUCCESS;
38 
39    // Check if the extend operation is allowed by the current command locality
40    if(!PCRIsExtendAllowed(in->pcrHandle))
41        return TPM_RC_LOCALITY;
42 
43    // If PCR is state saved and we need to update orderlyState, check NV
44    // availability
45    if(PCRIsStateSaved(in->pcrHandle) && gp.orderlyState != SHUTDOWN_NONE)
46    {
47        result = NvIsAvailable();
48        if(result != TPM_RC_SUCCESS) return result;
49        g_clearOrderly = TRUE;
50    }
51 
52 // Internal Data Update
53 
54    // Iterate input digest list to extend
55    for(i = 0; i < in->digests.count; i++)
56    {
57        PCRExtend(in->pcrHandle, in->digests.digests[i].hashAlg,
58                  CryptGetHashDigestSize(in->digests.digests[i].hashAlg),
59                  (BYTE *) &in->digests.digests[i].digest);
60    }
61 
62    return TPM_RC_SUCCESS;
63 }
64