xref: /optee_os/core/pta/hwrng.c (revision e27e865a6695ed84783eea86d2d3820cf5af238c)
1f2dad489SSergiy Kibrik // SPDX-License-Identifier: BSD-2-Clause
2f2dad489SSergiy Kibrik /*
3f2dad489SSergiy Kibrik  * Copyright (C) 2018, Linaro Limited
4f2dad489SSergiy Kibrik  * Copyright (c) 2021, EPAM Systems. All rights reserved.
5f2dad489SSergiy Kibrik  *
6f2dad489SSergiy Kibrik  * Based on plat-synquacer/rng_pta.c
7f2dad489SSergiy Kibrik  *
8f2dad489SSergiy Kibrik  */
9f2dad489SSergiy Kibrik 
10f2dad489SSergiy Kibrik #include <kernel/pseudo_ta.h>
11*e27e865aSEtienne Carriere #include <pta_rng.h>
12f2dad489SSergiy Kibrik #include <rng_support.h>
13f2dad489SSergiy Kibrik 
14f2dad489SSergiy Kibrik #define PTA_NAME "rng.pta"
15f2dad489SSergiy Kibrik 
16f2dad489SSergiy Kibrik static TEE_Result rng_get_entropy(uint32_t types,
17f2dad489SSergiy Kibrik 				  TEE_Param params[TEE_NUM_PARAMS])
18f2dad489SSergiy Kibrik {
19f2dad489SSergiy Kibrik 	uint8_t *e = NULL;
20f2dad489SSergiy Kibrik 	uint32_t i = 0;
21f2dad489SSergiy Kibrik 
22f2dad489SSergiy Kibrik 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
23f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE,
24f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE,
25f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE)) {
26f2dad489SSergiy Kibrik 		DMSG("bad parameters types: 0x%" PRIx32, types);
27f2dad489SSergiy Kibrik 		return TEE_ERROR_BAD_PARAMETERS;
28f2dad489SSergiy Kibrik 	}
29f2dad489SSergiy Kibrik 
30f2dad489SSergiy Kibrik 	e = (uint8_t *)params[0].memref.buffer;
31f2dad489SSergiy Kibrik 	if (!e)
32f2dad489SSergiy Kibrik 		return TEE_ERROR_BAD_PARAMETERS;
33f2dad489SSergiy Kibrik 
34f2dad489SSergiy Kibrik 	for (i = 0; i < params[0].memref.size; i++)
35f2dad489SSergiy Kibrik 		e[i] = hw_get_random_byte();
36f2dad489SSergiy Kibrik 
37f2dad489SSergiy Kibrik 	return TEE_SUCCESS;
38f2dad489SSergiy Kibrik }
39f2dad489SSergiy Kibrik 
40f2dad489SSergiy Kibrik static TEE_Result rng_get_info(uint32_t types,
41f2dad489SSergiy Kibrik 			       TEE_Param params[TEE_NUM_PARAMS])
42f2dad489SSergiy Kibrik {
43f2dad489SSergiy Kibrik 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
44f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE,
45f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE,
46f2dad489SSergiy Kibrik 				     TEE_PARAM_TYPE_NONE)) {
47f2dad489SSergiy Kibrik 		DMSG("bad parameters types: 0x%" PRIx32, types);
48f2dad489SSergiy Kibrik 		return TEE_ERROR_BAD_PARAMETERS;
49f2dad489SSergiy Kibrik 	}
50f2dad489SSergiy Kibrik 
51f2dad489SSergiy Kibrik 	params[0].value.a = CFG_HWRNG_RATE;
52f2dad489SSergiy Kibrik 	params[0].value.b = CFG_HWRNG_QUALITY;
53f2dad489SSergiy Kibrik 
54f2dad489SSergiy Kibrik 	return TEE_SUCCESS;
55f2dad489SSergiy Kibrik }
56f2dad489SSergiy Kibrik 
57f2dad489SSergiy Kibrik static TEE_Result invoke_command(void *session __unused,
58f2dad489SSergiy Kibrik 				 uint32_t cmd, uint32_t ptypes,
59f2dad489SSergiy Kibrik 				 TEE_Param params[TEE_NUM_PARAMS])
60f2dad489SSergiy Kibrik {
61f2dad489SSergiy Kibrik 	FMSG(PTA_NAME" command %#"PRIx32" ptypes %#"PRIx32, cmd, ptypes);
62f2dad489SSergiy Kibrik 
63f2dad489SSergiy Kibrik 	switch (cmd) {
64f2dad489SSergiy Kibrik 	case PTA_CMD_GET_ENTROPY:
65f2dad489SSergiy Kibrik 		return rng_get_entropy(ptypes, params);
66f2dad489SSergiy Kibrik 	case PTA_CMD_GET_RNG_INFO:
67f2dad489SSergiy Kibrik 		return rng_get_info(ptypes, params);
68f2dad489SSergiy Kibrik 	default:
69f2dad489SSergiy Kibrik 		break;
70f2dad489SSergiy Kibrik 	}
71f2dad489SSergiy Kibrik 
72f2dad489SSergiy Kibrik 	return TEE_ERROR_NOT_IMPLEMENTED;
73f2dad489SSergiy Kibrik }
74f2dad489SSergiy Kibrik 
75f2dad489SSergiy Kibrik pseudo_ta_register(.uuid = PTA_RNG_UUID, .name = PTA_NAME,
76f2dad489SSergiy Kibrik 		   .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT |
77f2dad489SSergiy Kibrik 			    TA_FLAG_DEVICE_ENUM,
78f2dad489SSergiy Kibrik 		   .invoke_command_entry_point = invoke_command);
79