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