Home | History | Annotate | Download | only in tpm2
      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 "PolicyCounterTimer_fp.h"
     10 #include "Policy_spt_fp.h"
     11 //
     12 //
     13 //     Error Returns                  Meaning
     14 //
     15 //     TPM_RC_POLICY                  the comparison of the selected portion of the TPMS_TIME_INFO with
     16 //                                    operandB failed
     17 //     TPM_RC_RANGE                   offset + size exceed size of TPMS_TIME_INFO structure
     18 //
     19 TPM_RC
     20 TPM2_PolicyCounterTimer(
     21    PolicyCounterTimer_In      *in              // IN: input parameter list
     22    )
     23 {
     24    TPM_RC                result;
     25    SESSION              *session;
     26    TIME_INFO             infoData;      // data buffer of TPMS_TIME_INFO
     27    TPM_CC                commandCode = TPM_CC_PolicyCounterTimer;
     28    HASH_STATE            hashState;
     29    TPM2B_DIGEST          argHash;
     30 
     31 // Input Validation
     32 
     33    // If the command is going to use any part of the counter or timer, need
     34    // to verify that time is advancing.
     35    // The time and clock vales are the first two 64-bit values in the clock
     36    if(in->offset < sizeof(UINT64) + sizeof(UINT64))
     37    {
     38        // Using Clock or Time so see if clock is running. Clock doesn't run while
     39        // NV is unavailable.
     40        // TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned here.
     41        result = NvIsAvailable();
     42        if(result != TPM_RC_SUCCESS)
     43            return result;
     44    }
     45    // Get pointer to the session structure
     46    session = SessionGet(in->policySession);
     47 
     48    //If this is a trial policy, skip all validations and the operation
     49    if(session->attributes.isTrialPolicy == CLEAR)
     50    {
     51        // Get time data info. The size of time info data equals the input
     52        // operand B size. A TPM_RC_RANGE error may be returned at this point
     53        result = TimeGetRange(in->offset, in->operandB.t.size, &infoData);
     54        if(result != TPM_RC_SUCCESS) return result;
     55 
     56          // Arithmetic Comparison
     57          switch(in->operation)
     58          {
     59              case TPM_EO_EQ:
     60                  // compare A = B
     61                  if(CryptCompare(in->operandB.t.size, infoData,
     62                                  in->operandB.t.size, in->operandB.t.buffer) != 0)
     63                      return TPM_RC_POLICY;
     64                  break;
     65              case TPM_EO_NEQ:
     66                  // compare A != B
     67                  if(CryptCompare(in->operandB.t.size, infoData,
     68                                 in->operandB.t.size, in->operandB.t.buffer)   == 0)
     69                     return TPM_RC_POLICY;
     70                 break;
     71             case TPM_EO_SIGNED_GT:
     72                 // compare A > B signed
     73                 if(CryptCompareSigned(in->operandB.t.size, infoData,
     74                                 in->operandB.t.size, in->operandB.t.buffer)   <= 0)
     75                     return TPM_RC_POLICY;
     76                 break;
     77             case TPM_EO_UNSIGNED_GT:
     78                 // compare A > B unsigned
     79                 if(CryptCompare(in->operandB.t.size, infoData,
     80                                 in->operandB.t.size, in->operandB.t.buffer)   <= 0)
     81                     return TPM_RC_POLICY;
     82                 break;
     83             case TPM_EO_SIGNED_LT:
     84                 // compare A < B signed
     85                 if(CryptCompareSigned(in->operandB.t.size, infoData,
     86                                 in->operandB.t.size, in->operandB.t.buffer)   >= 0)
     87                     return TPM_RC_POLICY;
     88                 break;
     89             case TPM_EO_UNSIGNED_LT:
     90                 // compare A < B unsigned
     91                 if(CryptCompare(in->operandB.t.size, infoData,
     92                                 in->operandB.t.size, in->operandB.t.buffer)   >= 0)
     93                     return TPM_RC_POLICY;
     94                 break;
     95             case TPM_EO_SIGNED_GE:
     96                 // compare A >= B signed
     97                 if(CryptCompareSigned(in->operandB.t.size, infoData,
     98                                 in->operandB.t.size, in->operandB.t.buffer)   < 0)
     99                     return TPM_RC_POLICY;
    100                 break;
    101             case TPM_EO_UNSIGNED_GE:
    102                 // compare A >= B unsigned
    103                 if(CryptCompare(in->operandB.t.size, infoData,
    104                                 in->operandB.t.size, in->operandB.t.buffer)   < 0)
    105                     return TPM_RC_POLICY;
    106                 break;
    107             case TPM_EO_SIGNED_LE:
    108                 // compare A <= B signed
    109                 if(CryptCompareSigned(in->operandB.t.size, infoData,
    110                                 in->operandB.t.size, in->operandB.t.buffer)   > 0)
    111                     return TPM_RC_POLICY;
    112                 break;
    113             case TPM_EO_UNSIGNED_LE:
    114                 // compare A <= B unsigned
    115                 if(CryptCompare(in->operandB.t.size, infoData,
    116                                 in->operandB.t.size, in->operandB.t.buffer)   > 0)
    117                     return TPM_RC_POLICY;
    118                 break;
    119             case TPM_EO_BITSET:
    120                 // All bits SET in B are SET in A. ((A&B)=B)
    121             {
    122                 UINT32 i;
    123                 for (i = 0; i < in->operandB.t.size; i++)
    124                     if(   (infoData[i] & in->operandB.t.buffer[i])
    125                        != in->operandB.t.buffer[i])
    126                         return TPM_RC_POLICY;
    127             }
    128             break;
    129             case TPM_EO_BITCLEAR:
    130                 // All bits SET in B are CLEAR in A. ((A&B)=0)
    131             {
    132                 UINT32 i;
    133                 for (i = 0; i < in->operandB.t.size; i++)
    134                   if((infoData[i] & in->operandB.t.buffer[i]) != 0)
    135                       return TPM_RC_POLICY;
    136           }
    137           break;
    138           default:
    139               pAssert(FALSE);
    140               break;
    141       }
    142   }
    143 
    144 // Internal Data Update
    145 
    146   // Start argument list hash
    147   argHash.t.size = CryptStartHash(session->authHashAlg, &hashState);
    148   // add operandB
    149   CryptUpdateDigest2B(&hashState, &in->operandB.b);
    150   // add offset
    151   CryptUpdateDigestInt(&hashState, sizeof(UINT16), &in->offset);
    152   // add operation
    153   CryptUpdateDigestInt(&hashState, sizeof(TPM_EO), &in->operation);
    154   // complete argument hash
    155   CryptCompleteHash2B(&hashState, &argHash.b);
    156 
    157   // update policyDigest
    158   // start hash
    159   CryptStartHash(session->authHashAlg, &hashState);
    160 
    161   // add old digest
    162   CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
    163 
    164   // add commandCode
    165   CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
    166 
    167   // add argument digest
    168   CryptUpdateDigest2B(&hashState, &argHash.b);
    169 
    170   // complete the digest
    171   CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
    172 
    173    return TPM_RC_SUCCESS;
    174 }
    175