Esempio n. 1
0
TSS_RESULT
fill_key_info2(struct key_disk_cache *d, struct key_mem_cache *m, TSS_KM_KEYINFO2 *key_info)
{
	BYTE tmp_blob[2048];
	UINT16 tmp_blob_size = 2048;
	TSS_KEY tmp_key;
	UINT64 offset;
	TSS_RESULT result;

	if (m == NULL) {
		key_info->fIsLoaded = FALSE;

		/* read key from disk */
		if ((result = ps_get_key_by_cache_entry(d, (BYTE *)&tmp_blob, &tmp_blob_size)))
			return result;

		offset = 0;
		/* XXX add a real context handle here */
		if ((result = UnloadBlob_TSS_KEY(&offset, tmp_blob, &tmp_key)))
			return result;

		if (tmp_key.hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &tmp_key.hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &tmp_key.authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
		destroy_key_refs(&tmp_key);
	} else {
		if (m->tpm_handle == NULL_TPM_HANDLE)
			key_info->fIsLoaded = FALSE;
		else
			key_info->fIsLoaded = TRUE;

		if (m->blob->hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &m->blob->hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &m->blob->authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
	}

	memcpy(&key_info->keyUUID, &d->uuid, sizeof(TSS_UUID));
	memcpy(&key_info->parentKeyUUID, &d->parent_uuid, sizeof(TSS_UUID));

	/* Fill the two new TSS_KM_KEYINFO2 fields here */
	key_info->persistentStorageTypeParent = d->flags & CACHE_FLAG_PARENT_PS_SYSTEM ?
						TSS_PS_TYPE_SYSTEM : TSS_PS_TYPE_USER;
	key_info->persistentStorageType = TSS_PS_TYPE_SYSTEM;

	return get_vendor_data(d, &key_info->ulVendorDataLength, &key_info->rgbVendorData);
}
Esempio n. 2
0
TSS_RESULT
TCS_GetRegisteredKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TSS_UUID *KeyUUID,		/* in */
			      TSS_KM_KEYINFO ** ppKeyInfo)	/* out */
{
	TSS_RESULT result;
	UINT64 offset;
	BYTE tcpaKeyBlob[1024];
	TSS_KEY tcpaKey;
	UINT16 keySize = sizeof (tcpaKeyBlob);
	TSS_UUID parentUUID;

	/* This should be set in case we return before the malloc */
	*ppKeyInfo = NULL;

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = ps_get_key_by_uuid(KeyUUID, tcpaKeyBlob, &keySize))) {
		return TCSERR(TSS_E_PS_KEY_NOTFOUND);
	}

	if ((result = getParentUUIDByUUID(KeyUUID, &parentUUID)))
		return TCSERR(TSS_E_FAIL);

	*ppKeyInfo = malloc(sizeof(TSS_KM_KEYINFO));
	if (*ppKeyInfo == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(TSS_KM_KEYINFO));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	UnloadBlob_TSS_KEY(&offset, tcpaKeyBlob, &tcpaKey);

	(*ppKeyInfo)->bAuthDataUsage = tcpaKey.authDataUsage;

	(*ppKeyInfo)->fIsLoaded = FALSE;

	if (tcpaKey.hdr.key12.tag == TPM_TAG_KEY12) {
		(*ppKeyInfo)->versionInfo.bMajor = TSS_SPEC_MAJOR;
		(*ppKeyInfo)->versionInfo.bMinor = TSS_SPEC_MINOR;
		(*ppKeyInfo)->versionInfo.bRevMajor = 0;
		(*ppKeyInfo)->versionInfo.bRevMinor = 0;
	} else {
		(*ppKeyInfo)->versionInfo.bMajor = tcpaKey.hdr.key11.ver.major;
		(*ppKeyInfo)->versionInfo.bMinor = tcpaKey.hdr.key11.ver.minor;
		(*ppKeyInfo)->versionInfo.bRevMajor = tcpaKey.hdr.key11.ver.revMajor;
		(*ppKeyInfo)->versionInfo.bRevMinor = tcpaKey.hdr.key11.ver.revMinor;
	}

	memcpy(&((*ppKeyInfo)->keyUUID), KeyUUID, sizeof(TSS_UUID));

	(*ppKeyInfo)->ulVendorDataLength = 0;
	(*ppKeyInfo)->rgbVendorData = 0;

	memcpy(&((*ppKeyInfo)->parentKeyUUID), &parentUUID, sizeof(TSS_UUID));
	return TSS_SUCCESS;
}
Esempio n. 3
0
TSS_RESULT
copy_key_info2(int fd, TSS_KM_KEYINFO2 *ki, struct key_disk_cache *c)
{
	TSS_KEY key;
	BYTE blob[4096];
	UINT64 offset;
	TSS_RESULT result;
	off_t off;

	/* Set the file pointer to the offset that the key blob is at */
	off = lseek(fd, TSSPS_BLOB_DATA_OFFSET(c), SEEK_SET);
	if (off == ((off_t)-1)) {
		LogDebug("lseek: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	/* Read in the key blob */
	if ((result = read_data(fd, (void *)blob, c->blob_size))) {
		LogDebug("%s", __FUNCTION__);
		return result;
	}

	/* Expand the blob into a useable form */
	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, blob, &key)))
		return result;

	if (key.hdr.key12.tag == TPM_TAG_KEY12) {
		ki->versionInfo.bMajor = TSS_SPEC_MAJOR;
		ki->versionInfo.bMinor = TSS_SPEC_MINOR;
		ki->versionInfo.bRevMajor = 0;
		ki->versionInfo.bRevMinor = 0;
	} else
		memcpy(&ki->versionInfo, &key.hdr.key11.ver, sizeof(TSS_VERSION));
	memcpy(&ki->keyUUID, &c->uuid, sizeof(TSS_UUID));
	memcpy(&ki->parentKeyUUID, &c->parent_uuid, sizeof(TSS_UUID));

	/* CHECK: fill the two new fields of TSS_KM_KEYINFO2 */
	ki->persistentStorageType = TSS_PS_TYPE_USER;
	ki->persistentStorageTypeParent = c->flags & CACHE_FLAG_PARENT_PS_SYSTEM ?
					  TSS_PS_TYPE_SYSTEM : TSS_PS_TYPE_USER;

	ki->bAuthDataUsage = key.authDataUsage;

	free_key_refs(&key);

	return TSS_SUCCESS;
}
Esempio n. 4
0
/*
 * disk store format:
 *
 * TrouSerS 0.2.0 and before:
 * Version 0:                  cached?
 * [UINT32   num_keys_on_disk]
 * [TSS_UUID uuid0           ] yes
 * [TSS_UUID uuid_parent0    ] yes
 * [UINT16   pub_data_size0  ] yes
 * [UINT16   blob_size0      ] yes
 * [UINT16   cache_flags0    ] yes
 * [BYTE[]   pub_data0       ]
 * [BYTE[]   blob0           ]
 * [...]
 *
 * TrouSerS 0.2.1+
 * Version 1:                  cached?
 * [BYTE     PS version = '\1']
 * [UINT32   num_keys_on_disk ]
 * [TSS_UUID uuid0            ] yes
 * [TSS_UUID uuid_parent0     ] yes
 * [UINT16   pub_data_size0   ] yes
 * [UINT16   blob_size0       ] yes
 * [UINT32   vendor_data_size0] yes
 * [UINT16   cache_flags0     ] yes
 * [BYTE[]   pub_data0        ]
 * [BYTE[]   blob0            ]
 * [BYTE[]   vendor_data0     ]
 * [...]
 *
 */
TSS_RESULT
psfile_write_key(int fd,
		TSS_UUID *uuid,
		TSS_UUID *parent_uuid,
		UINT32 *parent_ps,
		BYTE *vendor_data,
		UINT32 vendor_size,
		BYTE *key_blob,
		UINT16 key_blob_size)
{
	TSS_KEY key;
	UINT16 pub_key_size, cache_flags = CACHE_FLAG_VALID;
	UINT64 offset;
	int rc = 0;

	/* leaving the cache flag for parent ps type as 0 implies TSS_PS_TYPE_USER */
	if (*parent_ps == TSS_PS_TYPE_SYSTEM)
		cache_flags |= CACHE_FLAG_PARENT_PS_SYSTEM;

	/* Unload the blob to get the public key */
	offset = 0;
	if ((rc = UnloadBlob_TSS_KEY(&offset, key_blob, &key)))
		return rc;

	pub_key_size = key.pubKey.keyLength;

        if ((rc = write_key_init(fd, pub_key_size, key_blob_size, vendor_size)) < 0)
                goto done;

	/* offset now holds the number of bytes from the beginning of the file
	 * the key will be stored at
	 */
	offset = rc;

#ifdef TSS_DEBUG
	if (offset == 0)
		LogDebug("ERROR: key being written with offset 0!!");
#endif

	/* [TSS_UUID uuid0           ] yes */
        if ((rc = write_data(fd, (void *)uuid, sizeof(TSS_UUID)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [TSS_UUID uuid_parent0    ] yes */
        if ((rc = write_data(fd, (void *)parent_uuid, sizeof(TSS_UUID)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [UINT16   pub_data_size0  ] yes */
        if ((rc = write_data(fd, &pub_key_size, sizeof(UINT16)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [UINT16   blob_size0      ] yes */
        if ((rc = write_data(fd, &key_blob_size, sizeof(UINT16)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [UINT32   vendor_data_size0 ] yes */
        if ((rc = write_data(fd, &vendor_size, sizeof(UINT32)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [UINT16   cache_flags0    ] yes */
        if ((rc = write_data(fd, &cache_flags, sizeof(UINT16)))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [BYTE[]   pub_data0       ] no */
        if ((rc = write_data(fd, (void *)key.pubKey.key, pub_key_size))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [BYTE[]   blob0           ] no */
        if ((rc = write_data(fd, (void *)key_blob, key_blob_size))) {
		LogError("%s", __FUNCTION__);
                goto done;
	}

	/* [BYTE[]   vendor_data0    ] no */
	if (vendor_size > 0) {
		if ((rc = write_data(fd, (void *)vendor_data, vendor_size))) {
			LogError("%s", __FUNCTION__);
			goto done;
		}
	}

	if ((rc = cache_key((UINT32)offset, cache_flags, uuid, parent_uuid, pub_key_size,
					key_blob_size, vendor_size)))
                goto done;
done:
	destroy_key_refs(&key);

        return rc;
}
Esempio n. 5
0
TSS_RESULT
TCSP_TakeOwnership_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    UINT16 protocolID,	/* in */
			    UINT32 encOwnerAuthSize,	/* in  */
			    BYTE * encOwnerAuth,	/* in */
			    UINT32 encSrkAuthSize,	/* in */
			    BYTE * encSrkAuth,	/* in */
			    UINT32 srkInfoSize,	/*in */
			    BYTE * srkInfo,	/*in */
			    TPM_AUTH * ownerAuth,	/* in, out */
			    UINT32 * srkKeySize,	/*out */
			    BYTE ** srkKey)	/*out */
{
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	TSS_KEY srkKeyContainer;
	BYTE fake_pubkey[256] = { 0, }, fake_srk[2048] = { 0, };
	BYTE oldAuthDataUsage;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	/* Check on the Atmel Bug Patch */
	offset = 0;
	UnloadBlob_TSS_KEY(&offset, srkInfo, &srkKeyContainer);
	oldAuthDataUsage = srkKeyContainer.authDataUsage;
	LogDebug("auth data usage is %.2X", oldAuthDataUsage);

	offset = 0;
	if ((result = tpm_rqu_build(TPM_ORD_TakeOwnership, &offset, txBlob, protocolID,
				    encOwnerAuthSize, encOwnerAuth, encSrkAuthSize, encSrkAuth,
				    srkInfoSize, srkInfo, ownerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_TakeOwnership, txBlob, paramSize, srkKeySize,
					    srkKey, ownerAuth)))
			goto done;

		offset = 0;
		if ((result = UnloadBlob_TSS_KEY(&offset, *srkKey, &srkKeyContainer))) {
			*srkKeySize = 0;
			free(*srkKey);
			goto done;
		}

		if (srkKeyContainer.authDataUsage != oldAuthDataUsage) {
			LogDebug("AuthDataUsage was changed by TPM.  Atmel Bug. Fixing it in PS");
			srkKeyContainer.authDataUsage = oldAuthDataUsage;
		}

#ifdef TSS_BUILD_PS
		{
			BYTE *save;

			/* Once the key file is created, it stays forever. There could be
			 * migratable keys in the hierarchy that are still useful to someone.
			 */
			result = ps_remove_key(&SRK_UUID);
			if (result != TSS_SUCCESS && result != TCSERR(TSS_E_PS_KEY_NOTFOUND)) {
				destroy_key_refs(&srkKeyContainer);
				LogError("Error removing SRK from key file.");
				*srkKeySize = 0;
				free(*srkKey);
				goto done;
			}

			/* Set the SRK pubkey to all 0's before writing the SRK to disk, this is for
			 * privacy reasons as outlined in the TSS spec */
			save = srkKeyContainer.pubKey.key;
			srkKeyContainer.pubKey.key = fake_pubkey;
			offset = 0;
			LoadBlob_TSS_KEY(&offset, fake_srk, &srkKeyContainer);

			if ((result = ps_write_key(&SRK_UUID, &NULL_UUID, NULL, 0, fake_srk,
						   offset))) {
				destroy_key_refs(&srkKeyContainer);
				LogError("Error writing SRK to disk");
				*srkKeySize = 0;
				free(*srkKey);
				goto done;
			}

			srkKeyContainer.pubKey.key = save;
		}
#endif
		if ((result = mc_add_entry_init(SRK_TPM_HANDLE, SRK_TPM_HANDLE, &srkKeyContainer,
					        &SRK_UUID))) {
			destroy_key_refs(&srkKeyContainer);
			LogError("Error creating SRK mem cache entry");
			*srkKeySize = 0;
			free(*srkKey);
		}
		destroy_key_refs(&srkKeyContainer);
	}
	LogResult("TakeOwnership", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}
Esempio n. 6
0
TSS_RESULT
secret_TakeOwnership(TSS_HKEY hEndorsementPubKey,
		     TSS_HTPM hTPM,
		     TSS_HKEY hKeySRK,
		     TPM_AUTH * auth,
		     UINT32 * encOwnerAuthLength,
		     BYTE * encOwnerAuth, UINT32 * encSRKAuthLength, BYTE * encSRKAuth)
{
	TSS_RESULT result;
	UINT32 endorsementKeySize;
	BYTE *endorsementKey;
	TSS_KEY dummyKey;
	UINT64 offset;
	TCPA_SECRET ownerSecret;
	TCPA_SECRET srkSecret;
	TCPA_DIGEST digest;
	TSS_HPOLICY hSrkPolicy;
	TSS_HPOLICY hOwnerPolicy;
	UINT32 srkKeyBlobLength;
	BYTE *srkKeyBlob;
	TSS_HCONTEXT tspContext;
	UINT32 ownerMode, srkMode;
	Trspi_HashCtx hashCtx;


	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	/*************************************************
	 *	First, get the policy objects and check them for how
	 *		to handle the secrets.  If they cannot be found
	 *		or there is an error, then we must fail
	 **************************************************/

	/* First get the Owner Policy */
	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
		return result;

	/* Now get the SRK Policy */
	if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSrkPolicy, NULL)))
		return result;

	if ((result = obj_policy_get_mode(hOwnerPolicy, &ownerMode)))
		return result;

	if ((result = obj_policy_get_mode(hSrkPolicy, &srkMode)))
		return result;

	/* If the policy callback's aren't the same, that's an error if one is callback */
	if (srkMode == TSS_SECRET_MODE_CALLBACK || ownerMode == TSS_SECRET_MODE_CALLBACK) {
		if (srkMode != TSS_SECRET_MODE_CALLBACK || ownerMode != TSS_SECRET_MODE_CALLBACK) {
			LogError("Policy callback modes for SRK policy and Owner policy differ.");
			return TSPERR(TSS_E_BAD_PARAMETER);
		}
	}

	if (ownerMode != TSS_SECRET_MODE_CALLBACK) {
		/* First, get the Endorsement Public Key for Encrypting */
		if ((result = obj_rsakey_get_blob(hEndorsementPubKey, &endorsementKeySize,
						  &endorsementKey)))
			return result;

		/* now stick it in a Key Structure */
		offset = 0;
		if ((result = UnloadBlob_TSS_KEY(&offset, endorsementKey, &dummyKey))) {
			free_tspi(tspContext, endorsementKey);
			return result;
		}
		free_tspi(tspContext, endorsementKey);

		if ((result = obj_policy_get_secret(hOwnerPolicy, TR_SECRET_CTX_NEW,
						    &ownerSecret))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		if ((result = obj_policy_get_secret(hSrkPolicy, TR_SECRET_CTX_NEW, &srkSecret))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		/* Encrypt the Owner, SRK Authorizations */
		if ((result = Trspi_RSA_Encrypt(ownerSecret.authdata, 20, encOwnerAuth,
						encOwnerAuthLength, dummyKey.pubKey.key,
						dummyKey.pubKey.keyLength))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		if ((result = Trspi_RSA_Encrypt(srkSecret.authdata, 20, encSRKAuth,
						encSRKAuthLength, dummyKey.pubKey.key,
						dummyKey.pubKey.keyLength))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		free(dummyKey.pubKey.key);
		free(dummyKey.algorithmParms.parms);
	} else {
		*encOwnerAuthLength = 256;
		*encSRKAuthLength = 256;
		if ((result = obj_policy_do_takeowner(hOwnerPolicy, hTPM, hEndorsementPubKey,
						      *encOwnerAuthLength, encOwnerAuth)))
			return result;
	}

	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
		return result;

	/* Authorizatin Digest Calculation */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_OWNER);
	result |= Trspi_Hash_UINT32(&hashCtx, *encOwnerAuthLength);
	result |= Trspi_HashUpdate(&hashCtx, *encOwnerAuthLength, encOwnerAuth);
	result |= Trspi_Hash_UINT32(&hashCtx, *encSRKAuthLength);
	result |= Trspi_HashUpdate(&hashCtx, *encSRKAuthLength, encSRKAuth);
	result |= Trspi_HashUpdate(&hashCtx, srkKeyBlobLength, srkKeyBlob);
	free_tspi(tspContext, srkKeyBlob);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	/* HMAC for the final digest */
	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_TakeOwnership, hOwnerPolicy, FALSE,
					      &digest, auth)))
		return result;

	return TSS_SUCCESS;
}
Esempio n. 7
0
TSS_RESULT
Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext,	/* in */
			   TSS_HKEY hUnwrappingKey,	/* in */
			   UINT32 ulBlobLength,		/* in */
			   BYTE * rgbBlobData,		/* in */
			   TSS_HKEY * phKey)		/* out */
{
	TPM_AUTH auth;
	UINT64 offset;
	TCPA_DIGEST digest;
	TSS_RESULT result;
	UINT32 keyslot;
	TSS_HPOLICY hPolicy;
	TCS_KEY_HANDLE tcsParentHandle, myTCSKeyHandle;
	TSS_KEY keyContainer;
	TSS_BOOL useAuth;
	TPM_AUTH *pAuth;
	TSS_FLAG initFlags;
	UINT16 realKeyBlobSize;
	TCPA_KEY_USAGE keyUsage;
	UINT32 pubLen;
	Trspi_HashCtx hashCtx;
	TPM_COMMAND_CODE ordinal;

	if (phKey == NULL || rgbBlobData == NULL )
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!obj_is_rsakey(hUnwrappingKey))
		return TSPERR(TSS_E_INVALID_HANDLE);

	if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
		return result;

	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, rgbBlobData, &keyContainer)))
		return result;
	realKeyBlobSize = offset;
	pubLen = keyContainer.pubKey.keyLength;
	keyUsage = keyContainer.keyUsage;
	/* free these now, since they're not used below */
	free_key_refs(&keyContainer);

	if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
		return result;

	if (useAuth) {
		/* Create the Authorization */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
		result |= Trspi_HashUpdate(&hashCtx, ulBlobLength, rgbBlobData);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			return result;

		if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
						      &digest, &auth)))
			return result;

		pAuth = &auth;
	} else {
		pAuth = NULL;
	}

	if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, ulBlobLength,
							 rgbBlobData, pAuth, &myTCSKeyHandle,
							 &keyslot)))
		return result;

	if (useAuth) {
		/* ---  Validate return auth */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
		if (ordinal == TPM_ORD_LoadKey)
			result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			return result;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
			return result;
	}

	/* ---  Create a new Object */
	initFlags = 0;
	if (pubLen == 0x100)
		initFlags |= TSS_KEY_SIZE_2048;
	else if (pubLen == 0x80)
		initFlags |= TSS_KEY_SIZE_1024;
	else if (pubLen == 0x40)
		initFlags |= TSS_KEY_SIZE_512;

	/* clear the key type field */
	initFlags &= ~TSS_KEY_TYPE_MASK;

	if (keyUsage == TPM_KEY_STORAGE)
		initFlags |= TSS_KEY_TYPE_STORAGE;
	else
		initFlags |= TSS_KEY_TYPE_SIGNING;	/* loading the blob
							   will fix this
							   back to what it
							   should be. */

	if ((result = obj_rsakey_add(tspContext, initFlags, phKey))) {
		LogDebug("Failed create object");
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if ((result = obj_rsakey_set_tcpakey(*phKey,realKeyBlobSize, rgbBlobData))) {
		LogDebug("Key loaded but failed to setup the key object"
			  "correctly");
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return obj_rsakey_set_tcs_handle(*phKey, myTCSKeyHandle);
}
Esempio n. 8
0
TSS_RESULT
Tspi_Key_WrapKey(TSS_HKEY hKey,			/* in */
		 TSS_HKEY hWrappingKey,		/* in */
		 TSS_HPCRS hPcrComposite)	/* in, may be NULL */
{
	TSS_HPOLICY hUsePolicy, hMigPolicy;
	TCPA_SECRET usage, migration;
	TSS_RESULT result;
	BYTE *keyPrivBlob = NULL, *wrappingPubKey = NULL, *keyBlob = NULL;
	UINT32 keyPrivBlobLen, wrappingPubKeyLen, keyBlobLen;
	BYTE newPrivKey[214]; /* its not magic, see TPM 1.1b spec p.71 */
	BYTE encPrivKey[256];
	UINT32 newPrivKeyLen = 214, encPrivKeyLen = 256;
	UINT64 offset;
	TSS_KEY keyContainer;
	TCPA_DIGEST digest;
	TSS_HCONTEXT tspContext;
	Trspi_HashCtx hashCtx;

	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
		return result;

	if (hPcrComposite) {
		if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
			return result;
	}

	/* get the key to be wrapped's private key */
	if ((result = obj_rsakey_get_priv_blob(hKey, &keyPrivBlobLen, &keyPrivBlob)))
		goto done;

	/* get the key to be wrapped's blob */
	if ((result = obj_rsakey_get_blob(hKey, &keyBlobLen, &keyBlob)))
		goto done;

	/* get the wrapping key's public key */
	if ((result = obj_rsakey_get_modulus(hWrappingKey, &wrappingPubKeyLen, &wrappingPubKey)))
		goto done;

	/* get the key to be wrapped's usage policy */
	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hUsePolicy, NULL)))
		goto done;

	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_MIGRATION, &hMigPolicy, NULL)))
		goto done;

	if ((result = obj_policy_get_secret(hUsePolicy, TR_SECRET_CTX_NEW, &usage)))
		goto done;

	if ((result = obj_policy_get_secret(hMigPolicy, TR_SECRET_CTX_NEW, &migration)))
		goto done;

	memset(&keyContainer, 0, sizeof(TSS_KEY));

	/* unload the key to be wrapped's blob */
	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer)))
		return result;

	/* load the key's attributes into an object and get its hash value */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Hash_TSS_PRIVKEY_DIGEST(&hashCtx, &keyContainer);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	free_key_refs(&keyContainer);

	/* create the plaintext private key blob */
	offset = 0;
	Trspi_LoadBlob_BYTE(&offset, TCPA_PT_ASYM, newPrivKey);
	Trspi_LoadBlob(&offset, 20, newPrivKey, usage.authdata);
	Trspi_LoadBlob(&offset, 20, newPrivKey, migration.authdata);
	Trspi_LoadBlob(&offset, 20, newPrivKey, digest.digest);
	Trspi_LoadBlob_UINT32(&offset, keyPrivBlobLen, newPrivKey);
	Trspi_LoadBlob(&offset, keyPrivBlobLen, newPrivKey, keyPrivBlob);
	newPrivKeyLen = offset;

	/* encrypt the private key blob */
	if ((result = Trspi_RSA_Encrypt(newPrivKey, newPrivKeyLen, encPrivKey,
					&encPrivKeyLen, wrappingPubKey,
					wrappingPubKeyLen)))
		goto done;

	/* set the new encrypted private key in the wrapped key object */
	if ((result = obj_rsakey_set_privkey(hKey, FALSE, encPrivKeyLen, encPrivKey)))
		goto done;

done:
	free_tspi(tspContext, keyPrivBlob);
	free_tspi(tspContext, keyBlob);
	free_tspi(tspContext, wrappingPubKey);
	return result;
}
Esempio n. 9
0
TSS_RESULT
Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext,	/* in */
				TSS_FLAG persistentStorageType,	/* in */
				TSS_ALGORITHM_ID algID,		/* in */
				UINT32 ulPublicInfoLength,	/* in */
				BYTE * rgbPublicInfo,		/* in */
				TSS_HKEY * phKey)		/* out */
{
	TCPA_ALGORITHM_ID tcsAlgID;
	UINT32 keyBlobSize;
	BYTE *keyBlob;
	TSS_RESULT result;
	TSS_HKEY keyOutHandle;
	UINT32 flag = 0;
	TSS_KEY keyContainer;
	UINT64 offset;

	if (phKey == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!obj_is_context(tspContext))
		return TSPERR(TSS_E_INVALID_HANDLE);

	switch (algID) {
		case TSS_ALG_RSA:
			tcsAlgID = TCPA_ALG_RSA;
			break;
		default:
			LogError("Algorithm ID was not type RSA.");
			return TSPERR(TSS_E_BAD_PARAMETER);
	}

	if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
		if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID,
							       ulPublicInfoLength, rgbPublicInfo,
							       &keyBlobSize, &keyBlob)))
			return result;

	} else if (persistentStorageType == TSS_PS_TYPE_USER) {
		return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo,
					 phKey);
	} else
		return TSPERR(TSS_E_BAD_PARAMETER);

	/* need to setup the init flags of the create object based on
	 * the size of the blob's pubkey */
	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) {
		free(keyBlob);
		return result;
	}

	/* begin setting up the key object */
	switch (keyContainer.pubKey.keyLength) {
		case 16384/8:
			flag |= TSS_KEY_SIZE_16384;
			break;
		case 8192/8:
			flag |= TSS_KEY_SIZE_8192;
			break;
		case 4096/8:
			flag |= TSS_KEY_SIZE_4096;
			break;
		case 2048/8:
			flag |= TSS_KEY_SIZE_2048;
			break;
		case 1024/8:
			flag |= TSS_KEY_SIZE_1024;
			break;
		case 512/8:
			flag |= TSS_KEY_SIZE_512;
			break;
		default:
			LogError("Key was not a known keylength.");
			free(keyBlob);
			free_key_refs(&keyContainer);
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if (keyContainer.keyUsage == TPM_KEY_SIGNING)
		flag |= TSS_KEY_TYPE_SIGNING;
	else if (keyContainer.keyUsage == TPM_KEY_STORAGE)
		flag |= TSS_KEY_TYPE_STORAGE;
	else if (keyContainer.keyUsage == TPM_KEY_IDENTITY)
		flag |= TSS_KEY_TYPE_IDENTITY;
	else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE)
		flag |= TSS_KEY_TYPE_AUTHCHANGE;
	else if (keyContainer.keyUsage == TPM_KEY_BIND)
		flag |= TSS_KEY_TYPE_BIND;
	else if (keyContainer.keyUsage == TPM_KEY_LEGACY)
		flag |= TSS_KEY_TYPE_LEGACY;

	if (keyContainer.authDataUsage == TPM_AUTH_NEVER)
		flag |= TSS_KEY_NO_AUTHORIZATION;
	else
		flag |= TSS_KEY_AUTHORIZATION;

	if (keyContainer.keyFlags & TPM_MIGRATABLE)
		flag |= TSS_KEY_MIGRATABLE;
	else
		flag |= TSS_KEY_NOT_MIGRATABLE;

	if (keyContainer.keyFlags & TPM_VOLATILE)
		flag |= TSS_KEY_VOLATILE;
	else
		flag |= TSS_KEY_NON_VOLATILE;

#ifdef TSS_BUILD_CMK
	if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY)
		flag |= TSS_KEY_CERTIFIED_MIGRATABLE;
	else
		flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE;
#endif

	/* Create a new Key Object */
	if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) {
		free(keyBlob);
		free_key_refs(&keyContainer);
		return result;
	}
	/* Stick the info into this net KeyObject */
	if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) {
		free(keyBlob);
		free_key_refs(&keyContainer);
		return result;
	}

	free(keyBlob);
	free_key_refs(&keyContainer);
	*phKey = keyOutHandle;

	return TSS_SUCCESS;
}
Esempio n. 10
0
/*
 * read the PS file pointed to by fd and create a cache based on it
 */
int
init_disk_cache(int fd)
{
	UINT32 num_keys = get_num_keys_in_file(fd);
	UINT16 i;
	UINT64 tmp_offset;
	int rc = 0, offset;
	struct key_disk_cache *tmp, *prev = NULL;
	BYTE srk_blob[2048];
	TSS_KEY srk_key;
#ifdef TSS_DEBUG
	int valid_keys = 0;
#endif

	MUTEX_LOCK(disk_cache_lock);

	if (num_keys == 0) {
		key_disk_cache_head = NULL;
		MUTEX_UNLOCK(disk_cache_lock);
		return 0;
	} else {
		key_disk_cache_head = tmp = calloc(1, sizeof(struct key_disk_cache));
		if (tmp == NULL) {
			LogError("malloc of %zd bytes failed.",
						sizeof(struct key_disk_cache));
			rc = -1;
			goto err_exit;
		}
	}

	/* make sure the file pointer is where we expect, just after the number
	 * of keys on disk at the head of the file
	 */
	offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET);
	if (offset == ((off_t) - 1)) {
		LogError("lseek: %s", strerror(errno));
		rc = -1;
		goto err_exit;
	}

	for (i=0; i<num_keys; i++) {
		offset = lseek(fd, 0, SEEK_CUR);
		if (offset == ((off_t) - 1)) {
			LogError("lseek: %s", strerror(errno));
			rc = -1;
			goto err_exit;
		}
		tmp->offset = offset;
#ifdef TSS_DEBUG
		if (offset == 0)
			LogDebug("Storing key with file offset==0!!!");
#endif
		/* read UUID */
		if ((rc = read_data(fd, (void *)&tmp->uuid, sizeof(TSS_UUID)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}

		/* read parent UUID */
		if ((rc = read_data(fd, (void *)&tmp->parent_uuid, sizeof(TSS_UUID)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}

		/* pub data size */
		if ((rc = read_data(fd, &tmp->pub_data_size, sizeof(UINT16)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}
                tmp->pub_data_size = LE_16(tmp->pub_data_size);

		DBG_ASSERT(tmp->pub_data_size <= 2048 && tmp->pub_data_size > 0);

		/* blob size */
		if ((rc = read_data(fd, &tmp->blob_size, sizeof(UINT16)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}
                tmp->blob_size = LE_16(tmp->blob_size);
		DBG_ASSERT(tmp->blob_size <= 4096 && tmp->blob_size > 0);

		/* vendor data size */
		if ((rc = read_data(fd, &tmp->vendor_data_size, sizeof(UINT32)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}
                tmp->vendor_data_size = LE_32(tmp->vendor_data_size);

		/* cache flags */
		if ((rc = read_data(fd, &tmp->flags, sizeof(UINT16)))) {
			LogError("%s", __FUNCTION__);
			goto err_exit;
		}
                tmp->flags = LE_16(tmp->flags);

#ifdef TSS_DEBUG
		if (tmp->flags & CACHE_FLAG_VALID)
			valid_keys++;
#endif
		/* fast forward over the pub key */
		offset = lseek(fd, tmp->pub_data_size, SEEK_CUR);
		if (offset == ((off_t) - 1)) {
			LogError("lseek: %s", strerror(errno));
			rc = -1;
			goto err_exit;
		}

		/* if this is the SRK, load it into memory, since its already loaded in
		 * the chip */
		if (!memcmp(&SRK_UUID, &tmp->uuid, sizeof(TSS_UUID))) {
			/* read SRK blob from disk */
			if ((rc = read_data(fd, srk_blob, tmp->blob_size))) {
				LogError("%s", __FUNCTION__);
				goto err_exit;
			}

			tmp_offset = 0;
			if ((rc = UnloadBlob_TSS_KEY(&tmp_offset, srk_blob, &srk_key)))
				goto err_exit;
			/* add to the mem cache */
			if ((rc = mc_add_entry_init(SRK_TPM_HANDLE, SRK_TPM_HANDLE, &srk_key,
						    &SRK_UUID))) {
				LogError("Error adding SRK to mem cache.");
				destroy_key_refs(&srk_key);
				goto err_exit;
			}
			destroy_key_refs(&srk_key);
		} else {
			/* fast forward over the blob */
			offset = lseek(fd, tmp->blob_size, SEEK_CUR);
			if (offset == ((off_t) - 1)) {
				LogError("lseek: %s", strerror(errno));
				rc = -1;
				goto err_exit;
			}

			/* fast forward over the vendor data */
			offset = lseek(fd, tmp->vendor_data_size, SEEK_CUR);
			if (offset == ((off_t) - 1)) {
				LogError("lseek: %s", strerror(errno));
				rc = -1;
				goto err_exit;
			}
		}

		tmp->next = calloc(1, sizeof(struct key_disk_cache));
		if (tmp->next == NULL) {
			LogError("malloc of %zd bytes failed.",
					sizeof(struct key_disk_cache));
			rc = -1;
			goto err_exit;
		}
		prev = tmp;
		tmp = tmp->next;
	}

	/* delete the dangling, unfilled cache entry */
	free(tmp);
	prev->next = NULL;
	rc = 0;
	LogDebug("%s: found %d valid key(s) on disk.\n", __FUNCTION__, valid_keys);

err_exit:
	MUTEX_UNLOCK(disk_cache_lock);
	return rc;
}
Esempio n. 11
0
/*
 * disk store format:
 *
 * TrouSerS 0.2.1+
 * Version 1:                  cached?
 * [BYTE     PS version = '\1']
 * [UINT32   num_keys_on_disk ]
 * [TSS_UUID uuid0            ] yes
 * [TSS_UUID uuid_parent0     ] yes
 * [UINT16   pub_data_size0   ] yes
 * [UINT16   blob_size0       ] yes
 * [UINT32   vendor_data_size0] yes
 * [UINT16   cache_flags0     ] yes
 * [BYTE[]   pub_data0        ]
 * [BYTE[]   blob0            ]
 * [BYTE[]   vendor_data0     ]
 * [...]
 *
 */
TSS_RESULT
psfile_write_key(int fd,
		 TSS_UUID *uuid,
		 TSS_UUID *parent_uuid,
		 UINT32 parent_ps,
		 BYTE *key_blob,
		 UINT16 key_blob_size)
{
	TSS_RESULT result;
	TSS_KEY key;
	UINT32 zero = 0;
	UINT64 offset;
	UINT16 pub_key_size, cache_flags = 0;
	struct stat stat_buf;
	int rc, file_offset;

	/* leaving the cache flag for parent ps type as 0 implies TSS_PS_TYPE_USER */
	if (parent_ps == TSS_PS_TYPE_SYSTEM)
		cache_flags |= CACHE_FLAG_PARENT_PS_SYSTEM;

	if ((rc = fstat(fd, &stat_buf)) == -1) {
		LogDebugFn("stat failed: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	file_offset = stat_buf.st_size;

	if (file_offset < (int)TSSPS_KEYS_OFFSET) {
		if ((result = psfile_write_key_header(fd)))
			return result;
		file_offset = TSSPS_KEYS_OFFSET;
	}

	rc = lseek(fd, file_offset, SEEK_SET);
	if (rc == ((off_t)-1)) {
		LogDebug("lseek: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	/* Unload the blob to get the public key */
	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, key_blob, &key)))
		return result;

	pub_key_size = key.pubKey.keyLength;

	/* [TSS_UUID uuid0           ] yes */
        if ((result = write_data(fd, (void *)uuid, sizeof(TSS_UUID)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

	/* [TSS_UUID uuid_parent0    ] yes */
        if ((result = write_data(fd, (void *)parent_uuid, sizeof(TSS_UUID)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

	/* [UINT16   pub_data_size0  ] yes */
	pub_key_size = LE_16(pub_key_size);
        if ((result = write_data(fd, &pub_key_size, sizeof(UINT16)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}
	pub_key_size = LE_16(pub_key_size);

	/* [UINT16   blob_size0      ] yes */
	key_blob_size = LE_16(key_blob_size);
        if ((result = write_data(fd, &key_blob_size, sizeof(UINT16)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}
	key_blob_size = LE_16(key_blob_size);

	/* [UINT32   vendor_data_size0 ] yes */
        if ((result = write_data(fd, &zero, sizeof(UINT32)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

	/* [UINT16   cache_flags0    ] yes */
	cache_flags = LE_16(cache_flags);
        if ((result = write_data(fd, &cache_flags, sizeof(UINT16)))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}
	cache_flags = LE_16(cache_flags);

	/* [BYTE[]   pub_data0       ] no */
        if ((result = write_data(fd, (void *)key.pubKey.key, pub_key_size))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

	/* [BYTE[]   blob0           ] no */
        if ((result = write_data(fd, (void *)key_blob, key_blob_size))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

	if ((result = psfile_change_num_keys(fd, TSS_PSFILE_INCREMENT_NUM_KEYS))) {
		LogDebug("%s", __FUNCTION__);
		goto done;
	}

done:
	free_key_refs(&key);
        return result;
}