Coverage Report

Created: 2025-07-23 06:19

/src/ibmswtpm2/src/CryptHash.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*    Implementation of cryptographic functions for hashing.    */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: CryptHash.c 1311 2018-08-23 21:39:29Z kgoldman $   */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018       */
59
/*                    */
60
/********************************************************************************/
61
62
/* 10.2.14 CryptHash.c */
63
/* 10.2.14.1 Description */
64
/* This file contains implementation of cryptographic functions for hashing. */
65
/* 10.2.14.2 Includes, Defines, and Types */
66
#define _CRYPT_HASH_C_
67
#include "Tpm.h"
68
#define HASH_TABLE_SIZE     (HASH_COUNT + 1)
69
extern const HASH_INFO   g_hashData[HASH_COUNT + 1];
70
#if ALG_SHA1
71
HASH_DEF_TEMPLATE(SHA1);
72
#endif
73
#if ALG_SHA256
74
HASH_DEF_TEMPLATE(SHA256);
75
#endif
76
#if ALG_SHA384
77
HASH_DEF_TEMPLATE(SHA384);
78
#endif
79
#if ALG_SHA512
80
HASH_DEF_TEMPLATE(SHA512);
81
#endif
82
HASH_DEF nullDef = {{0}};
83
/* 10.2.14.3 Obligatory Initialization Functions */
84
/* This function is called by _TPM_Init() do perform the initialization operations for the
85
   library. */
86
BOOL
87
CryptHashInit(
88
        void
89
        )
90
491
{
91
491
    LibHashInit();
92
491
    return TRUE;
93
491
}
94
/* 10.2.13.3.2 CryptHashStartup() */
95
/* This function is called by TPM2_Startup() in case there is work to do at startup. Currently, this
96
   is a placeholder. */
97
BOOL
98
CryptHashStartup(
99
     void
100
     )
101
490
{
102
490
    return TRUE;
103
490
}
104
/* 10.2.14.4 Hash Information Access Functions */
105
/* 10.2.14.4.1 Introduction */
106
/* These functions provide access to the hash algorithm description information. */
107
/* 10.2.14.4.2 CryptGetHashDef() */
108
/* This function accesses the hash descriptor associated with a hash a algorithm. The function
109
   returns NULL for TPM_ALG_NULL and fails if hashAlg is not a hash algorithm. */
110
PHASH_DEF
111
CryptGetHashDef(
112
    TPM_ALG_ID       hashAlg
113
    )
114
74.0k
{
115
74.0k
    PHASH_DEF       retVal;
116
74.0k
    switch(hashAlg)
117
74.0k
  {
118
0
#if ALG_SHA1
119
18.5k
    case ALG_SHA1_VALUE:
120
18.5k
      return &SHA1_Def;
121
0
      break;
122
0
#endif
123
0
#if ALG_SHA256
124
18.5k
    case ALG_SHA256_VALUE:
125
18.5k
      retVal = &SHA256_Def;
126
18.5k
      break;
127
0
#endif
128
0
#if ALG_SHA384
129
18.5k
    case ALG_SHA384_VALUE:
130
18.5k
      retVal = &SHA384_Def;
131
18.5k
      break;
132
0
#endif
133
0
#if ALG_SHA512
134
18.5k
    case ALG_SHA512_VALUE:
135
18.5k
      retVal = &SHA512_Def;
136
18.5k
      break;
137
0
#endif
138
0
    default:
139
0
      retVal = &nullDef;
140
0
      break;
141
74.0k
  }
142
55.5k
    return retVal;
143
74.0k
}
144
/* 10.2.13.4.3 CryptHashIsValidAlg() */
145
/* This function tests to see if an algorithm ID is a valid hash algorithm. If flag is true, then
146
   TPM_ALG_NULL is a valid hash. */
147
/*     Return Value Meaning */
148
/*     TRUE hashAlg is a valid, implemented hash on this TPM. */
149
/*     FALSE  not valid */
150
BOOL
151
CryptHashIsValidAlg(
152
        TPM_ALG_ID       hashAlg,
153
        BOOL             flag
154
        )
155
0
{
156
0
    switch(hashAlg)
157
0
  {
158
0
#if ALG_SHA1
159
0
    case ALG_SHA1_VALUE:
160
0
#endif
161
0
#if ALG_SHA256
162
0
    case ALG_SHA256_VALUE:
163
0
#endif
164
0
#if ALG_SHA384
165
0
    case ALG_SHA384_VALUE:
166
0
#endif
167
0
#if ALG_SHA512
168
0
    case ALG_SHA512_VALUE:
169
0
#endif
170
#if ALG_SM3_256
171
    case ALG_SM3_256_VALUE:
172
#endif
173
0
      return TRUE;
174
0
      break;
175
0
    case ALG_NULL_VALUE:
176
0
      return flag;
177
0
      break;
178
0
    default:
179
0
      break;
180
0
  }
181
0
    return FALSE;
182
0
}
183
/* 10.2.14.4.4 GetHashInfoPointer() */
184
/* This function returns a pointer to the hash info for the algorithm. If the algorithm is not
185
   supported, function returns a pointer to the data block associated with TPM_ALG_NULL. */
186
/* NOTE: The data structure must have a digest size of 0 for TPM_ALG_NULL. */
187
static
188
const HASH_INFO *
189
GetHashInfoPointer(
190
       TPM_ALG_ID       hashAlg
191
       )
192
0
{
193
0
    UINT32              i;
194
    //
195
    // TPM_ALG_NULL is the stop value so search up to it
196
0
    for(i = 0; i < HASH_COUNT; i++)
197
0
  {
198
0
      if(g_hashData[i].alg == hashAlg)
199
0
    return &g_hashData[i];
200
0
  }
201
    // either the input was TPM_ALG_NUL or we didn't find the requested algorithm
202
    // in either case return a pointer to the TPM_ALG_NULL "hash" descriptor
203
0
    return &g_hashData[HASH_COUNT];
204
0
}
205
/* 10.2.14.4.5 CryptHashGetAlgByIndex() */
206
/* This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes
207
   that are not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return
208
   the first implemented hash and an index of 2 will return the last. All other index values will
209
   return TPM_ALG_NULL. */
210
/* Return Values Meaning */
211
/* TPM_ALG_xxx() a hash algorithm */
212
/* TPM_ALG_NULL this can be used as a stop value */
213
LIB_EXPORT TPM_ALG_ID
214
CryptHashGetAlgByIndex(
215
           UINT32           index          // IN: the index
216
           )
217
33.4k
{
218
33.4k
    if(index >= HASH_COUNT)
219
4.00k
  return TPM_ALG_NULL;
220
29.4k
    return g_hashData[index].alg;
221
33.4k
}
222
/* 10.2.14.4.6 CryptHashGetDigestSize() */
223
/* This function returns the size of the digest produced by the hash. If hashAlg is not a hash
224
   algorithm, the TPM will FAIL. */
225
/* Return Values Meaning */
226
/* 0 TPM_ALG_NULL */
227
/* > 0 the digest size */
228
LIB_EXPORT UINT16
229
CryptHashGetDigestSize(
230
           TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
231
           )
232
23.1k
{
233
23.1k
    return CryptGetHashDef(hashAlg)->digestSize;
234
23.1k
}
235
/* 10.2.14.4.7 CryptHashGetBlockSize() */
236
/* Returns the size of the block used by the hash. If hashAlg is not a hash algorithm, the TPM will
237
   FAIL. */
238
/* Return Values Meaning */
239
/* 0 TPM_ALG_NULL */
240
/* > 0 the digest size */
241
LIB_EXPORT UINT16
242
CryptHashGetBlockSize(
243
          TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
244
          )
245
176
{
246
176
    return CryptGetHashDef(hashAlg)->blockSize;
247
176
}
248
/* 10.2.14.4.8 CryptHashGetDer */
249
/* This function returns a pointer to the DER string for the algorithm and indicates its size. */
250
LIB_EXPORT UINT16
251
CryptHashGetDer(
252
    TPM_ALG_ID       hashAlg,       // IN: the algorithm to look up
253
    const BYTE      **p
254
    )
255
0
{
256
0
    const HASH_INFO       *q;
257
0
    q = GetHashInfoPointer(hashAlg);
258
0
    *p = &q->der[0];
259
0
    return q->derSize;
260
0
}
261
/* 10.2.14.4.9 CryptHashGetContextAlg() */
262
/* This function returns the hash algorithm associated with a hash context. */
263
TPM_ALG_ID
264
CryptHashGetContextAlg(
265
           PHASH_STATE      state          // IN: the context to check
266
           )
267
0
{
268
0
    return state->hashAlg;
269
0
}
270
/* 10.2.14.5 State Import and Export */
271
/* 10.2.14.5.1 CryptHashCopyState */
272
/* This function is used to clone a HASH_STATE. */
273
LIB_EXPORT void
274
CryptHashCopyState(
275
       HASH_STATE          *out,           // OUT: destination of the state
276
       const HASH_STATE    *in             // IN: source of the state
277
       )
278
0
{
279
0
    pAssert(out->type == in->type);
280
0
    out->hashAlg = in->hashAlg;
281
0
    out->def = in->def;
282
0
    if(in->hashAlg != TPM_ALG_NULL)
283
0
  {
284
      // Just verify that the hashAlg makes sense (is implemented)
285
0
      CryptGetHashDef(in->hashAlg);
286
      // ... and copy.
287
0
      HASH_STATE_COPY(out, in);
288
0
  }
289
0
    if(in->type == HASH_STATE_HMAC)
290
0
  {
291
0
      const HMAC_STATE    *hIn = (HMAC_STATE *)in;
292
0
      HMAC_STATE          *hOut = (HMAC_STATE *)out;
293
0
      hOut->hmacKey = hIn->hmacKey;
294
0
  }
295
0
    return;
296
0
}
297
/* 10.2.14.5.2 CryptHashExportState() */
298
/* This function is used to export a hash or HMAC hash state. This function would be called when
299
   preparing to context save a sequence object. */
300
void
301
CryptHashExportState(
302
         PCHASH_STATE         internalFmt,   // IN: the hash state formatted for use by
303
         //     library
304
         PEXPORT_HASH_STATE   externalFmt    // OUT: the exported hash state
305
         )
306
0
{
307
0
    BYTE                    *outBuf = (BYTE *)externalFmt;
308
    //
309
0
    cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
310
    // the following #define is used to move data from an aligned internal data
311
    // structure to a byte buffer (external format data.
312
0
#define CopyToOffset(value)           \
313
0
    memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value,  \
314
0
     sizeof(internalFmt->value))
315
    // Copy the hashAlg
316
0
    CopyToOffset(hashAlg);
317
0
    CopyToOffset(type);
318
0
#ifdef HASH_STATE_SMAC
319
0
    if(internalFmt->type == HASH_STATE_SMAC)
320
0
  {
321
0
      memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
322
0
      return;
323
0
  }
324
0
#endif
325
0
    if(internalFmt->type == HASH_STATE_HMAC)
326
0
  {
327
0
      HMAC_STATE              *from = (HMAC_STATE *)internalFmt;
328
0
      memcpy(&outBuf[offsetof(HMAC_STATE, hmacKey)], &from->hmacKey,
329
0
       sizeof(from->hmacKey));
330
0
  }
331
0
    if(internalFmt->hashAlg != TPM_ALG_NULL)
332
0
  HASH_STATE_EXPORT(externalFmt, internalFmt);
333
0
}
334
/* 10.2.14.5.3 CryptHashImportState() */
335
/* This function is used to import the hash state. This function would be called to import a hash
336
   state when the context of a sequence object was being loaded. */
337
void
338
CryptHashImportState(
339
         PHASH_STATE          internalFmt,   // OUT: the hash state formatted for use by
340
         //     the library
341
         PCEXPORT_HASH_STATE  externalFmt    // IN: the exported hash state
342
         )
343
0
{
344
0
    BYTE                    *inBuf = (BYTE *)externalFmt;
345
    //
346
0
#define CopyFromOffset(value)           \
347
0
    memcpy(&internalFmt->value, &inBuf[offsetof(HASH_STATE,value)], \
348
0
     sizeof(internalFmt->value))
349
    // Copy the hashAlg of the byte-aligned input structure to the structure-aligned
350
    // internal structure.
351
0
    CopyFromOffset(hashAlg);
352
0
    CopyFromOffset(type);
353
0
    if(internalFmt->hashAlg != TPM_ALG_NULL)
354
0
  {
355
0
#ifdef HASH_STATE_SMAC
356
0
      if(internalFmt->type == HASH_STATE_SMAC)
357
0
    {
358
0
        memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
359
0
        return;
360
0
    }
361
0
#endif
362
0
      internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
363
0
      HASH_STATE_IMPORT(internalFmt, inBuf);
364
0
      if(internalFmt->type == HASH_STATE_HMAC)
365
0
    {
366
0
        HMAC_STATE              *to = (HMAC_STATE *)internalFmt;
367
0
        memcpy(&to->hmacKey, &inBuf[offsetof(HMAC_STATE, hmacKey)],
368
0
         sizeof(to->hmacKey));
369
0
    }
370
0
  }
371
0
}
372
/* 10.2.14.6 State Modification Functions */
373
/* 10.2.14.6.1 HashEnd() */
374
/* Local function to complete a hash that uses the hashDef instead of an algorithm ID. This function
375
   is used to complete the hash and only return a partial digest. The return value is the size of
376
   the data copied. */
377
static UINT16
378
HashEnd(
379
  PHASH_STATE      hashState,     // IN: the hash state
380
  UINT32           dOutSize,      // IN: the size of receive buffer
381
  PBYTE            dOut           // OUT: the receive buffer
382
  )
383
24.0k
{
384
24.0k
    BYTE                temp[MAX_DIGEST_SIZE];
385
24.0k
    if((hashState->hashAlg == TPM_ALG_NULL)
386
24.0k
       || (hashState->type != HASH_STATE_HASH))
387
0
  dOutSize = 0;
388
24.0k
    if(dOutSize > 0)
389
23.3k
  {
390
23.3k
      hashState->def = CryptGetHashDef(hashState->hashAlg);
391
      // Set the final size
392
23.3k
      dOutSize = MIN(dOutSize, hashState->def->digestSize);
393
      // Complete into the temp buffer and then copy
394
23.3k
      HASH_END(hashState, temp);
395
      // Don't want any other functions calling the HASH_END method
396
      // directly.
397
23.3k
#undef HASH_END
398
23.3k
      memcpy(dOut, &temp, dOutSize);
399
23.3k
  }
400
24.0k
    hashState->type = HASH_STATE_EMPTY;
401
24.0k
    return (UINT16)dOutSize;
402
24.0k
}
403
/* 10.2.14.6.2 CryptHashStart() */
404
/* Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect,
405
   the value of stateSize in hashState is updated to indicate the number of bytes of state that were
406
   saved. This function calls GetHashServer() and that function will put the TPM into failure mode
407
   if the hash algorithm is not supported. */
408
/* This function does not use the sequence parameter. If it is necessary to import or export
409
   context, this will start the sequence in a local state and export the state to the input
410
   buffer. Will need to add a flag to the state structure to indicate that it needs to be imported
411
   before it can be used. (BLEH). */
412
/* Return Values Meaning */
413
/* 0 hash is TPM_ALG_NULL */
414
/* >0 digest size */
415
LIB_EXPORT UINT16
416
CryptHashStart(
417
         PHASH_STATE      hashState,     // OUT: the running hash state
418
         TPM_ALG_ID       hashAlg        // IN: hash algorithm
419
         )
420
27.0k
{
421
27.0k
    UINT16               retVal;
422
27.0k
    TEST(hashAlg);
423
27.0k
    hashState->hashAlg = hashAlg;
424
27.0k
    if(hashAlg == TPM_ALG_NULL)
425
0
  {
426
0
      retVal = 0;
427
0
  }
428
27.0k
    else
429
27.0k
  {
430
27.0k
      hashState->def = CryptGetHashDef(hashAlg);
431
27.0k
      HASH_START(hashState);
432
27.0k
      retVal = hashState->def->digestSize;
433
27.0k
  }
434
27.0k
#undef HASH_START
435
27.0k
    hashState->type = HASH_STATE_HASH;
436
27.0k
    return retVal;
437
27.0k
}
438
439
/* 10.2.14.6.3  CryptDigestUpdate() */
440
/* Add data to a hash or HMAC, SMAC stack. */
441
void
442
CryptDigestUpdate(
443
      PHASH_STATE      hashState,     // IN: the hash context information
444
      UINT32           dataSize,      // IN: the size of data to be added
445
      const BYTE      *data           // IN: data to be hashed
446
      )
447
24.2k
{
448
24.2k
    if(hashState->hashAlg != TPM_ALG_NULL)
449
24.2k
  {
450
24.2k
      if((hashState->type == HASH_STATE_HASH)
451
24.2k
         || (hashState->type == HASH_STATE_HMAC))
452
24.2k
    HASH_DATA(hashState, dataSize, (BYTE *)data);
453
0
#if SMAC_IMPLEMENTED
454
0
      else if(hashState->type == HASH_STATE_SMAC)
455
0
    (hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
456
0
               dataSize, data);
457
0
#endif // SMAC_IMPLEMENTED
458
0
      else
459
0
    FAIL(FATAL_ERROR_INTERNAL);
460
24.2k
  }
461
24.2k
    return;
462
24.2k
}
463
464
/* 10.2.14.6.4 CryptHashEnd() */
465
/* Complete a hash or HMAC computation. This function will place the smaller of digestSize or the
466
   size of the digest in dOut. The number of bytes in the placed in the buffer is returned. If there
467
   is a failure, the returned value is <= 0. */
468
/* Return Values Meaning */
469
/* 0 no data returned */
470
/* > 0 the number of bytes in the digest or dOutSize, whichever is smaller */
471
LIB_EXPORT UINT16
472
CryptHashEnd(
473
       PHASH_STATE      hashState,     // IN: the state of hash stack
474
       UINT32           dOutSize,      // IN: size of digest buffer
475
       BYTE            *dOut           // OUT: hash digest
476
       )
477
23.7k
{
478
23.7k
    pAssert(hashState->type == HASH_STATE_HASH);
479
23.7k
    return HashEnd(hashState, dOutSize, dOut);
480
23.7k
}
481
/* 10.2.14.6.5 CryptHashBlock() */
482
/* Start a hash, hash a single block, update digest and return the size of the results. */
483
/* The digestSize parameter can be smaller than the digest. If so, only the more significant bytes
484
   are returned. */
485
/* Return Values Meaning */
486
/* >= 0 number of bytes placed in dOut */
487
LIB_EXPORT UINT16
488
CryptHashBlock(
489
         TPM_ALG_ID       hashAlg,       // IN: The hash algorithm
490
         UINT32           dataSize,      // IN: size of buffer to hash
491
         const BYTE      *data,          // IN: the buffer to hash
492
         UINT32           dOutSize,      // IN: size of the digest buffer
493
         BYTE            *dOut           // OUT: digest buffer
494
         )
495
0
{
496
0
    HASH_STATE          state;
497
0
    CryptHashStart(&state, hashAlg);
498
0
    CryptDigestUpdate(&state, dataSize, data);
499
0
    return HashEnd(&state, dOutSize, dOut);
500
0
}
501
/* 10.2.14.6.6 CryptDigestUpdate2B() */
502
/* This function updates a digest (hash or HMAC) with a TPM2B. */
503
/* This function can be used for both HMAC and hash functions so the digestState is void so that
504
   either state type can be passed. */
505
LIB_EXPORT void
506
CryptDigestUpdate2B(
507
        PHASH_STATE      state,         // IN: the digest state
508
        const TPM2B     *bIn            // IN: 2B containing the data
509
        )
510
0
{
511
    // Only compute the digest if a pointer to the 2B is provided.
512
    // In CryptDigestUpdate(), if size is zero or buffer is NULL, then no change
513
    // to the digest occurs. This function should not provide a buffer if bIn is
514
    // not provided.
515
0
    pAssert(bIn != NULL);
516
0
    CryptDigestUpdate(state, bIn->size, bIn->buffer);
517
0
    return;
518
0
}
519
/* 10.2.14.6.7 CryptHashEnd2B() */
520
/* This function is the same as CryptCompleteHash() but the digest is placed in a TPM2B. This is the
521
   most common use and this is provided for specification clarity. 'digest.size' should be set to
522
   indicate the number of bytes to place in the buffer */
523
/* Return Values Meaning */
524
/* >=0 the number of bytes placed in 'digest.buffer' */
525
LIB_EXPORT UINT16
526
CryptHashEnd2B(
527
         PHASH_STATE      state,         // IN: the hash state
528
         P2B              digest         // IN: the size of the buffer Out: requested
529
         //     number of bytes
530
         )
531
11.4k
{
532
11.4k
    return CryptHashEnd(state, digest->size, digest->buffer);
533
11.4k
}
534
/* 10.2.14.6.8 CryptDigestUpdateInt() */
535
/* This function is used to include an integer value to a hash stack. The function marshals the
536
   integer into its canonical form before calling CryptDigestUpdate(). */
537
LIB_EXPORT void
538
CryptDigestUpdateInt(
539
         void            *state,         // IN: the state of hash stack
540
         UINT32           intSize,       // IN: the size of 'intValue' in bytes
541
         UINT64           intValue       // IN: integer value to be hashed
542
         )
543
0
{
544
0
#if LITTLE_ENDIAN_TPM
545
0
    intValue = REVERSE_ENDIAN_64(intValue);
546
0
#endif
547
0
    CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
548
0
}
549
/* 10.2.14.7 HMAC Functions */
550
/* 10.2.14.7.1 CryptHmacStart */
551
/* This function is used to start an HMAC using a temp hash context. The function does the
552
   initialization of the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad. */
553
/* The function returns the number of bytes in a digest produced by hashAlg. */
554
/* Return Values Meaning */
555
/* >= 0 number of bytes in digest produced by hashAlg (may be zero) */
556
LIB_EXPORT UINT16
557
CryptHmacStart(
558
         PHMAC_STATE      state,         // IN/OUT: the state buffer
559
         TPM_ALG_ID       hashAlg,       // IN: the algorithm to use
560
         UINT16           keySize,       // IN: the size of the HMAC key
561
         const BYTE      *key            // IN: the HMAC key
562
         )
563
176
{
564
176
    PHASH_DEF                hashDef;
565
176
    BYTE *                   pb;
566
176
    UINT32                   i;
567
    //
568
176
    hashDef = CryptGetHashDef(hashAlg);
569
176
    if(hashDef->digestSize != 0)
570
176
  {
571
      // If the HMAC key is larger than the hash block size, it has to be reduced
572
      // to fit. The reduction is a digest of the hashKey.
573
176
      if(keySize > hashDef->blockSize)
574
0
    {
575
        // if the key is too big, reduce it to a digest of itself
576
0
        state->hmacKey.t.size = CryptHashBlock(hashAlg, keySize, key,
577
0
                 hashDef->digestSize,
578
0
                 state->hmacKey.t.buffer);
579
0
    }
580
176
      else
581
176
    {
582
176
        memcpy(state->hmacKey.t.buffer, key, keySize);
583
176
        state->hmacKey.t.size = keySize;
584
176
    }
585
      // XOR the key with iPad (0x36)
586
176
      pb = state->hmacKey.t.buffer;
587
14.6k
      for(i = state->hmacKey.t.size; i > 0; i--)
588
14.4k
    *pb++ ^= 0x36;
589
      // if the keySize is smaller than a block, fill the rest with 0x36
590
2.64k
      for(i = hashDef->blockSize - state->hmacKey.t.size; i > 0; i--)
591
2.46k
    *pb++ = 0x36;
592
      // Increase the oPadSize to a full block
593
176
      state->hmacKey.t.size = hashDef->blockSize;
594
      // Start a new hash with the HMAC key
595
      // This will go in the caller's state structure and may be a sequence or not
596
176
      CryptHashStart((PHASH_STATE)state, hashAlg);
597
176
      CryptDigestUpdate((PHASH_STATE)state, state->hmacKey.t.size,
598
176
            state->hmacKey.t.buffer);
599
      // XOR the key block with 0x5c ^ 0x36
600
17.0k
      for(pb = state->hmacKey.t.buffer, i = hashDef->blockSize; i > 0; i--)
601
16.8k
    *pb++ ^= (0x5c ^ 0x36);
602
176
  }
603
    // Set the hash algorithm
604
176
    state->hashState.hashAlg = hashAlg;
605
    // Set the hash state type
606
176
    state->hashState.type = HASH_STATE_HMAC;
607
176
    return hashDef->digestSize;
608
176
}
609
/* 10.2.14.7.2 CryptHmacEnd() */
610
/* This function is called to complete an HMAC. It will finish the current digest, and start a new
611
   digest. It will then add the oPadKey and the completed digest and return the results in dOut. It
612
   will not return more than dOutSize bytes. */
613
/* Return Values Meaning */
614
/* >= 0 number of bytes in dOut (may be zero) */
615
LIB_EXPORT UINT16
616
CryptHmacEnd(
617
       PHMAC_STATE      state,         // IN: the hash state buffer
618
       UINT32           dOutSize,      // IN: size of digest buffer
619
       BYTE            *dOut           // OUT: hash digest
620
       )
621
176
{
622
176
    BYTE                 temp[MAX_DIGEST_SIZE];
623
176
    PHASH_STATE          hState = (PHASH_STATE)&state->hashState;
624
176
#if SMAC_IMPLEMENTED
625
176
    if(hState->type == HASH_STATE_SMAC)
626
0
  return (state->hashState.state.smac.smacMethods.end)
627
0
      (&state->hashState.state.smac.state,
628
0
       dOutSize,
629
0
       dOut);
630
176
#endif
631
176
    pAssert(hState->type == HASH_STATE_HMAC);
632
176
    hState->def = CryptGetHashDef(hState->hashAlg);
633
    // Change the state type for completion processing
634
176
    hState->type = HASH_STATE_HASH;
635
176
    if(hState->hashAlg == TPM_ALG_NULL)
636
0
  dOutSize = 0;
637
176
    else
638
176
  {
639
      // Complete the current hash
640
176
      HashEnd(hState, hState->def->digestSize, temp);
641
      // Do another hash starting with the oPad
642
176
      CryptHashStart(hState, hState->hashAlg);
643
176
      CryptDigestUpdate(hState, state->hmacKey.t.size, state->hmacKey.t.buffer);
644
176
      CryptDigestUpdate(hState, hState->def->digestSize, temp);
645
176
  }
646
176
    return HashEnd(hState, dOutSize, dOut);
647
176
}
648
/* 10.2.14.7.3 CryptHmacStart2B() */
649
/* This function starts an HMAC and returns the size of the digest that will be produced. */
650
/* This function is provided to support the most common use of starting an HMAC with a TPM2B key. */
651
/* The caller must provide a block of memory in which the hash sequence state is kept.  The caller
652
   should not alter the contents of this buffer until the hash sequence is completed or
653
   abandoned. */
654
/* Return Values Meaning */
655
/* > 0 the digest size of the algorithm */
656
/* = 0 the hashAlg was TPM_ALG_NULL */
657
LIB_EXPORT UINT16
658
CryptHmacStart2B(
659
     PHMAC_STATE      hmacState,     // OUT: the state of HMAC stack. It will be used
660
     //     in HMAC update and completion
661
     TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
662
     P2B              key            // IN: HMAC key
663
     )
664
0
{
665
0
    return CryptHmacStart(hmacState, hashAlg, key->size, key->buffer);
666
0
}
667
/*     10.2.14.7.4 CryptHmacEnd2B() */
668
/* This function is the same as CryptHmacEnd() but the HMAC result is returned in a TPM2B which is
669
   the most common use. */
670
/* Return Values Meaning */
671
/* >=0 the number of bytes placed in digest */
672
LIB_EXPORT UINT16
673
CryptHmacEnd2B(
674
         PHMAC_STATE      hmacState,     // IN: the state of HMAC stack
675
         P2B              digest         // OUT: HMAC
676
         )
677
0
{
678
0
    return CryptHmacEnd(hmacState, digest->size, digest->buffer);
679
0
}
680
/* 10.2.14.8 Mask and Key Generation Functions */
681
/* 10.2.14.8.1 _crypi_MGF1() */
682
/* This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed ||
683
   counter). This function returns the length of the mask produced which could be zero if the digest
684
   algorithm is not supported */
685
/* Return Values Meaning */
686
/* 0 hash algorithm was TPM_ALG_NULL */
687
/* > 0 should be the same as mSize */
688
LIB_EXPORT UINT16
689
CryptMGF1(
690
    UINT32           mSize,         // IN: length of the mask to be produced
691
    BYTE            *mask,          // OUT: buffer to receive the mask
692
    TPM_ALG_ID       hashAlg,       // IN: hash to use
693
    UINT32           seedSize,      // IN: size of the seed
694
    BYTE            *seed           // IN: seed size
695
    )
696
0
{
697
0
    HASH_STATE           hashState;
698
0
    PHASH_DEF            hDef = CryptGetHashDef(hashAlg);
699
0
    UINT32               remaining;
700
0
    UINT32               counter = 0;
701
0
    BYTE                 swappedCounter[4];
702
    // If there is no digest to compute return
703
0
    if((hashAlg == TPM_ALG_NULL) || (mSize == 0))
704
0
  return 0;
705
0
    for(remaining = mSize; ; remaining -= hDef->digestSize)
706
0
  {
707
      // Because the system may be either Endian...
708
0
      UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
709
      // Start the hash and include the seed and counter
710
0
      CryptHashStart(&hashState, hashAlg);
711
0
      CryptDigestUpdate(&hashState, seedSize, seed);
712
0
      CryptDigestUpdate(&hashState, 4, swappedCounter);
713
      // Handling the completion depends on how much space remains in the mask
714
      // buffer. If it can hold the entire digest, put it there. If not
715
      // put the digest in a temp buffer and only copy the amount that
716
      // will fit into the mask buffer.
717
0
      HashEnd(&hashState, remaining, mask);
718
0
      if(remaining <= hDef->digestSize)
719
0
    break;
720
0
      mask = &mask[hDef->digestSize];
721
0
      counter++;
722
0
  }
723
0
    return (UINT16)mSize;
724
0
}
725
/*     10.2.14.8.2 CryptKDFa() */
726
/* This function performs the key generation according to Part 1 of the TPM specification. */
727
/* This function returns the number of bytes generated which may be zero. */
728
/* The key and keyStream pointers are not allowed to be NULL. The other pointer values may be
729
   NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). */
730
/* The once parameter is set to allow incremental generation of a large value. If this flag is TRUE,
731
   sizeInBits will be used in the HMAC computation but only one iteration of the KDF is
732
   performed. This would be used for XOR obfuscation so that the mask value can be generated in
733
   digest-sized chunks rather than having to be generated all at once in an arbitrarily large buffer
734
   and then XORed() into the result. If once is TRUE, then sizeInBits must be a multiple of 8. */
735
/* Any error in the processing of this command is considered fatal. */
736
/* Return Values Meaning */
737
/* 0 hash algorithm is not supported or is TPM_ALG_NULL */
738
/* > 0 the number of bytes in the keyStream buffer */
739
LIB_EXPORT UINT16
740
CryptKDFa(
741
    TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
742
    const TPM2B     *key,           // IN: HMAC key
743
    const TPM2B     *label,         // IN: a label for the KDF
744
    const TPM2B     *contextU,      // IN: context U
745
    const TPM2B     *contextV,      // IN: context V
746
    UINT32           sizeInBits,    // IN: size of generated key in bits
747
    BYTE            *keyStream,     // OUT: key buffer
748
    UINT32          *counterInOut,  // IN/OUT: caller may provide the iteration
749
    //     counter for incremental operations to
750
    //     avoid large intermediate buffers.
751
    UINT16           blocks         // IN: If non-zero, this is the maximum number
752
    //     of blocks to be returned, regardless of sizeInBits
753
    )
754
0
{
755
0
    UINT32                   counter = 0;       // counter value
756
0
    INT16                    bytes;             // number of bytes to produce
757
0
    UINT16                   generated;         // number of bytes generated
758
0
    BYTE                    *stream = keyStream;
759
0
    HMAC_STATE               hState;
760
0
    UINT16                   digestSize = CryptHashGetDigestSize(hashAlg);
761
0
    pAssert(key != NULL && keyStream != NULL);
762
0
    TEST(TPM_ALG_KDF1_SP800_108);
763
0
    if(digestSize == 0)
764
0
  return 0;
765
0
    if(counterInOut != NULL)
766
0
  counter = *counterInOut;
767
    // If the size of the request is larger than the numbers will handle,
768
    // it is a fatal error.
769
0
    pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);
770
    // The number of bytes to be generated is the smaller of the sizeInBits bytes or
771
    // the number of requested blocks. The number of blocks is the smaller of the
772
    // number requested or the number allowed by sizeInBits. A partial block is
773
    // a full block.
774
0
    bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
775
0
    generated = bytes;
776
    // Generate required bytes
777
0
    for(; bytes > 0; bytes -= digestSize)
778
0
  {
779
0
      counter++;
780
      // Start HMAC
781
0
      if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
782
0
    return 0;
783
      // Adding counter
784
0
      CryptDigestUpdateInt(&hState.hashState, 4, counter);
785
      // Adding label
786
0
      if(label != NULL)
787
0
    HASH_DATA(&hState.hashState, label->size, (BYTE *)label->buffer);
788
      // Add a null. SP108 is not very clear about when the 0 is needed but to
789
      // make this like the previous version that did not add an 0x00 after
790
      // a null-terminated string, this version will only add a null byte
791
      // if the label parameter did not end in a null byte, or if no label
792
      // is present.
793
0
      if((label == NULL)
794
0
         || (label->size == 0)
795
0
         || (label->buffer[label->size - 1] != 0))
796
0
    CryptDigestUpdateInt(&hState.hashState, 1, 0);
797
      // Adding contextU
798
0
      if(contextU != NULL)
799
0
    HASH_DATA(&hState.hashState, contextU->size, contextU->buffer);
800
      // Adding contextV
801
0
      if(contextV != NULL)
802
0
    HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
803
      // Adding size in bits
804
0
      CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);
805
      // Complete and put the data in the buffer
806
0
      CryptHmacEnd(&hState, bytes, stream);
807
0
      stream = &stream[digestSize];
808
0
  }
809
    // Masking in the KDF is disabled. If the calling function wants something
810
    // less than even number of bytes, then the caller should do the masking
811
    // because there is no universal way to do it here
812
0
    if(counterInOut != NULL)
813
0
  *counterInOut = counter;
814
0
    return generated;
815
0
}
816
/*  10.2.14.8.3 CryptKDFe() */
817
/* KDFe() as defined in TPM specification part 1. */
818
/* This function returns the number of bytes generated which may be zero. */
819
/* The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be
820
   NULL. The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any
821
   error in the processing of this command is considered fatal. */
822
/* Return Values Meaning */
823
/* 0 hash algorithm is not supported or is TPM_ALG_NULL */
824
/* > 0 the number of bytes in the keyStream buffer */
825
LIB_EXPORT UINT16
826
CryptKDFe(
827
    TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
828
    TPM2B           *Z,             // IN: Z
829
    const TPM2B     *label,         // IN: a label value for the KDF
830
    TPM2B           *partyUInfo,    // IN: PartyUInfo
831
    TPM2B           *partyVInfo,    // IN: PartyVInfo
832
    UINT32           sizeInBits,    // IN: size of generated key in bits
833
    BYTE            *keyStream      // OUT: key buffer
834
    )
835
0
{
836
0
    HASH_STATE       hashState;
837
0
    PHASH_DEF        hashDef = CryptGetHashDef(hashAlg);
838
0
    UINT32           counter = 0;       // counter value
839
0
    UINT16           hLen;
840
0
    BYTE            *stream = keyStream;
841
0
    INT16            bytes;             // number of bytes to generate
842
0
    pAssert(keyStream != NULL && Z != NULL && ((sizeInBits + 7) / 8) < INT16_MAX);
843
    //
844
0
    hLen = hashDef->digestSize;
845
0
    bytes = (INT16)((sizeInBits + 7) / 8);
846
0
    if(hashAlg == TPM_ALG_NULL || bytes == 0)
847
0
  return 0;
848
    // Generate required bytes
849
    //The inner loop of that KDF uses:
850
    //  Hash[i] := H(counter | Z | OtherInfo) (5)
851
    // Where:
852
    //  Hash[i]   the hash generated on the i-th iteration of the loop.
853
    //  H()     an approved hash function
854
    //  counter a 32-bit counter that is initialized to 1 and incremented
855
    //          on each iteration
856
    //  Z       the X coordinate of the product of a public ECC key and a
857
    //          different private ECC key.
858
    //  OtherInfo   a collection of qualifying data for the KDF defined below.
859
    //  In this specification, OtherInfo will be constructed by:
860
    //      OtherInfo := Use | PartyUInfo  | PartyVInfo
861
0
    for(; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
862
0
  {
863
0
      if(bytes < hLen)
864
0
    hLen = bytes;
865
0
      counter++;
866
      // Do the hash
867
0
      CryptHashStart(&hashState, hashAlg);
868
      // Add counter
869
0
      CryptDigestUpdateInt(&hashState, 4, counter);
870
      // Add Z
871
0
      if(Z != NULL)
872
0
    CryptDigestUpdate2B(&hashState, Z);
873
      // Add label
874
0
      if(label != NULL)
875
0
    CryptDigestUpdate2B(&hashState, label);
876
      // Add a null. SP108 is not very clear about when the 0 is needed but to
877
      // make this like the previous version that did not add an 0x00 after
878
      // a null-terminated string, this version will only add a null byte
879
      // if the label parameter did not end in a null byte, or if no label
880
      // is present.
881
0
      if((label == NULL)
882
0
         || (label->size == 0)
883
0
         || (label->buffer[label->size - 1] != 0))
884
0
    CryptDigestUpdateInt(&hashState, 1, 0);
885
      // Add PartyUInfo
886
0
      if(partyUInfo != NULL)
887
0
    CryptDigestUpdate2B(&hashState, partyUInfo);
888
      // Add PartyVInfo
889
0
      if(partyVInfo != NULL)
890
0
    CryptDigestUpdate2B(&hashState, partyVInfo);
891
      // Compute Hash. hLen was changed to be the smaller of bytes or hLen
892
      // at the start of each iteration.
893
0
      CryptHashEnd(&hashState, hLen, stream);
894
0
  }
895
    // Mask off bits if the required bits is not a multiple of byte size
896
0
    if((sizeInBits % 8) != 0)
897
0
  keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
898
0
    return (UINT16)((sizeInBits + 7) / 8);
899
0
}