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