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-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
     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
     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
    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
    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
    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
    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
    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
    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