Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 |
Vadim Bendebury | 5b7832d | 2015-06-01 13:19:03 -0700 | [diff] [blame] | 38 | hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.buffer); |
Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 | } |