]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / TlsAuthConfigLib / TlsAuthConfigLib.c
CommitLineData
9c7d0d49
LE
1/** @file\r
2\r
3 A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile\r
4 variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe\r
5 (which is a UEFI_DRIVER) consume them.\r
6\r
7 Copyright (C) 2013, 2015, 2018, Red Hat, Inc.\r
8 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
9\r
b26f0cf9 10 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9c7d0d49
LE
11\r
12**/\r
13\r
14#include <Uefi/UefiBaseType.h>\r
15#include <Uefi/UefiSpec.h>\r
16\r
ba9c8a8c 17#include <Guid/HttpTlsCipherList.h>\r
9c7d0d49
LE
18#include <Guid/TlsAuthentication.h>\r
19\r
20#include <Library/BaseLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/QemuFwCfgLib.h>\r
24#include <Library/UefiRuntimeServicesTableLib.h>\r
25\r
26/**\r
27 Read the list of trusted CA certificates from the fw_cfg file\r
28 "etc/edk2/https/cacerts", and store it to\r
29 gEfiTlsCaCertificateGuid:EFI_TLS_CA_CERTIFICATE_VARIABLE.\r
30\r
31 The contents are validated (for well-formedness) by NetworkPkg/HttpDxe.\r
32**/\r
33STATIC\r
34VOID\r
35SetCaCerts (\r
36 VOID\r
37 )\r
38{\r
ac0a286f
MK
39 EFI_STATUS Status;\r
40 FIRMWARE_CONFIG_ITEM HttpsCaCertsItem;\r
41 UINTN HttpsCaCertsSize;\r
42 VOID *HttpsCaCerts;\r
9c7d0d49 43\r
ac0a286f
MK
44 Status = QemuFwCfgFindFile (\r
45 "etc/edk2/https/cacerts",\r
46 &HttpsCaCertsItem,\r
47 &HttpsCaCertsSize\r
48 );\r
9c7d0d49 49 if (EFI_ERROR (Status)) {\r
ac0a286f
MK
50 DEBUG ((\r
51 DEBUG_VERBOSE,\r
52 "%a:%a: not touching CA cert list\n",\r
53 gEfiCallerBaseName,\r
54 __FUNCTION__\r
55 ));\r
9c7d0d49
LE
56 return;\r
57 }\r
58\r
59 //\r
60 // Delete the current EFI_TLS_CA_CERTIFICATE_VARIABLE if it exists. This\r
61 // serves two purposes:\r
62 //\r
63 // (a) If the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we\r
64 // cannot make it volatile without deleting it first.\r
65 //\r
66 // (b) If we fail to recreate the variable later, deleting the current one is\r
67 // still justified if the fw_cfg file exists. Emptying the set of trusted\r
68 // CA certificates will fail HTTPS boot, which is better than trusting\r
69 // any certificate that's possibly missing from the fw_cfg file.\r
70 //\r
71 Status = gRT->SetVariable (\r
72 EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName\r
73 &gEfiTlsCaCertificateGuid, // VendorGuid\r
74 0, // Attributes\r
75 0, // DataSize\r
76 NULL // Data\r
77 );\r
78 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
79 //\r
80 // This is fatal.\r
81 //\r
ac0a286f
MK
82 DEBUG ((\r
83 DEBUG_ERROR,\r
84 "%a:%a: failed to delete %g:\"%s\"\n",\r
85 gEfiCallerBaseName,\r
86 __FUNCTION__,\r
87 &gEfiTlsCaCertificateGuid,\r
88 EFI_TLS_CA_CERTIFICATE_VARIABLE\r
89 ));\r
9c7d0d49
LE
90 ASSERT_EFI_ERROR (Status);\r
91 CpuDeadLoop ();\r
92 }\r
93\r
94 if (HttpsCaCertsSize == 0) {\r
ac0a286f
MK
95 DEBUG ((\r
96 DEBUG_VERBOSE,\r
97 "%a:%a: applied empty CA cert list\n",\r
98 gEfiCallerBaseName,\r
99 __FUNCTION__\r
100 ));\r
9c7d0d49
LE
101 return;\r
102 }\r
103\r
104 HttpsCaCerts = AllocatePool (HttpsCaCertsSize);\r
105 if (HttpsCaCerts == NULL) {\r
ac0a286f
MK
106 DEBUG ((\r
107 DEBUG_ERROR,\r
108 "%a:%a: failed to allocate HttpsCaCerts\n",\r
109 gEfiCallerBaseName,\r
110 __FUNCTION__\r
111 ));\r
9c7d0d49
LE
112 return;\r
113 }\r
114\r
115 QemuFwCfgSelectItem (HttpsCaCertsItem);\r
116 QemuFwCfgReadBytes (HttpsCaCertsSize, HttpsCaCerts);\r
117\r
118 Status = gRT->SetVariable (\r
119 EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName\r
120 &gEfiTlsCaCertificateGuid, // VendorGuid\r
121 EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes\r
122 HttpsCaCertsSize, // DataSize\r
123 HttpsCaCerts // Data\r
124 );\r
125 if (EFI_ERROR (Status)) {\r
ac0a286f
MK
126 DEBUG ((\r
127 DEBUG_ERROR,\r
128 "%a:%a: failed to set %g:\"%s\": %r\n",\r
129 gEfiCallerBaseName,\r
130 __FUNCTION__,\r
131 &gEfiTlsCaCertificateGuid,\r
132 EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
133 Status\r
134 ));\r
9c7d0d49
LE
135 goto FreeHttpsCaCerts;\r
136 }\r
137\r
ac0a286f
MK
138 DEBUG ((\r
139 DEBUG_VERBOSE,\r
140 "%a:%a: stored CA cert list (%Lu byte(s))\n",\r
141 gEfiCallerBaseName,\r
142 __FUNCTION__,\r
143 (UINT64)HttpsCaCertsSize\r
144 ));\r
9c7d0d49
LE
145\r
146FreeHttpsCaCerts:\r
147 FreePool (HttpsCaCerts);\r
148}\r
149\r
ba9c8a8c
LE
150/**\r
151 Read the list of trusted cipher suites from the fw_cfg file\r
152 "etc/edk2/https/ciphers", and store it to\r
153 gEdkiiHttpTlsCipherListGuid:EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE.\r
154\r
155 The contents are propagated by NetworkPkg/HttpDxe to NetworkPkg/TlsDxe; the\r
156 list is processed by the latter.\r
157**/\r
158STATIC\r
159VOID\r
160SetCipherSuites (\r
161 VOID\r
162 )\r
163{\r
ac0a286f
MK
164 EFI_STATUS Status;\r
165 FIRMWARE_CONFIG_ITEM HttpsCiphersItem;\r
166 UINTN HttpsCiphersSize;\r
167 VOID *HttpsCiphers;\r
ba9c8a8c 168\r
ac0a286f
MK
169 Status = QemuFwCfgFindFile (\r
170 "etc/edk2/https/ciphers",\r
171 &HttpsCiphersItem,\r
172 &HttpsCiphersSize\r
173 );\r
ba9c8a8c 174 if (EFI_ERROR (Status)) {\r
ac0a286f
MK
175 DEBUG ((\r
176 DEBUG_VERBOSE,\r
177 "%a:%a: not touching cipher suites\n",\r
178 gEfiCallerBaseName,\r
179 __FUNCTION__\r
180 ));\r
ba9c8a8c
LE
181 return;\r
182 }\r
ac0a286f 183\r
ba9c8a8c
LE
184 //\r
185 // From this point on, any failure is fatal. An ordered cipher preference\r
186 // list is available from QEMU, thus we cannot let the firmware attempt HTTPS\r
187 // boot with either pre-existent or non-existent preferences. An empty set of\r
188 // cipher suites does not fail HTTPS boot automatically; the default cipher\r
189 // suite preferences would take effect, and we must prevent that.\r
190 //\r
191 // Delete the current EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE if it exists. If\r
192 // the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we cannot\r
193 // make it volatile without deleting it first.\r
194 //\r
195 Status = gRT->SetVariable (\r
196 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName\r
197 &gEdkiiHttpTlsCipherListGuid, // VendorGuid\r
198 0, // Attributes\r
199 0, // DataSize\r
200 NULL // Data\r
201 );\r
202 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
ac0a286f
MK
203 DEBUG ((\r
204 DEBUG_ERROR,\r
205 "%a:%a: failed to delete %g:\"%s\"\n",\r
206 gEfiCallerBaseName,\r
207 __FUNCTION__,\r
208 &gEdkiiHttpTlsCipherListGuid,\r
209 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE\r
210 ));\r
ba9c8a8c
LE
211 goto Done;\r
212 }\r
213\r
214 if (HttpsCiphersSize == 0) {\r
ac0a286f
MK
215 DEBUG ((\r
216 DEBUG_ERROR,\r
217 "%a:%a: list of cipher suites must not be empty\n",\r
218 gEfiCallerBaseName,\r
219 __FUNCTION__\r
220 ));\r
ba9c8a8c
LE
221 Status = EFI_INVALID_PARAMETER;\r
222 goto Done;\r
223 }\r
224\r
225 HttpsCiphers = AllocatePool (HttpsCiphersSize);\r
226 if (HttpsCiphers == NULL) {\r
ac0a286f
MK
227 DEBUG ((\r
228 DEBUG_ERROR,\r
229 "%a:%a: failed to allocate HttpsCiphers\n",\r
230 gEfiCallerBaseName,\r
231 __FUNCTION__\r
232 ));\r
ba9c8a8c
LE
233 Status = EFI_OUT_OF_RESOURCES;\r
234 goto Done;\r
235 }\r
236\r
237 QemuFwCfgSelectItem (HttpsCiphersItem);\r
238 QemuFwCfgReadBytes (HttpsCiphersSize, HttpsCiphers);\r
239\r
240 Status = gRT->SetVariable (\r
241 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName\r
242 &gEdkiiHttpTlsCipherListGuid, // VendorGuid\r
243 EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes\r
244 HttpsCiphersSize, // DataSize\r
245 HttpsCiphers // Data\r
246 );\r
247 if (EFI_ERROR (Status)) {\r
ac0a286f
MK
248 DEBUG ((\r
249 DEBUG_ERROR,\r
250 "%a:%a: failed to set %g:\"%s\"\n",\r
251 gEfiCallerBaseName,\r
252 __FUNCTION__,\r
253 &gEdkiiHttpTlsCipherListGuid,\r
254 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE\r
255 ));\r
ba9c8a8c
LE
256 goto FreeHttpsCiphers;\r
257 }\r
258\r
ac0a286f
MK
259 DEBUG ((\r
260 DEBUG_VERBOSE,\r
261 "%a:%a: stored list of cipher suites (%Lu byte(s))\n",\r
262 gEfiCallerBaseName,\r
263 __FUNCTION__,\r
264 (UINT64)HttpsCiphersSize\r
265 ));\r
ba9c8a8c
LE
266\r
267FreeHttpsCiphers:\r
268 FreePool (HttpsCiphers);\r
269\r
270Done:\r
271 if (EFI_ERROR (Status)) {\r
272 ASSERT_EFI_ERROR (Status);\r
273 CpuDeadLoop ();\r
274 }\r
275}\r
276\r
9c7d0d49
LE
277RETURN_STATUS\r
278EFIAPI\r
279TlsAuthConfigInit (\r
280 VOID\r
281 )\r
282{\r
283 SetCaCerts ();\r
ba9c8a8c 284 SetCipherSuites ();\r
9c7d0d49
LE
285\r
286 return RETURN_SUCCESS;\r
287}\r