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