Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "Context_spt_fp.h"
     10 //
     11 //
     12 //            Functions
     13 //
     14 //              ComputeContextProtectionKey()
     15 //
     16 //      This function retrieves the symmetric protection key for context encryption It is used by
     17 //      TPM2_ConextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv
     18 //
     19 void
     20 ComputeContextProtectionKey(
     21      TPMS_CONTEXT      *contextBlob,    // IN: context blob
     22      TPM2B_SYM_KEY     *symKey,         // OUT: the symmetric key
     23      TPM2B_IV          *iv              // OUT: the IV.
     24      )
     25 {
     26      UINT16             symKeyBits;     // number of bits in the parent's
     27                                         //   symmetric key
     28      TPM2B_AUTH        *proof = NULL;   // the proof value to use. Is null for
     29                                         //   everything but a primary object in
     30                                         //   the Endorsement Hierarchy
     31      BYTE               kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
     32      TPM2B_DATA         sequence2B, handle2B;
     33      // Get proof value
     34      proof = HierarchyGetProof(contextBlob->hierarchy);
     35      // Get sequence value in 2B format
     36      sequence2B.t.size = sizeof(contextBlob->sequence);
     37      MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence,
     38                 sizeof(contextBlob->sequence),
     39                 sizeof(sequence2B.t.buffer));
     40      // Get handle value in 2B format
     41      handle2B.t.size = sizeof(contextBlob->savedHandle);
     42      MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle,
     43                 sizeof(contextBlob->savedHandle),
     44                 sizeof(handle2B.t.buffer));
     45      // Get the symmetric encryption key size
     46      symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
     47 //
     48    symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
     49    // Get the size of the IV for the algorithm
     50    iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
     51    // KDFa to generate symmetric key and IV value
     52    KDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, "CONTEXT", &sequence2B.b,
     53         &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL);
     54    // Copy part of the returned value as the key
     55    MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size,
     56               sizeof(symKey->t.buffer));
     57    // Copy the rest as the IV
     58    MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size,
     59               sizeof(iv->t.buffer));
     60    return;
     61 }
     62 //
     63 //
     64 //         ComputeContextIntegrity()
     65 //
     66 //     Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity hash
     67 //     and by TPM2_ContextLoad() to compare an integrity hash
     68 //
     69 void
     70 ComputeContextIntegrity(
     71    TPMS_CONTEXT       *contextBlob,      // IN: context blob
     72    TPM2B_DIGEST       *integrity         // OUT: integrity
     73    )
     74 {
     75    HMAC_STATE              hmacState;
     76    TPM2B_AUTH              *proof;
     77    UINT16                  integritySize;
     78    // Get proof value
     79    proof = HierarchyGetProof(contextBlob->hierarchy);
     80    // Start HMAC
     81    integrity->t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
     82                                         &proof->b, &hmacState);
     83    // Compute integrity size at the beginning of context blob
     84    integritySize = sizeof(integrity->t.size) + integrity->t.size;
     85    // Adding total reset counter so that the context cannot be
     86    // used after a TPM Reset
     87    CryptUpdateDigestInt(&hmacState, sizeof(gp.totalResetCount),
     88                         &gp.totalResetCount);
     89    // If this is a ST_CLEAR object, add the clear count
     90    // so that this contest cannot be loaded after a TPM Restart
     91    if(contextBlob->savedHandle == 0x80000002)
     92        CryptUpdateDigestInt(&hmacState, sizeof(gr.clearCount), &gr.clearCount);
     93    // Adding sequence number to the HMAC to make sure that it doesn't
     94    // get changed
     95    CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->sequence),
     96                         &contextBlob->sequence);
     97    // Protect the handle
     98    CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->savedHandle),
     99                          &contextBlob->savedHandle);
    100    // Adding sensitive contextData, skip the leading integrity area
    101      CryptUpdateDigest(&hmacState, contextBlob->contextBlob.t.size - integritySize,
    102                        contextBlob->contextBlob.t.buffer + integritySize);
    103      // Complete HMAC
    104      CryptCompleteHMAC2B(&hmacState, &integrity->b);
    105      return;
    106 }
    107 //
    108 //
    109 //           SequenceDataImportExport()
    110 //
    111 //      This function is used scan through the sequence object and either modify the hash state data for
    112 //      LIB_EXPORT or to import it into the internal format
    113 //
    114 void
    115 SequenceDataImportExport(
    116      OBJECT           *object,          // IN: the object containing the sequence data
    117      OBJECT           *exportObject,    // IN/OUT: the object structure that will get
    118                                         //     the exported hash state
    119      IMPORT_EXPORT     direction
    120      )
    121 {
    122      int                      count = 1;
    123      HASH_OBJECT             *internalFmt = (HASH_OBJECT *)object;
    124      HASH_OBJECT             *externalFmt = (HASH_OBJECT *)exportObject;
    125      if(object->attributes.eventSeq)
    126          count = HASH_COUNT;
    127      for(; count; count--)
    128          CryptHashStateImportExport(&internalFmt->state.hashState[count - 1],
    129                               externalFmt->state.hashState, direction);
    130 }
    131