Ejemplo n.º 1
0
static uint32_t load_ta(size_t num_params, struct tee_ioctl_param *params)
{
	int ta_found = 0;
	size_t size = 0;
	TEEC_UUID uuid;
	struct tee_ioctl_param_value *val_cmd;
	TEEC_SharedMemory shm_ta;

	memset(&shm_ta, 0, sizeof(shm_ta));

	if (num_params != 2 || get_value(num_params, params, 0, &val_cmd) ||
	    get_param(num_params, params, 1, &shm_ta))
		return TEEC_ERROR_BAD_PARAMETERS;

	uuid_from_octets(&uuid, (void *)val_cmd);

	size = shm_ta.size;
	ta_found = TEECI_LoadSecureModule(ta_dir, &uuid, shm_ta.buffer, &size);
	if (ta_found != TA_BINARY_FOUND) {
		EMSG("  TA not found");
		return TEEC_ERROR_ITEM_NOT_FOUND;
	}

	params[1].u.memref.size = size;

	/*
	 * If a buffer wasn't provided, just tell which size it should be.
	 * If it was provided but isn't big enough, report an error.
	 */
	if (shm_ta.buffer && size > shm_ta.size)
		return TEEC_ERROR_SHORT_BUFFER;

	return TEEC_SUCCESS;
}
Ejemplo n.º 2
0
/*
 * This function opens a new Session between the Client application and the
 * specified TEE application.
 *
 * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and
 * operation shall be set to NULL.
 */
TEEC_Result TEEC_OpenSession(TEEC_Context *context,
			     TEEC_Session *session,
			     const TEEC_UUID *destination,
			     uint32_t connection_method,
			     const void *connection_data,
			     TEEC_Operation *operation, uint32_t *error_origin)
{
	TEEC_Operation dummy_op;
	size_t ta_size = 0;
	struct tee_cmd tc;
	uint32_t origin = TEEC_ORIGIN_API;
	TEEC_Result res = TEEC_SUCCESS;
	void *ta = NULL;
	(void)connection_data;

	if (session != NULL)
		session->fd = -1;

	if ((context == NULL) || (session == NULL)) {
		res = TEEC_ERROR_BAD_PARAMETERS;
		goto error;
	}

	/* Check that context->fd is a valid file descriptor */
	session->fd = dup(context->fd);
	if (session->fd == -1) {
		res = TEEC_ERROR_BAD_PARAMETERS;
		goto error;
	}
	close(session->fd);
	session->fd = -1;

	if (connection_method != TEEC_LOGIN_PUBLIC) {
		res = TEEC_ERROR_NOT_SUPPORTED;
		goto error;
	}

	memset(&tc, 0, sizeof(struct tee_cmd));

	/*
	 * Save the fd in the session for later use when invoke command and
	 * close the session.
	 */
	session->fd = open(context->devname, O_RDWR);
	if (session->fd == -1) {
		res = TEEC_ERROR_BAD_PARAMETERS;
		goto error;
	}

	/*
	 * Check if the TA binary is found on the filesystem.
	 * If no, assume it is a static TA.
	 */
	if (TEECI_LoadSecureModule
	    (get_tee_target(context), destination, &ta,
	     &ta_size) == TA_BINARY_FOUND) {
		tc.uuid = (TEEC_UUID *)destination;
		tc.data = ta;
		tc.data_size = ta_size;
	} else {
		tc.uuid = (TEEC_UUID *)destination;
		tc.data = NULL;
		tc.data_size = 0;
	}

	if (operation == NULL) {
		/*
		 * The code here exist because Global Platform API states that
		 * it is allowed to give operation as a NULL pointer. In kernel
		 * and secure world we in most cases don't want this to be NULL,
		 * hence we use this dummy operation when a client doesn't
		 * provide any operation.
		 */
		memset(&dummy_op, 0, sizeof(TEEC_Operation));
		operation = &dummy_op;
	}

	tc.op = operation;

	if (ioctl(session->fd, TEE_OPEN_SESSION_IOC, &tc) != 0) {
		EMSG("Ioctl(TEE_OPEN_SESSION_IOC) failed! (%s)\n",
		     strerror(errno));
		origin = TEEC_ORIGIN_COMMS;
		res = TEEC_ERROR_COMMUNICATION;
		goto error;
	}

	if (tc.err != 0) {
		EMSG("UUID %x %x %x can't be loaded !!!\n",
		     destination->timeLow,
		     destination->timeMid, destination->timeHiAndVersion);
	}
	origin = tc.origin;
	res = tc.err;

error:
	/*
	 * We do this check at the end instead of checking on every place where
	 * we set the error origin.
	 */
	if (res != TEEC_SUCCESS) {
		if (session != NULL && session->fd != -1) {
			close(session->fd);
			session->fd = -1;
		}
	}

	if (error_origin != NULL)
		*error_origin = origin;

	if (ta)
		free(ta);

	return res;
}