xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_cmk.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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