]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TlsDxe/TlsDriver.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / TlsDxe / TlsDriver.c
CommitLineData
7618784b
HW
1/** @file\r
2 The Driver Binding and Service Binding Protocol for TlsDxe driver.\r
3\r
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5\r
ecf98fbc 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7618784b
HW
7\r
8**/\r
9\r
10#include "TlsImpl.h"\r
11\r
d1050b9d 12EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {\r
7618784b
HW
13 TlsServiceBindingCreateChild,\r
14 TlsServiceBindingDestroyChild\r
15};\r
16\r
17/**\r
18 Release all the resources used by the TLS instance.\r
19\r
20 @param[in] Instance The TLS instance data.\r
21\r
22**/\r
23VOID\r
24TlsCleanInstance (\r
d1050b9d 25 IN TLS_INSTANCE *Instance\r
7618784b
HW
26 )\r
27{\r
28 if (Instance != NULL) {\r
29 if (Instance->TlsConn != NULL) {\r
30 TlsFree (Instance->TlsConn);\r
31 }\r
32\r
33 FreePool (Instance);\r
34 }\r
35}\r
36\r
37/**\r
38 Create the TLS instance and initialize it.\r
39\r
40 @param[in] Service The pointer to the TLS service.\r
41 @param[out] Instance The pointer to the TLS instance.\r
42\r
43 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
44 @retval EFI_SUCCESS The TLS instance is created.\r
45\r
46**/\r
47EFI_STATUS\r
48TlsCreateInstance (\r
d1050b9d
MK
49 IN TLS_SERVICE *Service,\r
50 OUT TLS_INSTANCE **Instance\r
7618784b
HW
51 )\r
52{\r
d1050b9d 53 TLS_INSTANCE *TlsInstance;\r
7618784b
HW
54\r
55 *Instance = NULL;\r
56\r
57 TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));\r
58 if (TlsInstance == NULL) {\r
59 return EFI_OUT_OF_RESOURCES;\r
60 }\r
61\r
62 TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;\r
63 InitializeListHead (&TlsInstance->Link);\r
64 TlsInstance->InDestroy = FALSE;\r
65 TlsInstance->Service = Service;\r
66\r
67 CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));\r
68 CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));\r
69\r
70 TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;\r
71\r
72 *Instance = TlsInstance;\r
73\r
74 return EFI_SUCCESS;\r
75}\r
76\r
77/**\r
78 Release all the resources used by the TLS service binding instance.\r
79\r
80 @param[in] Service The TLS service data.\r
81\r
82**/\r
83VOID\r
84TlsCleanService (\r
d1050b9d 85 IN TLS_SERVICE *Service\r
7618784b
HW
86 )\r
87{\r
88 if (Service != NULL) {\r
89 if (Service->TlsCtx != NULL) {\r
90 TlsCtxFree (Service->TlsCtx);\r
91 }\r
92\r
93 FreePool (Service);\r
94 }\r
95}\r
96\r
97/**\r
98 Create then initialize a TLS service.\r
99\r
100 @param[in] Image ImageHandle of the TLS driver\r
101 @param[out] Service The service for TLS driver\r
102\r
103 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.\r
104 @retval EFI_SUCCESS The service is created for the driver.\r
105\r
106**/\r
107EFI_STATUS\r
108TlsCreateService (\r
d1050b9d
MK
109 IN EFI_HANDLE Image,\r
110 OUT TLS_SERVICE **Service\r
7618784b
HW
111 )\r
112{\r
d1050b9d 113 TLS_SERVICE *TlsService;\r
7618784b
HW
114\r
115 ASSERT (Service != NULL);\r
116\r
117 *Service = NULL;\r
118\r
119 //\r
120 // Allocate a TLS Service Data\r
121 //\r
122 TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));\r
123 if (TlsService == NULL) {\r
124 return EFI_OUT_OF_RESOURCES;\r
125 }\r
126\r
127 //\r
128 // Initialize TLS Service Data\r
129 //\r
d1050b9d 130 TlsService->Signature = TLS_SERVICE_SIGNATURE;\r
7618784b 131 CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));\r
d1050b9d 132 TlsService->TlsChildrenNum = 0;\r
7618784b 133 InitializeListHead (&TlsService->TlsChildrenList);\r
d1050b9d 134 TlsService->ImageHandle = Image;\r
7618784b
HW
135\r
136 *Service = TlsService;\r
137\r
138 return EFI_SUCCESS;\r
139}\r
140\r
141/**\r
142 Unloads an image.\r
143\r
144 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
145\r
146 @retval EFI_SUCCESS The image has been unloaded.\r
147 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.\r
148\r
149**/\r
150EFI_STATUS\r
151EFIAPI\r
152TlsUnload (\r
153 IN EFI_HANDLE ImageHandle\r
154 )\r
155{\r
d1050b9d
MK
156 EFI_STATUS Status;\r
157 UINTN HandleNum;\r
158 EFI_HANDLE *HandleBuffer;\r
159 UINT32 Index;\r
160 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
161 TLS_SERVICE *TlsService;\r
7618784b
HW
162\r
163 HandleBuffer = NULL;\r
164 ServiceBinding = NULL;\r
165 TlsService = NULL;\r
166\r
167 //\r
168 // Locate all the handles with Tls service binding protocol.\r
169 //\r
170 Status = gBS->LocateHandleBuffer (\r
171 ByProtocol,\r
172 &gEfiTlsServiceBindingProtocolGuid,\r
173 NULL,\r
174 &HandleNum,\r
175 &HandleBuffer\r
176 );\r
177 if (EFI_ERROR (Status)) {\r
178 return Status;\r
179 }\r
180\r
181 for (Index = 0; Index < HandleNum; Index++) {\r
182 //\r
183 // Firstly, find ServiceBinding interface\r
184 //\r
185 Status = gBS->OpenProtocol (\r
186 HandleBuffer[Index],\r
187 &gEfiTlsServiceBindingProtocolGuid,\r
d1050b9d 188 (VOID **)&ServiceBinding,\r
7618784b
HW
189 ImageHandle,\r
190 NULL,\r
191 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL\r
192 );\r
193 if (EFI_ERROR (Status)) {\r
194 return Status;\r
195 }\r
196\r
197 TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);\r
198\r
199 //\r
200 // Then, uninstall ServiceBinding interface\r
201 //\r
202 Status = gBS->UninstallMultipleProtocolInterfaces (\r
203 HandleBuffer[Index],\r
d1050b9d
MK
204 &gEfiTlsServiceBindingProtocolGuid,\r
205 ServiceBinding,\r
7618784b
HW
206 NULL\r
207 );\r
208 if (EFI_ERROR (Status)) {\r
209 return Status;\r
210 }\r
211\r
212 TlsCleanService (TlsService);\r
213 }\r
214\r
215 if (HandleBuffer != NULL) {\r
216 FreePool (HandleBuffer);\r
217 }\r
218\r
219 return EFI_SUCCESS;\r
220}\r
221\r
222/**\r
223 This is the declaration of an EFI image entry point. This entry point is\r
224 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
225 both device drivers and bus drivers.\r
226\r
227 @param ImageHandle The firmware allocated handle for the UEFI image.\r
228 @param SystemTable A pointer to the EFI System Table.\r
229\r
230 @retval EFI_SUCCESS The operation completed successfully.\r
231 @retval Others An unexpected error occurred.\r
232**/\r
233EFI_STATUS\r
234EFIAPI\r
235TlsDriverEntryPoint (\r
236 IN EFI_HANDLE ImageHandle,\r
237 IN EFI_SYSTEM_TABLE *SystemTable\r
238 )\r
239{\r
d1050b9d 240 EFI_STATUS Status;\r
7618784b 241\r
d1050b9d 242 TLS_SERVICE *TlsService;\r
7618784b
HW
243\r
244 //\r
245 // Create TLS Service\r
246 //\r
247 Status = TlsCreateService (ImageHandle, &TlsService);\r
248 if (EFI_ERROR (Status)) {\r
249 return Status;\r
250 }\r
251\r
252 ASSERT (TlsService != NULL);\r
253\r
254 //\r
255 // Initializes the OpenSSL library.\r
256 //\r
257 TlsInitialize ();\r
258\r
259 //\r
260 // Create a new SSL_CTX object as framework to establish TLS/SSL enabled\r
261 // connections. TLS 1.0 is used as the default version.\r
262 //\r
263 TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);\r
264 if (TlsService->TlsCtx == NULL) {\r
265 FreePool (TlsService);\r
266 return EFI_ABORTED;\r
267 }\r
268\r
269 //\r
270 // Install the TlsServiceBinding Protocol onto Handle\r
271 //\r
272 Status = gBS->InstallMultipleProtocolInterfaces (\r
273 &TlsService->Handle,\r
274 &gEfiTlsServiceBindingProtocolGuid,\r
275 &TlsService->ServiceBinding,\r
276 NULL\r
277 );\r
278 if (EFI_ERROR (Status)) {\r
279 goto ON_CLEAN_SERVICE;\r
280 }\r
281\r
282 return Status;\r
283\r
284ON_CLEAN_SERVICE:\r
285 TlsCleanService (TlsService);\r
286\r
287 return Status;\r
288}\r
289\r
290/**\r
291 Creates a child handle and installs a protocol.\r
292\r
293 The CreateChild() function installs a protocol on ChildHandle.\r
294 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
295 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
296\r
297 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
298 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
299 then a new handle is created. If it is a pointer to an existing UEFI handle,\r
300 then the protocol is added to the existing UEFI handle.\r
301\r
dad13c80 302 @retval EFI_SUCCESS The protocol was added to ChildHandle.\r
7618784b
HW
303 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
304 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
305 the child.\r
306 @retval other The child handle was not created.\r
307\r
308**/\r
309EFI_STATUS\r
310EFIAPI\r
311TlsServiceBindingCreateChild (\r
312 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
313 IN EFI_HANDLE *ChildHandle\r
314 )\r
315{\r
d1050b9d
MK
316 TLS_SERVICE *TlsService;\r
317 TLS_INSTANCE *TlsInstance;\r
318 EFI_STATUS Status;\r
319 EFI_TPL OldTpl;\r
7618784b
HW
320\r
321 if ((This == NULL) || (ChildHandle == NULL)) {\r
322 return EFI_INVALID_PARAMETER;\r
323 }\r
324\r
325 TlsService = TLS_SERVICE_FROM_THIS (This);\r
326\r
327 Status = TlsCreateInstance (TlsService, &TlsInstance);\r
328 if (EFI_ERROR (Status)) {\r
329 return Status;\r
330 }\r
331\r
332 ASSERT (TlsInstance != NULL);\r
333\r
334 //\r
335 // Create a new TLS connection object.\r
336 //\r
337 TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);\r
338 if (TlsInstance->TlsConn == NULL) {\r
339 Status = EFI_ABORTED;\r
340 goto ON_ERROR;\r
341 }\r
342\r
343 //\r
344 // Set default ConnectionEnd to EfiTlsClient\r
345 //\r
346 Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);\r
347 if (EFI_ERROR (Status)) {\r
348 goto ON_ERROR;\r
349 }\r
350\r
351 //\r
352 // Install TLS protocol and configuration protocol onto ChildHandle\r
353 //\r
354 Status = gBS->InstallMultipleProtocolInterfaces (\r
355 ChildHandle,\r
356 &gEfiTlsProtocolGuid,\r
357 &TlsInstance->Tls,\r
358 &gEfiTlsConfigurationProtocolGuid,\r
359 &TlsInstance->TlsConfig,\r
360 NULL\r
361 );\r
362 if (EFI_ERROR (Status)) {\r
363 goto ON_ERROR;\r
364 }\r
365\r
366 TlsInstance->ChildHandle = *ChildHandle;\r
367\r
368 //\r
369 // Add it to the TLS service's child list.\r
370 //\r
371 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
372\r
373 InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);\r
374 TlsService->TlsChildrenNum++;\r
375\r
376 gBS->RestoreTPL (OldTpl);\r
377\r
378 return EFI_SUCCESS;\r
379\r
380ON_ERROR:\r
381 TlsCleanInstance (TlsInstance);\r
382 return Status;\r
383}\r
384\r
385/**\r
386 Destroys a child handle with a protocol installed on it.\r
387\r
388 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
389 that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
390 last protocol on ChildHandle, then ChildHandle is destroyed.\r
391\r
392 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
393 @param ChildHandle Handle of the child to destroy.\r
394\r
dad13c80 395 @retval EFI_SUCCESS The protocol was removed from ChildHandle.\r
7618784b
HW
396 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
397 @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
398 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
399 because its services are being used.\r
400 @retval other The child handle was not destroyed.\r
401\r
402**/\r
403EFI_STATUS\r
404EFIAPI\r
405TlsServiceBindingDestroyChild (\r
406 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
407 IN EFI_HANDLE ChildHandle\r
408 )\r
409{\r
d1050b9d
MK
410 TLS_SERVICE *TlsService;\r
411 TLS_INSTANCE *TlsInstance;\r
7618784b 412\r
d1050b9d
MK
413 EFI_TLS_PROTOCOL *Tls;\r
414 EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;\r
415 EFI_STATUS Status;\r
416 EFI_TPL OldTpl;\r
7618784b
HW
417\r
418 if ((This == NULL) || (ChildHandle == NULL)) {\r
419 return EFI_INVALID_PARAMETER;\r
420 }\r
421\r
422 TlsService = TLS_SERVICE_FROM_THIS (This);\r
423\r
424 //\r
425 // Find TLS protocol interface installed in ChildHandle\r
426 //\r
427 Status = gBS->OpenProtocol (\r
428 ChildHandle,\r
429 &gEfiTlsProtocolGuid,\r
d1050b9d 430 (VOID **)&Tls,\r
7618784b
HW
431 TlsService->ImageHandle,\r
432 NULL,\r
433 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL\r
434 );\r
435 if (EFI_ERROR (Status)) {\r
436 return Status;\r
437 }\r
438\r
439 //\r
440 // Find TLS configuration protocol interface installed in ChildHandle\r
441 //\r
442 Status = gBS->OpenProtocol (\r
443 ChildHandle,\r
444 &gEfiTlsConfigurationProtocolGuid,\r
d1050b9d 445 (VOID **)&TlsConfig,\r
7618784b
HW
446 TlsService->ImageHandle,\r
447 NULL,\r
448 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL\r
449 );\r
450 if (EFI_ERROR (Status)) {\r
451 return Status;\r
452 }\r
453\r
d1050b9d 454 TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls);\r
7618784b
HW
455\r
456 if (TlsInstance->Service != TlsService) {\r
457 return EFI_INVALID_PARAMETER;\r
458 }\r
459\r
460 if (TlsInstance->InDestroy) {\r
461 return EFI_SUCCESS;\r
462 }\r
463\r
464 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
465\r
466 TlsInstance->InDestroy = TRUE;\r
467\r
468 //\r
469 // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.\r
470 //\r
471 Status = gBS->UninstallMultipleProtocolInterfaces (\r
472 ChildHandle,\r
473 &gEfiTlsProtocolGuid,\r
474 Tls,\r
475 &gEfiTlsConfigurationProtocolGuid,\r
476 TlsConfig,\r
477 NULL\r
478 );\r
479 if (EFI_ERROR (Status)) {\r
480 return Status;\r
481 }\r
482\r
483 RemoveEntryList (&TlsInstance->Link);\r
484 TlsService->TlsChildrenNum--;\r
485\r
486 gBS->RestoreTPL (OldTpl);\r
487\r
488 TlsCleanInstance (TlsInstance);\r
489\r
490 return EFI_SUCCESS;\r
491}\r