Exemplo n.º 1
0
TEE_Result tee_svc_wait(uint32_t timeout)
{
	TEE_Result res = TEE_SUCCESS;
	uint32_t mytime = 0;
	struct tee_ta_session *s;
	TEE_Time base_time;
	TEE_Time current_time;

	res = tee_ta_get_current_session(&s);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_time_get_sys_time(&base_time);
	if (res != TEE_SUCCESS)
		return res;

	while (true) {
		res = tee_time_get_sys_time(&current_time);
		if (res != TEE_SUCCESS)
			return res;

		if (session_is_cancelled(s, &current_time))
			return TEE_ERROR_CANCEL;

		mytime = (current_time.seconds - base_time.seconds) * 1000 +
		    (int)current_time.millis - (int)base_time.millis;
		if (mytime >= timeout)
			return TEE_SUCCESS;

		tee_wait_specific(timeout - mytime);
	}

	return res;
}
Exemplo n.º 2
0
__weak void plat_rng_init(void)
{
	TEE_Result res = TEE_SUCCESS;
	TEE_Time t;

#ifndef CFG_SECURE_TIME_SOURCE_REE
	/*
	 * This isn't much of a seed. Ideally we should either get a seed from
	 * a hardware RNG or from a previously saved seed.
	 *
	 * Seeding with hardware RNG is currently up to the platform to
	 * override this function.
	 *
	 * Seeding with a saved seed will require cooperation from normal
	 * world, this is still TODO.
	 */
	res = tee_time_get_sys_time(&t);
#else
	EMSG("Warning: seeding RNG with zeroes");
	memset(&t, 0, sizeof(t));
#endif
	if (!res)
		res = crypto_rng_init(&t, sizeof(t));
	if (res) {
		EMSG("Failed to initialize RNG: %#" PRIx32, res);
		panic();
	}
}
Exemplo n.º 3
0
TEE_Result tee_time_get_ta_time(const TEE_UUID *uuid, TEE_Time *time)
{
	TEE_Result res;
	const TEE_Time *offs;
	bool positive;
	TEE_Time t;
	TEE_Time t2;

	res = tee_time_ta_get_offs(uuid, &offs, &positive);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_time_get_sys_time(&t);
	if (res != TEE_SUCCESS)
		return res;

	if (positive) {
		TEE_TIME_ADD(t, *offs, t2);

		/* Detect wrapping, the wrapped time should be returned. */
		if (TEE_TIME_LT(t2, t))
			res = TEE_ERROR_OVERFLOW;
	} else {
		TEE_TIME_SUB(t, *offs, t2);

		/* Detect wrapping, the wrapped time should be returned. */
		if (TEE_TIME_LE(t, t2))
			res = TEE_ERROR_OVERFLOW;
	}
	*time = t2;

	return res;
}
Exemplo n.º 4
0
TEE_Result tee_svc_get_time(enum utee_time_category cat, TEE_Time *mytime)
{
	TEE_Result res, res2;
	struct tee_ta_session *s = NULL;
	TEE_Time t;

	res = tee_ta_get_current_session(&s);
	if (res != TEE_SUCCESS)
		return res;

	switch (cat) {
	case UTEE_TIME_CAT_SYSTEM:
		res = tee_time_get_sys_time(&t);
		break;
	case UTEE_TIME_CAT_TA_PERSISTENT:
		res =
		    tee_time_get_ta_time((const void *)&s->ctx->head->uuid, &t);
		break;
	case UTEE_TIME_CAT_REE:
		res = tee_time_get_ree_time(&t);
		break;
	default:
		res = TEE_ERROR_BAD_PARAMETERS;
		break;
	}

	if (res == TEE_SUCCESS || res == TEE_ERROR_OVERFLOW) {
		res2 = tee_svc_copy_to_user(s, mytime, &t, sizeof(t));
		if (res2 != TEE_SUCCESS)
			res = res2;
	}

	return res;
}
Exemplo n.º 5
0
static bool session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time)
{
	TEE_Time current_time;

	if (s->cancel_mask)
		return false;

	if (s->cancel)
		return true;

	if (s->cancel_time.seconds == UINT32_MAX)
		return false;

	if (curr_time != NULL)
		current_time = *curr_time;
	else if (tee_time_get_sys_time(&current_time) != TEE_SUCCESS)
		return false;

	if (current_time.seconds > s->cancel_time.seconds ||
	    (current_time.seconds == s->cancel_time.seconds &&
	     current_time.millis >= s->cancel_time.millis)) {
		return true;
	}

	return false;
}
Exemplo n.º 6
0
/*
 * Override this in your platform code to feed the PRNG platform-specific
 * jitter entropy. This implementation does not efficiently deliver entropy
 * and is here for backwards-compatibility.
 */
__weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid,
					 unsigned int *pnum)
{
	TEE_Time current;

#ifdef CFG_SECURE_TIME_SOURCE_REE
	if (CRYPTO_RNG_SRC_IS_QUICK(sid))
		return; /* Can't read REE time here */
#endif

	if (tee_time_get_sys_time(&current) == TEE_SUCCESS)
		crypto_rng_add_event(sid, pnum, &current, sizeof(current));
}
Exemplo n.º 7
0
TEE_Result tee_time_set_ta_time(const TEE_UUID *uuid, const TEE_Time *time)
{
	TEE_Result res;
	TEE_Time offs;
	TEE_Time t;

	/* Check that time is normalized. */
	if (time->millis >= TEE_TIME_MILLIS_BASE)
		return TEE_ERROR_BAD_PARAMETERS;

	res = tee_time_get_sys_time(&t);
	if (res != TEE_SUCCESS)
		return res;

	if (TEE_TIME_LT(t, *time)) {
		TEE_TIME_SUB(*time, t, offs);
		return tee_time_ta_set_offs(uuid, &offs, true);
	} else {
		TEE_TIME_SUB(t, *time, offs);
		return tee_time_ta_set_offs(uuid, &offs, false);
	}
}