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 "PolicyLocality_fp.h"
     10 //
     11 //     Limit a policy to a specific locality
     12 //
     13 //     Error Returns                       Meaning
     14 //
     15 //     TPM_RC_RANGE                        all the locality values selected by locality have been disabled by
     16 //                                         previous TPM2_PolicyLocality() calls.
     17 //
     18 TPM_RC
     19 TPM2_PolicyLocality(
     20     PolicyLocality_In        *in                 // IN: input parameter list
     21     )
     22 {
     23     SESSION        *session;
     24     BYTE            marshalBuffer[sizeof(TPMA_LOCALITY)];
     25     BYTE            prevSetting[sizeof(TPMA_LOCALITY)];
     26     UINT32          marshalSize;
     27     BYTE           *buffer;
     28     INT32           bufferSize;
     29     TPM_CC          commandCode = TPM_CC_PolicyLocality;
     30     HASH_STATE      hashState;
     31 
     32 // Input Validation
     33 
     34     // Get pointer to the session structure
     35     session = SessionGet(in->policySession);
     36 
     37     // Get new locality setting in canonical form
     38     buffer = marshalBuffer;
     39     bufferSize = sizeof(TPMA_LOCALITY);
     40     marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, &bufferSize);
     41 
     42     // Its an error if the locality parameter is zero
     43     if(marshalBuffer[0] == 0)
     44         return TPM_RC_RANGE + RC_PolicyLocality_locality;
     45 
     46     // Get existing locality setting in canonical form
     47     buffer = prevSetting;
     48     bufferSize = sizeof(TPMA_LOCALITY);
     49     TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, &bufferSize);
     50 
     51     // If the locality has previously been set
     52     if(    prevSetting[0] != 0
     53         // then the current locality setting and the requested have to be the same
     54         // type (that is, either both normal or both extended
     55         && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32)))
     56         return TPM_RC_RANGE + RC_PolicyLocality_locality;
     57 
     58     // See if the input is a regular or extended locality
     59     if(marshalBuffer[0] < 32)
     60     {
     61         // if there was no previous setting, start with all normal localities
     62         // enabled
     63         if(prevSetting[0] == 0)
     64             prevSetting[0] = 0x1F;
     65 
     66          // AND the new setting with the previous setting and store it in prevSetting
     67          prevSetting[0] &= marshalBuffer[0];
     68 
     69          // The result setting can not be 0
     70          if(prevSetting[0] == 0)
     71           return TPM_RC_RANGE + RC_PolicyLocality_locality;
     72   }
     73   else
     74   {
     75       // for extended locality
     76       // if the locality has already been set, then it must match the
     77       if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0])
     78           return TPM_RC_RANGE + RC_PolicyLocality_locality;
     79 
     80       // Setting is OK
     81       prevSetting[0] = marshalBuffer[0];
     82 
     83   }
     84 
     85 // Internal Data Update
     86 
     87   // Update policy hash
     88   // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality)
     89   // Start hash
     90   CryptStartHash(session->authHashAlg, &hashState);
     91 
     92   // add old digest
     93   CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
     94 
     95   // add commandCode
     96   CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
     97 
     98   // add input locality
     99   CryptUpdateDigest(&hashState, marshalSize, marshalBuffer);
    100 
    101   // complete the digest
    102   CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
    103 
    104   // update session locality by unmarshal function. The function must succeed
    105   // because both input and existing locality setting have been validated.
    106   buffer = prevSetting;
    107   TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer,
    108                           (INT32 *) &marshalSize);
    109 
    110    return TPM_RC_SUCCESS;
    111 }
    112