xref: /optee_os/core/include/drivers/versal_trng.h (revision abca35a69f9bea0496cf05e025c3c36e6d5ea68b)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (C) 2022 Xilinx, Inc.  All rights reserved.
4  * Copyright (C) 2022 Foundries Ltd.
5  * Copyright (C) 2023 ProvenRun S.A.S
6  */
7 
8 #ifndef __DRIVERS_VERSAL_TRNG_H
9 #define __DRIVERS_VERSAL_TRNG_H
10 
11 #include <stdint.h>
12 
13 /*
14  * IMPORTANT: The CFG_VERSAL_RNG_{IO,V1,V2,PLM} symbols are to be treated as
15  *            symbols internal to this TRNG driver and shall not be set via a
16  *            platform's conf.mk or similar!
17  */
18 #if defined(CFG_VERSAL_RNG_IO) || defined(CFG_VERSAL_RNG_V1) || \
19 	defined(CFG_VERSAL_RNG_V2) || defined(CFG_VERSAL_RNG_PLM)
20 #error "One or more CFG_VERSAL_RNG_{IO,V1,V2,PLM} symbols are already defined. \
21 This shall NOT be done! Definition is done automatically based on platform!"
22 #endif
23 
24 #if !defined(PLATFORM_FLAVOR_net)
25 #define CFG_VERSAL_RNG_IO 1
26 #define CFG_VERSAL_RNG_V1 1
27 #else
28 #if defined(CFG_VERSAL_CRYPTO_DRIVER) && defined(CFG_VERSAL_PKI)
29 #define CFG_VERSAL_RNG_IO 1
30 #define CFG_VERSAL_RNG_V2 1
31 #endif
32 #define CFG_VERSAL_RNG_PLM 1
33 #endif
34 
35 #ifdef CFG_VERSAL_RNG_IO
36 /* TRNG configuration  */
37 #define TRNG_PERS_STR_REGS	12
38 #define TRNG_PERS_STR_LEN	48
39 #define TRNG_SEED_LEN		48
40 #define TRNG_V2_SEED_LEN	128
41 #define RAND_BUF_LEN		4
42 
43 /* Derivative function helper macros */
44 #define DF_IP_IV_LEN		4
45 #define DF_PAD_DATA_LEN		8
46 #define MAX_PRE_DF_LEN		160
47 #define MAX_PRE_DF_LEN_WORDS	40
48 
49 enum trng_version {
50 	TRNG_V1 = 1,
51 	TRNG_V2,
52 };
53 
54 enum trng_status {
55 	TRNG_UNINITIALIZED = 0,
56 	TRNG_HEALTHY,
57 	TRNG_ERROR,
58 	TRNG_CATASTROPHIC
59 };
60 
61 enum trng_mode {
62 	TRNG_HRNG = 0,
63 	TRNG_DRNG,
64 	TRNG_PTRNG
65 };
66 
67 struct trng_cfg {
68 	paddr_t base;
69 	vaddr_t addr;
70 	size_t len;
71 	enum trng_version version;
72 };
73 
74 struct trng_usr_cfg {
75 	enum trng_mode mode;
76 	uint64_t seed_life;      /* number of TRNG requests per seed */
77 	bool predict_en;         /* enable prediction resistance     */
78 	bool pstr_en;            /* enable personalization string    */
79 	uint32_t pstr[TRNG_PERS_STR_REGS];
80 	bool iseed_en;           /* enable an initial seed           */
81 	uint32_t init_seed[MAX_PRE_DF_LEN_WORDS];
82 	uint32_t df_disable;     /* disable the derivative function  */
83 	uint32_t dfmul;          /* derivative function multiplier   */
84 };
85 
86 struct trng_stats {
87 	uint64_t bytes;
88 	uint64_t bytes_reseed;
89 	uint64_t elapsed_seed_life;
90 };
91 
92 /* block cipher derivative function algorithm */
93 struct trng_dfin {
94 	uint32_t ivc[DF_IP_IV_LEN];
95 	uint32_t val1;
96 	uint32_t val2;
97 	uint8_t entropy[MAX_PRE_DF_LEN];    /* input entropy                */
98 	uint8_t pstr[TRNG_PERS_STR_LEN];      /* personalization string       */
99 	uint8_t pad_data[DF_PAD_DATA_LEN];  /* pad to multiples of 16 bytes*/
100 };
101 
102 struct versal_trng {
103 	struct trng_cfg cfg;
104 	struct trng_usr_cfg usr_cfg;
105 	struct trng_stats stats;
106 	enum trng_status status;
107 	uint32_t buf[RAND_BUF_LEN];   /* buffer of random bits      */
108 	size_t len;
109 	struct trng_dfin dfin;
110 	uint8_t dfout[TRNG_SEED_LEN]; /* output of the DF operation */
111 };
112 
113 extern const uint8_t trng_pers_str[TRNG_PERS_STR_LEN];
114 
115 TEE_Result versal_trng_hw_init(struct versal_trng *trng,
116 			       struct trng_usr_cfg *usr_cfg);
117 TEE_Result versal_trng_get_random_bytes(struct versal_trng *trng,
118 					void *buf, size_t len);
119 #endif
120 
121 #endif
122