b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #include <common.h>
|
| 2 | #include <config.h>
|
| 3 | #include <ubi_uboot.h>
|
| 4 | #include <asm/arch/cpu.h>
|
| 5 | #include <kgdb.h>
|
| 6 | #include <asm/processor.h>
|
| 7 | #include <asm/io.h>
|
| 8 | #include <malloc.h>
|
| 9 | #include "asr_geu.h"
|
| 10 | #include "asr_rng.h"
|
| 11 |
|
| 12 | static struct random_data random_data = {
|
| 13 | .random_base = GEU_BASE,
|
| 14 | .random_num_saved = 0
|
| 15 | };
|
| 16 |
|
| 17 | #define random_read(x) readl(random_data.random_base + x)
|
| 18 | #define random_write(x, y) writel(y, (random_data.random_base + x))
|
| 19 |
|
| 20 | static void geu_rng_enable(void)
|
| 21 | {
|
| 22 | uint32_t val;
|
| 23 | uint32_t seed = read_timer(); //TODO
|
| 24 |
|
| 25 | val = random_read(GEU_PRNG_CTRL_REG);
|
| 26 | if (!(val & GEU_PRNG_EN)) {
|
| 27 | val |= GEU_PRNG_EN;
|
| 28 | random_write(GEU_PRNG_CTRL_REG, val);
|
| 29 | udelay(1000); /* means a reset happens */
|
| 30 | }
|
| 31 | random_write(GEU_HW_RANDOM_NUM_SEED, seed & 0xFF);
|
| 32 | }
|
| 33 |
|
| 34 | static uint32_t geu_get_random_data(void)
|
| 35 | {
|
| 36 | uint32_t val = 0;
|
| 37 | uint32_t timeout = 100, mytime;
|
| 38 | int ret = 0;
|
| 39 |
|
| 40 | uint32_t start = get_timer(0);
|
| 41 |
|
| 42 | do {
|
| 43 | val = random_read(GEU_HW_RANDOM_NUM_GEN);
|
| 44 | mytime = get_timer(start);
|
| 45 |
|
| 46 | if (mytime >= timeout) {
|
| 47 | // porintf("fail to generate rng seed, time out!");
|
| 48 | panic("fail to generate rng seed, time out!\n");
|
| 49 | }
|
| 50 | }while(val ==0 || val == random_data.random_num_saved);
|
| 51 |
|
| 52 | exit:
|
| 53 | random_data.random_num_saved = val;
|
| 54 |
|
| 55 | return val;
|
| 56 | }
|
| 57 |
|
| 58 | uint32_t crypto_rng_read(void *buf, size_t len)
|
| 59 | {
|
| 60 | uint32_t *rngbuf = buf;
|
| 61 | uint32_t val = 0;
|
| 62 |
|
| 63 | assert(buf);
|
| 64 |
|
| 65 | asr_geu_get();
|
| 66 | geu_enable_clk();
|
| 67 | geu_rng_enable();
|
| 68 |
|
| 69 | while (len) {
|
| 70 | val = geu_get_random_data();
|
| 71 | if (len > sizeof(uint32_t)) {
|
| 72 | len = len - sizeof(uint32_t);
|
| 73 | memcpy(rngbuf, &val, sizeof(uint32_t));
|
| 74 | rngbuf++;
|
| 75 | } else {
|
| 76 | memcpy(rngbuf, &val, len);
|
| 77 | len = 0;
|
| 78 | }
|
| 79 | }
|
| 80 | geu_disable_clk();
|
| 81 | asr_geu_put();
|
| 82 |
|
| 83 | return 0;
|
| 84 | }
|
| 85 |
|
| 86 | uint8_t hw_get_random_byte(void)
|
| 87 | {
|
| 88 | uint8_t data = 0;
|
| 89 |
|
| 90 | if (crypto_rng_read(&data, 1))
|
| 91 | panic("rng read failed\n");
|
| 92 |
|
| 93 | return data;
|
| 94 | }
|
| 95 |
|
| 96 | uint32_t hw_get_random_32(void)
|
| 97 | {
|
| 98 | uint32_t data = 0;
|
| 99 |
|
| 100 | if (crypto_rng_read(&data, 4))
|
| 101 | panic("rng read failed\n");
|
| 102 |
|
| 103 | return data;
|
| 104 | }
|
| 105 |
|
| 106 | void geu_random_test(void)
|
| 107 | {
|
| 108 | uint8_t buf[32] = {0};
|
| 109 | uint32_t size = sizeof(buf);
|
| 110 |
|
| 111 | if (crypto_rng_read(buf, size)) {
|
| 112 | printf("geu rng test failed");
|
| 113 | return;
|
| 114 | }
|
| 115 |
|
| 116 | for (uint32_t i = 0; i < size; i++) {
|
| 117 | printf("%.2x ", buf[i]);
|
| 118 | if ((i + 1) == 0)
|
| 119 | printf("\n");
|
| 120 | }
|
| 121 | printf("\n");
|
| 122 | } |