1fb605d4bSYu Chien Peter Lin // SPDX-License-Identifier: BSD-2-Clause 2fb605d4bSYu Chien Peter Lin /* 3fb605d4bSYu Chien Peter Lin * Copyright (c) 2024 Andes Technology Corporation 4fb605d4bSYu Chien Peter Lin */ 5fb605d4bSYu Chien Peter Lin 6fb605d4bSYu Chien Peter Lin #include <crypto/crypto.h> 7*47fd7209SYu Chien Peter Lin #include <encoding.h> 8*47fd7209SYu Chien Peter Lin #include <kernel/delay.h> 9fb605d4bSYu Chien Peter Lin #include <kernel/panic.h> 10fb605d4bSYu Chien Peter Lin #include <riscv.h> 11fb605d4bSYu Chien Peter Lin #include <rng_support.h> 12fb605d4bSYu Chien Peter Lin #include <tee/tee_cryp_utl.h> 13fb605d4bSYu Chien Peter Lin 14*47fd7209SYu Chien Peter Lin #define RNG_TIMEOUT_US 1000000 15*47fd7209SYu Chien Peter Lin seed_get_random_u16(uint16_t * val)16*47fd7209SYu Chien Peter Linstatic bool __must_check seed_get_random_u16(uint16_t *val) 17*47fd7209SYu Chien Peter Lin { 18*47fd7209SYu Chien Peter Lin uint64_t timeout = timeout_init_us(RNG_TIMEOUT_US); 19*47fd7209SYu Chien Peter Lin uint32_t seed = 0; 20*47fd7209SYu Chien Peter Lin uint32_t opst = 0; 21*47fd7209SYu Chien Peter Lin 22*47fd7209SYu Chien Peter Lin do { 23*47fd7209SYu Chien Peter Lin /* 24*47fd7209SYu Chien Peter Lin * The seed register must be accessed using CSR 25*47fd7209SYu Chien Peter Lin * read-write instructions. The write operation 26*47fd7209SYu Chien Peter Lin * is ignored and serves to indicate polling and 27*47fd7209SYu Chien Peter Lin * flushing. 28*47fd7209SYu Chien Peter Lin */ 29*47fd7209SYu Chien Peter Lin seed = swap_csr(CSR_SEED, 0); 30*47fd7209SYu Chien Peter Lin opst = seed & SEED_OPST; 31*47fd7209SYu Chien Peter Lin 32*47fd7209SYu Chien Peter Lin switch (opst) { 33*47fd7209SYu Chien Peter Lin case SEED_OPST_ES16: 34*47fd7209SYu Chien Peter Lin *val = seed & SEED_ENTROPY; 35*47fd7209SYu Chien Peter Lin return true; 36*47fd7209SYu Chien Peter Lin case SEED_OPST_DEAD: 37*47fd7209SYu Chien Peter Lin /* Unrecoverable self-test error */ 38*47fd7209SYu Chien Peter Lin return false; 39*47fd7209SYu Chien Peter Lin case SEED_OPST_BIST: 40*47fd7209SYu Chien Peter Lin case SEED_OPST_WAIT: 41*47fd7209SYu Chien Peter Lin default: 42*47fd7209SYu Chien Peter Lin riscv_cpu_pause(); 43*47fd7209SYu Chien Peter Lin } 44*47fd7209SYu Chien Peter Lin } while (!timeout_elapsed(timeout)); 45*47fd7209SYu Chien Peter Lin 46*47fd7209SYu Chien Peter Lin /* Consider timeout case due to normal world scheduler */ 47*47fd7209SYu Chien Peter Lin seed = swap_csr(CSR_SEED, 0); 48*47fd7209SYu Chien Peter Lin if ((seed & SEED_OPST) == SEED_OPST_ES16) { 49*47fd7209SYu Chien Peter Lin *val = seed & SEED_ENTROPY; 50*47fd7209SYu Chien Peter Lin return true; 51*47fd7209SYu Chien Peter Lin } 52*47fd7209SYu Chien Peter Lin 53*47fd7209SYu Chien Peter Lin EMSG("Failed to produce a sufficient amount of entropy"); 54*47fd7209SYu Chien Peter Lin 55*47fd7209SYu Chien Peter Lin return false; 56*47fd7209SYu Chien Peter Lin } 57fb605d4bSYu Chien Peter Lin hw_get_random_bytes(void * buf,size_t len)58fb605d4bSYu Chien Peter LinTEE_Result hw_get_random_bytes(void *buf, size_t len) 59fb605d4bSYu Chien Peter Lin { 60fb605d4bSYu Chien Peter Lin uint8_t *ptr = buf; 61*47fd7209SYu Chien Peter Lin uint16_t seed = 0; 62fb605d4bSYu Chien Peter Lin 63fb605d4bSYu Chien Peter Lin while (len > 0) { 64*47fd7209SYu Chien Peter Lin if (!seed_get_random_u16(&seed)) 65*47fd7209SYu Chien Peter Lin return TEE_ERROR_ACCESS_DENIED; 66*47fd7209SYu Chien Peter Lin *ptr++ = seed & 0xff; 67fb605d4bSYu Chien Peter Lin len--; 68fb605d4bSYu Chien Peter Lin if (len > 0) { 69*47fd7209SYu Chien Peter Lin *ptr++ = seed >> 8; 70fb605d4bSYu Chien Peter Lin len--; 71fb605d4bSYu Chien Peter Lin } 72fb605d4bSYu Chien Peter Lin } 73fb605d4bSYu Chien Peter Lin 74fb605d4bSYu Chien Peter Lin return TEE_SUCCESS; 75fb605d4bSYu Chien Peter Lin } 76fb605d4bSYu Chien Peter Lin plat_rng_init(void)77fb605d4bSYu Chien Peter Linvoid plat_rng_init(void) 78fb605d4bSYu Chien Peter Lin { 79fb605d4bSYu Chien Peter Lin if (!riscv_detect_csr_seed()) 80fb605d4bSYu Chien Peter Lin panic("RISC-V Zkr is not supported or unavailable in S-mode"); 81fb605d4bSYu Chien Peter Lin } 82