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 "PolicyAuthorize_fp.h"
     10 #include "Policy_spt_fp.h"
     11 //
     12 //
     13 //     Error Returns                     Meaning
     14 //
     15 //     TPM_RC_HASH                       hash algorithm in keyName is not supported
     16 //     TPM_RC_SIZE                       keyName is not the correct size for its hash algorithm
     17 //     TPM_RC_VALUE                      the current policyDigest of policySession does not match
     18 //                                       approvedPolicy; or checkTicket doesn't match the provided values
     19 //
     20 TPM_RC
     21 TPM2_PolicyAuthorize(
     22    PolicyAuthorize_In    *in                   // IN: input parameter list
     23    )
     24 {
     25    SESSION                     *session;
     26    TPM2B_DIGEST                 authHash;
     27    HASH_STATE                   hashState;
     28    TPMT_TK_VERIFIED             ticket;
     29    TPM_ALG_ID                   hashAlg;
     30    UINT16                       digestSize;
     31 
     32 // Input Validation
     33 
     34    // Get pointer to the session structure
     35    session = SessionGet(in->policySession);
     36 
     37    // Extract from the Name of the key, the algorithm used to compute it's Name
     38    hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
     39 
     40    // 'keySign' parameter needs to use a supported hash algorithm, otherwise
     41    // can't tell how large the digest should be
     42    digestSize = CryptGetHashDigestSize(hashAlg);
     43    if(digestSize == 0)
     44        return TPM_RC_HASH + RC_PolicyAuthorize_keySign;
     45 
     46    if(digestSize != (in->keySign.t.size - 2))
     47        return TPM_RC_SIZE + RC_PolicyAuthorize_keySign;
     48 
     49    //If this is a trial policy, skip all validations
     50    if(session->attributes.isTrialPolicy == CLEAR)
     51    {
     52        // Check that "approvedPolicy" matches the current value of the
     53        // policyDigest in policy session
     54        if(!Memory2BEqual(&session->u2.policyDigest.b,
     55                          &in->approvedPolicy.b))
     56            return TPM_RC_VALUE + RC_PolicyAuthorize_approvedPolicy;
     57 
     58          // Validate ticket TPMT_TK_VERIFIED
     59          // Compute aHash. The authorizing object sign a digest
     60          // aHash := hash(approvedPolicy || policyRef).
     61          // Start hash
     62          authHash.t.size = CryptStartHash(hashAlg, &hashState);
     63 
     64          // add approvedPolicy
     65          CryptUpdateDigest2B(&hashState, &in->approvedPolicy.b);
     66 
     67       // add policyRef
     68       CryptUpdateDigest2B(&hashState, &in->policyRef.b);
     69 
     70       // complete hash
     71       CryptCompleteHash2B(&hashState, &authHash.b);
     72 
     73       // re-compute TPMT_TK_VERIFIED
     74       TicketComputeVerified(in->checkTicket.hierarchy, &authHash,
     75                             &in->keySign, &ticket);
     76 
     77       // Compare ticket digest. If not match, return error
     78       if(!Memory2BEqual(&in->checkTicket.digest.b, &ticket.digest.b))
     79           return TPM_RC_VALUE+ RC_PolicyAuthorize_checkTicket;
     80   }
     81 
     82 // Internal Data Update
     83 
     84   // Set policyDigest to zero digest
     85   MemorySet(session->u2.policyDigest.t.buffer, 0,
     86             session->u2.policyDigest.t.size);
     87 
     88   // Update policyDigest
     89   PolicyContextUpdate(TPM_CC_PolicyAuthorize, &in->keySign, &in->policyRef,
     90                       NULL, 0, session);
     91 
     92   return TPM_RC_SUCCESS;
     93 
     94 }
     95