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