efi_rng.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2019, Linaro Limited
  4. */
  5. #define LOG_CATEGORY LOGC_EFI
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <efi_loader.h>
  9. #include <efi_rng.h>
  10. #include <log.h>
  11. #include <rng.h>
  12. #include <asm/global_data.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID;
  15. /**
  16. * platform_get_rng_device() - retrieve random number generator
  17. *
  18. * This function retrieves the udevice implementing a hardware random
  19. * number generator.
  20. *
  21. * This function may be overridden if special initialization is needed.
  22. *
  23. * @dev: udevice
  24. * Return: status code
  25. */
  26. __weak efi_status_t platform_get_rng_device(struct udevice **dev)
  27. {
  28. int ret;
  29. struct udevice *devp;
  30. ret = uclass_get_device(UCLASS_RNG, 0, &devp);
  31. if (ret) {
  32. debug("Unable to get rng device\n");
  33. return EFI_DEVICE_ERROR;
  34. }
  35. *dev = devp;
  36. return EFI_SUCCESS;
  37. }
  38. /**
  39. * rng_getinfo() - get information about random number generation
  40. *
  41. * This function implement the GetInfo() service of the EFI random number
  42. * generator protocol. See the UEFI spec for details.
  43. *
  44. * @this: random number generator protocol instance
  45. * @rng_algorithm_list_size: number of random number generation algorithms
  46. * @rng_algorithm_list: descriptions of random number generation
  47. * algorithms
  48. * Return: status code
  49. */
  50. static efi_status_t EFIAPI rng_getinfo(struct efi_rng_protocol *this,
  51. efi_uintn_t *rng_algorithm_list_size,
  52. efi_guid_t *rng_algorithm_list)
  53. {
  54. efi_status_t ret = EFI_SUCCESS;
  55. efi_guid_t rng_algo_guid = EFI_RNG_ALGORITHM_RAW;
  56. EFI_ENTRY("%p, %p, %p", this, rng_algorithm_list_size,
  57. rng_algorithm_list);
  58. if (!this || !rng_algorithm_list_size) {
  59. ret = EFI_INVALID_PARAMETER;
  60. goto back;
  61. }
  62. if (!rng_algorithm_list ||
  63. *rng_algorithm_list_size < sizeof(*rng_algorithm_list)) {
  64. *rng_algorithm_list_size = sizeof(*rng_algorithm_list);
  65. ret = EFI_BUFFER_TOO_SMALL;
  66. goto back;
  67. }
  68. /*
  69. * For now, use EFI_RNG_ALGORITHM_RAW as the default
  70. * algorithm. If a new algorithm gets added in the
  71. * future through a Kconfig, rng_algo_guid will be set
  72. * based on that Kconfig option
  73. */
  74. *rng_algorithm_list_size = sizeof(*rng_algorithm_list);
  75. guidcpy(rng_algorithm_list, &rng_algo_guid);
  76. back:
  77. return EFI_EXIT(ret);
  78. }
  79. /**
  80. * rng_getrng() - get random value
  81. *
  82. * This function implement the GetRng() service of the EFI random number
  83. * generator protocol. See the UEFI spec for details.
  84. *
  85. * @this: random number generator protocol instance
  86. * @rng_algorithm: random number generation algorithm
  87. * @rng_value_length: number of random bytes to generate, buffer length
  88. * @rng_value: buffer to receive random bytes
  89. * Return: status code
  90. */
  91. static efi_status_t EFIAPI getrng(struct efi_rng_protocol *this,
  92. efi_guid_t *rng_algorithm,
  93. efi_uintn_t rng_value_length,
  94. uint8_t *rng_value)
  95. {
  96. int ret;
  97. efi_status_t status = EFI_SUCCESS;
  98. struct udevice *dev;
  99. const efi_guid_t rng_raw_guid = EFI_RNG_ALGORITHM_RAW;
  100. EFI_ENTRY("%p, %p, %zu, %p", this, rng_algorithm, rng_value_length,
  101. rng_value);
  102. if (!this || !rng_value || !rng_value_length) {
  103. status = EFI_INVALID_PARAMETER;
  104. goto back;
  105. }
  106. if (rng_algorithm) {
  107. EFI_PRINT("RNG algorithm %pUs\n", rng_algorithm);
  108. if (guidcmp(rng_algorithm, &rng_raw_guid)) {
  109. status = EFI_UNSUPPORTED;
  110. goto back;
  111. }
  112. }
  113. ret = platform_get_rng_device(&dev);
  114. if (ret != EFI_SUCCESS) {
  115. EFI_PRINT("Rng device not found\n");
  116. status = EFI_UNSUPPORTED;
  117. goto back;
  118. }
  119. ret = dm_rng_read(dev, rng_value, rng_value_length);
  120. if (ret < 0) {
  121. EFI_PRINT("Rng device read failed\n");
  122. status = EFI_DEVICE_ERROR;
  123. goto back;
  124. }
  125. back:
  126. return EFI_EXIT(status);
  127. }
  128. static const struct efi_rng_protocol efi_rng_protocol = {
  129. .get_info = rng_getinfo,
  130. .get_rng = getrng,
  131. };
  132. /**
  133. * efi_rng_register() - register EFI_RNG_PROTOCOL
  134. *
  135. * If a RNG device is available, the Random Number Generator Protocol is
  136. * registered.
  137. *
  138. * Return: An error status is only returned if adding the protocol fails.
  139. */
  140. efi_status_t efi_rng_register(void)
  141. {
  142. efi_status_t ret;
  143. struct udevice *dev;
  144. ret = platform_get_rng_device(&dev);
  145. if (ret != EFI_SUCCESS) {
  146. log_warning("Missing RNG device for EFI_RNG_PROTOCOL\n");
  147. return EFI_SUCCESS;
  148. }
  149. ret = efi_add_protocol(efi_root, &efi_guid_rng_protocol,
  150. (void *)&efi_rng_protocol);
  151. if (ret != EFI_SUCCESS)
  152. log_err("Cannot install EFI_RNG_PROTOCOL\n");
  153. return ret;
  154. }