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 //
10 //     This function is called to process a _TPM_Hash_End() indication.
11 //
12 void
_TPM_Hash_End(void)13 _TPM_Hash_End(
14    void
15    )
16 {
17 
18    UINT32            i;
19    TPM2B_DIGEST      digest;
20    HASH_OBJECT      *hashObject;
21    TPMI_DH_PCR       pcrHandle;
22 
23    // If the DRTM handle is not being used, then either _TPM_Hash_Start has not
24    // been called, _TPM_Hash_End was previously called, or some other command
25    // was executed and the sequence was aborted.
26    if(g_DRTMHandle == TPM_RH_UNASSIGNED)
27        return;
28 
29    // Get DRTM sequence object
30    hashObject = (HASH_OBJECT *)ObjectGet(g_DRTMHandle);
31 
32    // Is this _TPM_Hash_End after Startup or before
33    if(TPMIsStarted())
34    {
35        // After
36 
37          // Reset the DRTM PCR
38          PCRResetDynamics();
39 
40          // Extend the DRTM_PCR.
41          pcrHandle = PCR_FIRST + DRTM_PCR;
42 
43          // DRTM sequence increments restartCount
44          gr.restartCount++;
45    }
46    else
47    {
48        pcrHandle = PCR_FIRST + HCRTM_PCR;
49    }
50 
51    // Complete hash and extend PCR, or if this is an HCRTM, complete
52    // the hash, reset the H-CRTM register (PCR[0]) to 0...04, and then
53    // extend the H-CRTM data
54    for(i = 0; i < HASH_COUNT; i++)
55    {
56        TPMI_ALG_HASH       hash = CryptGetHashAlgByIndex(i);
57        // make sure that the PCR is implemented for this algorithm
58        if(PcrIsAllocated(pcrHandle,
59                            hashObject->state.hashState[i].state.hashAlg))
60        {
61            // Complete hash
62            digest.t.size = CryptGetHashDigestSize(hash);
63            CryptCompleteHash2B(&hashObject->state.hashState[i], &digest.b);
64 
65               PcrDrtm(pcrHandle, hash, &digest);
66          }
67    }
68 
69    // Flush sequence object.
70 //
71    ObjectFlush(g_DRTMHandle);
72 
73    g_DRTMHandle = TPM_RH_UNASSIGNED;
74 
75    g_DrtmPreStartup = TRUE;
76 
77    return;
78 }
79