bootloader_random.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "sdkconfig.h"
  7. #include "bootloader_random.h"
  8. #include "hal/cpu_hal.h"
  9. #include "soc/wdev_reg.h"
  10. #ifndef BOOTLOADER_BUILD
  11. #include "esp_system.h"
  12. #include "esp_private/periph_ctrl.h"
  13. __attribute__((weak)) void bootloader_fill_random(void *buffer, size_t length)
  14. {
  15. return esp_fill_random(buffer, length);
  16. }
  17. #else
  18. #if !defined CONFIG_IDF_TARGET_ESP32S3
  19. #define RNG_CPU_WAIT_CYCLE_NUM (80 * 32 * 2) /* extra factor of 2 is precautionary */
  20. #else
  21. #define RNG_CPU_WAIT_CYCLE_NUM (80 * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */
  22. #endif
  23. __attribute__((weak)) void bootloader_fill_random(void *buffer, size_t length)
  24. {
  25. uint8_t *buffer_bytes = (uint8_t *)buffer;
  26. uint32_t random;
  27. uint32_t start, now;
  28. assert(buffer != NULL);
  29. for (size_t i = 0; i < length; i++) {
  30. if (i == 0 || i % 4 == 0) { /* redundant check is for a compiler warning */
  31. /* in bootloader with ADC feeding HWRNG, we accumulate 1
  32. bit of entropy per 40 APB cycles (==80 CPU cycles.)
  33. To avoid reading the entire RNG hardware state out
  34. as-is, we repeatedly read the RNG register and XOR all
  35. values.
  36. */
  37. random = REG_READ(WDEV_RND_REG);
  38. start = cpu_hal_get_cycle_count();
  39. do {
  40. random ^= REG_READ(WDEV_RND_REG);
  41. now = cpu_hal_get_cycle_count();
  42. } while (now - start < RNG_CPU_WAIT_CYCLE_NUM);
  43. }
  44. buffer_bytes[i] = random >> ((i % 4) * 8);
  45. }
  46. }
  47. #ifndef CONFIG_IDF_ENV_FPGA
  48. #else // CONFIG_IDF_ENV_FPGA
  49. #include "esp_log.h"
  50. static void s_non_functional(const char *func)
  51. {
  52. ESP_EARLY_LOGW("rand", "%s non-functional for FPGA builds", func);
  53. }
  54. void bootloader_random_enable()
  55. {
  56. s_non_functional(__func__);
  57. }
  58. void bootloader_random_disable()
  59. {
  60. s_non_functional(__func__);
  61. }
  62. #endif // CONFIG_IDF_ENV_FPGA
  63. #endif // BOOTLOADER_BUILD