xref: /optee_os/core/drivers/riscv_zkr_rng.c (revision 25675979615c01f3c6bfbe105f53e07e939dd739)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2024 Andes Technology Corporation
4  */
5 
6 #include <crypto/crypto.h>
7 #include <kernel/panic.h>
8 #include <riscv.h>
9 #include <rng_support.h>
10 #include <tee/tee_cryp_utl.h>
11 
12 #define OPST_BIST 0b00
13 #define OPST_WAIT 0b01
14 #define OPST_ES16 0b10
15 #define OPST_DEAD 0b11
16 
17 TEE_Result hw_get_random_bytes(void *buf, size_t len)
18 {
19 	uint8_t *ptr = buf;
20 	uint32_t val = 0;
21 
22 	while (len > 0) {
23 		/*
24 		 * The seed register must be accessed using CSR read-write
25 		 * instructions. The write operation is ignored and serves
26 		 * to indicate polling and flushing.
27 		 */
28 		val = swap_csr(CSR_SEED, val);
29 
30 		switch (val >> 30) {
31 		case OPST_BIST:
32 		case OPST_WAIT:
33 			continue;
34 		case OPST_ES16:
35 			*ptr++ = val & 0xff;
36 			len--;
37 			if (len > 0) {
38 				*ptr++ = val >> 8;
39 				len--;
40 			}
41 			break;
42 		case OPST_DEAD:
43 			/* Unrecoverable self-test error */
44 			return TEE_ERROR_BAD_STATE;
45 		default:
46 			break; /* can't happen */
47 		}
48 	}
49 
50 	return TEE_SUCCESS;
51 }
52 
53 void plat_rng_init(void)
54 {
55 	if (!riscv_detect_csr_seed())
56 		panic("RISC-V Zkr is not supported or unavailable in S-mode");
57 }
58