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. 2007
8 *
9 */
10
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <inttypes.h>
16
17 #include "trousers/tss.h"
18 #include "trousers/trousers.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "obj.h"
22 #include "tsplog.h"
23
24
25 TSS_RESULT
Tspi_TPM_CMKSetRestrictions(TSS_HTPM hTpm,TSS_CMK_DELEGATE CmkDelegate)26 Tspi_TPM_CMKSetRestrictions(TSS_HTPM hTpm, /* in */
27 TSS_CMK_DELEGATE CmkDelegate) /* in */
28 {
29 TSS_HCONTEXT hContext;
30 TSS_HPOLICY hPolicy;
31 Trspi_HashCtx hashCtx;
32 TPM_DIGEST digest;
33 TPM_AUTH ownerAuth;
34 TSS_RESULT result;
35
36 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
37 return result;
38
39 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
40 return result;
41
42 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
43 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions);
44 result |= Trspi_Hash_UINT32(&hashCtx, CmkDelegate);
45 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
46 return result;
47
48 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_SetRestrictions,
49 hPolicy, FALSE, &digest, &ownerAuth)))
50 return result;
51
52 if ((result = RPC_CMK_SetRestrictions(hContext, CmkDelegate, &ownerAuth)))
53 return result;
54
55 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
56 result |= Trspi_Hash_UINT32(&hashCtx, result);
57 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions);
58 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
59 return result;
60
61 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
62 return result;
63
64 return result;
65 }
66
67 TSS_RESULT
Tspi_TPM_CMKApproveMA(TSS_HTPM hTpm,TSS_HMIGDATA hMaAuthData)68 Tspi_TPM_CMKApproveMA(TSS_HTPM hTpm, /* in */
69 TSS_HMIGDATA hMaAuthData) /* in */
70 {
71 TSS_HCONTEXT hContext;
72 TSS_HPOLICY hPolicy;
73 UINT32 blobSize;
74 BYTE *blob;
75 TPM_DIGEST msaDigest;
76 TPM_HMAC msaHmac;
77 Trspi_HashCtx hashCtx;
78 TPM_DIGEST digest;
79 TPM_AUTH ownerAuth;
80 TSS_RESULT result;
81
82 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
83 return result;
84
85 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
86 return result;
87
88 if ((result = obj_migdata_get_msa_digest(hMaAuthData, &blobSize, &blob)))
89 return result;
90 memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest));
91 free_tspi(hContext, blob);
92
93 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
94 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA);
95 result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest);
96 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
97 return result;
98
99 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_ApproveMA,
100 hPolicy, FALSE, &digest, &ownerAuth)))
101 return result;
102
103 if ((result = RPC_CMK_ApproveMA(hContext, msaDigest, &ownerAuth, &msaHmac)))
104 return result;
105
106 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
107 result |= Trspi_Hash_UINT32(&hashCtx, result);
108 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA);
109 result |= Trspi_Hash_HMAC(&hashCtx, msaHmac.digest);
110 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
111 return result;
112
113 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
114 return result;
115
116 if ((result = obj_migdata_set_msa_hmac(hMaAuthData, sizeof(msaHmac.digest), msaHmac.digest)))
117 return result;
118
119 return result;
120 }
121
122 TSS_RESULT
Tspi_TPM_CMKCreateTicket(TSS_HTPM hTpm,TSS_HKEY hVerifyKey,TSS_HMIGDATA hSigData)123 Tspi_TPM_CMKCreateTicket(TSS_HTPM hTpm, /* in */
124 TSS_HKEY hVerifyKey, /* in */
125 TSS_HMIGDATA hSigData) /* in */
126 {
127 TSS_HCONTEXT hContext;
128 TSS_HPOLICY hPolicy;
129 UINT32 pubKeySize;
130 BYTE *pubKey = NULL;
131 UINT32 blobSize;
132 BYTE *blob;
133 TPM_DIGEST sigData;
134 UINT32 sigSize;
135 BYTE *sig = NULL;
136 TPM_HMAC sigTicket;
137 Trspi_HashCtx hashCtx;
138 TPM_DIGEST digest;
139 TPM_AUTH ownerAuth;
140 TSS_RESULT result;
141
142 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
143 return result;
144
145 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
146 return result;
147
148 if ((result = obj_rsakey_get_pub_blob(hVerifyKey, &pubKeySize, &pubKey)))
149 return result;
150
151 if ((result = obj_migdata_get_sig_data(hSigData, &blobSize, &blob)))
152 goto done;
153 memcpy(sigData.digest, blob, sizeof(sigData.digest));
154 free_tspi(hContext, blob);
155
156 if ((result = obj_migdata_get_sig_value(hSigData, &sigSize, &sig)))
157 goto done;
158
159 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
160 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket);
161 result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKey);
162 result |= Trspi_Hash_DIGEST(&hashCtx, sigData.digest);
163 result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
164 result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
165 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
166 goto done;
167
168 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_CreateTicket,
169 hPolicy, FALSE, &digest, &ownerAuth)))
170 goto done;
171
172 if ((result = RPC_CMK_CreateTicket(hContext, pubKeySize, pubKey, sigData, sigSize, sig,
173 &ownerAuth, &sigTicket)))
174 goto done;
175
176 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
177 result |= Trspi_Hash_UINT32(&hashCtx, result);
178 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket);
179 result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest);
180 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
181 goto done;
182
183 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
184 goto done;
185
186 if ((result = obj_migdata_set_sig_ticket(hSigData, sizeof(sigTicket.digest), sigTicket.digest)))
187 goto done;
188
189 done:
190 free_tspi(hContext, pubKey);
191 free_tspi(hContext, sig);
192
193 return result;
194 }
195
196 TSS_RESULT
Tspi_Key_CMKCreateBlob(TSS_HKEY hKeyToMigrate,TSS_HKEY hParentKey,TSS_HMIGDATA hMigrationData,UINT32 * pulRandomLength,BYTE ** prgbRandom)197 Tspi_Key_CMKCreateBlob(TSS_HKEY hKeyToMigrate, /* in */
198 TSS_HKEY hParentKey, /* in */
199 TSS_HMIGDATA hMigrationData, /* in */
200 UINT32* pulRandomLength, /* out */
201 BYTE** prgbRandom) /* out */
202 {
203 TSS_HCONTEXT hContext;
204 TSS_HPOLICY hPolicy;
205 TSS_BOOL usageAuth;
206 TCS_KEY_HANDLE tcsKeyHandle;
207 TSS_MIGRATE_SCHEME migScheme;
208 UINT32 migTicketSize;
209 BYTE *migTicket = NULL;
210 TPM_MIGRATIONKEYAUTH tpmMigKeyAuth;
211 UINT32 msaListSize, restrictTicketSize, sigTicketSize, blobSize;
212 BYTE *msaList = NULL, *restrictTicket = NULL, *blob = NULL;
213 BYTE *sigTicket = NULL;
214 UINT32 pubBlobSize;
215 BYTE *pubBlob = NULL;
216 TPM_DIGEST srcPubKeyDigest;
217 TSS_KEY tssKey;
218 UINT32 randomDataSize, outDataSize, newBlobSize;
219 BYTE *randomData = NULL, *outData = NULL, *newBlob = NULL;
220 Trspi_HashCtx hashCtx;
221 TPM_DIGEST digest;
222 TPM_AUTH parentAuth, *pAuth;
223 UINT64 offset;
224 TSS_RESULT result;
225
226 __tspi_memset(&tssKey, 0, sizeof(tssKey));
227
228 if (!pulRandomLength || !prgbRandom)
229 return TSPERR(TSS_E_BAD_PARAMETER);
230
231 if (!obj_rsakey_is_cmk(hKeyToMigrate))
232 return TSPERR(TSS_E_BAD_PARAMETER);
233
234 if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext)))
235 return result;
236
237 if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth)))
238 return result;
239
240 if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle)))
241 return result;
242
243 if ((result = obj_migdata_get_ticket_blob(hMigrationData, &migTicketSize, &migTicket)))
244 return result;
245
246 /* Just to get the migration scheme... */
247 offset = 0;
248 if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, migTicket, &tpmMigKeyAuth)))
249 goto done;
250 /* ... so free everything now */
251 free(tpmMigKeyAuth.migrationKey.algorithmParms.parms);
252 free(tpmMigKeyAuth.migrationKey.pubKey.key);
253 migScheme = tpmMigKeyAuth.migrationScheme;
254
255 if ((result = obj_rsakey_get_pub_blob(hKeyToMigrate, &pubBlobSize, &pubBlob)))
256 goto done;
257 if ((result = obj_migdata_calc_pubkey_digest(pubBlobSize, pubBlob, &srcPubKeyDigest)))
258 goto done;
259
260 if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList)))
261 goto done;
262
263 if (tpmMigKeyAuth.migrationScheme == TPM_MS_RESTRICT_APPROVE_DOUBLE) {
264 if ((result = obj_migdata_get_cmk_auth_blob(hMigrationData, &restrictTicketSize,
265 &restrictTicket)))
266 goto done;
267 if ((result = obj_migdata_get_sig_ticket(hMigrationData, &sigTicketSize,
268 &sigTicket)))
269 goto done;
270 } else {
271 restrictTicketSize = 0;
272 sigTicketSize = 0;
273 }
274
275 if ((result = obj_rsakey_get_blob(hKeyToMigrate, &blobSize, &blob)))
276 goto done;
277
278 offset = 0;
279 if ((result = UnloadBlob_TSS_KEY(&offset, blob, &tssKey)))
280 goto done;
281
282 if (usageAuth) {
283 pAuth = &parentAuth;
284
285 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
286 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob);
287 result |= Trspi_Hash_UINT16(&hashCtx, migScheme);
288 result |= Trspi_HashUpdate(&hashCtx, migTicketSize, migTicket);
289 result |= Trspi_Hash_DIGEST(&hashCtx, srcPubKeyDigest.digest);
290 result |= Trspi_Hash_UINT32(&hashCtx, msaListSize);
291 result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList);
292 result |= Trspi_Hash_UINT32(&hashCtx, restrictTicketSize);
293 result |= Trspi_HashUpdate(&hashCtx, restrictTicketSize, restrictTicket);
294 result |= Trspi_Hash_UINT32(&hashCtx, sigTicketSize);
295 result |= Trspi_HashUpdate(&hashCtx, sigTicketSize, sigTicket);
296 result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize);
297 result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData);
298 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
299 goto done;
300
301 if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_CreateBlob,
302 hPolicy, FALSE, &digest, pAuth)))
303 goto done;
304 } else
305 pAuth = NULL;
306
307 if ((result = RPC_CMK_CreateBlob(hContext, tcsKeyHandle, migScheme,
308 migTicketSize, migTicket, srcPubKeyDigest, msaListSize, msaList,
309 restrictTicketSize, restrictTicket, sigTicketSize, sigTicket,
310 tssKey.encSize, tssKey.encData, pAuth, &randomDataSize, &randomData,
311 &outDataSize, &outData)))
312 goto done;
313
314 if (pAuth) {
315 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
316 result |= Trspi_Hash_UINT32(&hashCtx, result);
317 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob);
318 result |= Trspi_Hash_UINT32(&hashCtx, randomDataSize);
319 result |= Trspi_HashUpdate(&hashCtx, randomDataSize, randomData);
320 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
321 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
322 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
323 goto done;
324 }
325
326 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
327 goto done;
328
329 /* Create the migdata key blob */
330 free(tssKey.encData);
331 tssKey.encSize = outDataSize;
332 tssKey.encData = outData;
333 /* Set outData to null since it will now be freed during key ref freeing */
334 outData = NULL;
335
336 offset = 0;
337 LoadBlob_TSS_KEY(&offset, NULL, &tssKey);
338
339 newBlobSize = offset;
340 if ((newBlob = malloc(newBlobSize)) == NULL) {
341 LogError("malloc of %u bytes failed.", newBlobSize);
342 result = TSPERR(TSS_E_OUTOFMEMORY);
343 goto done;
344 }
345 offset = 0;
346 LoadBlob_TSS_KEY(&offset, newBlob, &tssKey);
347
348 if ((result = obj_migdata_set_blob(hMigrationData, newBlobSize, newBlob)))
349 goto done;
350
351 if ((*prgbRandom = calloc_tspi(hContext, randomDataSize)) == NULL) {
352 LogError("malloc of %u bytes failed.", randomDataSize);
353 result = TSPERR(TSS_E_OUTOFMEMORY);
354 goto done;
355 }
356 memcpy(*prgbRandom, randomData, randomDataSize);
357 *pulRandomLength = randomDataSize;
358
359 done:
360 free_tspi(hContext, migTicket);
361 free_tspi(hContext, pubBlob);
362 free_tspi(hContext, msaList);
363 free_tspi(hContext, restrictTicket);
364 free_tspi(hContext, sigTicket);
365 free_tspi(hContext, blob);
366 free(randomData);
367 free(outData);
368 free(newBlob);
369 free_key_refs(&tssKey);
370
371 return result;
372 }
373
374 TSS_RESULT
Tspi_Key_CMKConvertMigration(TSS_HKEY hKeyToMigrate,TSS_HKEY hParentKey,TSS_HMIGDATA hMigrationData,UINT32 ulRandomLength,BYTE * rgbRandom)375 Tspi_Key_CMKConvertMigration(TSS_HKEY hKeyToMigrate, /* in */
376 TSS_HKEY hParentKey, /* in */
377 TSS_HMIGDATA hMigrationData, /* in */
378 UINT32 ulRandomLength, /* in */
379 BYTE* rgbRandom) /* in */
380 {
381 TSS_HCONTEXT hContext;
382 TSS_HPOLICY hPolicy;
383 TSS_BOOL usageAuth;
384 TCS_KEY_HANDLE tcsKeyHandle;
385 TPM_CMK_AUTH restrictTicket;
386 UINT32 blobSize;
387 BYTE *blob;
388 TPM_HMAC sigTicket;
389 UINT32 migDataSize, msaListSize;
390 BYTE *migData = NULL, *msaList = NULL;
391 UINT32 outDataSize;
392 BYTE *outData = NULL;
393 Trspi_HashCtx hashCtx;
394 TPM_DIGEST digest;
395 TPM_AUTH parentAuth, *pAuth;
396 TSS_RESULT result;
397
398 if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext)))
399 return result;
400
401 if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth)))
402 return result;
403
404 if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle)))
405 return result;
406
407 if ((result = obj_migdata_get_cmk_auth(hMigrationData, &restrictTicket)))
408 return result;
409
410 if ((result = obj_migdata_get_sig_ticket(hMigrationData, &blobSize, &blob)))
411 return result;
412 memcpy(sigTicket.digest, blob, sizeof(sigTicket.digest));
413 free_tspi(hContext, blob);
414
415 if ((result = obj_migdata_get_blob(hMigrationData, &migDataSize, &migData)))
416 goto done;
417
418 if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList)))
419 goto done;
420
421 if (usageAuth) {
422 pAuth = &parentAuth;
423
424 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
425 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration);
426 result |= Trspi_HashUpdate(&hashCtx, sizeof(restrictTicket),
427 (BYTE *)&restrictTicket);
428 result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest);
429 result |= Trspi_HashUpdate(&hashCtx, migDataSize, migData);
430 result |= Trspi_Hash_UINT32(&hashCtx, msaListSize);
431 result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList);
432 result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength);
433 result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom);
434 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
435 goto done;
436
437 if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_ConvertMigration,
438 hPolicy, FALSE, &digest, pAuth)))
439 goto done;
440 } else
441 pAuth = NULL;
442
443 if ((result = RPC_CMK_ConvertMigration(hContext, tcsKeyHandle, restrictTicket, sigTicket,
444 migDataSize, migData, msaListSize, msaList, ulRandomLength, rgbRandom,
445 pAuth, &outDataSize, &outData)))
446 goto done;
447
448 if (pAuth) {
449 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
450 result |= Trspi_Hash_UINT32(&hashCtx, result);
451 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration);
452 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
453 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
454 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
455 goto done;
456 }
457
458 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
459 goto done;
460
461 /* Set the key object to the now migrated key */
462 if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, migDataSize, migData)))
463 goto done;
464 if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData)))
465 goto done;
466 result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0);
467
468 done:
469 free_tspi(hContext, migData);
470 free_tspi(hContext, msaList);
471 free(outData);
472
473 return result;
474 }
475
476