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