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 "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
     20 TPM2_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