1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2004-2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "capabilities.h"
22 #include "tsplog.h"
23 #include "obj.h"
24 #include "authsess.h"
25 
26 #define TPM_STORE_ASYMKEY_LEN 214 /* Entire TPM_STORE_ASYMKEY length */
27 #define USAGE_MIG_DIGEST_FLD_LEN 20 /* Usage, Migration and Digest lengths for
28                                        TPM_STORE_ASYMKEY */
29 #define TPM_STORE_PRIVKEY_LEN 151 /* Extracted directly from TPM_STORE_ASYMKEY
30                                      field */
31 
32 TSS_RESULT
Tspi_Key_UnloadKey(TSS_HKEY hKey)33 Tspi_Key_UnloadKey(TSS_HKEY hKey)       /* in */
34 {
35           TSS_HCONTEXT tspContext;
36           TCS_KEY_HANDLE hTcsKey;
37           TSS_RESULT result;
38 
39           if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
40                     return result;
41 
42           if ((result = obj_rsakey_get_tcs_handle(hKey, &hTcsKey)))
43                     return result;
44 
45           return __tspi_free_resource(tspContext, hTcsKey, TPM_RT_KEY);
46 }
47 
48 TSS_RESULT
Tspi_Key_LoadKey(TSS_HKEY hKey,TSS_HKEY hUnwrappingKey)49 Tspi_Key_LoadKey(TSS_HKEY hKey,                             /* in */
50                      TSS_HKEY hUnwrappingKey)     /* in */
51 {
52           TPM_AUTH auth;
53           TCPA_DIGEST digest;
54           TSS_RESULT result;
55           UINT32 keyslot;
56           TSS_HCONTEXT tspContext;
57           TSS_HPOLICY hPolicy;
58           UINT32 keySize;
59           BYTE *keyBlob;
60           TCS_KEY_HANDLE tcsKey, tcsParentHandle;
61           TSS_BOOL usesAuth;
62           TPM_AUTH *pAuth;
63           Trspi_HashCtx hashCtx;
64           TPM_COMMAND_CODE ordinal;
65 
66           if (!obj_is_rsakey(hUnwrappingKey))
67                     return TSPERR(TSS_E_INVALID_HANDLE);
68 
69           if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
70                     return result;
71 
72           if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
73                     return result;
74 
75           if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
76                     return result;
77 
78           if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
79                     return result;
80 
81           if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy,
82                                                       &usesAuth))) {
83                     free_tspi(tspContext, keyBlob);
84                     return result;
85           }
86 
87           if (usesAuth) {
88                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
89                     result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
90                     result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
91                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
92                               free_tspi(tspContext, keyBlob);
93                               return result;
94                     }
95 
96                     if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
97                                                                   &digest, &auth))) {
98                               free_tspi(tspContext, keyBlob);
99                               return result;
100                     }
101                     pAuth = &auth;
102           } else {
103                     pAuth = NULL;
104           }
105 
106           if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, keySize,
107                                                                        keyBlob, pAuth, &tcsKey, &keyslot))) {
108                     free_tspi(tspContext, keyBlob);
109                     return result;
110           }
111 
112           free_tspi(tspContext, keyBlob);
113 
114           if (usesAuth) {
115                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
116                     result |= Trspi_Hash_UINT32(&hashCtx, result);
117                     result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
118                     if (ordinal == TPM_ORD_LoadKey)
119                               result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
120                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
121                               return result;
122 
123                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
124                               return result;
125           }
126 
127           return obj_rsakey_set_tcs_handle(hKey, tcsKey);
128 }
129 
130 TSS_RESULT
Tspi_Key_GetPubKey(TSS_HKEY hKey,UINT32 * pulPubKeyLength,BYTE ** prgbPubKey)131 Tspi_Key_GetPubKey(TSS_HKEY hKey,                 /* in */
132                        UINT32 * pulPubKeyLength,  /* out */
133                        BYTE ** prgbPubKey)                  /* out */
134 {
135           TPM_AUTH auth;
136           TPM_AUTH *pAuth;
137           TCPA_DIGEST digest;
138           TCPA_RESULT result;
139           TSS_HCONTEXT tspContext;
140           TSS_HPOLICY hPolicy;
141           TCS_KEY_HANDLE tcsKeyHandle;
142           TSS_BOOL usesAuth;
143           Trspi_HashCtx hashCtx;
144 
145           if (pulPubKeyLength == NULL || prgbPubKey == NULL)
146                     return TSPERR(TSS_E_BAD_PARAMETER);
147 
148           if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
149                     return result;
150 
151           if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE,
152                                                       &hPolicy, &usesAuth)))
153                     return result;
154 
155           if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
156                     return result;
157 
158           if (usesAuth) {
159                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
160                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey);
161                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
162                               return result;
163 
164                     if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetPubKey, hPolicy, FALSE,
165                                                                   &digest, &auth)))
166                               return result;
167                     pAuth = &auth;
168           } else {
169                     pAuth = NULL;
170           }
171 
172           if ((result = TCS_API(tspContext)->GetPubKey(tspContext, tcsKeyHandle, pAuth,
173                                                                  pulPubKeyLength, prgbPubKey)))
174                     return result;
175 
176           if (usesAuth) {
177                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
178                     result |= Trspi_Hash_UINT32(&hashCtx, result);
179                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey);
180                     result |= Trspi_HashUpdate(&hashCtx, *pulPubKeyLength, *prgbPubKey);
181                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
182                               goto error;
183 
184                     /* goto error here since prgbPubKey has been set */
185                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
186                               goto error;
187           }
188 
189           if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey)))
190                     goto error;
191 
192           if (tcsKeyHandle == TPM_KEYHND_SRK)
193                     obj_rsakey_set_pubkey(hKey, TRUE, *prgbPubKey);
194 
195           return TSS_SUCCESS;
196 error:
197           free(*prgbPubKey);
198           *prgbPubKey = NULL;
199           *pulPubKeyLength = 0;
200           return result;
201 }
202 
203 TSS_RESULT
Tspi_Key_CreateKey(TSS_HKEY hKey,TSS_HKEY hWrappingKey,TSS_HPCRS hPcrComposite)204 Tspi_Key_CreateKey(TSS_HKEY hKey,                 /* in */
205                        TSS_HKEY hWrappingKey,     /* in */
206                        TSS_HPCRS hPcrComposite)   /* in, may be NULL */
207 {
208 #ifdef TSS_BUILD_CMK
209           UINT32 blobSize;
210           BYTE *blob;
211           TSS_BOOL isCmk = FALSE;
212           TPM_HMAC msaApproval;
213           TPM_DIGEST msaDigest;
214 #endif
215           TCPA_DIGEST digest;
216           TCPA_RESULT result;
217           TCS_KEY_HANDLE parentTCSKeyHandle;
218           BYTE *keyBlob = NULL;
219           UINT32 keySize;
220           UINT32 newKeySize;
221           BYTE *newKey = NULL;
222           UINT32 ordinal = TPM_ORD_CreateWrapKey;
223           TSS_HCONTEXT tspContext;
224           Trspi_HashCtx hashCtx;
225           struct authsess *xsap = NULL;
226 
227           if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
228                     return result;
229 
230           if (hPcrComposite) {
231                     /* its possible that hPcrComposite could be a bad handle here,
232                      * or that no indices of it are yet set, which would throw
233                      * internal error. Blanket both those codes with bad
234                      * parameter to help the user out */
235                     if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
236                               return TSPERR(TSS_E_BAD_PARAMETER);
237           }
238 
239           if ((result = obj_rsakey_get_tcs_handle(hWrappingKey, &parentTCSKeyHandle)))
240                     return result;
241 
242           if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
243                     return result;
244 
245 #ifdef TSS_BUILD_CMK
246           isCmk = obj_rsakey_is_cmk(hKey);
247           if (isCmk) {
248                     if ((result = obj_rsakey_get_msa_approval(hKey, &blobSize, &blob)))
249                               goto done;
250                     memcpy(msaApproval.digest, blob, sizeof(msaApproval.digest));
251                     free_tspi(tspContext, blob);
252 
253                     if ((result = obj_rsakey_get_msa_digest(hKey, &blobSize, &blob)))
254                               goto done;
255                     memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest));
256                     free_tspi(tspContext, blob);
257 
258                     ordinal = TPM_ORD_CMK_CreateKey;
259           }
260 #endif
261 
262           if ((result = authsess_xsap_init(tspContext, hWrappingKey, hKey, TSS_AUTH_POLICY_REQUIRED,
263                                                    ordinal, TPM_ET_KEYHANDLE, &xsap)))
264                     return result;
265 
266           /* Setup the Hash Data for the HMAC */
267           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
268           result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
269 #ifdef TSS_BUILD_CMK
270           if (isCmk) {
271                     result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
272                     result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
273                     result |= Trspi_Hash_HMAC(&hashCtx, msaApproval.digest);
274                     result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest);
275           } else {
276 #endif
277                     result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
278                     result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthMig.authdata);
279                     result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
280 #ifdef TSS_BUILD_CMK
281           }
282 #endif
283           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
284                     goto done;
285 
286           if ((result = authsess_xsap_hmac(xsap, &digest)))
287                     goto done;
288 
289           /* Now call the function */
290 #ifdef TSS_BUILD_CMK
291           if (isCmk) {
292                     if ((newKey = malloc(keySize)) == NULL) {
293                               LogError("malloc of %u bytes failed.", keySize);
294                               result = TSPERR(TSS_E_OUTOFMEMORY);
295                               goto done;
296                     }
297                     memcpy(newKey, keyBlob, keySize);
298                     newKeySize = keySize;
299 
300                     if ((result = RPC_CMK_CreateKey(tspContext, parentTCSKeyHandle,
301                                                             (TPM_ENCAUTH *)&xsap->encAuthUse,
302                                                             &msaApproval, &msaDigest, &newKeySize, &newKey,
303                                                             xsap->pAuth)))
304                               goto done;
305           } else {
306 #endif
307                     if ((result = TCS_API(tspContext)->CreateWrapKey(tspContext, parentTCSKeyHandle,
308                                                                                  (TPM_ENCAUTH *)&xsap->encAuthUse,
309                                                                                  (TPM_ENCAUTH *)&xsap->encAuthMig,
310                                                                                  keySize, keyBlob, &newKeySize,
311                                                                                  &newKey, xsap->pAuth)))
312                               goto done;
313 #ifdef TSS_BUILD_CMK
314           }
315 #endif
316 
317           /* Validate the Authorization before using the new key */
318           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
319           result |= Trspi_Hash_UINT32(&hashCtx, result);
320           result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
321           result |= Trspi_HashUpdate(&hashCtx, newKeySize, newKey);
322           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
323                     goto done;
324 
325           if (authsess_xsap_verify(xsap, &digest)) {
326                     result = TSPERR(TSS_E_TSP_AUTHFAIL);
327                     goto done;
328           }
329 
330           /* Push the new key into the existing object */
331           result = obj_rsakey_set_tcpakey(hKey, newKeySize, newKey);
332 
333 done:
334           authsess_free(xsap);
335           free_tspi(tspContext, keyBlob);
336           free(newKey);
337 
338           return result;
339 }
340 
341 TSS_RESULT
Tspi_Key_WrapKey(TSS_HKEY hKey,TSS_HKEY hWrappingKey,TSS_HPCRS hPcrComposite)342 Tspi_Key_WrapKey(TSS_HKEY hKey,                             /* in */
343                      TSS_HKEY hWrappingKey,                 /* in */
344                      TSS_HPCRS hPcrComposite)     /* in, may be NULL */
345 {
346           TSS_HPOLICY hUsePolicy, hMigPolicy;
347           TCPA_SECRET usage, migration;
348           TSS_RESULT result;
349           BYTE *keyPrivBlob = NULL, *wrappingPubKey = NULL, *keyBlob = NULL;
350           UINT32 keyPrivBlobLen, wrappingPubKeyLen, keyBlobLen;
351           BYTE newPrivKey[TPM_STORE_ASYMKEY_LEN]; /* This reflects the size of the
352                                                TPM_STORE_ASYMKEY structure
353                                                in both TPM 1.1b and 1.2 */
354           BYTE encPrivKey[256];
355           UINT32 newPrivKeyLen = TPM_STORE_ASYMKEY_LEN, encPrivKeyLen = 256;
356           UINT64 offset;
357           TSS_KEY keyContainer;
358           TCPA_DIGEST digest;
359           TSS_HCONTEXT tspContext;
360           Trspi_HashCtx hashCtx;
361 
362           if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
363                     return result;
364 
365           if (hPcrComposite) {
366                     if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
367                               return result;
368           }
369 
370           /* get the key to be wrapped's private key */
371           if ((result = obj_rsakey_get_priv_blob(hKey, &keyPrivBlobLen, &keyPrivBlob)))
372                     goto done;
373     /* verify if its under the maximum size, according to the
374      * TPM_STORE_ASYMKEY specification */
375     if (keyPrivBlobLen > TPM_STORE_PRIVKEY_LEN)
376         return TSPERR(TSS_E_ENC_INVALID_LENGTH);
377 
378           /* get the key to be wrapped's blob */
379           if ((result = obj_rsakey_get_blob(hKey, &keyBlobLen, &keyBlob)))
380                     goto done;
381 
382           /* get the wrapping key's public key */
383           if ((result = obj_rsakey_get_modulus(hWrappingKey, &wrappingPubKeyLen, &wrappingPubKey)))
384                     goto done;
385 
386           /* get the key to be wrapped's usage policy */
387           if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hUsePolicy, NULL)))
388                     goto done;
389 
390           if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_MIGRATION, &hMigPolicy, NULL)))
391                     goto done;
392 
393           if ((result = obj_policy_get_secret(hUsePolicy, TR_SECRET_CTX_NEW, &usage)))
394                     goto done;
395 
396           if ((result = obj_policy_get_secret(hMigPolicy, TR_SECRET_CTX_NEW, &migration)))
397                     goto done;
398 
399           __tspi_memset(&keyContainer, 0, sizeof(TSS_KEY));
400 
401           /* unload the key to be wrapped's blob */
402           offset = 0;
403           if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer)))
404                     return result;
405 
406           /* load the key's attributes into an object and get its hash value */
407           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
408           result |= Hash_TSS_PRIVKEY_DIGEST(&hashCtx, &keyContainer);
409           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
410                     return result;
411 
412           free_key_refs(&keyContainer);
413 
414           /* create the plaintext private key blob. This is the point where the
415      * TPM structure TPM_STORE_ASYMKEY is crafted in the buffer */
416           offset = 0;
417           Trspi_LoadBlob_BYTE(&offset, TCPA_PT_ASYM, newPrivKey);
418           Trspi_LoadBlob(&offset, USAGE_MIG_DIGEST_FLD_LEN,
419                    newPrivKey, usage.authdata);
420           Trspi_LoadBlob(&offset, USAGE_MIG_DIGEST_FLD_LEN,
421                    newPrivKey, migration.authdata);
422           Trspi_LoadBlob(&offset, USAGE_MIG_DIGEST_FLD_LEN,
423                    newPrivKey, digest.digest);
424           Trspi_LoadBlob_UINT32(&offset, keyPrivBlobLen, newPrivKey);
425           Trspi_LoadBlob(&offset, keyPrivBlobLen, newPrivKey, keyPrivBlob);
426           newPrivKeyLen = offset;
427 
428           /* encrypt the private key blob */
429           if ((result = Trspi_RSA_Encrypt(newPrivKey, newPrivKeyLen, encPrivKey,
430                                                   &encPrivKeyLen, wrappingPubKey,
431                                                   wrappingPubKeyLen)))
432                     goto done;
433 
434           /* set the new encrypted private key in the wrapped key object */
435           if ((result = obj_rsakey_set_privkey(hKey, FALSE, encPrivKeyLen, encPrivKey)))
436                     goto done;
437 
438 done:
439           free_tspi(tspContext, keyPrivBlob);
440           free_tspi(tspContext, keyBlob);
441           free_tspi(tspContext, wrappingPubKey);
442           return result;
443 }
444 
445 TSS_RESULT
Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext,TSS_HKEY hUnwrappingKey,UINT32 ulBlobLength,BYTE * rgbBlobData,TSS_HKEY * phKey)446 Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext,         /* in */
447                                  TSS_HKEY hUnwrappingKey,   /* in */
448                                  UINT32 ulBlobLength,                 /* in */
449                                  BYTE * rgbBlobData,                  /* in */
450                                  TSS_HKEY * phKey)                    /* out */
451 {
452           TPM_AUTH auth;
453           UINT64 offset;
454           TCPA_DIGEST digest;
455           TSS_RESULT result;
456           UINT32 keyslot;
457           TSS_HPOLICY hPolicy;
458           TCS_KEY_HANDLE tcsParentHandle, myTCSKeyHandle;
459           TSS_KEY keyContainer;
460           TSS_BOOL useAuth;
461           TPM_AUTH *pAuth;
462           TSS_FLAG initFlags;
463           UINT16 realKeyBlobSize;
464           TCPA_KEY_USAGE keyUsage;
465           UINT32 pubLen;
466           Trspi_HashCtx hashCtx;
467           TPM_COMMAND_CODE ordinal;
468 
469           if (phKey == NULL || rgbBlobData == NULL )
470                     return TSPERR(TSS_E_BAD_PARAMETER);
471 
472           if (!obj_is_rsakey(hUnwrappingKey))
473                     return TSPERR(TSS_E_INVALID_HANDLE);
474 
475           if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
476                     return result;
477 
478           if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
479                     return result;
480 
481           offset = 0;
482           if ((result = UnloadBlob_TSS_KEY(&offset, rgbBlobData, &keyContainer)))
483                     return result;
484           realKeyBlobSize = offset;
485           pubLen = keyContainer.pubKey.keyLength;
486           keyUsage = keyContainer.keyUsage;
487           /* free these now, since they're not used below */
488           free_key_refs(&keyContainer);
489 
490           if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
491                     return result;
492 
493           if (useAuth) {
494                     /* Create the Authorization */
495                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
496                     result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
497                     result |= Trspi_HashUpdate(&hashCtx, ulBlobLength, rgbBlobData);
498                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
499                               return result;
500 
501                     if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
502                                                                   &digest, &auth)))
503                               return result;
504 
505                     pAuth = &auth;
506           } else {
507                     pAuth = NULL;
508           }
509 
510           if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, ulBlobLength,
511                                                                        rgbBlobData, pAuth, &myTCSKeyHandle,
512                                                                        &keyslot)))
513                     return result;
514 
515           if (useAuth) {
516                     /* ---  Validate return auth */
517                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
518                     result |= Trspi_Hash_UINT32(&hashCtx, result);
519                     result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
520                     if (ordinal == TPM_ORD_LoadKey)
521                               result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
522                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
523                               return result;
524 
525                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
526                               return result;
527           }
528 
529           /* ---  Create a new Object */
530           initFlags = 0;
531           if (pubLen == 0x100)
532                     initFlags |= TSS_KEY_SIZE_2048;
533           else if (pubLen == 0x80)
534                     initFlags |= TSS_KEY_SIZE_1024;
535           else if (pubLen == 0x40)
536                     initFlags |= TSS_KEY_SIZE_512;
537 
538           /* clear the key type field */
539           initFlags &= ~TSS_KEY_TYPE_MASK;
540 
541           if (keyUsage == TPM_KEY_STORAGE)
542                     initFlags |= TSS_KEY_TYPE_STORAGE;
543           else
544                     initFlags |= TSS_KEY_TYPE_SIGNING;      /* loading the blob
545                                                                          will fix this
546                                                                          back to what it
547                                                                          should be. */
548 
549           if ((result = obj_rsakey_add(tspContext, initFlags, phKey))) {
550                     LogDebug("Failed create object");
551                     return TSPERR(TSS_E_INTERNAL_ERROR);
552           }
553 
554           if ((result = obj_rsakey_set_tcpakey(*phKey,realKeyBlobSize, rgbBlobData))) {
555                     LogDebug("Key loaded but failed to setup the key object"
556                                 "correctly");
557                     return TSPERR(TSS_E_INTERNAL_ERROR);
558           }
559 
560           return obj_rsakey_set_tcs_handle(*phKey, myTCSKeyHandle);
561 }
562 
563 TSS_RESULT
Tspi_TPM_OwnerGetSRKPubKey(TSS_HTPM hTPM,UINT32 * pulPuKeyLength,BYTE ** prgbPubKey)564 Tspi_TPM_OwnerGetSRKPubKey(TSS_HTPM hTPM,                   /* in */
565                                  UINT32 * pulPuKeyLength,   /* out */
566                                  BYTE ** prgbPubKey)                  /* out */
567 {
568           TSS_RESULT result;
569           TSS_HPOLICY hPolicy;
570           TSS_HCONTEXT tspContext;
571           TCS_KEY_HANDLE hKey;
572           TPM_AUTH auth;
573           Trspi_HashCtx hashCtx;
574           TCPA_DIGEST digest;
575 
576           if (pulPuKeyLength == NULL || prgbPubKey == NULL)
577                     return TSPERR(TSS_E_BAD_PARAMETER);
578 
579           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
580                     return result;
581 
582           hKey = TPM_KEYHND_SRK;
583 
584           if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
585                     return result;
586 
587           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
588           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
589           result |= Trspi_Hash_UINT32(&hashCtx, hKey);
590           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
591                     return result;
592 
593           if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub,
594                                                         hPolicy, FALSE, &digest, &auth)))
595                     return result;
596 
597           if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, hKey, &auth,
598                                                                                 pulPuKeyLength, prgbPubKey)))
599                     return result;
600 
601           /* Validate return auth */
602           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
603           result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
604           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
605           result |= Trspi_HashUpdate(&hashCtx, *pulPuKeyLength, *prgbPubKey);
606           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
607                     goto error;
608 
609           if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
610                     goto error;
611 
612           /* Call a special SRK-seeking command to transparently add the public data to the object */
613           if ((result = obj_rsakey_set_srk_pubkey(*prgbPubKey))) {
614                     LogError("Error setting SRK public data, SRK key object may not exist");
615           }
616 
617           if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey)))
618                     goto error;
619 
620           return result;
621 
622 error:
623           free(*prgbPubKey);
624           pulPuKeyLength = 0;
625           return result;
626 }
627 
628 /* TSS 1.2-only interfaces */
629 #ifdef TSS_BUILD_TSS12
630 TSS_RESULT
Tspi_TPM_KeyControlOwner(TSS_HTPM hTPM,TSS_HKEY hTssKey,UINT32 attribName,TSS_BOOL attribValue,TSS_UUID * pUuidData)631 Tspi_TPM_KeyControlOwner(TSS_HTPM hTPM,           /* in */
632                                TSS_HKEY hTssKey,  /* in */
633                                UINT32 attribName, /* in */
634                                TSS_BOOL attribValue,        /* in */
635                                TSS_UUID* pUuidData)         /* out */
636 {
637           TSS_RESULT result;
638           TSS_HPOLICY hPolicy;
639           TSS_HCONTEXT tspContext;
640           TCS_KEY_HANDLE hTcsKey;
641           BYTE *pubKey = NULL;
642           UINT32 pubKeyLen;
643           TPM_KEY_CONTROL tpmAttribName;
644           Trspi_HashCtx hashCtx;
645           TCPA_DIGEST digest;
646           TPM_AUTH ownerAuth;
647 
648           LogDebugFn("Enter");
649 
650           /* Check valid TPM context, get TSP context */
651           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
652                     return result;
653 
654           /* Get Tcs KeyHandle */
655           if ((result = obj_rsakey_get_tcs_handle(hTssKey, &hTcsKey)))
656                     return result;
657 
658           /* Validate/convert attribName */
659           switch (attribName) {
660                     case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
661                               tpmAttribName = TPM_KEY_CONTROL_OWNER_EVICT;
662                               break;
663                     default:
664                               return TSPERR(TSS_E_BAD_PARAMETER);
665           }
666 
667           /* Begin Auth - get TPM Policy Handler */
668           if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
669                     return result;
670 
671           /* Get associated pubKey */
672           if ((result = obj_rsakey_get_pub_blob(hTssKey, &pubKeyLen, &pubKey)))
673                     return result;
674 
675           /* Create hash digest */
676           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
677           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
678           LogDebugData(pubKeyLen, pubKey);
679           result |= Trspi_HashUpdate(&hashCtx, pubKeyLen, pubKey);
680           result |= Trspi_Hash_UINT32(&hashCtx, tpmAttribName);
681           result |= Trspi_Hash_BOOL(&hashCtx, attribValue);
682           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
683                     free_tspi(tspContext, pubKey);
684                     return result;
685           }
686 
687           if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KeyControlOwner, hPolicy, FALSE,
688                                                         &digest, &ownerAuth))) {
689                     free_tspi(tspContext, pubKey);
690                     return result;
691           }
692 
693           if ((result = RPC_KeyControlOwner(tspContext, hTcsKey, pubKeyLen, pubKey, tpmAttribName,
694                                                     attribValue, &ownerAuth, pUuidData))) {
695                     free_tspi(tspContext, pubKey);
696                     return result;
697           }
698 
699           /* Validate return auth */
700           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
701           result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
702           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
703           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
704                     return result;
705 
706           if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
707                     return result;
708 
709           /* change hKey internal flag, according to attrib[Name|Value] */
710           switch (attribName) {
711                     case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
712                               result = obj_rsakey_set_ownerevict(hTssKey, attribValue);
713                               break;
714                     default:
715                               /* NOT-REACHED */
716                               result = TSPERR(TSS_E_BAD_PARAMETER);
717           }
718 
719           return result;
720 }
721 #endif
722