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