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