Home | History | Annotate | Line # | Download | only in tspi
      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-2006
      8  *
      9  */
     10 
     11 #include <stdlib.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <inttypes.h>
     15 
     16 #include "trousers/tss.h"
     17 #include "trousers/trousers.h"
     18 #include "trousers_types.h"
     19 #include "spi_utils.h"
     20 #include "capabilities.h"
     21 #include "tsplog.h"
     22 #include "obj.h"
     23 
     24 
     25 TSS_RESULT
     26 Tspi_TPM_AuthorizeMigrationTicket(TSS_HTPM hTPM,			/* in */
     27 				  TSS_HKEY hMigrationKey,		/* in */
     28 				  TSS_MIGRATION_SCHEME migrationScheme,	/* in */
     29 				  UINT32 * pulMigTicketLength,		/* out */
     30 				  BYTE ** prgbMigTicket)		/* out */
     31 {
     32 	UINT64 offset;
     33 	TCPA_DIGEST digest;
     34 	TCPA_RESULT result;
     35 	TSS_HPOLICY hOwnerPolicy;
     36 	UINT32 migrationKeySize;
     37 	BYTE *migrationKeyBlob;
     38 	TSS_KEY tssKey;
     39 	BYTE pubKeyBlob[0x1000];
     40 	TPM_AUTH ownerAuth;
     41 	UINT32 pubKeySize;
     42 	TSS_HCONTEXT tspContext;
     43 	UINT32 tpmMigrationScheme;
     44 	Trspi_HashCtx hashCtx;
     45 
     46 	if (pulMigTicketLength == NULL || prgbMigTicket == NULL)
     47 		return TSPERR(TSS_E_BAD_PARAMETER);
     48 
     49 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
     50 		return result;
     51 
     52 	/*  get the tpm Policy */
     53 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
     54 		return result;
     55 
     56 	switch (migrationScheme) {
     57 		case TSS_MS_MIGRATE:
     58 			tpmMigrationScheme = TCPA_MS_MIGRATE;
     59 			break;
     60 		case TSS_MS_REWRAP:
     61 			tpmMigrationScheme = TCPA_MS_REWRAP;
     62 			break;
     63 		case TSS_MS_MAINT:
     64 			tpmMigrationScheme = TCPA_MS_MAINT;
     65 			break;
     66 #ifdef TSS_BUILD_CMK
     67 		case TSS_MS_RESTRICT_MIGRATE:
     68 			tpmMigrationScheme = TPM_MS_RESTRICT_MIGRATE;
     69 			break;
     70 
     71 		case TSS_MS_RESTRICT_APPROVE_DOUBLE:
     72 			tpmMigrationScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE;
     73 			break;
     74 #endif
     75 		default:
     76 			return TSPERR(TSS_E_BAD_PARAMETER);
     77 			break;
     78 	}
     79 
     80 	/*  Get the migration key blob */
     81 	if ((result = obj_rsakey_get_blob(hMigrationKey, &migrationKeySize, &migrationKeyBlob)))
     82 		return result;
     83 
     84 	/* First, turn the keyBlob into a TSS_KEY structure */
     85 	offset = 0;
     86 	__tspi_memset(&tssKey, 0, sizeof(TSS_KEY));
     87 	if ((result = UnloadBlob_TSS_KEY(&offset, migrationKeyBlob, &tssKey))) {
     88 		free_tspi(tspContext, migrationKeyBlob);
     89 		return result;
     90 	}
     91 	free_tspi(tspContext, migrationKeyBlob);
     92 
     93 	/* Then pull the _PUBKEY portion out of that struct into a blob */
     94 	offset = 0;
     95 	Trspi_LoadBlob_KEY_PARMS(&offset, pubKeyBlob, &tssKey.algorithmParms);
     96 	Trspi_LoadBlob_STORE_PUBKEY(&offset, pubKeyBlob, &tssKey.pubKey);
     97 	pubKeySize = offset;
     98 	free_key_refs(&tssKey);
     99 
    100 	/* Auth */
    101 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    102 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_AuthorizeMigrationKey);
    103 	result |= Trspi_Hash_UINT16(&hashCtx, tpmMigrationScheme);
    104 	result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKeyBlob);
    105 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    106 		return result;
    107 
    108 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_AuthorizeMigrationKey, hOwnerPolicy,
    109 					      FALSE, &digest, &ownerAuth)))
    110 		return result;
    111 
    112 	/* Send command */
    113 	if ((result = TCS_API(tspContext)->AuthorizeMigrationKey(tspContext, migrationScheme,
    114 								 pubKeySize, pubKeyBlob, &ownerAuth,
    115 								 pulMigTicketLength,
    116 								 prgbMigTicket)))
    117 		return result;
    118 
    119 	/* Validate Auth */
    120 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    121 	result |= Trspi_Hash_UINT32(&hashCtx, result);
    122 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_AuthorizeMigrationKey);
    123 	result |= Trspi_HashUpdate(&hashCtx, *pulMigTicketLength, *prgbMigTicket);
    124 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
    125 		*pulMigTicketLength = 0;
    126 		free(*prgbMigTicket);
    127 		return result;
    128 	}
    129 
    130 	if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth))) {
    131 		*pulMigTicketLength = 0;
    132 		free(*prgbMigTicket);
    133 		return result;
    134 	}
    135 
    136 	if ((result = __tspi_add_mem_entry(tspContext, *prgbMigTicket))) {
    137 		*pulMigTicketLength = 0;
    138 		free(*prgbMigTicket);
    139 		return result;
    140 	}
    141 
    142 	return TSS_SUCCESS;
    143 }
    144 
    145 TSS_RESULT
    146 Tspi_Key_CreateMigrationBlob(TSS_HKEY hKeyToMigrate,		/* in */
    147 			     TSS_HKEY hParentKey,		/* in */
    148 			     UINT32 ulMigTicketLength,		/* in */
    149 			     BYTE * rgbMigTicket,		/* in */
    150 			     UINT32 * pulRandomLength,		/* out */
    151 			     BYTE ** prgbRandom,		/* out */
    152 			     UINT32 * pulMigrationBlobLength,	/* out */
    153 			     BYTE ** prgbMigrationBlob)		/* out */
    154 {
    155 	TPM_AUTH parentAuth, entityAuth;
    156 	TPM_AUTH *pParentAuth;
    157 	TCPA_RESULT result;
    158 	UINT64 offset;
    159 	TCPA_DIGEST digest;
    160 	UINT32 keyToMigrateSize;
    161 	BYTE *keyToMigrateBlob = NULL;
    162 	TSS_HPOLICY hParentPolicy;
    163 	TSS_HPOLICY hMigratePolicy;
    164 	TCPA_MIGRATIONKEYAUTH migAuth;
    165 	TSS_KEY tssKey;
    166 	TCS_KEY_HANDLE parentHandle;
    167 	TSS_BOOL parentUsesAuth;
    168 	UINT32 randomSize;
    169 	BYTE *random = NULL;
    170 	UINT32 blobSize;
    171 	BYTE *blob = NULL;
    172 	TSS_HCONTEXT tspContext;
    173 	Trspi_HashCtx hashCtx;
    174 
    175 	__tspi_memset(&tssKey, 0, sizeof(TSS_KEY));
    176 
    177 	if (pulRandomLength == NULL || prgbRandom == NULL || rgbMigTicket == NULL ||
    178 	    pulMigrationBlobLength == NULL || prgbMigrationBlob == NULL)
    179 		return TSPERR(TSS_E_BAD_PARAMETER);
    180 
    181 	if (!obj_is_rsakey(hKeyToMigrate))
    182 		return TSPERR(TSS_E_INVALID_HANDLE);
    183 
    184 	if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &tspContext)))
    185 		return result;
    186 
    187 	if ((result = obj_rsakey_get_blob(hKeyToMigrate, &keyToMigrateSize, &keyToMigrateBlob)))
    188 		goto done;
    189 
    190 	if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hParentPolicy,
    191 					    &parentUsesAuth)))
    192 		goto done;
    193 
    194 	if ((result = obj_rsakey_get_policy(hKeyToMigrate, TSS_POLICY_MIGRATION, &hMigratePolicy,
    195 					    NULL)))
    196 		goto done;
    197 
    198 	/*  Parsing the migration scheme from the blob and key object */
    199 	__tspi_memset(&migAuth, 0, sizeof(TCPA_MIGRATIONKEYAUTH));
    200 
    201 	offset = 0;
    202 	if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, rgbMigTicket, &migAuth)))
    203 		goto done;
    204 
    205 	/* free these now, since none are used below */
    206 	free(migAuth.migrationKey.algorithmParms.parms);
    207 	migAuth.migrationKey.algorithmParms.parmSize = 0;
    208 	free(migAuth.migrationKey.pubKey.key);
    209 	migAuth.migrationKey.pubKey.keyLength = 0;
    210 
    211 	offset = 0;
    212 	if ((result = UnloadBlob_TSS_KEY(&offset, keyToMigrateBlob, &tssKey)))
    213 		goto done;
    214 
    215 	/* Generate the Authorization data */
    216 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    217 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMigrationBlob);
    218 	result |= Trspi_Hash_UINT16(&hashCtx, migAuth.migrationScheme);
    219 	result |= Trspi_HashUpdate(&hashCtx, ulMigTicketLength, rgbMigTicket);
    220 	result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize);
    221 	result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData);
    222 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    223 		goto done;
    224 
    225 	if (parentUsesAuth) {
    226 		if ((result = secret_PerformAuth_OIAP(hParentPolicy, TPM_ORD_CreateMigrationBlob,
    227 						      hParentPolicy, FALSE, &digest,
    228 						      &parentAuth)))
    229 			goto done;
    230 		pParentAuth = &parentAuth;
    231 	} else {
    232 		pParentAuth = NULL;
    233 	}
    234 
    235 	if ((result = secret_PerformAuth_OIAP(hKeyToMigrate, TPM_ORD_CreateMigrationBlob,
    236 					      hMigratePolicy, FALSE, &digest, &entityAuth)))
    237 		goto done;
    238 
    239 	if ((result = obj_rsakey_get_tcs_handle(hParentKey, &parentHandle)))
    240 		goto done;
    241 
    242 	if ((result = TCS_API(tspContext)->CreateMigrationBlob(tspContext, parentHandle,
    243 							       migAuth.migrationScheme,
    244 							       ulMigTicketLength, rgbMigTicket,
    245 							       tssKey.encSize, tssKey.encData,
    246 							       pParentAuth, &entityAuth,
    247 							       &randomSize, &random,
    248 							       &blobSize, &blob)))
    249 		goto done;
    250 
    251 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    252 	result |= Trspi_Hash_UINT32(&hashCtx, result);
    253 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMigrationBlob);
    254 	result |= Trspi_Hash_UINT32(&hashCtx, randomSize);
    255 	result |= Trspi_HashUpdate(&hashCtx, randomSize, random);
    256 	result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
    257 	result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
    258 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    259 		goto done;
    260 
    261 	if (parentUsesAuth) {
    262 		if ((result = obj_policy_validate_auth_oiap(hParentPolicy, &digest, &parentAuth)))
    263 			goto done;
    264 	}
    265 
    266 	if ((result = obj_policy_validate_auth_oiap(hMigratePolicy, &digest, &entityAuth)))
    267 		goto done;
    268 
    269 	free(tssKey.encData);
    270 	tssKey.encSize = blobSize;
    271 	tssKey.encData = blob;
    272 	/* Set blob to null since it will now be freed during key ref freeing */
    273 	blob = NULL;
    274 
    275 	offset = 0;
    276 	LoadBlob_TSS_KEY(&offset, NULL, &tssKey);
    277 
    278 	*pulMigrationBlobLength = offset;
    279 	*prgbMigrationBlob = calloc_tspi(tspContext, *pulMigrationBlobLength);
    280 	if (*prgbMigrationBlob == NULL) {
    281 		LogError("malloc of %u bytes failed.", *pulMigrationBlobLength);
    282 		result = TSPERR(TSS_E_OUTOFMEMORY);
    283 		goto done;
    284 	}
    285 	offset = 0;
    286 	LoadBlob_TSS_KEY(&offset, *prgbMigrationBlob, &tssKey);
    287 
    288 	if (randomSize) {
    289 		if ((result = __tspi_add_mem_entry(tspContext, random)))
    290 			goto done;
    291 	}
    292 	*pulRandomLength = randomSize;
    293 	*prgbRandom = random;
    294 
    295 done:
    296 	if (result)
    297 		free(random);
    298 	free_tspi(tspContext, keyToMigrateBlob);
    299 	free_key_refs(&tssKey);
    300 	free(blob);
    301 
    302 	return result;
    303 }
    304 
    305 TSS_RESULT
    306 Tspi_Key_ConvertMigrationBlob(TSS_HKEY hKeyToMigrate,		/* in */
    307 			      TSS_HKEY hParentKey,		/* in */
    308 			      UINT32 ulRandomLength,		/* in */
    309 			      BYTE * rgbRandom,			/* in */
    310 			      UINT32 ulMigrationBlobLength,	/* in */
    311 			      BYTE * rgbMigrationBlob)		/* in */
    312 {
    313 	TCPA_RESULT result;
    314 	TSS_KEY tssKey;
    315 	UINT32 outDataSize;
    316 	BYTE *outData = NULL;
    317 	TCS_KEY_HANDLE parentHandle;
    318 	TPM_AUTH parentAuth;
    319 	TSS_HPOLICY hParentPolicy;
    320 	TCPA_DIGEST digest;
    321 	TSS_BOOL useAuth;
    322 	TPM_AUTH *pParentAuth;
    323 	TSS_HCONTEXT tspContext;
    324 	Trspi_HashCtx hashCtx;
    325 	UINT64 offset;
    326 
    327 	__tspi_memset(&tssKey, 0, sizeof(TSS_KEY));
    328 
    329 	if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &tspContext)))
    330 		return result;
    331 
    332 	if (!obj_is_rsakey(hParentKey))
    333 		return TSPERR(TSS_E_INVALID_HANDLE);
    334 
    335 	/* Get the parent key handle */
    336 	if ((result = obj_rsakey_get_tcs_handle(hParentKey, &parentHandle)))
    337 		return result;
    338 
    339 	/* Get the policy */
    340 	if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE,
    341 					&hParentPolicy, &useAuth)))
    342 		return result;
    343 
    344 	offset = 0;
    345 	if ((result = UnloadBlob_TSS_KEY(&offset, rgbMigrationBlob, &tssKey)))
    346 		return result;
    347 
    348 	/* Generate the authorization */
    349 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    350 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ConvertMigrationBlob);
    351 	result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize);
    352 	result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData);
    353 	result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength);
    354 	result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom);
    355 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    356 		goto done;
    357 
    358 	if (useAuth) {
    359 		if ((result = secret_PerformAuth_OIAP(hParentPolicy, TPM_ORD_ConvertMigrationBlob,
    360 						      hParentPolicy, FALSE, &digest, &parentAuth)))
    361 			goto done;
    362 		pParentAuth = &parentAuth;
    363 	} else {
    364 		pParentAuth = NULL;
    365 	}
    366 
    367 	if ((result = TCS_API(tspContext)->ConvertMigrationBlob(tspContext, parentHandle,
    368 								tssKey.encSize, tssKey.encData,
    369 								ulRandomLength, rgbRandom,
    370 								pParentAuth,
    371 								&outDataSize, &outData)))
    372 		goto done;
    373 
    374 	/* add validation */
    375 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    376 	result |= Trspi_Hash_UINT32(&hashCtx, result);
    377 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ConvertMigrationBlob);
    378 	result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
    379 	result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
    380 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    381 		goto done;
    382 
    383 	if (useAuth) {
    384 		if ((result = obj_policy_validate_auth_oiap(hParentPolicy, &digest, &parentAuth)))
    385 			goto done;
    386 	}
    387 
    388 	/* Set the key object to the now migrated key */
    389 	if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, ulMigrationBlobLength, rgbMigrationBlob)))
    390 		goto done;
    391 	if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData)))
    392 		goto done;
    393 	result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0);
    394 
    395 done:
    396 	free_key_refs(&tssKey);
    397 	free(outData);
    398 
    399 	return result;
    400 }
    401