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