Esempio n. 1
0
/*
 * The data to hash is 48 bytes made up of:
 * - 16 bytes: the UUID of the calling TA.
 * - 32 bytes: the hardware device ID
 * The resulting endorsement seed is 32 bytes.
 *
 * The output buffer is the "binary" struct defined in
 * the "prop_value" union and therefore comprises:
 * -  4 bytes: the size of the binary value data (32)
 * - 32 bytes: the binary value data (endorsement seed)
 *
 * Note that this code assumes an endorsement seed
 * size == device ID size for convenience.
 */
static TEE_Result get_prop_endorsement(struct tee_ta_session *sess,
				       void *buf, size_t *blen)
{
	TEE_Result res;
	uint32_t ta_endorsement_seed_size = 32;
	uint8_t data[sizeof(TEE_UUID) + ta_endorsement_seed_size];
	uint32_t bin[1 + ta_endorsement_seed_size / sizeof(uint32_t)];
	uint32_t *bin_len = (uint32_t *)bin;
	uint8_t *bin_val = (uint8_t *)(&bin[1]);

	if (*blen < sizeof(bin)) {
		*blen = sizeof(bin);
		return TEE_ERROR_SHORT_BUFFER;
	}
	*blen = sizeof(bin);

	memcpy(data, &sess->ctx->uuid, sizeof(TEE_UUID));

	if (tee_otp_get_die_id(&data[sizeof(TEE_UUID)],
			       ta_endorsement_seed_size))
		return TEE_ERROR_BAD_STATE;

	res = tee_hash_createdigest(TEE_ALG_SHA256, data, sizeof(data),
				    bin_val, ta_endorsement_seed_size);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_BAD_STATE;

	*bin_len = ta_endorsement_seed_size;

	return tee_svc_copy_to_user((void *)buf, bin, sizeof(bin));
}
Esempio n. 2
0
TEE_Result tee_svc_sys_get_property(uint32_t prop, tee_uaddr_t buf, size_t blen)
{
	static const char api_vers[] = "1.0";
	static const char descr[] = "Version N.N";
	/*
	 * Value 100 means:
	 * System time based on REE-controlled timers. Can be tampered by the
	 * REE.  The implementation must still guarantee that the system time
	 * is monotonous, i.e., successive calls to TEE_GetSystemTime must
	 * return increasing values of the system time.
	 */
	static const uint32_t sys_time_prot_lvl = 100;
	static const uint32_t ta_time_prot_lvl = 100;
	struct tee_ta_session *sess;
	TEE_Result res;

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

	switch (prop) {
	case UTEE_PROP_TEE_API_VERSION:
		if (blen < sizeof(api_vers))
			return TEE_ERROR_SHORT_BUFFER;
		return tee_svc_copy_to_user(sess, (void *)buf, api_vers,
					    sizeof(api_vers));

	case UTEE_PROP_TEE_DESCR:
		if (blen < sizeof(descr))
			return TEE_ERROR_SHORT_BUFFER;
		return tee_svc_copy_to_user(sess, (void *)buf, descr,
					    sizeof(descr));

	case UTEE_PROP_TEE_DEV_ID:
		{
			TEE_UUID uuid;
			const size_t nslen = 4;
			uint8_t data[4 +
				     FVR_DIE_ID_NUM_REGS * sizeof(uint32_t)] = {
			    'S', 'T', 'E', 'E' };

			if (blen < sizeof(uuid))
				return TEE_ERROR_SHORT_BUFFER;

			if (tee_otp_get_die_id
					(data + nslen, sizeof(data) - nslen))
				return TEE_ERROR_BAD_STATE;

			res = tee_hash_createdigest(
					TEE_ALG_SHA256,
					data, sizeof(data),
					(uint8_t *)&uuid, sizeof(uuid));
			if (res != TEE_SUCCESS)
				return TEE_ERROR_BAD_STATE;

			/*
			 * Changes the random value into and UUID as specifiec
			 * in RFC 4122. The magic values are from the example
			 * code in the RFC.
			 *
			 * TEE_UUID is defined slightly different from the RFC,
			 * but close enough for our purpose.
			 */

			uuid.timeHiAndVersion &= 0x0fff;
			uuid.timeHiAndVersion |= 5 << 12;

			/* uuid.clock_seq_hi_and_reserved in the RFC */
			uuid.clockSeqAndNode[0] &= 0x3f;
			uuid.clockSeqAndNode[0] |= 0x80;

			return tee_svc_copy_to_user(sess, (void *)buf, &uuid,
						    sizeof(TEE_UUID));
		}

	case UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL:
		if (blen < sizeof(sys_time_prot_lvl))
			return TEE_ERROR_SHORT_BUFFER;
		return tee_svc_copy_to_user(sess, (void *)buf,
					    &sys_time_prot_lvl,
					    sizeof(sys_time_prot_lvl));

	case UTEE_PROP_TEE_TA_TIME_PROT_LEVEL:
		if (blen < sizeof(ta_time_prot_lvl))
			return TEE_ERROR_SHORT_BUFFER;
		return tee_svc_copy_to_user(sess, (void *)buf,
					    &ta_time_prot_lvl,
					    sizeof(ta_time_prot_lvl));

	case UTEE_PROP_TEE_ARITH_MAX_BIG_INT_SIZE:
		{
			uint32_t v = LTC_MAX_BITS_PER_VARIABLE / 2;

			if (blen < sizeof(v))
				return TEE_ERROR_SHORT_BUFFER;

			return tee_svc_copy_to_user(sess, (void *)buf, &v,
						    sizeof(v));
		}

	case UTEE_PROP_CLIENT_ID:
		{
			if (blen < sizeof(TEE_Identity))
				return TEE_ERROR_SHORT_BUFFER;

			return tee_svc_copy_to_user(sess, (void *)buf,
						    &sess->clnt_id,
						    sizeof(TEE_Identity));
		}
	case UTEE_PROP_TA_APP_ID:
		{
			if (blen < sizeof(TEE_UUID))
				return TEE_ERROR_SHORT_BUFFER;

			return tee_svc_copy_to_user(sess, (void *)buf,
						    &sess->ctx->head->uuid,
						    sizeof(TEE_UUID));
		}

	default:
		break;
	}
	return TEE_ERROR_NOT_IMPLEMENTED;
}
static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in,
			 size_t in_size)
{
	return tee_hash_createdigest(TEE_ALG_SHA256, in, in_size,
				     out, out_size);
}