]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/TlsDxe/TlsDriver.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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,
205 ServiceBinding,
206 NULL
207 );
208 if (EFI_ERROR (Status)) {
209 return Status;
210 }
211
212 TlsCleanService (TlsService);
213 }
214
215 if (HandleBuffer != NULL) {
216 FreePool (HandleBuffer);
217 }
218
219 return EFI_SUCCESS;
220 }
221
222 /**
223 This is the declaration of an EFI image entry point. This entry point is
224 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
225 both device drivers and bus drivers.
226
227 @param ImageHandle The firmware allocated handle for the UEFI image.
228 @param SystemTable A pointer to the EFI System Table.
229
230 @retval EFI_SUCCESS The operation completed successfully.
231 @retval Others An unexpected error occurred.
232 **/
233 EFI_STATUS
234 EFIAPI
235 TlsDriverEntryPoint (
236 IN EFI_HANDLE ImageHandle,
237 IN EFI_SYSTEM_TABLE *SystemTable
238 )
239 {
240 EFI_STATUS Status;
241
242 TLS_SERVICE *TlsService;
243
244 //
245 // Create TLS Service
246 //
247 Status = TlsCreateService (ImageHandle, &TlsService);
248 if (EFI_ERROR (Status)) {
249 return Status;
250 }
251
252 ASSERT (TlsService != NULL);
253
254 //
255 // Initializes the OpenSSL library.
256 //
257 TlsInitialize ();
258
259 //
260 // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
261 // connections. TLS 1.0 is used as the default version.
262 //
263 TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
264 if (TlsService->TlsCtx == NULL) {
265 FreePool (TlsService);
266 return EFI_ABORTED;
267 }
268
269 //
270 // Install the TlsServiceBinding Protocol onto Handle
271 //
272 Status = gBS->InstallMultipleProtocolInterfaces (
273 &TlsService->Handle,
274 &gEfiTlsServiceBindingProtocolGuid,
275 &TlsService->ServiceBinding,
276 NULL
277 );
278 if (EFI_ERROR (Status)) {
279 goto ON_CLEAN_SERVICE;
280 }
281
282 return Status;
283
284 ON_CLEAN_SERVICE:
285 TlsCleanService (TlsService);
286
287 return Status;
288 }
289
290 /**
291 Creates a child handle and installs a protocol.
292
293 The CreateChild() function installs a protocol on ChildHandle.
294 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
295 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
296
297 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
298 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
299 then a new handle is created. If it is a pointer to an existing UEFI handle,
300 then the protocol is added to the existing UEFI handle.
301
302 @retval EFI_SUCCESS The protocol was added to ChildHandle.
303 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
304 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
305 the child.
306 @retval other The child handle was not created.
307
308 **/
309 EFI_STATUS
310 EFIAPI
311 TlsServiceBindingCreateChild (
312 IN EFI_SERVICE_BINDING_PROTOCOL *This,
313 IN EFI_HANDLE *ChildHandle
314 )
315 {
316 TLS_SERVICE *TlsService;
317 TLS_INSTANCE *TlsInstance;
318 EFI_STATUS Status;
319 EFI_TPL OldTpl;
320
321 if ((This == NULL) || (ChildHandle == NULL)) {
322 return EFI_INVALID_PARAMETER;
323 }
324
325 TlsService = TLS_SERVICE_FROM_THIS (This);
326
327 Status = TlsCreateInstance (TlsService, &TlsInstance);
328 if (EFI_ERROR (Status)) {
329 return Status;
330 }
331
332 ASSERT (TlsInstance != NULL);
333
334 //
335 // Create a new TLS connection object.
336 //
337 TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
338 if (TlsInstance->TlsConn == NULL) {
339 Status = EFI_ABORTED;
340 goto ON_ERROR;
341 }
342
343 //
344 // Set default ConnectionEnd to EfiTlsClient
345 //
346 Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
347 if (EFI_ERROR (Status)) {
348 goto ON_ERROR;
349 }
350
351 //
352 // Install TLS protocol and configuration protocol onto ChildHandle
353 //
354 Status = gBS->InstallMultipleProtocolInterfaces (
355 ChildHandle,
356 &gEfiTlsProtocolGuid,
357 &TlsInstance->Tls,
358 &gEfiTlsConfigurationProtocolGuid,
359 &TlsInstance->TlsConfig,
360 NULL
361 );
362 if (EFI_ERROR (Status)) {
363 goto ON_ERROR;
364 }
365
366 TlsInstance->ChildHandle = *ChildHandle;
367
368 //
369 // Add it to the TLS service's child list.
370 //
371 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
372
373 InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
374 TlsService->TlsChildrenNum++;
375
376 gBS->RestoreTPL (OldTpl);
377
378 return EFI_SUCCESS;
379
380 ON_ERROR:
381 TlsCleanInstance (TlsInstance);
382 return Status;
383 }
384
385 /**
386 Destroys a child handle with a protocol installed on it.
387
388 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
389 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
390 last protocol on ChildHandle, then ChildHandle is destroyed.
391
392 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
393 @param ChildHandle Handle of the child to destroy.
394
395 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
396 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
397 @retval EFI_INVALID_PARAMETER Child handle is NULL.
398 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
399 because its services are being used.
400 @retval other The child handle was not destroyed.
401
402 **/
403 EFI_STATUS
404 EFIAPI
405 TlsServiceBindingDestroyChild (
406 IN EFI_SERVICE_BINDING_PROTOCOL *This,
407 IN EFI_HANDLE ChildHandle
408 )
409 {
410 TLS_SERVICE *TlsService;
411 TLS_INSTANCE *TlsInstance;
412
413 EFI_TLS_PROTOCOL *Tls;
414 EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
415 EFI_STATUS Status;
416 EFI_TPL OldTpl;
417
418 if ((This == NULL) || (ChildHandle == NULL)) {
419 return EFI_INVALID_PARAMETER;
420 }
421
422 TlsService = TLS_SERVICE_FROM_THIS (This);
423
424 //
425 // Find TLS protocol interface installed in ChildHandle
426 //
427 Status = gBS->OpenProtocol (
428 ChildHandle,
429 &gEfiTlsProtocolGuid,
430 (VOID **)&Tls,
431 TlsService->ImageHandle,
432 NULL,
433 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
434 );
435 if (EFI_ERROR (Status)) {
436 return Status;
437 }
438
439 //
440 // Find TLS configuration protocol interface installed in ChildHandle
441 //
442 Status = gBS->OpenProtocol (
443 ChildHandle,
444 &gEfiTlsConfigurationProtocolGuid,
445 (VOID **)&TlsConfig,
446 TlsService->ImageHandle,
447 NULL,
448 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
449 );
450 if (EFI_ERROR (Status)) {
451 return Status;
452 }
453
454 TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls);
455
456 if (TlsInstance->Service != TlsService) {
457 return EFI_INVALID_PARAMETER;
458 }
459
460 if (TlsInstance->InDestroy) {
461 return EFI_SUCCESS;
462 }
463
464 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
465
466 TlsInstance->InDestroy = TRUE;
467
468 //
469 // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
470 //
471 Status = gBS->UninstallMultipleProtocolInterfaces (
472 ChildHandle,
473 &gEfiTlsProtocolGuid,
474 Tls,
475 &gEfiTlsConfigurationProtocolGuid,
476 TlsConfig,
477 NULL
478 );
479 if (EFI_ERROR (Status)) {
480 return Status;
481 }
482
483 RemoveEntryList (&TlsInstance->Link);
484 TlsService->TlsChildrenNum--;
485
486 gBS->RestoreTPL (OldTpl);
487
488 TlsCleanInstance (TlsInstance);
489
490 return EFI_SUCCESS;
491 }