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 <string.h>
      9 
     10 #include     "OsslCryptoEngine.h"
     11 #include     "CpriHashData.c"
     12 #define OSSL_HASH_STATE_DATA_SIZE     (MAX_HASH_STATE_SIZE - 8)
     13 typedef struct {
     14    union    {
     15        EVP_MD_CTX context;
     16        BYTE         data[OSSL_HASH_STATE_DATA_SIZE];
     17    } u;
     18    INT16            copySize;
     19 } OSSL_HASH_STATE;
     20 //
     21 //     Temporary aliasing of SM3 to SHA256 until SM3 is available
     22 //
     23 #define EVP_sm3_256 EVP_sha256
     24 //
     25 //
     26 //          Static Functions
     27 //
     28 //          GetHashServer()
     29 //
     30 //     This function returns the address of the hash server function
     31 //
     32 static EVP_MD *
     33 GetHashServer(
     34      TPM_ALG_ID      hashAlg
     35 )
     36 {
     37    switch (hashAlg)
     38    {
     39 #ifdef TPM_ALG_SHA1
     40    case TPM_ALG_SHA1:
     41        return (EVP_MD *)EVP_sha1();
     42        break;
     43 #endif
     44 #ifdef TPM_ALG_SHA256
     45    case TPM_ALG_SHA256:
     46        return (EVP_MD *)EVP_sha256();
     47        break;
     48 #endif
     49 #ifdef TPM_ALG_SHA384
     50    case TPM_ALG_SHA384:
     51        return (EVP_MD *)EVP_sha384();
     52        break;
     53 #endif
     54 #ifdef TPM_ALG_SHA512
     55    case TPM_ALG_SHA512:
     56        return (EVP_MD *)EVP_sha512();
     57        break;
     58 #endif
     59 #ifdef TPM_ALG_SM3_256
     60    case TPM_ALG_SM3_256:
     61        return (EVP_MD *)EVP_sm3_256();
     62        break;
     63 #endif
     64    case TPM_ALG_NULL:
     65        return NULL;
     66    default:
     67        FAIL(FATAL_ERROR_INTERNAL);
     68    }
     69    return NULL; // Never reached.
     70 }
     71 //
     72 //
     73 //        MarshalHashState()
     74 //
     75 //     This function copies an OpenSSL() hash context into a caller provided buffer.
     76 //
     77 //     Return Value                     Meaning
     78 //
     79 //     >0                               the number of bytes of buf used.
     80 //
     81 static UINT16
     82 MarshalHashState(
     83     EVP_MD_CTX         *ctxt,               // IN: Context to marshal
     84     BYTE               *buf                 // OUT: The buffer that will receive the
     85                                             //     context. This buffer is at least
     86                                             //     MAX_HASH_STATE_SIZE byte
     87     )
     88 {
     89     // make sure everything will fit
     90     pAssert(ctxt->digest->ctx_size <= OSSL_HASH_STATE_DATA_SIZE);
     91     // Copy the context data
     92     memcpy(buf, (void*) ctxt->md_data, ctxt->digest->ctx_size);
     93     return (UINT16)ctxt->digest->ctx_size;
     94 }
     95 //
     96 //
     97 //        GetHashState()
     98 //
     99 //     This function will unmarshal a caller provided buffer into an OpenSSL() hash context. The function returns
    100 //     the number of bytes copied (which may be zero).
    101 //
    102 static UINT16
    103 GetHashState(
    104     EVP_MD_CTX         *ctxt,               // OUT: The context structure to receive the
    105                                             //     result of unmarshaling.
    106     TPM_ALG_ID          algType,            // IN: The hash algorithm selector
    107     BYTE               *buf                 // IN: Buffer containing marshaled hash data
    108     )
    109 {
    110     EVP_MD             *evpmdAlgorithm = NULL;
    111     pAssert(ctxt != NULL);
    112     EVP_MD_CTX_init(ctxt);
    113     evpmdAlgorithm = GetHashServer(algType);
    114     if(evpmdAlgorithm == NULL)
    115         return 0;
    116     // This also allocates the ctxt->md_data
    117     if((EVP_DigestInit_ex(ctxt, evpmdAlgorithm, NULL)) != 1)
    118         FAIL(FATAL_ERROR_INTERNAL);
    119     pAssert(ctxt->digest->ctx_size < sizeof(ALIGNED_HASH_STATE));
    120     memcpy(ctxt->md_data, buf, ctxt->digest->ctx_size);
    121 //
    122     return (UINT16)ctxt->digest->ctx_size;
    123 }
    124 //
    125 //
    126 //          GetHashInfoPointer()
    127 //
    128 //      This function returns a pointer to the hash info for the algorithm. If the algorithm is not supported, function
    129 //      returns a pointer to the data block associated with TPM_ALG_NULL.
    130 //
    131 static const HASH_INFO *
    132 GetHashInfoPointer(
    133     TPM_ALG_ID           hashAlg
    134     )
    135 {
    136     UINT32 i, tableSize;
    137     // Get the table size of g_hashData
    138     tableSize = sizeof(g_hashData) / sizeof(g_hashData[0]);
    139     for(i = 0; i < tableSize - 1; i++)
    140     {
    141         if(g_hashData[i].alg == hashAlg)
    142             return &g_hashData[i];
    143     }
    144     return &g_hashData[tableSize-1];
    145 }
    146 //
    147 //
    148 //           Hash Functions
    149 //
    150 //          _cpri__HashStartup()
    151 //
    152 //      Function that is called to initialize the hash service. In this implementation, this function does nothing but
    153 //      it is called by the CryptUtilStartup() function and must be present.
    154 //
    155 LIB_EXPORT BOOL
    156 _cpri__HashStartup(
    157     void
    158     )
    159 {
    160     // On startup, make sure that the structure sizes are compatible. It would
    161     // be nice if this could be done at compile time but I couldn't figure it out.
    162     CPRI_HASH_STATE *cpriState = NULL;
    163 //     NUMBYTES        evpCtxSize = sizeof(EVP_MD_CTX);
    164     NUMBYTES        cpriStateSize = sizeof(cpriState->state);
    165 //     OSSL_HASH_STATE *osslState;
    166     NUMBYTES        osslStateSize = sizeof(OSSL_HASH_STATE);
    167 //     int             dataSize = sizeof(osslState->u.data);
    168     pAssert(cpriStateSize >= osslStateSize);
    169     return TRUE;
    170 }
    171 //
    172 //
    173 //          _cpri__GetHashAlgByIndex()
    174 //
    175 //      This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
    176 //      not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
    177 //      implemented hash and and index of 2 will return the last. All other index values will return
    178 //      TPM_ALG_NULL.
    179 //
    180 //
    181 //
    182 //
    183 //      Return Value                      Meaning
    184 //
    185 //      TPM_ALG_xxx()                     a hash algorithm
    186 //      TPM_ALG_NULL                      this can be used as a stop value
    187 //
    188 LIB_EXPORT TPM_ALG_ID
    189 _cpri__GetHashAlgByIndex(
    190     UINT32               index               // IN: the index
    191     )
    192 {
    193     if(index >= HASH_COUNT)
    194         return TPM_ALG_NULL;
    195     return g_hashData[index].alg;
    196 }
    197 //
    198 //
    199 //         _cpri__GetHashBlockSize()
    200 //
    201 //      Returns the size of the block used for the hash
    202 //
    203 //      Return Value                      Meaning
    204 //
    205 //      <0                                the algorithm is not a supported hash
    206 //      >=                                the digest size (0 for TPM_ALG_NULL)
    207 //
    208 LIB_EXPORT UINT16
    209 _cpri__GetHashBlockSize(
    210     TPM_ALG_ID           hashAlg             // IN: hash algorithm to look up
    211     )
    212 {
    213     return GetHashInfoPointer(hashAlg)->blockSize;
    214 }
    215 //
    216 //
    217 //         _cpri__GetHashDER
    218 //
    219 //      This function returns a pointer to the DER string for the algorithm and indicates its size.
    220 //
    221 LIB_EXPORT UINT16
    222 _cpri__GetHashDER(
    223     TPM_ALG_ID           hashAlg,            // IN: the algorithm to look up
    224     const BYTE          **p
    225     )
    226 {
    227     const HASH_INFO       *q;
    228     q = GetHashInfoPointer(hashAlg);
    229     *p = &q->der[0];
    230     return q->derSize;
    231 }
    232 //
    233 //
    234 //         _cpri__GetDigestSize()
    235 //
    236 //      Gets the digest size of the algorithm. The algorithm is required to be supported.
    237 //
    238 //      Return Value                      Meaning
    239 //
    240 //      =0                                the digest size for TPM_ALG_NULL
    241 //      >0                                the digest size of a hash algorithm
    242 //
    243 LIB_EXPORT UINT16
    244 _cpri__GetDigestSize(
    245     TPM_ALG_ID           hashAlg               // IN: hash algorithm to look up
    246     )
    247 {
    248     return GetHashInfoPointer(hashAlg)->digestSize;
    249 }
    250 //
    251 //
    252 //         _cpri__GetContextAlg()
    253 //
    254 //      This function returns the algorithm associated with a hash context
    255 //
    256 LIB_EXPORT TPM_ALG_ID
    257 _cpri__GetContextAlg(
    258     CPRI_HASH_STATE         *hashState             // IN: the hash context
    259     )
    260 {
    261     return hashState->hashAlg;
    262 }
    263 //
    264 //
    265 //         _cpri__CopyHashState
    266 //
    267 //      This function is used to clone a CPRI_HASH_STATE. The return value is the size of the state.
    268 //
    269 LIB_EXPORT UINT16
    270 _cpri__CopyHashState (
    271     CPRI_HASH_STATE         *out,                  // OUT: destination of the state
    272     CPRI_HASH_STATE         *in                    // IN: source of the state
    273     )
    274 {
    275     OSSL_HASH_STATE    *i = (OSSL_HASH_STATE *)&in->state;
    276     OSSL_HASH_STATE    *o = (OSSL_HASH_STATE *)&out->state;
    277     pAssert(sizeof(i) <= sizeof(in->state));
    278     EVP_MD_CTX_init(&o->u.context);
    279     EVP_MD_CTX_copy_ex(&o->u.context, &i->u.context);
    280     o->copySize = i->copySize;
    281     out->hashAlg = in->hashAlg;
    282     return sizeof(CPRI_HASH_STATE);
    283 }
    284 //
    285 //
    286 //         _cpri__StartHash()
    287 //
    288 //      Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect, the value of
    289 //      stateSize in hashState is updated to indicate the number of bytes of state that were saved. This function
    290 //      calls GetHashServer() and that function will put the TPM into failure mode if the hash algorithm is not
    291 //      supported.
    292 //
    293 //      Return Value                      Meaning
    294 //
    295 //      0                                 hash is TPM_ALG_NULL
    296 //      >0                                digest size
    297 //
    298 LIB_EXPORT UINT16
    299 _cpri__StartHash(
    300     TPM_ALG_ID               hashAlg,              // IN: hash algorithm
    301     BOOL                     sequence,             // IN: TRUE if the state should be saved
    302     CPRI_HASH_STATE         *hashState             // OUT: the state of hash stack.
    303     )
    304 {
    305     EVP_MD_CTX           localState;
    306    OSSL_HASH_STATE    *state = (OSSL_HASH_STATE *)&hashState->state;
    307    BYTE               *stateData = state->u.data;
    308    EVP_MD_CTX         *context;
    309    EVP_MD             *evpmdAlgorithm = NULL;
    310    UINT16              retVal = 0;
    311    if(sequence)
    312        context = &localState;
    313    else
    314        context = &state->u.context;
    315    hashState->hashAlg = hashAlg;
    316    EVP_MD_CTX_init(context);
    317    evpmdAlgorithm = GetHashServer(hashAlg);
    318    if(evpmdAlgorithm == NULL)
    319        goto Cleanup;
    320    if(EVP_DigestInit_ex(context, evpmdAlgorithm, NULL) != 1)
    321        FAIL(FATAL_ERROR_INTERNAL);
    322    retVal = (CRYPT_RESULT)EVP_MD_CTX_size(context);
    323 Cleanup:
    324    if(retVal > 0)
    325    {
    326        if (sequence)
    327        {
    328             if((state->copySize = MarshalHashState(context, stateData)) == 0)
    329             {
    330                 // If MarshalHashState returns a negative number, it is an error
    331                 // code and not a hash size so copy the error code to be the return
    332                 // from this function and set the actual stateSize to zero.
    333                 retVal = state->copySize;
    334                 state->copySize = 0;
    335             }
    336             // Do the cleanup
    337             EVP_MD_CTX_cleanup(context);
    338        }
    339        else
    340             state->copySize = -1;
    341    }
    342    else
    343        state->copySize = 0;
    344    return retVal;
    345 }
    346 //
    347 //
    348 //         _cpri__UpdateHash()
    349 //
    350 //      Add data to a hash or HMAC stack.
    351 //
    352 LIB_EXPORT void
    353 _cpri__UpdateHash(
    354    CPRI_HASH_STATE           *hashState,      // IN: the hash context information
    355    UINT32                     dataSize,       // IN: the size of data to be added to the
    356                                               //     digest
    357    BYTE                      *data            // IN: data to be hashed
    358    )
    359 {
    360    EVP_MD_CTX       localContext;
    361    OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
    362    BYTE            *stateData = state->u.data;
    363    EVP_MD_CTX      *context;
    364    CRYPT_RESULT     retVal = CRYPT_SUCCESS;
    365 //
    366     // If there is no context, return
    367     if(state->copySize == 0)
    368         return;
    369     if(state->copySize > 0)
    370     {
    371         context = &localContext;
    372         if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
    373             return;
    374     }
    375     else
    376         context = &state->u.context;
    377     if(EVP_DigestUpdate(context, data, dataSize) != 1)
    378         FAIL(FATAL_ERROR_INTERNAL);
    379     else if(    state->copySize > 0
    380                 && (retVal= MarshalHashState(context, stateData)) >= 0)
    381     {
    382         // retVal is the size of the marshaled data. Make sure that it is consistent
    383         // by ensuring that we didn't get more than allowed
    384         if(retVal < state->copySize)
    385              FAIL(FATAL_ERROR_INTERNAL);
    386         else
    387              EVP_MD_CTX_cleanup(context);
    388     }
    389     return;
    390 }
    391 //
    392 //
    393 //       _cpri__CompleteHash()
    394 //
    395 //      Complete a hash or HMAC computation. This function will place the smaller of digestSize or the size of
    396 //      the digest in dOut. The number of bytes in the placed in the buffer is returned. If there is a failure, the
    397 //      returned value is <= 0.
    398 //
    399 //      Return Value                      Meaning
    400 //
    401 //      0                                 no data returned
    402 //      >0                                the number of bytes in the digest
    403 //
    404 LIB_EXPORT UINT16
    405 _cpri__CompleteHash(
    406     CPRI_HASH_STATE         *hashState,             // IN: the state of hash stack
    407     UINT32                   dOutSize,              // IN: size of digest buffer
    408     BYTE                    *dOut                   // OUT: hash digest
    409     )
    410 {
    411     EVP_MD_CTX          localState;
    412     OSSL_HASH_STATE    *state = (OSSL_HASH_STATE *)&hashState->state;
    413     BYTE               *stateData = state->u.data;
    414     EVP_MD_CTX         *context;
    415     UINT16              retVal;
    416     int                 hLen;
    417     BYTE                temp[MAX_DIGEST_SIZE];
    418     BYTE               *rBuffer = dOut;
    419     if(state->copySize == 0)
    420         return 0;
    421     if(state->copySize > 0)
    422     {
    423         context = &localState;
    424         if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
    425             goto Cleanup;
    426     }
    427     else
    428         context = &state->u.context;
    429    hLen = EVP_MD_CTX_size(context);
    430    if((unsigned)hLen > dOutSize)
    431        rBuffer = temp;
    432    if(EVP_DigestFinal_ex(context, rBuffer, NULL) == 1)
    433    {
    434        if(rBuffer != dOut)
    435        {
    436             if(dOut != NULL)
    437             {
    438                 memcpy(dOut, temp, dOutSize);
    439             }
    440             retVal = (UINT16)dOutSize;
    441        }
    442        else
    443        {
    444             retVal = (UINT16)hLen;
    445        }
    446        state->copySize = 0;
    447    }
    448    else
    449    {
    450        retVal = 0; // Indicate that no data is returned
    451    }
    452 Cleanup:
    453    EVP_MD_CTX_cleanup(context);
    454    return retVal;
    455 }
    456 //
    457 //
    458 //       _cpri__ImportExportHashState()
    459 //
    460 //      This function is used to import or export the hash state. This function would be called to export state when
    461 //      a sequence object was being prepared for export
    462 //
    463 LIB_EXPORT void
    464 _cpri__ImportExportHashState(
    465    CPRI_HASH_STATE           *osslFmt,          // IN/OUT: the hash state formated for use
    466                                                 //     by openSSL
    467    EXPORT_HASH_STATE         *externalFmt,      // IN/OUT: the exported hash state
    468    IMPORT_EXPORT              direction         //
    469    )
    470 {
    471    UNREFERENCED_PARAMETER(direction);
    472    UNREFERENCED_PARAMETER(externalFmt);
    473    UNREFERENCED_PARAMETER(osslFmt);
    474    return;
    475 #if 0
    476    if(direction == IMPORT_STATE)
    477    {
    478        // don't have the import export functions yet so just copy
    479        _cpri__CopyHashState(osslFmt, (CPRI_HASH_STATE *)externalFmt);
    480    }
    481    else
    482    {
    483        _cpri__CopyHashState((CPRI_HASH_STATE *)externalFmt, osslFmt);
    484    }
    485 #endif
    486 }
    487 //
    488 //
    489 //
    490 //       _cpri__HashBlock()
    491 //
    492 //      Start a hash, hash a single block, update digest and return the size of the results.
    493 //      The digestSize parameter can be smaller than the digest. If so, only the more significant bytes are
    494 //      returned.
    495 //
    496 //      Return Value                      Meaning
    497 //
    498 //      >= 0                              number of bytes in digest (may be zero)
    499 //
    500 LIB_EXPORT UINT16
    501 _cpri__HashBlock(
    502       TPM_ALG_ID         hashAlg,            //   IN: The hash algorithm
    503       UINT32             dataSize,           //   IN: size of buffer to hash
    504       BYTE              *data,               //   IN: the buffer to hash
    505       UINT32             digestSize,         //   IN: size of the digest buffer
    506       BYTE              *digest              //   OUT: hash digest
    507       )
    508 {
    509       EVP_MD_CTX        hashContext;
    510       EVP_MD           *hashServer = NULL;
    511       UINT16            retVal = 0;
    512       BYTE              b[MAX_DIGEST_SIZE]; // temp buffer in case digestSize not
    513       // a full digest
    514       unsigned int      dSize = _cpri__GetDigestSize(hashAlg);
    515       // If there is no digest to compute return
    516       if(dSize == 0)
    517           return 0;
    518       // After the call to EVP_MD_CTX_init(), will need to call EVP_MD_CTX_cleanup()
    519       EVP_MD_CTX_init(&hashContext);     // Initialize the local hash context
    520       hashServer = GetHashServer(hashAlg); // Find the hash server
    521       // It is an error if the digest size is non-zero but there is no                server
    522       if(   (hashServer == NULL)
    523          || (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
    524          || (EVP_DigestUpdate(&hashContext, data, dataSize) != 1))
    525           FAIL(FATAL_ERROR_INTERNAL);
    526       else
    527       {
    528           // If the size of the digest produced (dSize) is larger than                the available
    529           // buffer (digestSize), then put the digest in a temp buffer                and only copy
    530           // the most significant part into the available buffer.
    531           if(dSize > digestSize)
    532           {
    533                if(EVP_DigestFinal_ex(&hashContext, b, &dSize) != 1)
    534                    FAIL(FATAL_ERROR_INTERNAL);
    535                memcpy(digest, b, digestSize);
    536                retVal = (UINT16)digestSize;
    537           }
    538           else
    539           {
    540                if((EVP_DigestFinal_ex(&hashContext, digest, &dSize)) !=               1)
    541                    FAIL(FATAL_ERROR_INTERNAL);
    542                retVal = (UINT16) dSize;
    543           }
    544       }
    545       EVP_MD_CTX_cleanup(&hashContext);
    546       return retVal;
    547 }
    548 //
    549 //
    550 //
    551 //           HMAC Functions
    552 //
    553 //          _cpri__StartHMAC
    554 //
    555 //      This function is used to start an HMAC using a temp hash context. The function does the initialization of
    556 //      the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad.
    557 //      The function returns the number of bytes in a digest produced by hashAlg.
    558 //
    559 //      Return Value                    Meaning
    560 //
    561 //      >= 0                            number of bytes in digest produced by hashAlg (may be zero)
    562 //
    563 LIB_EXPORT UINT16
    564 _cpri__StartHMAC(
    565       TPM_ALG_ID              hashAlg,          //   IN: the algorithm to use
    566       BOOL                    sequence,         //   IN: indicates if the state should be
    567                                                 //       saved
    568       CPRI_HASH_STATE        *state,            //   IN/OUT: the state buffer
    569       UINT16                  keySize,          //   IN: the size of the HMAC key
    570       BYTE                   *key,              //   IN: the HMAC key
    571       TPM2B                  *oPadKey           //   OUT: the key prepared for the oPad round
    572       )
    573 {
    574       CPRI_HASH_STATE localState;
    575       UINT16           blockSize = _cpri__GetHashBlockSize(hashAlg);
    576       UINT16           digestSize;
    577       BYTE            *pb;         // temp pointer
    578       UINT32           i;
    579       // If the key size is larger than the block size, then the hash of the key
    580       // is used as the key
    581       if(keySize > blockSize)
    582       {
    583           // large key so digest
    584           if((digestSize = _cpri__StartHash(hashAlg, FALSE, &localState)) == 0)
    585               return 0;
    586           _cpri__UpdateHash(&localState, keySize, key);
    587           _cpri__CompleteHash(&localState, digestSize, oPadKey->buffer);
    588           oPadKey->size = digestSize;
    589       }
    590       else
    591       {
    592           // key size is ok
    593           memcpy(oPadKey->buffer, key, keySize);
    594           oPadKey->size = keySize;
    595       }
    596       // XOR the key with iPad (0x36)
    597       pb = oPadKey->buffer;
    598       for(i = oPadKey->size; i > 0; i--)
    599           *pb++ ^= 0x36;
    600       // if the keySize is smaller than a block, fill the rest with 0x36
    601       for(i = blockSize - oPadKey->size; i > 0; i--)
    602           *pb++ = 0x36;
    603       // Increase the oPadSize to a full block
    604       oPadKey->size = blockSize;
    605       // Start a new hash with the HMAC key
    606       // This will go in the caller's state structure and may be a sequence or not
    607       if((digestSize = _cpri__StartHash(hashAlg, sequence, state)) > 0)
    608       {
    609           _cpri__UpdateHash(state, oPadKey->size, oPadKey->buffer);
    610           // XOR the key block with 0x5c ^ 0x36
    611           for(pb = oPadKey->buffer, i = blockSize; i > 0; i--)
    612               *pb++ ^= (0x5c ^ 0x36);
    613       }
    614       return digestSize;
    615 }
    616 //
    617 //
    618 //          _cpri_CompleteHMAC()
    619 //
    620 //      This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will
    621 //      then add the oPadKey and the completed digest and return the results in dOut. It will not return more than
    622 //      dOutSize bytes.
    623 //
    624 //      Return Value                      Meaning
    625 //
    626 //      >= 0                              number of bytes in dOut (may be zero)
    627 //
    628 LIB_EXPORT UINT16
    629 _cpri__CompleteHMAC(
    630       CPRI_HASH_STATE        *hashState,          //   IN: the state of hash stack
    631       TPM2B                  *oPadKey,            //   IN: the HMAC key in oPad format
    632       UINT32                  dOutSize,           //   IN: size of digest buffer
    633       BYTE                   *dOut                //   OUT: hash digest
    634       )
    635 {
    636       BYTE             digest[MAX_DIGEST_SIZE];
    637       CPRI_HASH_STATE *state = (CPRI_HASH_STATE *)hashState;
    638       CPRI_HASH_STATE localState;
    639       UINT16           digestSize = _cpri__GetDigestSize(state->hashAlg);
    640       _cpri__CompleteHash(hashState, digestSize, digest);
    641       // Using the local hash state, do a hash with the oPad
    642       if(_cpri__StartHash(state->hashAlg, FALSE, &localState) != digestSize)
    643           return 0;
    644       _cpri__UpdateHash(&localState, oPadKey->size, oPadKey->buffer);
    645       _cpri__UpdateHash(&localState, digestSize, digest);
    646       return _cpri__CompleteHash(&localState, dOutSize, dOut);
    647 }
    648 //
    649 //
    650 //           Mask and Key Generation Functions
    651 //
    652 //          _crypi_MGF1()
    653 //
    654 //      This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || counter). This
    655 //      function returns the length of the mask produced which could be zero if the digest algorithm is not
    656 //      supported
    657 //
    658 //      Return Value                      Meaning
    659 //
    660 //      0                                 hash algorithm not supported
    661 //      >0                                should be the same as mSize
    662 //
    663 LIB_EXPORT CRYPT_RESULT
    664 _cpri__MGF1(
    665    UINT32              mSize,          //   IN: length of the mask to be produced
    666    BYTE               *mask,           //   OUT: buffer to receive the mask
    667    TPM_ALG_ID          hashAlg,        //   IN: hash to use
    668    UINT32              sSize,          //   IN: size of the seed
    669    BYTE               *seed            //   IN: seed size
    670    )
    671 {
    672    EVP_MD_CTX           hashContext;
    673    EVP_MD              *hashServer = NULL;
    674    CRYPT_RESULT         retVal = 0;
    675    BYTE                 b[MAX_DIGEST_SIZE]; // temp buffer in case mask is not an
    676    // even multiple of a full digest
    677    CRYPT_RESULT         dSize = _cpri__GetDigestSize(hashAlg);
    678    unsigned int         digestSize = (UINT32)dSize;
    679    UINT32               remaining;
    680    UINT32               counter;
    681    BYTE                 swappedCounter[4];
    682    // Parameter check
    683    if(mSize > (1024*16)) // Semi-arbitrary maximum
    684        FAIL(FATAL_ERROR_INTERNAL);
    685    // If there is no digest to compute return
    686    if(dSize <= 0)
    687        return 0;
    688    EVP_MD_CTX_init(&hashContext);     // Initialize the local hash context
    689    hashServer = GetHashServer(hashAlg); // Find the hash server
    690    if(hashServer == NULL)
    691        // If there is no server, then there is no digest
    692        return 0;
    693    for(counter = 0, remaining = mSize; remaining > 0; counter++)
    694    {
    695        // Because the system may be either Endian...
    696        UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
    697         // Start the hash and include the seed and counter
    698         if(    (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
    699             || (EVP_DigestUpdate(&hashContext, seed, sSize) != 1)
    700             || (EVP_DigestUpdate(&hashContext, swappedCounter, 4) != 1)
    701           )
    702              FAIL(FATAL_ERROR_INTERNAL);
    703         // Handling the completion depends on how much space remains in the mask
    704         // buffer. If it can hold the entire digest, put it there. If not
    705         // put the digest in a temp buffer and only copy the amount that
    706         // will fit into the mask buffer.
    707         if(remaining < (unsigned)dSize)
    708         {
    709              if(EVP_DigestFinal_ex(&hashContext, b, &digestSize) != 1)
    710                  FAIL(FATAL_ERROR_INTERNAL);
    711              memcpy(mask, b, remaining);
    712              break;
    713         }
    714         else
    715         {
    716              if(EVP_DigestFinal_ex(&hashContext, mask, &digestSize) != 1)
    717                  FAIL(FATAL_ERROR_INTERNAL);
    718              remaining -= dSize;
    719              mask = &mask[dSize];
    720         }
    721         retVal = (CRYPT_RESULT)mSize;
    722    }
    723    EVP_MD_CTX_cleanup(&hashContext);
    724     return retVal;
    725 }
    726 //
    727 //
    728 //          _cpri_KDFa()
    729 //
    730 //      This function performs the key generation according to Part 1 of the TPM specification.
    731 //      This function returns the number of bytes generated which may be zero.
    732 //      The key and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL.
    733 //      The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes).
    734 //      The once parameter is set to allow incremental generation of a large value. If this flag is TRUE,
    735 //      sizeInBits will be used in the HMAC computation but only one iteration of the KDF is performed. This
    736 //      would be used for XOR obfuscation so that the mask value can be generated in digest-sized chunks
    737 //      rather than having to be generated all at once in an arbitrarily large buffer and then XORed() into the
    738 //      result. If once is TRUE, then sizeInBits must be a multiple of 8.
    739 //      Any error in the processing of this command is considered fatal.
    740 //
    741 //      Return Value                      Meaning
    742 //
    743 //      0                                 hash algorithm is not supported or is TPM_ALG_NULL
    744 //      >0                                the number of bytes in the keyStream buffer
    745 //
    746 LIB_EXPORT UINT16
    747 _cpri__KDFa(
    748     TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
    749     TPM2B              *key,                 //   IN: HMAC key
    750     const char         *label,               //   IN: a 0-byte terminated label used in KDF
    751     TPM2B              *contextU,            //   IN: context U
    752     TPM2B              *contextV,            //   IN: context V
    753     UINT32              sizeInBits,          //   IN: size of generated key in bit
    754     BYTE               *keyStream,           //   OUT: key buffer
    755     UINT32             *counterInOut,        //   IN/OUT: caller may provide the iteration
    756                                              //       counter for incremental operations to
    757                                              //       avoid large intermediate buffers.
    758     BOOL                once                 //   IN: TRUE if only one iteration is performed
    759                                              //       FALSE if iteration count determined by
    760                                              //       "sizeInBits"
    761     )
    762 {
    763     UINT32                         counter = 0;    // counter value
    764     INT32                          lLen = 0;       // length of the label
    765     INT16                          hLen;           // length of the hash
    766     INT16                          bytes;          // number of bytes to produce
    767     BYTE                          *stream = keyStream;
    768     BYTE                           marshaledUint32[4];
    769     CPRI_HASH_STATE                hashState;
    770     TPM2B_MAX_HASH_BLOCK           hmacKey;
    771     pAssert(key != NULL && keyStream != NULL);
    772     pAssert(once == FALSE || (sizeInBits & 7) == 0);
    773     if(counterInOut != NULL)
    774         counter = *counterInOut;
    775     // Prepare label buffer. Calculate its size and keep the last 0 byte
    776     if(label != NULL)
    777         for(lLen = 0; label[lLen++] != 0; );
    778     // Get the hash size. If it is less than or 0, either the
    779     // algorithm is not supported or the hash is TPM_ALG_NULL
    780 //
    781    // In either case the digest size is zero. This is the only return
    782    // other than the one at the end. All other exits from this function
    783    // are fatal errors. After we check that the algorithm is supported
    784    // anything else that goes wrong is an implementation flaw.
    785    if((hLen = (INT16) _cpri__GetDigestSize(hashAlg)) == 0)
    786        return 0;
    787    // If the size of the request is larger than the numbers will handle,
    788    // it is a fatal error.
    789    pAssert(((sizeInBits + 7)/ 8) <= INT16_MAX);
    790    bytes = once ? hLen : (INT16)((sizeInBits + 7) / 8);
    791    // Generate required bytes
    792    for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
    793    {
    794        if(bytes < hLen)
    795            hLen = bytes;
    796         counter++;
    797         // Start HMAC
    798         if(_cpri__StartHMAC(hashAlg,
    799                             FALSE,
    800                             &hashState,
    801                             key->size,
    802                             &key->buffer[0],
    803                             &hmacKey.b)          <= 0)
    804             FAIL(FATAL_ERROR_INTERNAL);
    805         // Adding counter
    806         UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
    807         _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
    808         // Adding label
    809         if(label != NULL)
    810             _cpri__UpdateHash(&hashState,   lLen, (BYTE *)label);
    811         // Adding contextU
    812         if(contextU != NULL)
    813             _cpri__UpdateHash(&hashState, contextU->size, contextU->buffer);
    814         // Adding contextV
    815         if(contextV != NULL)
    816             _cpri__UpdateHash(&hashState, contextV->size, contextV->buffer);
    817         // Adding size in bits
    818         UINT32_TO_BYTE_ARRAY(sizeInBits, marshaledUint32);
    819         _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
    820         // Compute HMAC. At the start of each iteration, hLen is set
    821         // to the smaller of hLen and bytes. This causes bytes to decrement
    822         // exactly to zero to complete the loop
    823         _cpri__CompleteHMAC(&hashState, &hmacKey.b, hLen, stream);
    824    }
    825    // Mask off bits if the required bits is not a multiple of byte size
    826    if((sizeInBits % 8) != 0)
    827        keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
    828    if(counterInOut != NULL)
    829        *counterInOut = counter;
    830    return (CRYPT_RESULT)((sizeInBits + 7)/8);
    831 }
    832 //
    833 //
    834 //
    835 //         _cpri__KDFe()
    836 //
    837 //      KDFe() as defined in TPM specification part 1.
    838 //      This function returns the number of bytes generated which may be zero.
    839 //      The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. The
    840 //      value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any error in the processing
    841 //      of this command is considered fatal.
    842 //
    843 //      Return Value                      Meaning
    844 //
    845 //      0                                 hash algorithm is not supported or is TPM_ALG_NULL
    846 //      >0                                the number of bytes in the keyStream buffer
    847 //
    848 LIB_EXPORT UINT16
    849 _cpri__KDFe(
    850     TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
    851     TPM2B              *Z,                   //   IN: Z
    852     const char         *label,               //   IN: a 0 terminated label using in KDF
    853     TPM2B              *partyUInfo,          //   IN: PartyUInfo
    854     TPM2B              *partyVInfo,          //   IN: PartyVInfo
    855     UINT32              sizeInBits,          //   IN: size of generated key in bit
    856     BYTE               *keyStream            //   OUT: key buffer
    857     )
    858 {
    859     UINT32       counter = 0;        // counter value
    860     UINT32       lSize = 0;
    861     BYTE        *stream = keyStream;
    862     CPRI_HASH_STATE         hashState;
    863     INT16        hLen = (INT16) _cpri__GetDigestSize(hashAlg);
    864     INT16        bytes;              // number of bytes to generate
    865     BYTE         marshaledUint32[4];
    866     pAssert(     keyStream != NULL
    867                  && Z != NULL
    868                  && ((sizeInBits + 7) / 8) < INT16_MAX);
    869     if(hLen == 0)
    870         return 0;
    871     bytes = (INT16)((sizeInBits + 7) / 8);
    872     // Prepare label buffer. Calculate its size and keep the last 0 byte
    873     if(label != NULL)
    874         for(lSize = 0; label[lSize++] != 0;);
    875     // Generate required bytes
    876     //The inner loop of that KDF uses:
    877     // Hashi := H(counter | Z | OtherInfo) (5)
    878     // Where:
    879     // Hashi    the hash generated on the i-th iteration of the loop.
    880     // H()      an approved hash function
    881     // counter a 32-bit counter that is initialized to 1 and incremented
    882     //          on each iteration
    883     // Z        the X coordinate of the product of a public ECC key and a
    884     //          different private ECC key.
    885     // OtherInfo    a collection of qualifying data for the KDF defined below.
    886     // In this specification, OtherInfo will be constructed by:
    887     //      OtherInfo := Use | PartyUInfo | PartyVInfo
    888     for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
    889     {
    890         if(bytes < hLen)
    891             hLen = bytes;
    892 //
    893         counter++;
    894         // Start hash
    895         if(_cpri__StartHash(hashAlg, FALSE,   &hashState) == 0)
    896             return 0;
    897         // Add counter
    898         UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
    899         _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
    900         // Add Z
    901         if(Z != NULL)
    902             _cpri__UpdateHash(&hashState, Z->size, Z->buffer);
    903         // Add label
    904         if(label != NULL)
    905              _cpri__UpdateHash(&hashState, lSize, (BYTE *)label);
    906         else
    907               // The SP800-108 specification requires a zero between the label
    908               // and the context.
    909               _cpri__UpdateHash(&hashState, 1, (BYTE *)"");
    910         // Add PartyUInfo
    911         if(partyUInfo != NULL)
    912             _cpri__UpdateHash(&hashState, partyUInfo->size, partyUInfo->buffer);
    913         // Add PartyVInfo
    914         if(partyVInfo != NULL)
    915             _cpri__UpdateHash(&hashState, partyVInfo->size, partyVInfo->buffer);
    916         // Compute Hash. hLen was changed to be the smaller of bytes or hLen
    917         // at the start of each iteration.
    918         _cpri__CompleteHash(&hashState, hLen, stream);
    919    }
    920    // Mask off bits if the required bits is not a multiple of byte size
    921    if((sizeInBits % 8) != 0)
    922        keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
    923    return (CRYPT_RESULT)((sizeInBits + 7) / 8);
    924 }
    925