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