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 "HMAC_fp.h" 10 // 11 // 12 // Error Returns Meaning 13 // 14 // TPM_RC_ATTRIBUTES key referenced by handle is not a signing key or is a restricted key 15 // TPM_RC_TYPE key referenced by handle is not an HMAC key 16 // TPM_RC_VALUE hashAlg is not compatible with the hash algorithm of the scheme of 17 // the object referenced by handle 18 // 19 TPM_RC TPM2_HMAC(HMAC_In * in,HMAC_Out * out)20TPM2_HMAC( 21 HMAC_In *in, // IN: input parameter list 22 HMAC_Out *out // OUT: output parameter list 23 ) 24 { 25 HMAC_STATE hmacState; 26 OBJECT *hmacObject; 27 TPMI_ALG_HASH hashAlg; 28 TPMT_PUBLIC *publicArea; 29 30 // Input Validation 31 32 // Get HMAC key object and public area pointers 33 hmacObject = ObjectGet(in->handle); 34 publicArea = &hmacObject->publicArea; 35 36 // Make sure that the key is an HMAC key 37 if(publicArea->type != TPM_ALG_KEYEDHASH) 38 return TPM_RC_TYPE + RC_HMAC_handle; 39 40 // and that it is unrestricted 41 if(publicArea->objectAttributes.restricted == SET) 42 return TPM_RC_ATTRIBUTES + RC_HMAC_handle; 43 44 // and that it is a signing key 45 if(publicArea->objectAttributes.sign != SET) 46 return TPM_RC_KEY + RC_HMAC_handle; 47 48 // See if the key has a default 49 if(publicArea->parameters.keyedHashDetail.scheme.scheme == TPM_ALG_NULL) 50 // it doesn't so use the input value 51 hashAlg = in->hashAlg; 52 else 53 { 54 // key has a default so use it 55 hashAlg 56 = publicArea->parameters.keyedHashDetail.scheme.details.hmac.hashAlg; 57 // and verify that the input was either the TPM_ALG_NULL or the default 58 if(in->hashAlg != TPM_ALG_NULL && in->hashAlg != hashAlg) 59 hashAlg = TPM_ALG_NULL; 60 } 61 // if we ended up without a hash algorith then return an error 62 if(hashAlg == TPM_ALG_NULL) 63 return TPM_RC_VALUE + RC_HMAC_hashAlg; 64 65 // Command Output 66 67 // Start HMAC stack 68 out->outHMAC.t.size = CryptStartHMAC2B(hashAlg, 69 &hmacObject->sensitive.sensitive.bits.b, 70 &hmacState); 71 // Adding HMAC data 72 CryptUpdateDigest2B(&hmacState, &in->buffer.b); 73 74 // Complete HMAC 75 CryptCompleteHMAC2B(&hmacState, &out->outHMAC.b); 76 77 return TPM_RC_SUCCESS; 78 } 79