1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022, Vaisala Oyj 4 */ 5 6 #include <assert.h> 7 #include <io.h> 8 #include <kernel/boot.h> 9 #include <kernel/delay.h> 10 #include <kernel/dt.h> 11 #include <kernel/dt_driver.h> 12 #include <kernel/spinlock.h> 13 #include <libfdt.h> 14 #include <platform_config.h> 15 #include <rng_support.h> 16 #include <string.h> 17 #include <tee/tee_cryp_utl.h> 18 19 #define CONTROL_REG 0x00000000 20 #define STATUS_REG 0x00000004 21 #define RAND_REG 0x00000000 22 23 #define HOST_TO_TRNG_RESET 0x00000001 24 #define HOST_TO_TRNG_RELEASE_RESET 0x00000002 25 #define HOST_TO_TRNG_ENABLE 0x80000000 26 #define HOST_TO_TRNG_ZEROIZE 0x80000004 27 #define HOST_TO_TRNG_ACK_ZEROIZE 0x80000008 28 #define HOST_TO_TRNG_READ 0x8000000F 29 30 /* trng statuses */ 31 #define TRNG_ACK_RESET 0x000000AC 32 #define TRNG_SUCCESSFUL_STARTUP 0x00000057 33 #define TRNG_FAILED_STARTUP 0x000000FA 34 #define TRNG_NEW_RAND_AVAILABLE 0x000000ED 35 36 static unsigned int trng_lock = SPINLOCK_UNLOCK; 37 38 static vaddr_t xiphera_trng_base; 39 40 static uint32_t xiphera_trng_read32(void) 41 { 42 uint32_t value = 0; 43 uint32_t exceptions = 0; 44 uint32_t status = 0; 45 46 while (true) { 47 /* Wait until we have value available */ 48 status = io_read32(xiphera_trng_base + STATUS_REG); 49 if (status != TRNG_NEW_RAND_AVAILABLE) 50 continue; 51 52 value = io_read32(xiphera_trng_base + RAND_REG); 53 54 /* 55 * Ack that RNG value has been consumed and trigger new one to 56 * be generated 57 */ 58 io_write32(xiphera_trng_base + CONTROL_REG, HOST_TO_TRNG_READ); 59 io_write32(xiphera_trng_base + CONTROL_REG, 60 HOST_TO_TRNG_ENABLE); 61 62 break; 63 } 64 65 return value; 66 } 67 68 /* This is a true RNG, no need for seeding */ 69 void plat_rng_init(void) 70 { 71 } 72 73 TEE_Result hw_get_random_bytes(void *buf, size_t len) 74 { 75 static union { 76 uint32_t val; 77 uint8_t byte[4]; 78 } fifo; 79 static size_t fifo_pos; 80 uint8_t *buffer = buf; 81 size_t buffer_pos = 0; 82 83 assert(xiphera_trng_base); 84 85 while (buffer_pos < len) { 86 uint32_t exceptions = cpu_spin_lock_xsave(&trng_lock); 87 88 /* Refill our FIFO */ 89 if (fifo_pos == 0) 90 fifo.val = xiphera_trng_read32(); 91 92 buffer[buffer_pos++] = fifo.byte[fifo_pos++]; 93 fifo_pos %= 4; 94 95 cpu_spin_unlock_xrestore(&trng_lock, exceptions); 96 } 97 98 return TEE_SUCCESS; 99 } 100 101 static TEE_Result xiphera_trng_probe(const void *fdt, int node, 102 const void *compat_data __unused) 103 { 104 int dt_status = _fdt_get_status(fdt, node); 105 uint32_t status = 0; 106 size_t size = 0; 107 108 /* Skip non-secure instances */ 109 if (dt_status != DT_STATUS_OK_SEC) 110 return TEE_ERROR_NODE_DISABLED; 111 112 if (xiphera_trng_base) { 113 EMSG("Only one secure instance is supported"); 114 return TEE_ERROR_GENERIC; 115 } 116 117 if (dt_map_dev(fdt, node, &xiphera_trng_base, &size) < 0) 118 return TEE_ERROR_GENERIC; 119 120 /* 121 * The TRNG needs to be first reset in order to provide stable 122 * operation. 123 * 124 * Reset of the chip should complete within 200 us but in some cases it 125 * could take up to 400 us. If it is not ready within 400 us assume 126 * there is problem. 127 */ 128 io_write32(xiphera_trng_base + CONTROL_REG, HOST_TO_TRNG_RESET); 129 udelay(200); 130 131 status = io_read32(xiphera_trng_base + STATUS_REG); 132 if (status != TRNG_ACK_RESET) { 133 /* 134 * Give it additional 200 us to allow it to reset. 135 * 136 * If still not done -> error out. 137 */ 138 udelay(200); 139 status = io_read32(xiphera_trng_base + STATUS_REG); 140 if (status != TRNG_ACK_RESET) { 141 EMSG("Failed to reset TRNG\n"); 142 return TEE_ERROR_GENERIC; 143 } 144 } 145 146 /* 147 * Now TRNG should be internally stable. 148 * 149 * Clear internal random number generation engine to start in stable 150 * state and give it 20 ms to enable good random number entropy and 151 * then check that random number engine is ready. 152 */ 153 io_write32(xiphera_trng_base + CONTROL_REG, 154 HOST_TO_TRNG_RELEASE_RESET); 155 io_write32(xiphera_trng_base + CONTROL_REG, HOST_TO_TRNG_ENABLE); 156 io_write32(xiphera_trng_base + CONTROL_REG, HOST_TO_TRNG_ZEROIZE); 157 mdelay(20); 158 159 status = io_read32(xiphera_trng_base + STATUS_REG); 160 if (status != TRNG_SUCCESSFUL_STARTUP) { 161 /* 162 * Check specifically if there were startup test errors to aid 163 * in debugging TRNG implementation in FPGA 164 */ 165 if (status == TRNG_FAILED_STARTUP) { 166 EMSG("Startup tests have failed\n"); 167 return TEE_ERROR_GENERIC; 168 } 169 170 EMSG("Startup tests yielded no response -> TRNG stuck\n"); 171 return TEE_ERROR_GENERIC; 172 } 173 174 io_write32(xiphera_trng_base + CONTROL_REG, HOST_TO_TRNG_ACK_ZEROIZE); 175 176 DMSG("TRNG initialized\n"); 177 178 return TEE_SUCCESS; 179 } 180 181 static const struct dt_device_match xiphera_trng_match_table[] = { 182 { .compatible = "xiphera,xip8001b-trng" }, 183 { } 184 }; 185 186 DEFINE_DT_DRIVER(xiphera_trng_dt_driver) = { 187 .name = "xiphera_trng", 188 .type = DT_DRIVER_NOTYPE, 189 .match_table = xiphera_trng_match_table, 190 .probe = xiphera_trng_probe, 191 }; 192