예제 #1
0
/*
 * Determine the default path to the persistent storage file and create it if it doesn't exist.
 */
TSS_RESULT
get_user_ps_path(char **file)
{
	TSS_RESULT result;
	char *file_name = NULL, *home_dir = NULL;
	struct passwd *pwp;
#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
	struct passwd pw;
#endif
	struct stat stat_buf;
	char buf[PASSWD_BUFSIZE];
	uid_t euid;
	int rc;

	if ((file_name = getenv("TSS_USER_PS_FILE"))) {
		*file = strdup(file_name);
		return (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY);
	}
#if (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__))
	MUTEX_LOCK(user_ps_path);
#endif

	euid = geteuid();

#if defined (SOLARIS)
	/*
         * Solaris keeps user PS in a local directory instead of
         * in the user's home directory, which may be shared
         * by multiple systems.
         *
         * The directory path on Solaris is /var/tpm/userps/[EUID]/
         */
        rc = snprintf(buf, sizeof (buf), "%s/%d", TSS_USER_PS_DIR, euid);
#else
	setpwent();
	while (1) {
#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
		rc = getpwent_r(&pw, buf, PASSWD_BUFSIZE, &pwp);
		if (rc) {
			LogDebugFn("USER PS: Error getting path to home directory: getpwent_r: %s",
				   strerror(rc));
			endpwent();
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}

#elif (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__))
		if ((pwp = getpwent()) == NULL) {
			LogDebugFn("USER PS: Error getting path to home directory: getpwent: %s",
                                   strerror(rc));
			endpwent();
			MUTEX_UNLOCK(user_ps_path);
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}
#endif
		if (euid == pwp->pw_uid) {
                        home_dir = strdup(pwp->pw_dir);
                        break;
                }
        }
        endpwent();

	if (!home_dir)
		return TSPERR(TSS_E_OUTOFMEMORY);

	/* Tack on TSS_USER_PS_DIR and see if it exists */
	rc = snprintf(buf, sizeof (buf), "%s/%s", home_dir, TSS_USER_PS_DIR);
#endif /* SOLARIS */
	if (rc == sizeof (buf)) {
		LogDebugFn("USER PS: Path to file too long! (> %d bytes)", PASSWD_BUFSIZE);
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto done;
	}

	errno = 0;
	if ((rc = stat(buf, &stat_buf)) == -1) {
		if (errno == ENOENT) {
			errno = 0;
			/* Create the user's ps directory if it is not there. */
			if ((rc = mkdir(buf, 0700)) == -1) {
				LogDebugFn("USER PS: Error creating dir: %s: %s", buf,
					   strerror(errno));
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		} else {
			LogDebugFn("USER PS: Error stating dir: %s: %s", buf, strerror(errno));
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

	/* Directory exists or has been created, return the path to the file */
#if defined (SOLARIS)
	rc = snprintf(buf, sizeof (buf), "%s/%d/%s", TSS_USER_PS_DIR, euid,
		      TSS_USER_PS_FILE);
#else
	rc = snprintf(buf, sizeof (buf), "%s/%s/%s", home_dir, TSS_USER_PS_DIR,
		      TSS_USER_PS_FILE);
#endif
	if (rc == sizeof (buf)) {
		LogDebugFn("USER PS: Path to file too long! (> %zd bytes)", sizeof (buf));
	} else
		*file = strdup(buf);

	result = (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY);
done:
	free(home_dir);
	return result;
}
예제 #2
0
TSS_RESULT
Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext,		/* in */
				     TSS_FLAG persistentStorageType,	/* in */
				     TSS_UUID * pUuidData,		/* in */
				     UINT32 * pulKeyHierarchySize,	/* out */
				     TSS_KM_KEYINFO ** ppKeyHierarchy)	/* out */
{
	TSS_RESULT result;
	TSS_KM_KEYINFO *tcsHier, *tspHier;
	UINT32 tcsHierSize, tspHierSize;
	TSS_UUID tcs_uuid;

	if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

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

	if (pUuidData) {
		if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
			if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData,
							     pulKeyHierarchySize,
							     ppKeyHierarchy)))
				return result;
		} else if (persistentStorageType == TSS_PS_TYPE_USER) {
			if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid,
							     &tspHierSize, &tspHier)))
				return result;

			if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize,
							     &tcsHier))) {
				free(tspHier);
				return result;
			}

			result = merge_key_hierarchies(tspContext, tspHierSize, tspHier,
						       tcsHierSize, tcsHier, pulKeyHierarchySize,
						       ppKeyHierarchy);
			free(tcsHier);
			free(tspHier);
		} else
			return TSPERR(TSS_E_BAD_PARAMETER);
	} else {
		if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize,
						     &tcsHier)))
			return result;

		if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) {
			free(tcsHier);
			return result;
		}

		result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize,
					       tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
		free(tcsHier);
		free(tspHier);
	}

	if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) {
		free(*ppKeyHierarchy);
		*ppKeyHierarchy = NULL;
		*pulKeyHierarchySize = 0;
	}

	return result;
}
예제 #3
0
TSS_RESULT
RPC_GetAuditDigestSigned_TP(struct host_table_entry *hte,
			    TCS_KEY_HANDLE keyHandle,		/* in */
			    TSS_BOOL closeAudit,		/* in */
			    TPM_NONCE *antiReplay,		/* in */
			    TPM_AUTH *privAuth,		/* in/out */
			    UINT32 *counterValueSize,		/* out */
			    BYTE **counterValue,		/* out */
			    TPM_DIGEST *auditDigest,		/* out */
			    TPM_DIGEST *ordinalDigest,		/* out */
			    UINT32 *sigSize,			/* out */
			    BYTE **sig)			/* out */
{
	TSS_RESULT result;
	TPM_AUTH null_auth;
	int i;

	initData(&hte->comm, 5);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGESTSIGNED;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	memset(&null_auth, 0, sizeof(TPM_AUTH));

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BOOL, 2, &closeAudit, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 3, antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (privAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	else {
		if (setData(TCSD_PACKET_TYPE_AUTH, 4, &null_auth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (privAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, counterValueSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*counterValue = (BYTE *)malloc(*counterValueSize);
		if (*counterValue == NULL) {
			LogError("malloc of %u bytes failed.", *counterValueSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *counterValue, *counterValueSize, &hte->comm)) {
			free(*counterValue);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_DIGEST, i++, auditDigest, 0, &hte->comm)) {
			free(*counterValue);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_DIGEST, i++, ordinalDigest, 0, &hte->comm)) {
			free(*counterValue);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) {
			free(*counterValue);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*sig = (BYTE *)malloc(*sigSize);
		if (*sig == NULL) {
			LogError("malloc of %u bytes failed.", *sigSize);
			free(*counterValue);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) {
			free(*counterValue);
			free(*sig);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

done:
	return result;
}
예제 #4
0
파일: rsa.c 프로젝트: ajinkya93/netbsd-src
/* XXX int set to unsigned int values */
int
Trspi_RSA_Encrypt(unsigned char *dataToEncrypt, /* in */
		unsigned int dataToEncryptLen,  /* in */
		unsigned char *encryptedData,   /* out */
		unsigned int *encryptedDataLen, /* out */
		unsigned char *publicKey,
		unsigned int keysize)
{
	int rv;
	unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* 65537 hex */
	unsigned char oaepPad[] = "TCPA";
	int oaepPadLen = 4;
	RSA *rsa = RSA_new();
	BYTE encodedData[256];
	int encodedDataLen;

	if (rsa == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	/* set the public key value in the OpenSSL object */
	rsa->n = BN_bin2bn(publicKey, keysize, rsa->n);
	/* set the public exponent */
	rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e);

	if (rsa->n == NULL || rsa->e == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	/* padding constraint for PKCS#1 OAEP padding */
	if ((int)dataToEncryptLen >= (RSA_size(rsa) - ((2 * SHA_DIGEST_LENGTH) + 1))) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	encodedDataLen = MIN(RSA_size(rsa), 256);

	/* perform our OAEP padding here with custom padding parameter */
	rv = RSA_padding_add_PKCS1_OAEP(encodedData, encodedDataLen, dataToEncrypt,
			dataToEncryptLen, oaepPad, oaepPadLen);
	if (rv != EVP_SUCCESS) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	/* call OpenSSL with no additional padding */
	rv = RSA_public_encrypt(encodedDataLen, encodedData,
				encryptedData, rsa, RSA_NO_PADDING);
	if (rv == -1) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	/* RSA_public_encrypt returns the size of the encrypted data */
	*encryptedDataLen = rv;
	rv = TSS_SUCCESS;
	goto out;

err:
	DEBUG_print_openssl_errors();
out:
	if (rsa)
		RSA_free(rsa);
        return rv;
}
예제 #5
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;
}
예제 #6
0
TSS_RESULT
authsess_oiap_get(TSS_HOBJECT obj, TPM_COMMAND_CODE ord, TPM_DIGEST *digest, TPM_AUTH *auth)
{
	TSS_RESULT result = TSS_SUCCESS;
	TSS_BOOL bExpired;
	UINT32 mode;
	TPM_SECRET secret;
	TSS_HCONTEXT tspContext;
	TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack
	TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack


	if (obj_is_tpm(obj))
		result = obj_tpm_get_tsp_context(obj, hContext);
	else if (obj_is_rsakey(obj))
		result = obj_rsakey_get_tsp_context(obj, hContext);
	else if (obj_is_encdata(obj))
		result = obj_encdata_get_tsp_context(obj, hContext);
	else if (obj_is_nvstore(obj))
		result = obj_nvstore_get_tsp_context(obj, hContext);
	else
		result = TSPERR(TSS_E_INVALID_HANDLE);

#if 0
	/* This validates that the secret can be used */
	if ((result = obj_policy_has_expired(hPolicy, &bExpired)))
		return result;

	if (bExpired == TRUE)
		return TSPERR(TSS_E_INVALID_OBJ_ACCESS);

	if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext)))
		return result;

	if ((result = obj_policy_get_mode(hPolicy, &mode)))
		return result;
#else
	if ((result = obj_policy_get_authsess_params()))
		return result;
#endif
	if ((result = Init_AuthNonce(tspContext, cas, auth)))
		return result;

	/* XXX hack for opening a transport session */
	if (cas) {
		OIAP = RPC_OIAP;
		TerminateHandle = RPC_TerminateHandle;
	} else {
		OIAP = TCS_API(tspContext)->OIAP;
		TerminateHandle = TCS_API(tspContext)->TerminateHandle;
	}

	/* added retry logic */
	if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) {
		if (result == TCPA_E_RESOURCES) {
			int retry = 0;
			do {
				/* POSIX sleep time, { secs, nanosecs } */
				struct timespec t = { 0, AUTH_RETRY_NANOSECS };

				nanosleep(&t, NULL);

				result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven);
			} while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT);
		}

		if (result)
			return result;
	}

	switch (mode) {
		case TSS_SECRET_MODE_CALLBACK:
			result = obj_policy_do_hmac(hPolicy, hAuthorizedObject,
						    TRUE, ulPendingFn,
						    auth->fContinueAuthSession,
						    20,
						    auth->NonceEven.nonce,
						    auth->NonceOdd.nonce,
						    NULL, NULL, 20,
						    hashDigest->digest,
						    (BYTE *)&auth->HMAC);
			break;
		case TSS_SECRET_MODE_SHA1:
		case TSS_SECRET_MODE_PLAIN:
		case TSS_SECRET_MODE_POPUP:
			if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW,
							    &secret)))
				break;

			HMAC_Auth(secret.authdata, hashDigest->digest, auth);
			break;
		case TSS_SECRET_MODE_NONE:
			/* fall through */
		default:
			result = TSPERR(TSS_E_POLICY_NO_SECRET);
			break;
	}

	if (result) {
		TerminateHandle(tspContext, auth->AuthHandle);
		return result;
	}

	return obj_policy_dec_counter(hPolicy);
}
예제 #7
0
파일: rsa.c 프로젝트: ajinkya93/netbsd-src
TSS_RESULT
Trspi_Verify(UINT32 HashType, BYTE *pHash, UINT32 iHashLength,
	     unsigned char *pModulus, int iKeyLength,
	     BYTE *pSignature, UINT32 sig_len)
{
	int rv, nid;
	unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* The default public exponent for the TPM */
	unsigned char buf[256];
	RSA *rsa = RSA_new();

	if (rsa == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	/* We assume we're verifying data from a TPM, so there are only
	 * two options, SHA1 data and PKCSv1.5 encoded signature data.
	 */
	switch (HashType) {
		case TSS_HASH_SHA1:
			nid = NID_sha1;
			break;
		case TSS_HASH_OTHER:
			nid = NID_undef;
			break;
		default:
			rv = TSPERR(TSS_E_BAD_PARAMETER);
			goto out;
			break;
	}

	/* set the public key value in the OpenSSL object */
	rsa->n = BN_bin2bn(pModulus, iKeyLength, rsa->n);
	/* set the public exponent */
	rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e);

	if (rsa->n == NULL || rsa->e == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	/* if we don't know the structure of the data we're verifying, do a public decrypt
	 * and compare manually. If we know we're looking for a SHA1 hash, allow OpenSSL
	 * to do the work for us.
	 */
	if (nid == NID_undef) {
		rv = RSA_public_decrypt(sig_len, pSignature, buf, rsa, RSA_PKCS1_PADDING);
		if ((UINT32)rv != iHashLength) {
			rv = TSPERR(TSS_E_FAIL);
			goto out;
		} else if (memcmp(pHash, buf, iHashLength)) {
			rv = TSPERR(TSS_E_FAIL);
			goto out;
		}
	} else {
		if ((rv = RSA_verify(nid, pHash, iHashLength, pSignature, sig_len, rsa)) == 0) {
			rv = TSPERR(TSS_E_FAIL);
			goto out;
		}
	}

	rv = TSS_SUCCESS;
	goto out;

err:
	DEBUG_print_openssl_errors();
out:
	if (rsa)
		RSA_free(rsa);
        return rv;
}
예제 #8
0
TSS_RESULT
RPC_ChangeAuth_TP(struct host_table_entry *hte,
			       TCS_KEY_HANDLE parentHandle,	/* in */
			       TCPA_PROTOCOL_ID protocolID,	/* in */
			       TCPA_ENCAUTH *newAuth,	/* in */
			       TCPA_ENTITY_TYPE entityType,	/* in */
			       UINT32 encDataSize,	/* in */
			       BYTE * encData,	/* in */
			       TPM_AUTH * ownerAuth,	/* in, out */
			       TPM_AUTH * entityAuth,	/* in, out */
			       UINT32 * outDataSize,	/* out */
			       BYTE ** outData)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 9);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTH;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 2, &protocolID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, newAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 4, &entityType, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 5, &encDataSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 6, encData, encDataSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 8, entityAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_AUTH, 1, entityAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 2, outDataSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*outData = (BYTE *) malloc(*outDataSize);
		if (*outData == NULL) {
			LogError("malloc of %u bytes failed.", *outDataSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *outData, *outDataSize, &hte->comm)) {
			free(*outData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}
예제 #9
0
/* XXX Split into two functions */
TSS_RESULT
Tspi_TPM_GetAuditDigest(TSS_HTPM            hTpm,		/* in */
			TSS_HKEY            hKey,		/* in */
			TSS_BOOL            closeAudit,		/* in */
			UINT32*             pulAuditDigestSize,	/* out */
			BYTE**              prgbAuditDigest,	/* out */
			TPM_COUNTER_VALUE*  pCounterValue,	/* out */
			TSS_VALIDATION*     pValidationData,	/* out */
			UINT32*             ordSize,		/* out */
			UINT32**            ordList)		/* out */
{
	TSS_HCONTEXT tspContext;
	UINT32 counterValueSize;
	BYTE *counterValue = NULL;
	TPM_DIGEST auditDigest;
	TSS_RESULT result = TSS_SUCCESS;
	UINT64 offset;

	if ((pulAuditDigestSize == NULL) || (prgbAuditDigest == NULL) || (pCounterValue == NULL))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (hKey == NULL_HKEY)
		if ((ordSize == NULL) || (ordList == NULL))
			return TSPERR(TSS_E_BAD_PARAMETER);

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

	if (hKey == NULL_HKEY) {
		UINT32 startOrdinal = 0;
		TSS_BOOL more;
		UINT32 tcsOrdSize;
		UINT32 *tcsOrdList = NULL;
		UINT32 *pulTemp;

		*prgbAuditDigest = NULL;
		*pulAuditDigestSize = 0;
		*ordList = NULL;
		*ordSize = 0;
		do {
			if ((result = TCS_API(tspContext)->GetAuditDigest(tspContext, startOrdinal,
									  &auditDigest,
									  &counterValueSize,
									  &counterValue, &more,
									  &tcsOrdSize,
									  &tcsOrdList)))
				goto done1;

			if ((pulTemp =
			    calloc_tspi(tspContext,
				        (*ordSize + tcsOrdSize) * sizeof(UINT32))) == NULL) {
				LogError("malloc of %u bytes failed.", *ordSize + tcsOrdSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done1;
			}

			if (*ordList)
				memcpy(pulTemp, *ordList, *ordSize * sizeof(UINT32));
			memcpy(pulTemp + *ordSize, tcsOrdList, tcsOrdSize * sizeof(UINT32));

			free(tcsOrdList);
			tcsOrdList = NULL;

			if (*ordList)
				free_tspi(tspContext, *ordList);
			*ordList = pulTemp;
			*ordSize += tcsOrdSize;

			if (more == TRUE) {
				offset = 0;
				Trspi_UnloadBlob_UINT32(&offset, &startOrdinal,
							(BYTE *)(*ordList + (*ordSize - 1)));
				startOrdinal++;
				free(counterValue);
				counterValue = NULL;
			}
		} while (more == TRUE);

		*pulAuditDigestSize = sizeof(auditDigest.digest);
		if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) {
			LogError("malloc of %u bytes failed.", *pulAuditDigestSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done1;
		}
		offset = 0;
		Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest);

		offset = 0;
		Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue);

		result = TSS_SUCCESS;

done1:
		if (result != TSS_SUCCESS) {
			if (*prgbAuditDigest)
				free_tspi(tspContext, *prgbAuditDigest);
			if (*ordList)
				free_tspi(tspContext, *ordList);
			*prgbAuditDigest = NULL;
			*pulAuditDigestSize = 0;
			*ordList = NULL;
			*ordSize = 0;
		}
		free(counterValue);
		free(tcsOrdList);

		return result;
	}
	else {
		TSS_HPOLICY hPolicy;
		TSS_BOOL usesAuth;
		TCS_KEY_HANDLE tcsKeyHandle;
		TPM_AUTH keyAuth, *pAuth;
		Trspi_HashCtx hashCtx;
		TCPA_DIGEST digest;
		TPM_NONCE antiReplay;
		TPM_DIGEST auditDigest;
		TPM_DIGEST ordinalDigest;
		UINT32 sigSize;
		BYTE *sig = NULL;
		TPM_SIGN_INFO signInfo;
		UINT32 signInfoBlobSize;
		BYTE *signInfoBlob = NULL;

		if (pValidationData == NULL) {
			LogDebug("Internal Verify");
			if ((result = get_local_random(tspContext, FALSE, TPM_NONCE_SIZE,
						       (BYTE **)antiReplay.nonce)))
				return result;
		} else {
			LogDebug("External Verify");
			if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce))
				return TSPERR(TSS_E_BAD_PARAMETER);

			if (pValidationData->rgbExternalData == NULL)
				return TSPERR(TSS_E_BAD_PARAMETER);

			memcpy(antiReplay.nonce, pValidationData->rgbExternalData,
			       sizeof(antiReplay.nonce));

			pValidationData->ulDataLength = 0;
			pValidationData->rgbData = NULL;
			pValidationData->ulValidationDataLength = 0;
			pValidationData->rgbValidationData = NULL;
		}

		if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
			return result;

		if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
			return result;

		if (usesAuth) {
			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned);
			result |= Trspi_Hash_BOOL(&hashCtx, closeAudit);
			result |= Trspi_Hash_NONCE(&hashCtx, antiReplay.nonce);
			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
				return result;

			pAuth = &keyAuth;
			if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetAuditDigestSigned,
							      hPolicy, FALSE, &digest, pAuth)))
				return result;
		}
		else
			pAuth = NULL;

		if ((result = TCS_API(tspContext)->GetAuditDigestSigned(tspContext, tcsKeyHandle,
									closeAudit, &antiReplay,
									pAuth, &counterValueSize,
									&counterValue, &auditDigest,
									&ordinalDigest, &sigSize,
									&sig)))
			return result;

		memset(&signInfo, 0, sizeof(signInfo));
		signInfo.tag = TPM_TAG_SIGNINFO;
		memcpy(signInfo.fixed, "ADIG", strlen("ADIG"));
		signInfo.replay = antiReplay;
		signInfo.dataLen = sizeof(auditDigest.digest) + counterValueSize +
				   sizeof(ordinalDigest.digest);
		if ((signInfo.data = malloc(signInfo.dataLen)) == NULL) {
			LogError("malloc of %u bytes failed.", signInfo.dataLen);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done2;
		}
		offset = 0;
		Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &auditDigest);
		Trspi_LoadBlob(&offset, counterValueSize, signInfo.data, counterValue);
		Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &ordinalDigest);

		if (usesAuth) {
			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
			result |= Trspi_Hash_UINT32(&hashCtx, result);
			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned);
			result |= Trspi_HashUpdate(&hashCtx, counterValueSize, counterValue);
			result |= Trspi_Hash_DIGEST(&hashCtx, auditDigest.digest);
			result |= Trspi_Hash_DIGEST(&hashCtx, ordinalDigest.digest);
			result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
			result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
				goto done2;

			if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
				goto done2;
		}

		offset = 0;
		Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo);
		signInfoBlobSize = offset;
		signInfoBlob = malloc(signInfoBlobSize);
		if (signInfoBlob == NULL) {
			LogError("malloc of %u bytes failed.", signInfoBlobSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done2;
		}
		offset = 0;
		Trspi_LoadBlob_SIGN_INFO(&offset, signInfoBlob, &signInfo);

		if (pValidationData == NULL) {
			if ((result = Trspi_Hash(TSS_HASH_SHA1, signInfoBlobSize, signInfoBlob,
						 digest.digest)))
				goto done2;

			if ((result = __tspi_rsa_verify(hKey, TSS_HASH_SHA1, sizeof(digest.digest),
						 digest.digest, sigSize, sig))) {
				result = TSPERR(TSS_E_VERIFICATION_FAILED);
				goto done2;
			}
		} else {
			pValidationData->ulDataLength = signInfoBlobSize;
			pValidationData->rgbData = calloc_tspi(tspContext, signInfoBlobSize);
			if (pValidationData->rgbData == NULL) {
				LogError("malloc of %u bytes failed.", signInfoBlobSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done2;
			}
			memcpy(pValidationData->rgbData, signInfoBlob, signInfoBlobSize);

			pValidationData->ulValidationDataLength = sigSize;
			pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize);
			if (pValidationData->rgbValidationData == NULL) {
				LogError("malloc of %u bytes failed.", sigSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done2;
			}
			memcpy(pValidationData->rgbValidationData, sig, sigSize);
		}

		*pulAuditDigestSize = sizeof(auditDigest.digest);
		if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) {
			LogError("malloc of %u bytes failed.", *pulAuditDigestSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done2;
		}
		offset = 0;
		Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest);

		offset = 0;
		Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue);

		result = TSS_SUCCESS;

done2:
		if (result != TSS_SUCCESS) {
			if (*prgbAuditDigest)
				free_tspi(tspContext, *prgbAuditDigest);
			*prgbAuditDigest = NULL;
			*pulAuditDigestSize = 0;
			if (pValidationData != NULL) {
				if (pValidationData->rgbData)
					free_tspi(tspContext, pValidationData->rgbData);
				if (pValidationData->rgbValidationData)
					free_tspi(tspContext, pValidationData->rgbValidationData);
				pValidationData->ulDataLength = 0;
				pValidationData->rgbData = NULL;
				pValidationData->ulValidationDataLength = 0;
				pValidationData->rgbValidationData = NULL;
			}
		}
		free(counterValue);
		free(sig);
		free(signInfo.data);
		free(signInfoBlob);

		return result;
	}
}
예제 #10
0
TSS_RESULT
obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore,
				TSS_HPCRS hPcrComposite,
				UINT32 *size,
				BYTE **data)
{
	struct tsp_object *obj;
	BYTE pdata[MAX_PUBLIC_DATA_SIZE];
	UINT32 dataLen;
	UINT64 offset;
	TSS_HCONTEXT tspContext;
	TSS_RESULT result = TSS_SUCCESS;
	BYTE*  ppbHashData;
	UINT32 i;
	BYTE  digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, };
	UINT32 tmp_locAtRelease;
	TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE
					| TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR;
	BYTE tmp_pcr_select[3] = {0, 0, 0};
	TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select};

	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	tspContext = obj->tspContext;

	if (hPcrComposite) {
		if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) {
			LogDebug("get_selection error from hReadPcrComposite");
			goto out;
		}

		/* the index should not >= 24, so the sizeofselect should not be >3*/
		if (dataLen - sizeof(UINT16) > 3) {
			result = TSPERR(TSS_E_BAD_PARAMETER);
			goto out;
		}
		offset = 0;
		Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect);

		if (pcrSelect.sizeOfSelect != 0) {
			if ((result = obj_pcrs_get_digest_at_release(hPcrComposite,
								     &dataLen, &ppbHashData))) {
				LogDebug("get_composite error from hReadPcrComposite");
				goto out;
			}
			memcpy(digAtRelease, ppbHashData, dataLen);
			free_tspi(tspContext, ppbHashData);
		} else {
			pcrSelect.sizeOfSelect = 3;
			pcrSelect.pcrSelect = tmp_pcr_select;
		}

		if (pcrSelect.sizeOfSelect < 3) {
			for (i = 0; i < pcrSelect.sizeOfSelect; i++) {
				tmp_pcr_select[i] = pcrSelect.pcrSelect[i];
			}
			pcrSelect.sizeOfSelect = 3;
			pcrSelect.pcrSelect = tmp_pcr_select;
		}

		if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease)))
			goto out;
		locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK);
	}

	*size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN;
	*data = calloc_tspi(tspContext, *size);
	if (*data == NULL) {
		LogError("malloc of %u bytes failed.", *size);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto out;
	}

	offset = 0;
	Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect);
	Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data);
	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease);

out:
	obj_list_put(&nvstore_list);
	return result;
}
예제 #11
0
TSS_RESULT
Trspi_UnloadBlob_DAA_PK(UINT64 *offset, BYTE *blob, TSS_DAA_PK *pk)
{
	UINT32 i = 0, j;

	memset(pk, 0, sizeof(TSS_DAA_PK));

	Trspi_UnloadBlob_TSS_VERSION(offset, blob, &pk->versionInfo);

	Trspi_UnloadBlob_UINT32(offset, &pk->modulusLength, blob);
	if (pk->modulusLength > 0) {
		if ((pk->modulus = malloc(pk->modulusLength)) == NULL)
			return TSPERR(TSS_E_OUTOFMEMORY);

		Trspi_UnloadBlob(offset, pk->modulusLength, blob, pk->modulus);
	} else {
		pk->modulus = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalSLength, blob);
	if (pk->capitalSLength > 0) {
		if ((pk->capitalS = malloc(pk->capitalSLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->capitalSLength, blob, pk->capitalS);
	} else {
		pk->capitalS = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalZLength, blob);
	if (pk->capitalZLength > 0) {
		if ((pk->capitalZ = malloc(pk->capitalZLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->capitalZLength, blob, pk->capitalZ);
	} else {
		pk->capitalZ = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalR0Length, blob);
	if (pk->capitalR0Length > 0) {
		if ((pk->capitalR0 = malloc(pk->capitalR0Length)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->capitalR0Length, blob, pk->capitalR0);
	} else {
		pk->capitalR0 = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalR1Length, blob);
	if (pk->capitalR1Length > 0) {
		if ((pk->capitalR1 = malloc(pk->capitalR1Length)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->capitalR1Length, blob, pk->capitalR1);
	} else {
		pk->capitalR1 = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->gammaLength, blob);
	if (pk->gammaLength > 0) {
		if ((pk->gamma = malloc(pk->gammaLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->gammaLength, blob, pk->gamma);
	} else {
		pk->gamma = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalGammaLength, blob);
	if (pk->capitalGammaLength > 0) {
		if ((pk->capitalGamma = malloc(pk->capitalGammaLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->capitalGammaLength, blob, pk->capitalGamma);
	} else {
		pk->capitalGamma = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->rhoLength, blob);
	if (pk->rhoLength > 0) {
		if ((pk->rho = malloc(pk->rhoLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->rhoLength, blob, pk->rho);
	} else {
		pk->rho = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength, blob);
	Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength2, blob);

	if (pk->capitalYLength > 0 && pk->capitalYLength2 > 0) {
		if ((pk->capitalY = calloc(pk->capitalYLength, sizeof(BYTE *))) == NULL)
			goto error;

		for (i = 0; i < pk->capitalYLength; i++) {
			if ((pk->capitalY[i] = malloc(pk->capitalYLength2)) == NULL)
				goto error;

			Trspi_UnloadBlob(offset, pk->capitalYLength2, blob, pk->capitalY[i]);
		}
	} else {
		pk->capitalY = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &pk->capitalYPlatformLength, blob);

	Trspi_UnloadBlob_UINT32(offset, &pk->issuerBaseNameLength, blob);
	if (pk->issuerBaseNameLength > 0) {
		if ((pk->issuerBaseName = malloc(pk->issuerBaseNameLength)) == NULL)
			goto error;

		Trspi_UnloadBlob(offset, pk->issuerBaseNameLength, blob, pk->issuerBaseName);
	} else {
		pk->issuerBaseName = NULL;
	}

	return TSS_SUCCESS;

error:
	free(pk->modulus);
	free(pk->capitalS);
	free(pk->capitalZ);
	free(pk->capitalR0);
	free(pk->capitalR1);
	free(pk->gamma);
	free(pk->capitalGamma);
	free(pk->rho);
	if (pk->capitalY) {
		for (j = 0; j < i; j++)
			free(pk->capitalY[j]);

		free(pk->capitalY);
	}
	free(pk->issuerBaseName);

	memset(pk, 0, sizeof(TSS_DAA_PK));

	return TSPERR(TSS_E_OUTOFMEMORY);
}
예제 #12
0
TSS_RESULT
obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public)
{
	struct tsp_object *obj;
	TSS_HCONTEXT  hContext;
	TSS_HTPM hTpm;
	TSS_RESULT result;
	struct tr_nvstore_obj *nvstore;
	UINT32 uiResultLen;
	BYTE *pResult;
	UINT32 i;
	TPM_BOOL defined_index = FALSE;

	if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	hContext = obj->tspContext;
	nvstore = (struct tr_nvstore_obj *)obj->data;

	if ((result = obj_tpm_get(hContext, &hTpm)))
		goto out;

	if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
				 NULL, &uiResultLen, &pResult))) {
		goto out;
	}

	for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
		if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
			defined_index = TRUE;
			break;
		}
	}

	free_tspi(hContext, pResult);

	if (!defined_index) {
		result = TSPERR(TPM_E_BADINDEX);
		goto out;
	}

	if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX,
					     sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)),
					     &uiResultLen, &pResult))) {
		LogDebug("get the index capability error");
		goto out;
	}

	if (uiResultLen > *size) {
		free_tspi(hContext, pResult);
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto out;
	}
	*size = uiResultLen;
	memcpy(nv_data_public, pResult, uiResultLen);
	free_tspi(hContext, pResult);

out:
	obj_list_put(&nvstore_list);
	return result;
}
예제 #13
0
TSS_RESULT
psfile_get_registered_keys2(int fd,
			   TSS_UUID *uuid,
			   TSS_UUID *tcs_uuid,
			   UINT32 *size,
			   TSS_KM_KEYINFO2 **keys)
{
	TSS_RESULT result;
	struct key_disk_cache *cache_entries;
	UINT32 cache_size, i, j;
	TSS_KM_KEYINFO2 *keyinfos = NULL;
	TSS_UUID *find_uuid;

        if ((result = psfile_get_all_cache_entries(fd, &cache_size, &cache_entries)))
                return result;

	if (cache_size == 0) {
		if (uuid)
			return TSPERR(TSS_E_PS_KEY_NOTFOUND);
		else {
			*size = 0;
			*keys = NULL;
			return TSS_SUCCESS;
		}
	}

	if (uuid) {
		find_uuid = uuid;
		j = 0;

		restart_search:
			/* Search for the requested UUID.  When found, allocate new space for it, copy
			 * it in, then change the uuid to be searched for it its parent and start over. */
			for (i = 0; i < cache_size; i++) {
				/*Return 0 if normal finish*/
				if (!memcmp(&cache_entries[i].uuid, find_uuid, sizeof(TSS_UUID))) {
					if (!(keyinfos = realloc(keyinfos,
							(j+1) * sizeof(TSS_KM_KEYINFO2)))) {
						free(cache_entries);
						free(keyinfos);
						return TSPERR(TSS_E_OUTOFMEMORY);
					}
					/* Here the key UUID is found and needs to be copied for the array*/
					/* Initializes the keyinfos with 0's*/
					memset(&keyinfos[j], 0, sizeof(TSS_KM_KEYINFO2));

					if ((result = copy_key_info2(fd, &keyinfos[j], &cache_entries[i]))) {
						free(cache_entries);
						free(keyinfos);
						return result;
					}

					find_uuid = &keyinfos[j].parentKeyUUID;
					j++;
					goto restart_search;
				}
			}

		/* Searching for keys in the user PS will always lead us up to some key in the
		 * system PS. Return that key's uuid so that the upper layers can call down to TCS
		 * to search for it. */
		memcpy(tcs_uuid, find_uuid, sizeof(TSS_UUID));

		*size = j;
	} else {
		if ((keyinfos = calloc(cache_size, sizeof(TSS_KM_KEYINFO2))) == NULL) {
			LogDebug("malloc of %zu bytes failed.",
					cache_size * sizeof(TSS_KM_KEYINFO2));
			free(cache_entries);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}

		for (i = 0; i < cache_size; i++) {
			if ((result = copy_key_info2(fd, &keyinfos[i], &cache_entries[i]))) {
				free(cache_entries);
				free(keyinfos);
				return result;
			}
		}

		*size = cache_size;
	}

	free(cache_entries);

	*keys = keyinfos;

	return TSS_SUCCESS;
}
예제 #14
0
TSS_RESULT
psfile_get_all_cache_entries(int fd, UINT32 *size, struct key_disk_cache **c)
{
	UINT32 i, num_keys = psfile_get_num_keys(fd);
	int offset;
	TSS_RESULT result;
	struct key_disk_cache *tmp = NULL;

	if (num_keys == 0) {
		*size = 0;
		*c = NULL;
		return TSS_SUCCESS;
	}

	/* 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)) {
		LogDebug("lseek: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if ((tmp = malloc(num_keys * sizeof(struct key_disk_cache))) == NULL) {
		LogDebug("malloc of %zu bytes failed.", num_keys * sizeof(struct key_disk_cache));
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	for (i = 0; i < num_keys; i++) {
		offset = lseek(fd, 0, SEEK_CUR);
		if (offset == ((off_t)-1)) {
			LogDebug("lseek: %s", strerror(errno));
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto err_exit;
		}
		tmp[i].offset = offset;

		/* read UUID */
		if ((result = read_data(fd, &tmp[i].uuid, sizeof(TSS_UUID)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}

		/* read parent UUID */
		if ((result = read_data(fd, &tmp[i].parent_uuid, sizeof(TSS_UUID)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}

		/* pub data size */
		if ((result = read_data(fd, &tmp[i].pub_data_size, sizeof(UINT16)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}
		tmp[i].pub_data_size = LE_16(tmp[i].pub_data_size);

		DBG_ASSERT(tmp[i].pub_data_size <= 2048);

		/* blob size */
		if ((result = read_data(fd, &tmp[i].blob_size, sizeof(UINT16)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}
		tmp[i].blob_size = LE_16(tmp[i].blob_size);

		DBG_ASSERT(tmp[i].blob_size <= 4096);

		/* vendor data size */
		if ((result = read_data(fd, &tmp[i].vendor_data_size, sizeof(UINT32)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}
		tmp[i].vendor_data_size = LE_32(tmp[i].vendor_data_size);

		/* cache flags */
		if ((result = read_data(fd, &tmp[i].flags, sizeof(UINT16)))) {
			LogDebug("%s", __FUNCTION__);
			goto err_exit;
		}
		tmp[i].flags = LE_16(tmp[i].flags);

		/* fast forward over the pub key */
		offset = lseek(fd, tmp[i].pub_data_size, SEEK_CUR);
		if (offset == ((off_t)-1)) {
			LogDebug("lseek: %s", strerror(errno));
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto err_exit;
		}

		/* fast forward over the blob */
		offset = lseek(fd, tmp[i].blob_size, SEEK_CUR);
		if (offset == ((off_t)-1)) {
			LogDebug("lseek: %s", strerror(errno));
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto err_exit;
		}

		/* ignore vendor data for user ps */
	}

	*size = num_keys;
	*c = tmp;

	return TSS_SUCCESS;

err_exit:
	free(tmp);
	return result;
}
예제 #15
0
TSS_RESULT
secret_PerformAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn,
			TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy,
			TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20],
			TPM_AUTH *auth, BYTE *hashDigest,
			TCPA_NONCE *nonceEvenOSAP)
{
	TSS_RESULT result;
	UINT32 keyMode, usageMode, migMode = 0;

	if ((result = obj_policy_get_mode(hPolicy, &keyMode)))
		return result;

	if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode)))
		return result;

	if (hMigPolicy) {
		if ((result = obj_policy_get_mode(hMigPolicy, &migMode)))
			return result;
	}

	/* ---  If any of them is a callback */
	if (keyMode == TSS_SECRET_MODE_CALLBACK ||
	    usageMode == TSS_SECRET_MODE_CALLBACK ||
	    (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) {
		/* ---  And they're not all callback */
		if (keyMode != TSS_SECRET_MODE_CALLBACK ||
		    usageMode != TSS_SECRET_MODE_CALLBACK ||
		    (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK))
			return TSPERR(TSS_E_BAD_PARAMETER);
	}

	if (keyMode == TSS_SECRET_MODE_CALLBACK) {
		if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject,
						 TRUE, ulPendingFn,
						 auth->fContinueAuthSession,
						 20,
						 auth->NonceEven.nonce,
						 NULL,
						 nonceEvenOSAP->nonce,
						 auth->NonceOdd.nonce, 20,
						 hashDigest,
						 (BYTE *)&auth->HMAC)))
			return result;
	} else {
		HMAC_Auth(sharedSecret, hashDigest, auth);
	}

	if ((result = obj_policy_dec_counter(hPolicy)))
		return result;

	if ((result = obj_policy_dec_counter(hUsagePolicy)))
		return result;

	if (hMigPolicy) {
		if ((result = obj_policy_dec_counter(hMigPolicy)))
			return result;
	}

	return TSS_SUCCESS;
}
예제 #16
0
TSS_RESULT
obj_pcrs_set_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 size, BYTE *value)
{
	struct tsp_object *obj;
	struct tr_pcrs_obj *pcrs;
	TSS_RESULT result = TSS_SUCCESS;
	TPM_PCR_SELECTION *select;
	TPM_COMPOSITE_HASH *compHash;
	UINT16 bytes_to_hold = (idx / 8) + 1;

	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	pcrs = (struct tr_pcrs_obj *)obj->data;

	switch(pcrs->type) {
		case TSS_PCRS_STRUCT_INFO:
			bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold;
			select = &pcrs->info.info11.pcrSelection;
			compHash = &pcrs->info.info11.digestAtRelease;
			break;
		case TSS_PCRS_STRUCT_INFO_SHORT:
			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
			select = &pcrs->info.infoshort.pcrSelection;
			compHash = &pcrs->info.infoshort.digestAtRelease;
			break;
		case TSS_PCRS_STRUCT_INFO_LONG:
			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
			select = &pcrs->info.infolong.releasePCRSelection;
			compHash = &pcrs->info.infolong.digestAtRelease;
			break;
		default:
			LogDebugFn("Undefined type of PCRs object");
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
			break;
	}

	/* allocate the selection structure */
	if (select->pcrSelect == NULL) {
		if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		select->sizeOfSelect = bytes_to_hold;
		memset(select->pcrSelect, 0, bytes_to_hold);

		/* allocate the pcr array */
		if ((pcrs->pcrs = malloc(bytes_to_hold * 8 *
					 TCPA_SHA1_160_HASH_LEN)) == NULL) {
			LogError("malloc of %d bytes failed.",
				bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	} else if (select->sizeOfSelect < bytes_to_hold) {
		if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		/* set the newly allocated bytes to 0 */
		memset(&select->pcrSelect[select->sizeOfSelect], 0,
				bytes_to_hold - select->sizeOfSelect);
		select->sizeOfSelect = bytes_to_hold;

		/* realloc the pcrs array */
		if ((pcrs->pcrs = realloc(pcrs->pcrs, bytes_to_hold * 8 *
					  sizeof(TPM_PCRVALUE))) == NULL) {
			LogError("malloc of %d bytes failed.",
					bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	}

	/* set the bit in the selection structure */
	select->pcrSelect[idx / 8] |= (1 << (idx % 8));

	/* set the value in the pcrs array */
	memcpy(&(pcrs->pcrs[idx]), value, size);

	result = pcrs_calc_composite(select, pcrs->pcrs, compHash);

done:
	obj_list_put(&pcrs_list);

	return result;
}
예제 #17
0
TSS_RESULT
OSAP_Calc(TSS_HCONTEXT tspContext, UINT16 EntityType, UINT32 EntityValue,
	  BYTE * authSecret, BYTE * usageSecret, BYTE * migSecret,
	  TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig,
	  BYTE * sharedSecret, TPM_AUTH * auth)
{
	TSS_RESULT rc;
	TCPA_NONCE nonceEvenOSAP;
	UINT64 offset;
	BYTE hmacBlob[0x200];
	BYTE hashBlob[0x200];
	BYTE xorUsageAuth[20];
	BYTE xorMigAuth[20];
	UINT32 i;

	if ((rc = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
				   (BYTE **)auth->NonceOdd.nonce))) {
		LogError("Failed creating random nonce");
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	auth->fContinueAuthSession = 0x00;

	if ((rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, &auth->NonceOdd,
					    &auth->AuthHandle, &auth->NonceEven, &nonceEvenOSAP))) {
		if (rc == TCPA_E_RESOURCES) {
			int retry = 0;
			do {
				/* POSIX sleep time, { secs, nanosecs } */
				struct timespec t = { 0, AUTH_RETRY_NANOSECS };

				nanosleep(&t, NULL);

				rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue,
							       &auth->NonceOdd, &auth->AuthHandle,
							       &auth->NonceEven, &nonceEvenOSAP);
			} while (rc == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT);
		}

		if (rc)
			return rc;
	}

	offset = 0;
	Trspi_LoadBlob(&offset, 20, hmacBlob, nonceEvenOSAP.nonce);
	Trspi_LoadBlob(&offset, 20, hmacBlob, auth->NonceOdd.nonce);

	Trspi_HMAC(TSS_HASH_SHA1, 20, authSecret, offset, hmacBlob, sharedSecret);

	offset = 0;
	Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret);
	Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceEven.nonce);

	if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorUsageAuth)))
		return rc;

	offset = 0;
	Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret);
	Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceOdd.nonce);
	if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorMigAuth)))
		return rc;

	for (i = 0; i < sizeof(TCPA_ENCAUTH); i++)
		encAuthUsage->authdata[i] = usageSecret[i] ^ xorUsageAuth[i];
	for (i = 0; i < sizeof(TCPA_ENCAUTH); i++)
		encAuthMig->authdata[i] = migSecret[i] ^ xorMigAuth[i];

	return TSS_SUCCESS;
}
예제 #18
0
TSS_RESULT
obj_pcrs_select_index_ex(TSS_HPCRS hPcrs, UINT32 dir, UINT32 idx)
{
	struct tsp_object *obj;
	struct tr_pcrs_obj *pcrs;
	TSS_RESULT result = TSS_SUCCESS;
	TPM_PCR_SELECTION *select;
	UINT16 bytes_to_hold = (idx / 8) + 1;

	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	pcrs = (struct tr_pcrs_obj *)obj->data;

	switch(pcrs->type) {
		case TSS_PCRS_STRUCT_INFO:
			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
			goto done;
		case TSS_PCRS_STRUCT_INFO_SHORT:
			if (dir == TSS_PCRS_DIRECTION_CREATION) {
				result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
				goto done;
			}
			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
			select = &pcrs->info.infoshort.pcrSelection;
			break;
		case TSS_PCRS_STRUCT_INFO_LONG:
			bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold;
			if (dir == TSS_PCRS_DIRECTION_CREATION)
				select = &pcrs->info.infolong.creationPCRSelection;
			else
				select = &pcrs->info.infolong.releasePCRSelection;
			break;
		default:
			LogDebugFn("Undefined type of PCRs object");
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
			break;
	}

	/* allocate the selection structure */
	if (select->pcrSelect == NULL) {
		if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		select->sizeOfSelect = bytes_to_hold;
		memset(select->pcrSelect, 0, bytes_to_hold);

		/* alloc the pcrs array */
		if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
				 TCPA_SHA1_160_HASH_LEN);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	} else if (select->sizeOfSelect < bytes_to_hold) {
		if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		/* set the newly allocated bytes to 0 */
		memset(&select->pcrSelect[select->sizeOfSelect], 0,
		       bytes_to_hold - select->sizeOfSelect);
		select->sizeOfSelect = bytes_to_hold;

		/* realloc the pcrs array */
		if ((pcrs->pcrs = realloc(pcrs->pcrs,
					  bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) {
			LogError("malloc of %d bytes failed.", bytes_to_hold * 8 *
				 TCPA_SHA1_160_HASH_LEN);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	}

	/* set the bit in the selection structure */
	select->pcrSelect[idx / 8] |= (1 << (idx % 8));

done:
	obj_list_put(&pcrs_list);

	return result;
}
예제 #19
0
/* Create an OSAP session. @requirements is used in different ways depending on the command to
 * indicate whether we should require a policy or auth value */
TSS_RESULT
authsess_xsap_init(TSS_HCONTEXT     tspContext,
		   TSS_HOBJECT	    obj_parent,
		   TSS_HOBJECT      obj_child,
		   TSS_BOOL	    requirements,
		   TPM_COMMAND_CODE command,
		   TPM_ENTITY_TYPE  entity_type,
		   struct authsess  **xsess)
{
	TSS_RESULT result;
	TSS_BOOL authdatausage = FALSE, req_auth = TRUE, get_child_auth = TRUE, secret_set = FALSE;
	BYTE hmacBlob[2 * sizeof(TPM_DIGEST)];
	UINT64 offset;
	TSS_BOOL new_secret = TR_SECRET_CTX_NOT_NEW;
	struct authsess *sess;

	if ((sess = calloc(1, sizeof(struct authsess))) == NULL) {
		LogError("malloc of %zd bytes failed", sizeof(struct authsess));
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	switch (command) {
	/* Parent is Key for the cases below */
	case TPM_ORD_Delegate_CreateKeyDelegation:
	case TPM_ORD_CreateWrapKey:
	case TPM_ORD_CMK_CreateKey:
	case TPM_ORD_Seal:
	case TPM_ORD_Sealx:
	case TPM_ORD_Unseal:
	case TPM_ORD_ChangeAuth:
		if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE,
						    &sess->hUsageParent, NULL)))
			goto error;
		break;
	/* Parent is TPM for the cases below */
	case TPM_ORD_Delegate_CreateOwnerDelegation:
		req_auth = FALSE;
		/* fall through */
	case TPM_ORD_MakeIdentity:
	case TPM_ORD_NV_DefineSpace:
		if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE,
						 &sess->hUsageParent)))
			goto error;
		break;
	case TPM_ORD_ChangeAuthOwner:
		/* Special case, ChangeAuthOwner is used to change Owner and SRK auth */
		if (obj_is_rsakey(obj_parent)) {
			if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE,
							    &sess->hUsageParent, NULL)))
				goto error;
		} else {
			if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE,
							 &sess->hUsageParent)))
				goto error;
		}
		break;
	default:
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto error;
	}

	if (requirements && !sess->hUsageParent) {
		result = TSPERR(TSS_E_TSP_AUTHREQUIRED);
		goto error;
	}

	if (sess->hUsageParent) {
		/* These are trousers callback functions which will be used to process the auth
		 * session. If the policy type is callback for hUsageParent, they will be
		 * overwritten by the application defined callback functions in the policy */
		sess->cb_xor.callback = authsess_callback_xor;
		sess->cb_xor.appData = (PVOID)sess;
		sess->cb_hmac.callback = authsess_callback_hmac;
		sess->cb_hmac.appData = (PVOID)sess;

		/* XXX the parent object doesn't always hold the callbacks */
		if ((result = obj_policy_get_xsap_params(sess->hUsageParent, command,
							 &sess->entity_type, &sess->entityValueSize,
							 &sess->entityValue,
							 sess->parentSecret.authdata, &sess->cb_xor,
							 &sess->cb_hmac, NULL, &sess->parentMode, 
							 new_secret)))
			goto error;
	} else
		sess->parentMode = TSS_SECRET_MODE_NONE;

	switch (command) {
	/* Child is a Key object */
	case TPM_ORD_CreateWrapKey:
	case TPM_ORD_CMK_CreateKey:
		if ((result = obj_rsakey_get_policies(obj_child, &sess->hUsageChild,
						      &sess->hMigChild, &authdatausage)))
			goto error;

		if (authdatausage && !sess->hUsageChild) {
			result = TSPERR(TSS_E_TSP_AUTHREQUIRED);
			goto error;
		}

		if (obj_rsakey_is_migratable(obj_child)) {
			if (!sess->hMigChild) {
				result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY);
				goto error;
			}

			if ((result = obj_policy_get_xsap_params(sess->hMigChild, 0, NULL, NULL,
								 NULL, sess->encAuthMig.authdata,
								 NULL, NULL, NULL, &sess->mMode,
								 new_secret)))
				goto error;
		}

		if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent)))
			goto error;
		break;
	/* Child is an Encdata object */
	case TPM_ORD_Unseal:
#ifdef TSS_BUILD_SEALX
	case TPM_ORD_Sealx:
		/* These may be overwritten down below, when obj_policy_get_xsap_params is called
		 * on the child usage policy */
		sess->cb_sealx.callback = sealx_mask_cb;
		sess->cb_sealx.appData = (PVOID)sess;
		/* fall through */
#endif
	case TPM_ORD_Seal:
		if ((result = obj_encdata_get_policy(obj_child, TSS_POLICY_USAGE,
						     &sess->hUsageChild)))
			goto error;

		if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent)))
			goto error;
		break;
#ifdef TSS_BUILD_NV
	/* Child is an NV object */
	case TPM_ORD_NV_DefineSpace:
		/* The requirements variable tells us whether nv object auth is required */
		req_auth = requirements;

		if (req_auth) {
			if (sess->parentMode == TSS_SECRET_MODE_NONE) {
				result = TSPERR(TSS_E_TSP_AUTHREQUIRED);
				goto error;
			}

			if ((result = obj_nvstore_get_policy(obj_child, TSS_POLICY_USAGE,
							     &sess->hUsageChild)))
				goto error;

			/* According to the spec, we must fall back on the TSP context's policy for
			 * auth if none is set in the NV object */
			if (!sess->hUsageChild) {
				if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE,
								     &sess->hUsageChild)))
					goto error;
			}

			if ((result = obj_policy_is_secret_set(sess->hUsageChild, &secret_set)))
				goto error;

			if (!secret_set) {
				result = TSPERR(TSS_E_TSP_AUTHREQUIRED);
				goto error;
			}
		} else {
			/* In this case, the TPM is owned, but we're creating a no-auth NV area */
			get_child_auth = FALSE;
		}

		break;
#endif
	/* Child is a Key object */
	case TPM_ORD_MakeIdentity:
		if ((result = obj_rsakey_get_policy(obj_child, TSS_POLICY_USAGE,
						    &sess->hUsageChild, NULL)))
			goto error;
		break;
	/* Child is a Policy object */
	case TPM_ORD_Delegate_CreateKeyDelegation:
	case TPM_ORD_ChangeAuth:
		if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent)))
			goto error;
		/* fall through */
	case TPM_ORD_Delegate_CreateOwnerDelegation:
	case TPM_ORD_ChangeAuthOwner:
		sess->hUsageChild = obj_child;
		new_secret = TR_SECRET_CTX_NEW;
		break;
	default:
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto error;
	}

	/* If req_auth is FALSE here, we don't actually need to set up an auth session, so returning
	 * is OK.  At this point, authsess->pAuth is NULL, so the TCS API will not get any
	 * authdata. */
	if (req_auth == FALSE && sess->parentMode == TSS_SECRET_MODE_NONE)
		goto done;

	if (get_child_auth) {
		if ((result = obj_policy_get_xsap_params(sess->hUsageChild, 0, 0, NULL, NULL,
							 sess->encAuthUse.authdata, NULL, NULL,
							 &sess->cb_sealx, &sess->uMode,
							 new_secret)))
			goto error;
	}

	if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
				       (BYTE **)sess->nonceOddxSAP.nonce)))
		goto error;

	sess->obj_child = obj_child;
	sess->tspContext = tspContext;
	sess->pAuth = &sess->auth;
	sess->command = command;

#ifdef TSS_BUILD_DELEGATION
	/* if entityValue is set, we have a custom entity, i.e. delegation blob or row */
	if (sess->entityValue) {
		/* DSAP's entity type was pulled from the policy in the authsess_xsap_init call
		 * above */
		if ((result = authsess_do_dsap(sess)))
			goto error;
	}
#endif
	if (!sess->entityValue) {
		sess->entity_type = entity_type;
		if ((result = authsess_do_osap(sess)))
			goto error;
	}

	if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
				       (BYTE **)sess->auth.NonceOdd.nonce)))
		goto error;

	/* We have both OSAP nonces, so calculate the shared secret if we're responsible for it */
	if (sess->parentMode != TSS_SECRET_MODE_CALLBACK) {
		offset = 0;
		Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceEvenxSAP.nonce);
		Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceOddxSAP.nonce);

		if ((result = Trspi_HMAC(TSS_HASH_SHA1, sizeof(TPM_ENCAUTH),
					 sess->parentSecret.authdata, offset, hmacBlob,
					 sess->sharedSecret.digest)))
			goto error;
	}

	/* XXX What does a PurposeSecret of TRUE mean here? */
	if ((result =
	     ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HOBJECT, TSS_FLAG,
	       UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
	       BYTE *))sess->cb_xor.callback)(sess->cb_xor.appData, sess->hUsageParent,
					      sess->hUsageChild, TRUE, sizeof(TPM_DIGEST),
					      sess->auth.NonceEven.nonce, sess->auth.NonceOdd.nonce,
					      sess->nonceEvenxSAP.nonce, sess->nonceOddxSAP.nonce,
					      sizeof(TPM_ENCAUTH), sess->encAuthUse.authdata,
					      sess->encAuthMig.authdata)))
		return result;

done:
	*xsess = sess;

	return TSS_SUCCESS;
error:
	free(sess);
	return result;
}
예제 #20
0
TSS_RESULT
obj_pcrs_create_info_long(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info)
{
	struct tsp_object *obj;
	struct tr_pcrs_obj *pcrs;
	TSS_RESULT result = TSS_SUCCESS;
	TPM_PCR_INFO_LONG infolong;
	BYTE dummyBits[3] = { 0, 0, 0 };
	TPM_PCR_SELECTION dummySelection = { 3, dummyBits };
	UINT64 offset;
	UINT32 ret_size;
	BYTE *ret;

	if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	pcrs = (struct tr_pcrs_obj *)obj->data;

	/* Set everything that is not assigned to be all zeroes */
	memset(&infolong, 0, sizeof(infolong));

	infolong.tag = TPM_TAG_PCR_INFO_LONG;
	/* localityAtCreation and creationPCRSelection certainly do not need to be set here, but
	 * some chips such as Winbond do not ignore them on input, so we must give them dummy
	 * "good" values */
	infolong.localityAtCreation = TPM_LOC_ZERO;
	infolong.creationPCRSelection = dummySelection;
	switch (pcrs->type) {
		case TSS_PCRS_STRUCT_INFO:
			infolong.localityAtRelease = TSS_LOCALITY_ALL;
			infolong.releasePCRSelection = pcrs->info.info11.pcrSelection;
			infolong.digestAtRelease = pcrs->info.info11.digestAtRelease;
			break;
		case TSS_PCRS_STRUCT_INFO_LONG:
			infolong.localityAtRelease = pcrs->info.infolong.localityAtRelease;
			infolong.releasePCRSelection = pcrs->info.infolong.releasePCRSelection;
			infolong.digestAtRelease = pcrs->info.infolong.digestAtRelease;
			break;
		case TSS_PCRS_STRUCT_INFO_SHORT:
			infolong.localityAtRelease = pcrs->info.infoshort.localityAtRelease;
			infolong.releasePCRSelection = pcrs->info.infoshort.pcrSelection;
			infolong.digestAtRelease = pcrs->info.infoshort.digestAtRelease;
			break;
		default:
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
	}

	offset = 0;
	Trspi_LoadBlob_PCR_INFO_LONG(&offset, NULL, &infolong);
	ret_size = offset;

	if ((ret = calloc(1, ret_size)) == NULL) {
		result = TSPERR(TSS_E_OUTOFMEMORY);
		LogDebug("malloc of %u bytes failed.", ret_size);
		goto done;
	}

	offset = 0;
	Trspi_LoadBlob_PCR_INFO_LONG(&offset, ret, &infolong);

	*info = ret;
	*size = ret_size;

done:
	obj_list_put(&pcrs_list);

	return result;
}
예제 #21
0
파일: rsa.c 프로젝트: ajinkya93/netbsd-src
int
Trspi_RSA_Public_Encrypt(unsigned char *in, unsigned int inlen,
			 unsigned char *out, unsigned int *outlen,
			 unsigned char *pubkey, unsigned int pubsize,
			 unsigned int e, int padding)
{
	int rv, e_size = 3;
	unsigned char exp[] = { 0x01, 0x00, 0x01 };
	RSA *rsa = RSA_new();

	if (rsa == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	switch (e) {
		case 0:
			/* fall through */
		case 65537:
			break;
		case 17:
			exp[0] = 17;
			e_size = 1;
			break;
		case 3:
			exp[0] = 3;
			e_size = 1;
			break;
		default:
			rv = TSPERR(TSS_E_INTERNAL_ERROR);
			goto out;
			break;
	}

	switch (padding) {
		case TR_RSA_PKCS1_OAEP_PADDING:
			padding = RSA_PKCS1_OAEP_PADDING;
			break;
		case TR_RSA_PKCS1_PADDING:
			padding = RSA_PKCS1_PADDING;
			break;
		case TR_RSA_NO_PADDING:
			padding = RSA_NO_PADDING;
			break;
		default:
			rv = TSPERR(TSS_E_INTERNAL_ERROR);
			goto out;
			break;
	}

	/* set the public key value in the OpenSSL object */
	rsa->n = BN_bin2bn(pubkey, pubsize, rsa->n);
	/* set the public exponent */
	rsa->e = BN_bin2bn(exp, e_size, rsa->e);

	if (rsa->n == NULL || rsa->e == NULL) {
		rv = TSPERR(TSS_E_OUTOFMEMORY);
		goto err;
	}

	rv = RSA_public_encrypt(inlen, in, out, rsa, padding);
	if (rv == -1) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	/* RSA_public_encrypt returns the size of the encrypted data */
	*outlen = rv;
	rv = TSS_SUCCESS;
	goto out;

err:
	DEBUG_print_openssl_errors();
out:
	if (rsa)
		RSA_free(rsa);
        return rv;
}
예제 #22
0
TSS_RESULT
obj_pcrs_create_info_short(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info)
{
	struct tsp_object *obj;
	struct tr_pcrs_obj *pcrs;
	TSS_RESULT result = TSS_SUCCESS;
	TPM_PCR_INFO_SHORT infoshort;
	BYTE select[] = { 0, 0, 0 };
	UINT64 offset;
	UINT32 ret_size;
	BYTE *ret;

	/* Set everything that is not assigned to be all zeroes */
	memset(&infoshort, 0, sizeof(infoshort));

	if (hPcrs != NULL_HPCRS) {
		if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL)
			return TSPERR(TSS_E_INVALID_HANDLE);

		pcrs = (struct tr_pcrs_obj *)obj->data;

		switch (pcrs->type) {
			case TSS_PCRS_STRUCT_INFO:
				infoshort.pcrSelection = pcrs->info.info11.pcrSelection;
				infoshort.localityAtRelease = TSS_LOCALITY_ALL;
				infoshort.digestAtRelease = pcrs->info.info11.digestAtRelease;
				break;
			case TSS_PCRS_STRUCT_INFO_LONG:
				infoshort.pcrSelection = pcrs->info.infolong.releasePCRSelection;
				infoshort.localityAtRelease = pcrs->info.infolong.localityAtRelease;
				infoshort.digestAtRelease = pcrs->info.infolong.digestAtRelease;
				break;
			case TSS_PCRS_STRUCT_INFO_SHORT:
				infoshort = pcrs->info.infoshort;
				break;
			default:
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
		}
	} else {
		infoshort.pcrSelection.sizeOfSelect = sizeof(select);
		infoshort.pcrSelection.pcrSelect = select;
		infoshort.localityAtRelease = TSS_LOCALITY_ALL;
	}

	offset = 0;
	Trspi_LoadBlob_PCR_INFO_SHORT(&offset, NULL, &infoshort);
	ret_size = offset;

	if ((ret = calloc(1, ret_size)) == NULL) {
		result = TSPERR(TSS_E_OUTOFMEMORY);
		LogDebug("malloc of %u bytes failed.", ret_size);
		goto done;
	}

	offset = 0;
	Trspi_LoadBlob_PCR_INFO_SHORT(&offset, ret, &infoshort);

	*info = ret;
	*size = ret_size;

done:
	if (hPcrs != NULL_HPCRS)
		obj_list_put(&pcrs_list);

	return result;
}
예제 #23
0
VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipState, INT *pUncalX, INT *pUncalY)
{
	static int PrevX=0;
	static int PrevY=0;
	int TmpX = 0;
	int TmpY = 0;

	//TSPMSG((_T("[TSP] ++DdsiTouchPanelGetPoint()\r\n")));

	if (g_pVIC1Reg->VICRAWINTR & (1<<(PHYIRQ_PENDN-VIC1_BIT_OFFSET)))		// gIntrTouch Interrupt Case
	{
		//TSPMSG((_T("[TSP] gIntrTouch(PHYIRQ_PENDN) Case\r\n")));

		*pTipState = TouchSampleValidFlag;

		if ((g_pADCReg->ADCDAT0 & D_UPDOWN_UP)
			|| (g_pADCReg->ADCDAT1 & D_UPDOWN_UP))
		{
			//TSPMSG((_T("[TSP] Pen Up\r\n")));

			g_bTSP_DownFlag = FALSE;

			g_pADCReg->ADCTSC = ADCTSC_WAIT_PENDOWN;

			*pUncalX = PrevX;
			*pUncalY = PrevY;

			TSP_SampleStop();
		}
		else
		{
			//TSPMSG((_T("[TSP] Pen Down\r\n")));

			g_bTSP_DownFlag = TRUE;

			g_pADCReg->ADCTSC = ADCTSC_WAIT_PENUP;

			*pTipState |= TouchSampleIgnore;

			*pUncalX = PrevX;
			*pUncalY = PrevY;

			*pTipState |= TouchSampleDownFlag;

			TSP_SampleStart();
		}

		g_pADCReg->ADCCLRWK = CLEAR_ADCWK_INT;

		InterruptDone(gIntrTouch);		// Not handled in MDD
	}
	else// if (g_pVIC0Reg->VICRAWINTR & (1<<(PHYIRQ_TIMER3)))		// gIntrTouchTimer Interrupt Case
	{
		//TSPMSG((_T("[TSP] gIntrTouchChanged(PHYIRQ_TIMER3) Case\r\n")));

		// Check for Pen-Up case on the event of timer3 interrupt
		if ((g_pADCReg->ADCDAT0 & D_UPDOWN_UP)
			|| (g_pADCReg->ADCDAT1 & D_UPDOWN_UP))
		{
			//TSPMSG((_T("[TSP] Pen Up +\r\n")));

			g_bTSP_DownFlag = FALSE;

			g_pADCReg->ADCTSC = ADCTSC_WAIT_PENDOWN;

			*pUncalX = PrevX;
			*pUncalY = PrevY;

			*pTipState = TouchSampleValidFlag;

			TSP_SampleStop();
		}
		else if (g_bTSP_DownFlag)
		{
			if (TSP_GetXY(&TmpX, &TmpY) == TRUE)
			{
				//TSP_TransXY(&TmpX, &TmpY);

				if(Touch_Pen_Filtering(&TmpX, &TmpY))
				{
					*pTipState = TouchSampleValidFlag | TouchSampleDownFlag;
					*pTipState &= ~TouchSampleIgnore;
				}
				else		// Invalid touch pen
				{
					*pTipState = TouchSampleValidFlag;
					*pTipState |= TouchSampleIgnore;
				}

				*pUncalX = PrevX = TmpX;
				*pUncalY = PrevY = TmpY;

				g_pADCReg->ADCTSC = ADCTSC_WAIT_PENUP;

				//TSPMSG((_T("[TSP] UncalX = %d, UncalY = %d\r\n"), *pUncalX,*pUncalY));
			}
			else
			{
				*pTipState = TouchSampleIgnore;
			}
		}
		else
		{
			TSPERR((_T("[TSP] Unknown State\r\n")));

			*pTipState = TouchSampleIgnore;
			TSP_SampleStop();
		}

		// timer3 interrupt status clear
		//g_pPWMReg->TINT_CSTAT |= (1<<8);		// Do not use OR/AND operation on TINTC_CSTAT
		g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_PENDING_CLEAR;

		InterruptDone(gIntrTouchChanged);		// Not Handled in MDD
	}

	//TSPMSG((_T("[TSP] --DdsiTouchPanelGetPoint()\r\n")));
}
예제 #24
0
TSS_RESULT
Tspi_Data_Unseal(TSS_HENCDATA hEncData,		/* in */
		 TSS_HKEY hKey,			/* in */
		 UINT32 * pulUnsealedDataLength,/* out */
		 BYTE ** prgbUnsealedData)	/* out */
{
	UINT64 offset;
	TPM_AUTH privAuth2;
	TPM_DIGEST digest;
	TPM_NONCE authLastNonceEven;
	TSS_RESULT result;
	TSS_HPOLICY hPolicy, hEncPolicy;
	TCS_KEY_HANDLE tcsKeyHandle;
        TSS_HCONTEXT tspContext;
	UINT32 ulDataLen, unSealedDataLen;
	BYTE *data = NULL, *unSealedData = NULL, *maskedData;
	UINT16 mask;
	Trspi_HashCtx hashCtx;
	struct authsess *xsap = NULL;

	if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL)))
		return result;

	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy)))
		return result;

	if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data)))
		return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
		       TSPERR(TSS_E_ENC_NO_DATA) :
		       result;

	offset = 0;
	Trspi_UnloadBlob_UINT16(&offset, &mask, data);
	if (mask == TPM_TAG_STORED_DATA12) {
		/* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero
		 * then we must unmask the unsealed data after it returns from the TCS */
		Trspi_UnloadBlob_UINT16(&offset, &mask, data);
	} else
		mask = 0;

	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
		goto error;

	if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
					 TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap)))
		goto error;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
	result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest,
					      &privAuth2)))
		goto error;

	if (mask) {
		/* save off last nonce even to pass to sealx callback */
		   memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE));
	}

	if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data,
						  xsap->pAuth, &privAuth2, &unSealedDataLen,
						  &unSealedData)))
		goto error;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
	result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen);
	result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
		free(unSealedData);
		goto error;
	}

	if ((result = authsess_xsap_verify(xsap, &digest))) {
		free(unSealedData);
		goto error;
	}

	if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) {
		free(unSealedData);
		goto error;
	}

	/* If the data is masked, use the callback set up in authsess_xsap_init */
	if (mask) {
		maskedData = unSealedData;

		if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) {
			free(maskedData);
			LogError("malloc of %u bytes failed", unSealedDataLen);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto error;
		}

		/* XXX pass in out saved-off authLastNonceEven. This conflicts with the
		 * description of the rgbNonceEven parameter in the spec, but without it, its not
		 * possible to compute the MGF1 key */
		if ((result =
		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
		       UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
		       BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData,
							 xsap->cb_sealx.alg, sizeof(TPM_NONCE),
							 authLastNonceEven.nonce,
							 xsap->auth.NonceOdd.nonce,
							 xsap->nonceEvenxSAP.nonce,
							 xsap->nonceOddxSAP.nonce,
							 unSealedDataLen, maskedData,
							 unSealedData))) {
			free(maskedData);
			goto error;
		}

		free(maskedData);
	} else {
		if ((result = __tspi_add_mem_entry(tspContext, unSealedData)))
			goto error;
	}

	*pulUnsealedDataLength = unSealedDataLen;
	*prgbUnsealedData = unSealedData;

error:
	authsess_free(xsap);
	if (data)
		free_tspi(tspContext, data);

	return result;
}
예제 #25
0
TSS_RESULT
Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext,		/* in */
			   TSS_FLAG persistentStorageType,	/* in */
			   TSS_UUID uuidData,			/* in */
			   TSS_HKEY * phKey)			/* out */
{
	TSS_RESULT result;
	TSS_UUID parentUUID;
	UINT32 keyBlobSize, parentPSType;
	BYTE *keyBlob = NULL;
	TCS_KEY_HANDLE tcsKeyHandle;
	TSS_HKEY parentTspHandle;
	TCS_LOADKEY_INFO info;
	UINT32		ulPubKeyLength;
	BYTE		*rgbPubKey;

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

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

	/* This key is in the System Persistant storage */
	if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
#if 1
		memset(&info, 0, sizeof(TCS_LOADKEY_INFO));

		result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle);

		if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) {
			TSS_HKEY keyHandle;
			TSS_HPOLICY hPolicy;

			/* load failed, due to some key in the chain needing auth
			 * which doesn't yet exist at the TCS level. However, the
			 * auth may already be set in policies at the TSP level.
			 * To find out, get the key handle of the key requiring
			 * auth. First, look at the list of keys in memory. */
			if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) {
				/* If that failed, look on disk, in User PS. */
				if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID,
						       &keyHandle))
					return result;
			}

			if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE,
						  &hPolicy, NULL))
				return result;

			if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE,
						    &info.paramDigest, &info.authData))
				return result;

			if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info,
							&tcsKeyHandle)))
				return result;
		} else if (result)
			return result;

		/*check if provided UUID has an owner evict key UUID prefix */
		if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) {
			if ((result = obj_rsakey_add(tspContext, TSS_RSAKEY_FLAG_OWNEREVICT,
						      phKey)))
				return result;
			if ((result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle)))
				return result;

			//The cached public key portion of the owner evict key is used 
			//further by TPM_KEY_CONTROLOWNER command for sanity check
			if ((result = Tspi_Key_GetPubKey(*phKey, &ulPubKeyLength, &rgbPubKey)))
				return result;

			result = obj_rsakey_set_pubkey(*phKey, FALSE, rgbPubKey);

			free(rgbPubKey);		
			if (result != TSS_SUCCESS)
				return result;
		} else {
			if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize,
							       &keyBlob)))
				return result;

			if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob,
							    TSS_OBJ_FLAG_SYSTEM_PS, phKey))) {
				free (keyBlob);
				return result;
			}
	
			result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle);

			free (keyBlob);
		}
#else
		if ((result = load_from_system_ps(tspContext, &uuidData, phKey)))
			return result;
#endif
	} else if (persistentStorageType == TSS_PS_TYPE_USER) {
		if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID)))
			return result;

		/* If the parent is not in memory, recursively call ourselves on it */
		if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) {
			if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType)))
				return result;

			if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType,
								 parentUUID, &parentTspHandle)))
				return result;
		}

		if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey)))
			return result;

		/* The parent is loaded and we have the parent key handle, so call the TCS to
		 * actually load the child. */
		return Tspi_Key_LoadKey(*phKey, parentTspHandle);
	} else {
		return TSPERR(TSS_E_BAD_PARAMETER);
	}

	return TSS_SUCCESS;
}
예제 #26
0
TSS_RESULT
Tspi_Data_Seal(TSS_HENCDATA hEncData,	/* in */
	       TSS_HKEY hEncKey,	/* in */
	       UINT32 ulDataLength,	/* in */
	       BYTE * rgbDataToSeal,	/* in */
	       TSS_HPCRS hPcrComposite)	/* in */
{
	TPM_DIGEST digest;
	TSS_RESULT result;
	TSS_HPOLICY hPolicy, hEncPolicy;
	BYTE *encData = NULL;
	BYTE *pcrData = NULL;
	UINT32 encDataSize;
	UINT32 pcrDataSize;
	UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT;
	UINT32 sealOrdinal = TPM_ORD_Seal;
	TCS_KEY_HANDLE tcsKeyHandle;
	TSS_HCONTEXT tspContext;
	Trspi_HashCtx hashCtx;
	BYTE *sealData = NULL;
	struct authsess *xsap = NULL;
#ifdef TSS_BUILD_SEALX
	UINT32 protectMode;
#endif

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

	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE,
					    &hPolicy, NULL)))
		return result;

	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE,
					     &hEncPolicy)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle)))
		return result;

#ifdef TSS_BUILD_SEALX
	/* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute
	   to determine the seal function to invoke */
	if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode)))
		return result;

	if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) {
		sealOrdinal = TPM_ORD_Seal;
		pcrInfoType = 0;
	} else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) {
		sealOrdinal = TPM_ORD_Sealx;
		pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
	} else
		return TSPERR(TSS_E_INTERNAL_ERROR);
#endif

	/* If PCR's are of interest */
	pcrDataSize = 0;
	if (hPcrComposite) {
		if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize,
							&pcrData)))
			return result;
	}

	if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
					 sealOrdinal, TPM_ET_KEYHANDLE, &xsap)))
		goto error;

#ifdef TSS_BUILD_SEALX
	if (sealOrdinal == TPM_ORD_Seal)
		sealData = rgbDataToSeal;
	else {
		if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) {
			LogError("malloc of %u bytes failed", ulDataLength);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto error;
		}

		if ((result =
		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
		     UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
		     BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData,
						      xsap->cb_sealx.alg, sizeof(TPM_NONCE),
						      xsap->auth.NonceEven.nonce,
						      xsap->auth.NonceOdd.nonce,
						      xsap->nonceEvenxSAP.nonce,
						      xsap->nonceOddxSAP.nonce, ulDataLength,
						      rgbDataToSeal, sealData)))
			goto error;
	}
#else
	sealData = rgbDataToSeal;
#endif

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize);
	result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
	result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
	result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
		goto error;
	}

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

#ifdef TSS_BUILD_SEALX
	if (sealOrdinal == TPM_ORD_Seal) {
		if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
							pcrDataSize, pcrData, ulDataLength,
							sealData, xsap->pAuth, &encDataSize,
							&encData))) {
			goto error;
		}
	} else if (sealOrdinal == TPM_ORD_Sealx) {
		if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse,
						    pcrDataSize, pcrData, ulDataLength, sealData,
						    xsap->pAuth, &encDataSize, &encData))) {
			goto error;
		}
	} else {
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto error;
	}
#else
	if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
						pcrDataSize, pcrData, ulDataLength, sealData,
						xsap->pAuth, &encDataSize, &encData)))
		goto error;
#endif

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
	result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_verify(xsap, &digest)))
		goto error;

	/* Need to set the object with the blob and the pcr's */
	if ((result = obj_encdata_set_data(hEncData, encDataSize, encData)))
		goto error;

	if (pcrDataSize)
		result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData);

error:
	authsess_free(xsap);
	free(encData);
	free(pcrData);
	if (sealData != rgbDataToSeal)
		free(sealData);
	return result;
}
예제 #27
0
TSS_RESULT
Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext,		/* in */
				     TSS_FLAG persistentStorageType,	/* in */
				     TSS_UUID * pUuidData,		/* in */
				     UINT32 * pulKeyHierarchySize,	/* out */
				     TSS_KM_KEYINFO2 ** ppKeyHierarchy)	/* out */
{
	TSS_RESULT result;
	TSS_KM_KEYINFO2 *tcsHier, *tspHier;
	UINT32 tcsHierSize, tspHierSize;
	TSS_UUID tcs_uuid;

	/* If out parameters are NULL, return error */
	if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
			return TSPERR(TSS_E_BAD_PARAMETER);

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

	if (pUuidData) {
		/* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of
		 * TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key
		 * hierarchy regarding that key. The first array entry is the key addressed by the
		 * given UUID followed by its parent key up to and including the root key. */
		if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
			if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData,
							      pulKeyHierarchySize, ppKeyHierarchy)))
				return result;
		} else if (persistentStorageType == TSS_PS_TYPE_USER) {
			if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize,
							      &tspHier)))
				return result;
			/* The tcs_uuid returned by ps_get_registered_key2 will always be a parent
			 * of some key into the system ps of a user key into the user ps. This key
			 * needs to be searched for in the system ps to be merged */
			if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize,
							      &tcsHier))) {
				free(tspHier);
				return result;
			}

			result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier,
							tcsHierSize, tcsHier, pulKeyHierarchySize,
							ppKeyHierarchy);
			free(tcsHier);
			free(tspHier);
		} else
			return TSPERR(TSS_E_BAD_PARAMETER);
	} else {
		/* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures
		 * contains data reflecting the entire key hierarchy starting with root key. The
		 * array will include keys from both the user and the system TSS key store. The
		 * persistentStorageType field will be ignored. */
		if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize,
						      &tcsHier)))
			return result;

		if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) {
			free(tcsHier);
			return result;
		}

		result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize,
						tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
		free(tcsHier);
		free(tspHier);
	}

	if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) {
		free(*ppKeyHierarchy);
		*ppKeyHierarchy = NULL;
		*pulKeyHierarchySize = 0;
	}

	return result;
}
예제 #28
0
TSS_RESULT
secret_PerformXOR_OSAP(TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy,
		       TSS_HPOLICY hMigrationPolicy, TSS_HOBJECT hOSAPObject,
		       UINT16 osapType, UINT32 osapData,
		       TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig,
		       BYTE *sharedSecret, TPM_AUTH * auth, TCPA_NONCE * nonceEvenOSAP)
{
	TSS_BOOL bExpired;
	TCPA_SECRET keySecret;
	TCPA_SECRET usageSecret;
	TCPA_SECRET migSecret = { { 0, } };
	UINT32 keyMode, usageMode, migMode = 0;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;


	if ((result = obj_policy_has_expired(hPolicy, &bExpired)))
		return result;

	if (bExpired == TRUE)
		return TSPERR(TSS_E_INVALID_OBJ_ACCESS);

	if ((result = obj_policy_has_expired(hUsagePolicy, &bExpired)))
		return result;

	if (bExpired == TRUE)
		return TSPERR(TSS_E_INVALID_OBJ_ACCESS);

	if (hMigrationPolicy) {
		if ((result = obj_policy_has_expired(hMigrationPolicy, &bExpired)))
			return result;

		if (bExpired == TRUE)
			return TSPERR(TSS_E_INVALID_OBJ_ACCESS);

		if ((result = obj_policy_get_mode(hMigrationPolicy, &migMode)))
			return result;
	}

	if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext)))
		return result;

	if ((result = obj_policy_get_mode(hPolicy, &keyMode)))
		return result;

	if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode)))
		return result;

	if (keyMode == TSS_SECRET_MODE_CALLBACK ||
	    usageMode == TSS_SECRET_MODE_CALLBACK ||
	    (hMigrationPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) {
		if (keyMode != TSS_SECRET_MODE_CALLBACK ||
		    usageMode != TSS_SECRET_MODE_CALLBACK ||
		    (hMigrationPolicy && migMode != TSS_SECRET_MODE_CALLBACK))
			return TSPERR(TSS_E_BAD_PARAMETER);
	}

	if (keyMode != TSS_SECRET_MODE_CALLBACK) {
		if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, &keySecret)))
			return result;

		if ((result = obj_policy_get_secret(hUsagePolicy, TR_SECRET_CTX_NEW, &usageSecret)))
			return result;

		if (hMigrationPolicy) {
			if ((result = obj_policy_get_secret(hMigrationPolicy, TR_SECRET_CTX_NEW,
							&migSecret)))
				return result;
		}

		if ((result = OSAP_Calc(tspContext, osapType, osapData,
					keySecret.authdata, usageSecret.authdata,
					migSecret.authdata, encAuthUsage,
					encAuthMig, sharedSecret, auth)))
			return result;
	} else {
		/* If the secret mode is NONE here, we don't return an error. This is
		 * because there are commands such as CreateKey, which require an auth
		 * session even when creating no-auth keys. A secret of all 0's will be
		 * used in this case. */
		if ((result = TCS_API(tspContext)->OSAP(tspContext, osapType, osapData,
							&auth->NonceOdd, &auth->AuthHandle,
							&auth->NonceEven, nonceEvenOSAP)))
			return result;

		if ((result = obj_policy_do_xor(hPolicy, hOSAPObject,
						hPolicy, TRUE, 20,
						auth->NonceEven.nonce, NULL,
						nonceEvenOSAP->nonce,
						auth->NonceOdd.nonce, 20,
						encAuthUsage->authdata,
						encAuthMig->authdata))) {
			TCS_API(tspContext)->TerminateHandle(tspContext, auth->AuthHandle);
			return result;
		}
	}

	return TSS_SUCCESS;
}
예제 #29
0
TSS_RESULT
RPC_GetAuditDigest_TP(struct host_table_entry *hte,
		      UINT32 startOrdinal,		/* in */
		      TPM_DIGEST *auditDigest,		/* out */
		      UINT32 *counterValueSize,	/* out */
		      BYTE **counterValue,		/* out */
		      TSS_BOOL *more,			/* out */
		      UINT32 *ordSize,			/* out */
		      UINT32 **ordList)		/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGEST;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &startOrdinal, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, auditDigest, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, counterValueSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*counterValue = (BYTE *)malloc(*counterValueSize);
		if (*counterValue == NULL) {
			LogError("malloc of %u bytes failed.", *counterValueSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *counterValue, *counterValueSize, &hte->comm)) {
			free(*counterValue);
			*counterValue = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_BOOL, 3, more, 0, &hte->comm)) {
			free(*counterValue);
			*counterValue = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 4, ordSize, 0, &hte->comm)) {
			free(*counterValue);
			*counterValue = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*ordList = (UINT32 *)malloc(*ordSize * sizeof(UINT32));
		if (*ordList == NULL) {
			LogError("malloc of %u bytes failed.", *ordSize);
			free(*counterValue);
			*counterValue = NULL;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 5, *ordList, *ordSize * sizeof(UINT32), &hte->comm)) {
			free(*counterValue);
			*counterValue = NULL;
			free(*ordList);
			*ordList = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

done:
	return result;
}
예제 #30
0
TSS_RESULT
psfile_remove_key(int fd, TSS_UUID *uuid)
{
        TSS_RESULT result;
        UINT32 head_offset = 0, tail_offset;
	int rc, size = 0;
	struct key_disk_cache c;
	BYTE buf[4096];

	if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &c)))
		return result;

	/* head_offset is the offset the beginning of the key */
	head_offset = TSSPS_UUID_OFFSET(&c);

	/* tail_offset is the offset the beginning of the next key */
	tail_offset = TSSPS_VENDOR_DATA_OFFSET(&c) + c.vendor_data_size;

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

	/* read in from tail, write out to head to fill the gap */
	while ((rc = read(fd, buf, sizeof(buf))) > 0) {
		size = rc;
		tail_offset += size;

		/* set the file pointer to where we want to write */
		rc = lseek(fd, head_offset, SEEK_SET);
		if (rc == ((off_t)-1)) {
			LogDebug("lseek: %s", strerror(errno));
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}

		/* write the data */
		if ((result = write_data(fd, (void *)buf, size))) {
			LogDebug("%s", __FUNCTION__);
			return result;
		}
		head_offset += size;

		/* set the file pointer to where we want to read in the next
		 * loop */
		rc = lseek(fd, tail_offset, SEEK_SET);
		if (rc == ((off_t)-1)) {
			LogDebug("lseek: %s", strerror(errno));
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

	if (rc < 0) {
		LogDebug("read: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	/* set the file pointer to where we want to write */
	rc = lseek(fd, head_offset, SEEK_SET);
	if (rc == ((off_t)-1)) {
		LogDebug("lseek: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	/* head_offset now contains a pointer to where we want to truncate the
	 * file. Zero out the old tail end of the file and truncate it. */

	memset(buf, 0, sizeof(buf));

	/* Zero out the old tail end of the file */
	if ((result = write_data(fd, (void *)buf, tail_offset - head_offset))) {
		LogDebug("%s", __FUNCTION__);
		return result;
	}

	if ((rc = ftruncate(fd, head_offset)) < 0) {
		LogDebug("ftruncate: %s", strerror(errno));
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	/* we succeeded in removing a key from the disk. Decrement the number
	 * of keys in the file */
	if ((result = psfile_change_num_keys(fd, TSS_PSFILE_DECREMENT_NUM_KEYS)))
		return result;

	return TSS_SUCCESS;
}