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 "ClockSet_fp.h"
10 //
11 //     Read the current TPMS_TIMER_INFO structure settings
12 //
13 //     Error Returns                 Meaning
14 //
15 //     TPM_RC_VALUE                  invalid new clock
16 //
17 TPM_RC
TPM2_ClockSet(ClockSet_In * in)18 TPM2_ClockSet(
19    ClockSet_In       *in              // IN: input parameter list
20    )
21 {
22 #define CLOCK_UPDATE_MASK    ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1)
23    UINT64      clockNow;
24 
25 // Input Validation
26 
27    // new time can not be bigger than 0xFFFF000000000000 or smaller than
28    // current clock
29    if(in->newTime > 0xFFFF000000000000ULL
30            || in->newTime < go.clock)
31        return TPM_RC_VALUE + RC_ClockSet_newTime;
32 
33 // Internal Data Update
34 
35    // Internal Data Update
36    clockNow = go.clock;    // grab the old value
37    go.clock = in->newTime;       // set the new value
38    // Check to see if the update has caused a need for an nvClock update
39    if((in->newTime & CLOCK_UPDATE_MASK) > (clockNow & CLOCK_UPDATE_MASK))
40    {
41        CryptDrbgGetPutState(GET_STATE);
42        NvWriteReserved(NV_ORDERLY_DATA, &go);
43 
44        // Now the time state is safe
45        go.clockSafe = YES;
46    }
47 
48    return TPM_RC_SUCCESS;
49 }
50