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 <assert.h>
11 #include <config.h>
12 #include <crypto/crypto.h>
13 #include <kernel/pseudo_ta.h>
14 #include <pta_rng.h>
15 #include <rng_support.h>
16 
17 #define PTA_NAME "rng.pta"
18 
19 /* This PTA only works with hardware random number generators */
20 static_assert(!IS_ENABLED(CFG_WITH_SOFTWARE_PRNG));
21 
rng_get_entropy(uint32_t types,TEE_Param params[TEE_NUM_PARAMS])22 static TEE_Result rng_get_entropy(uint32_t types,
23 				  TEE_Param params[TEE_NUM_PARAMS])
24 {
25 	uint8_t *e = NULL;
26 
27 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
28 				     TEE_PARAM_TYPE_NONE,
29 				     TEE_PARAM_TYPE_NONE,
30 				     TEE_PARAM_TYPE_NONE)) {
31 		DMSG("bad parameters types: 0x%" PRIx32, types);
32 		return TEE_ERROR_BAD_PARAMETERS;
33 	}
34 
35 	e = (uint8_t *)params[0].memref.buffer;
36 	if (!e)
37 		return TEE_ERROR_BAD_PARAMETERS;
38 
39 	return crypto_rng_read(e, params[0].memref.size);
40 }
41 
rng_get_info(uint32_t types,TEE_Param params[TEE_NUM_PARAMS])42 static TEE_Result rng_get_info(uint32_t types,
43 			       TEE_Param params[TEE_NUM_PARAMS])
44 {
45 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
46 				     TEE_PARAM_TYPE_NONE,
47 				     TEE_PARAM_TYPE_NONE,
48 				     TEE_PARAM_TYPE_NONE)) {
49 		DMSG("bad parameters types: 0x%" PRIx32, types);
50 		return TEE_ERROR_BAD_PARAMETERS;
51 	}
52 
53 	params[0].value.a = CFG_HWRNG_RATE;
54 	params[0].value.b = CFG_HWRNG_QUALITY;
55 
56 	return TEE_SUCCESS;
57 }
58 
invoke_command(void * session __unused,uint32_t cmd,uint32_t ptypes,TEE_Param params[TEE_NUM_PARAMS])59 static TEE_Result invoke_command(void *session __unused,
60 				 uint32_t cmd, uint32_t ptypes,
61 				 TEE_Param params[TEE_NUM_PARAMS])
62 {
63 	FMSG(PTA_NAME" command %#"PRIx32" ptypes %#"PRIx32, cmd, ptypes);
64 
65 	switch (cmd) {
66 	case PTA_CMD_GET_ENTROPY:
67 		return rng_get_entropy(ptypes, params);
68 	case PTA_CMD_GET_RNG_INFO:
69 		return rng_get_info(ptypes, params);
70 	default:
71 		break;
72 	}
73 
74 	return TEE_ERROR_NOT_IMPLEMENTED;
75 }
76 
77 pseudo_ta_register(.uuid = PTA_RNG_UUID, .name = PTA_NAME,
78 		   .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT |
79 			    TA_FLAG_DEVICE_ENUM,
80 		   .invoke_command_entry_point = invoke_command);
81