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