efi_rng.c 4.3 KB

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