NetworkPkg: Convert files to CRLF line ending
[mirror_edk2.git] / NetworkPkg / TlsDxe / TlsProtocol.c
1 /** @file\r
2   Implementation of EFI TLS Protocol Interfaces.\r
3 \r
4   Copyright (c) 2016 - 2017, 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
18 EFI_TLS_PROTOCOL  mTlsProtocol = {\r
19   TlsSetSessionData,\r
20   TlsGetSessionData,\r
21   TlsBuildResponsePacket,\r
22   TlsProcessPacket\r
23 };\r
24 \r
25 /**\r
26   Set TLS session data.\r
27 \r
28   The SetSessionData() function set data for a new TLS session. All session data should\r
29   be set before BuildResponsePacket() invoked.\r
30 \r
31   @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.\r
32   @param[in]  DataType            TLS session data type.\r
33   @param[in]  Data                Pointer to session data.\r
34   @param[in]  DataSize            Total size of session data.\r
35 \r
36   @retval EFI_SUCCESS             The TLS session data is set successfully.\r
37   @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:\r
38                                   This is NULL.\r
39                                   Data is NULL.\r
40                                   DataSize is 0.\r
41   @retval EFI_UNSUPPORTED         The DataType is unsupported.\r
42   @retval EFI_ACCESS_DENIED       If the DataType is one of below:\r
43                                   EfiTlsClientRandom\r
44                                   EfiTlsServerRandom\r
45                                   EfiTlsKeyMaterial\r
46   @retval EFI_NOT_READY           Current TLS session state is NOT\r
47                                   EfiTlsSessionStateNotStarted.\r
48   @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.\r
49 **/\r
50 EFI_STATUS\r
51 EFIAPI\r
52 TlsSetSessionData (\r
53   IN     EFI_TLS_PROTOCOL              *This,\r
54   IN     EFI_TLS_SESSION_DATA_TYPE     DataType,\r
55   IN     VOID                          *Data,\r
56   IN     UINTN                         DataSize\r
57   )\r
58 {\r
59   EFI_STATUS                Status;\r
60   TLS_INSTANCE              *Instance;\r
61   UINT16                    *CipherId;\r
62   UINTN                     Index;\r
63 \r
64   EFI_TPL                   OldTpl;\r
65 \r
66   Status = EFI_SUCCESS;\r
67   CipherId = NULL;\r
68 \r
69   if (This == NULL || Data == NULL || DataSize == 0) {\r
70     return EFI_INVALID_PARAMETER;\r
71   }\r
72 \r
73   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
74 \r
75   Instance = TLS_INSTANCE_FROM_PROTOCOL (This);\r
76 \r
77   if (DataType != EfiTlsSessionState  && Instance->TlsSessionState != EfiTlsSessionNotStarted){\r
78     Status = EFI_NOT_READY;\r
79     goto ON_EXIT;\r
80   }\r
81 \r
82   switch (DataType) {\r
83   //\r
84   // Session Configuration\r
85   //\r
86   case EfiTlsVersion:\r
87     if (DataSize != sizeof (EFI_TLS_VERSION)) {\r
88       Status = EFI_INVALID_PARAMETER;\r
89       goto ON_EXIT;\r
90     }\r
91 \r
92     Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);\r
93     break;\r
94   case EfiTlsConnectionEnd:\r
95     if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {\r
96       Status = EFI_INVALID_PARAMETER;\r
97       goto ON_EXIT;\r
98     }\r
99 \r
100     Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));\r
101     break;\r
102   case EfiTlsCipherList:\r
103     CipherId = AllocatePool (DataSize);\r
104     if (CipherId == NULL) {\r
105       Status = EFI_OUT_OF_RESOURCES;\r
106       goto ON_EXIT;\r
107     }\r
108 \r
109     for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {\r
110       *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));\r
111     }\r
112 \r
113     Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));\r
114 \r
115     FreePool (CipherId);\r
116     break;\r
117   case EfiTlsCompressionMethod:\r
118     //\r
119     // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the\r
120     // record protocol will not be compressed.\r
121     // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html\r
122     // The TLS RFC does however not specify compression methods or their corresponding identifiers,\r
123     // so there is currently no compatible way to integrate compression with unknown peers.\r
124     // It is therefore currently not recommended to integrate compression into applications.\r
125     // Applications for non-public use may agree on certain compression methods.\r
126     // Using different compression methods with the same identifier will lead to connection failure.\r
127     //\r
128     for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {\r
129       Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));\r
130       if (EFI_ERROR (Status)) {\r
131         break;\r
132       }\r
133     }\r
134 \r
135     break;\r
136   case EfiTlsExtensionData:\r
137     Status = EFI_UNSUPPORTED;\r
138     goto ON_EXIT;\r
139   case EfiTlsVerifyMethod:\r
140     if (DataSize != sizeof (EFI_TLS_VERIFY)) {\r
141       Status = EFI_INVALID_PARAMETER;\r
142       goto ON_EXIT;\r
143     }\r
144 \r
145     TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));\r
146     break;\r
147   case EfiTlsSessionID:\r
148     if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {\r
149       Status = EFI_INVALID_PARAMETER;\r
150       goto ON_EXIT;\r
151     }\r
152 \r
153     Status = TlsSetSessionId (\r
154                Instance->TlsConn,\r
155                ((EFI_TLS_SESSION_ID *) Data)->Data,\r
156                ((EFI_TLS_SESSION_ID *) Data)->Length\r
157                );\r
158     break;\r
159   case EfiTlsSessionState:\r
160     if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {\r
161       Status = EFI_INVALID_PARAMETER;\r
162       goto ON_EXIT;\r
163     }\r
164 \r
165     Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;\r
166     break;\r
167   //\r
168   // Session information\r
169   //\r
170   case EfiTlsClientRandom:\r
171     Status = EFI_ACCESS_DENIED;\r
172     break;\r
173   case EfiTlsServerRandom:\r
174     Status = EFI_ACCESS_DENIED;\r
175     break;\r
176   case EfiTlsKeyMaterial:\r
177     Status = EFI_ACCESS_DENIED;\r
178     break;\r
179   //\r
180   // Unsupported type.\r
181   //\r
182   default:\r
183     Status = EFI_UNSUPPORTED;\r
184   }\r
185 \r
186 ON_EXIT:\r
187   gBS->RestoreTPL (OldTpl);\r
188   return Status;\r
189 }\r
190 \r
191 /**\r
192   Get TLS session data.\r
193 \r
194   The GetSessionData() function return the TLS session information.\r
195 \r
196   @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.\r
197   @param[in]       DataType       TLS session data type.\r
198   @param[in, out]  Data           Pointer to session data.\r
199   @param[in, out]  DataSize       Total size of session data. On input, it means\r
200                                   the size of Data buffer. On output, it means the size\r
201                                   of copied Data buffer if EFI_SUCCESS, and means the\r
202                                   size of desired Data buffer if EFI_BUFFER_TOO_SMALL.\r
203 \r
204   @retval EFI_SUCCESS             The TLS session data is got successfully.\r
205   @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:\r
206                                   This is NULL.\r
207                                   DataSize is NULL.\r
208                                   Data is NULL if *DataSize is not zero.\r
209   @retval EFI_UNSUPPORTED         The DataType is unsupported.\r
210   @retval EFI_NOT_FOUND           The TLS session data is not found.\r
211   @retval EFI_NOT_READY           The DataType is not ready in current session state.\r
212   @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.\r
213 **/\r
214 EFI_STATUS\r
215 EFIAPI\r
216 TlsGetSessionData (\r
217   IN     EFI_TLS_PROTOCOL              *This,\r
218   IN     EFI_TLS_SESSION_DATA_TYPE     DataType,\r
219   IN OUT VOID                          *Data,  OPTIONAL\r
220   IN OUT UINTN                         *DataSize\r
221   )\r
222 {\r
223   EFI_STATUS                Status;\r
224   TLS_INSTANCE              *Instance;\r
225 \r
226   EFI_TPL                   OldTpl;\r
227 \r
228   Status = EFI_SUCCESS;\r
229 \r
230   if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {\r
231     return EFI_INVALID_PARAMETER;\r
232   }\r
233 \r
234   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
235 \r
236   Instance = TLS_INSTANCE_FROM_PROTOCOL (This);\r
237 \r
238   if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&\r
239     (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||\r
240     DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {\r
241     Status = EFI_NOT_READY;\r
242     goto ON_EXIT;\r
243   }\r
244 \r
245   switch (DataType) {\r
246   case EfiTlsVersion:\r
247     if (*DataSize < sizeof (EFI_TLS_VERSION)) {\r
248       *DataSize = sizeof (EFI_TLS_VERSION);\r
249       Status = EFI_BUFFER_TOO_SMALL;\r
250       goto ON_EXIT;\r
251     }\r
252     *DataSize = sizeof (EFI_TLS_VERSION);\r
253     *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));\r
254     break;\r
255   case EfiTlsConnectionEnd:\r
256     if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {\r
257       *DataSize = sizeof (EFI_TLS_CONNECTION_END);\r
258       Status = EFI_BUFFER_TOO_SMALL;\r
259       goto ON_EXIT;\r
260     }\r
261     *DataSize = sizeof (EFI_TLS_CONNECTION_END);\r
262     *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);\r
263     break;\r
264   case EfiTlsCipherList:\r
265     //\r
266     // Get the current session cipher suite.\r
267     //\r
268     if (*DataSize < sizeof (EFI_TLS_CIPHER)) {\r
269       *DataSize = sizeof (EFI_TLS_CIPHER);\r
270       Status = EFI_BUFFER_TOO_SMALL;\r
271       goto ON_EXIT;\r
272     }\r
273     *DataSize = sizeof(EFI_TLS_CIPHER);\r
274     Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);\r
275     *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));\r
276     break;\r
277   case EfiTlsCompressionMethod:\r
278     //\r
279     // Get the current session compression method.\r
280     //\r
281     if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {\r
282       *DataSize = sizeof (EFI_TLS_COMPRESSION);\r
283       Status = EFI_BUFFER_TOO_SMALL;\r
284       goto ON_EXIT;\r
285     }\r
286     *DataSize = sizeof (EFI_TLS_COMPRESSION);\r
287     Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);\r
288     break;\r
289   case EfiTlsExtensionData:\r
290     Status = EFI_UNSUPPORTED;\r
291     goto ON_EXIT;\r
292   case EfiTlsVerifyMethod:\r
293     if (*DataSize < sizeof (EFI_TLS_VERIFY)) {\r
294       *DataSize = sizeof (EFI_TLS_VERIFY);\r
295       Status = EFI_BUFFER_TOO_SMALL;\r
296       goto ON_EXIT;\r
297     }\r
298     *DataSize = sizeof (EFI_TLS_VERIFY);\r
299     *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);\r
300     break;\r
301   case EfiTlsSessionID:\r
302     if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {\r
303       *DataSize = sizeof (EFI_TLS_SESSION_ID);\r
304       Status = EFI_BUFFER_TOO_SMALL;\r
305       goto ON_EXIT;\r
306     }\r
307     *DataSize = sizeof (EFI_TLS_SESSION_ID);\r
308     Status = TlsGetSessionId (\r
309                Instance->TlsConn,\r
310                ((EFI_TLS_SESSION_ID *) Data)->Data,\r
311                &(((EFI_TLS_SESSION_ID *) Data)->Length)\r
312                );\r
313     break;\r
314   case EfiTlsSessionState:\r
315     if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {\r
316       *DataSize = sizeof (EFI_TLS_SESSION_STATE);\r
317       Status = EFI_BUFFER_TOO_SMALL;\r
318       goto ON_EXIT;\r
319     }\r
320     *DataSize = sizeof (EFI_TLS_SESSION_STATE);\r
321     CopyMem (Data, &Instance->TlsSessionState, *DataSize);\r
322     break;\r
323   case EfiTlsClientRandom:\r
324     if (*DataSize < sizeof (EFI_TLS_RANDOM)) {\r
325       *DataSize = sizeof (EFI_TLS_RANDOM);\r
326       Status = EFI_BUFFER_TOO_SMALL;\r
327       goto ON_EXIT;\r
328     }\r
329     *DataSize = sizeof (EFI_TLS_RANDOM);\r
330     TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);\r
331     break;\r
332   case EfiTlsServerRandom:\r
333     if (*DataSize < sizeof (EFI_TLS_RANDOM)) {\r
334       *DataSize = sizeof (EFI_TLS_RANDOM);\r
335       Status = EFI_BUFFER_TOO_SMALL;\r
336       goto ON_EXIT;\r
337     }\r
338     *DataSize = sizeof (EFI_TLS_RANDOM);\r
339     TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);\r
340     break;\r
341   case EfiTlsKeyMaterial:\r
342     if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {\r
343       *DataSize = sizeof (EFI_TLS_MASTER_SECRET);\r
344       Status = EFI_BUFFER_TOO_SMALL;\r
345       goto ON_EXIT;\r
346     }\r
347     *DataSize = sizeof (EFI_TLS_MASTER_SECRET);\r
348     Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);\r
349     break;\r
350   //\r
351   // Unsupported type.\r
352   //\r
353   default:\r
354     Status = EFI_UNSUPPORTED;\r
355   }\r
356 \r
357 ON_EXIT:\r
358   gBS->RestoreTPL (OldTpl);\r
359   return Status;\r
360 }\r
361 \r
362 /**\r
363   Build response packet according to TLS state machine. This function is only valid for\r
364   alert, handshake and change_cipher_spec content type.\r
365 \r
366   The BuildResponsePacket() function builds TLS response packet in response to the TLS\r
367   request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and\r
368   RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session\r
369   will be initiated and the response packet needs to be ClientHello. If RequestBuffer is\r
370   NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS\r
371   session will be closed and response packet needs to be CloseNotify. If RequestBuffer is\r
372   NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS\r
373   session has errors and the response packet needs to be Alert message based on error\r
374   type.\r
375 \r
376   @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.\r
377   @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL\r
378                                   means TLS need initiate the TLS session and response\r
379                                   packet need to be ClientHello.\r
380   @param[in]       RequestSize    Packet size in bytes for the most recently received TLS\r
381                                   packet. 0 is only valid when RequestBuffer is NULL.\r
382   @param[out]      Buffer         Pointer to the buffer to hold the built packet.\r
383   @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is\r
384                                   the buffer size provided by the caller. On output, it\r
385                                   is the buffer size in fact needed to contain the\r
386                                   packet.\r
387 \r
388   @retval EFI_SUCCESS             The required TLS packet is built successfully.\r
389   @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:\r
390                                   This is NULL.\r
391                                   RequestBuffer is NULL but RequestSize is NOT 0.\r
392                                   RequestSize is 0 but RequestBuffer is NOT NULL.\r
393                                   BufferSize is NULL.\r
394                                   Buffer is NULL if *BufferSize is not zero.\r
395   @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.\r
396   @retval EFI_NOT_READY           Current TLS session state is NOT ready to build\r
397                                   ResponsePacket.\r
398   @retval EFI_ABORTED             Something wrong build response packet.\r
399 **/\r
400 EFI_STATUS\r
401 EFIAPI\r
402 TlsBuildResponsePacket (\r
403   IN     EFI_TLS_PROTOCOL              *This,\r
404   IN     UINT8                         *RequestBuffer, OPTIONAL\r
405   IN     UINTN                         RequestSize, OPTIONAL\r
406      OUT UINT8                         *Buffer, OPTIONAL\r
407   IN OUT UINTN                         *BufferSize\r
408   )\r
409 {\r
410   EFI_STATUS                Status;\r
411   TLS_INSTANCE              *Instance;\r
412   EFI_TPL                   OldTpl;\r
413 \r
414   Status = EFI_SUCCESS;\r
415 \r
416   if ((This == NULL) || (BufferSize == NULL) ||\r
417       (RequestBuffer == NULL && RequestSize != 0) ||\r
418       (RequestBuffer != NULL && RequestSize == 0) ||\r
419       (Buffer == NULL && *BufferSize !=0)) {\r
420     return EFI_INVALID_PARAMETER;\r
421   }\r
422 \r
423   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
424 \r
425   Instance = TLS_INSTANCE_FROM_PROTOCOL (This);\r
426 \r
427   if(RequestBuffer == NULL && RequestSize == 0) {\r
428     switch (Instance->TlsSessionState) {\r
429     case EfiTlsSessionNotStarted:\r
430       //\r
431       // ClientHello.\r
432       //\r
433       Status = TlsDoHandshake (\r
434                  Instance->TlsConn,\r
435                  NULL,\r
436                  0,\r
437                  Buffer,\r
438                  BufferSize\r
439                  );\r
440       if (EFI_ERROR (Status)) {\r
441         goto ON_EXIT;\r
442       }\r
443 \r
444       //\r
445       // *BufferSize should not be zero when ClientHello.\r
446       //\r
447       if (*BufferSize == 0) {\r
448         Status = EFI_ABORTED;\r
449         goto ON_EXIT;\r
450       }\r
451 \r
452       Instance->TlsSessionState = EfiTlsSessionHandShaking;\r
453 \r
454       break;\r
455     case EfiTlsSessionClosing:\r
456       //\r
457       // TLS session will be closed and response packet needs to be CloseNotify.\r
458       //\r
459       Status = TlsCloseNotify (\r
460                  Instance->TlsConn,\r
461                  Buffer,\r
462                  BufferSize\r
463                  );\r
464       if (EFI_ERROR (Status)) {\r
465         goto ON_EXIT;\r
466       }\r
467 \r
468       //\r
469       // *BufferSize should not be zero when build CloseNotify message.\r
470       //\r
471       if (*BufferSize == 0) {\r
472         Status = EFI_ABORTED;\r
473         goto ON_EXIT;\r
474       }\r
475 \r
476       break;\r
477     case EfiTlsSessionError:\r
478       //\r
479       // TLS session has errors and the response packet needs to be Alert\r
480       // message based on error type.\r
481       //\r
482       Status = TlsHandleAlert (\r
483                  Instance->TlsConn,\r
484                  NULL,\r
485                  0,\r
486                  Buffer,\r
487                  BufferSize\r
488                  );\r
489       if (EFI_ERROR (Status)) {\r
490         goto ON_EXIT;\r
491       }\r
492 \r
493       break;\r
494     default:\r
495       //\r
496       // Current TLS session state is NOT ready to build ResponsePacket.\r
497       //\r
498       Status = EFI_NOT_READY;\r
499     }\r
500   } else {\r
501     //\r
502     // 1. Received packet may have multiple TLS record messages.\r
503     // 2. One TLS record message may have multiple handshake protocol.\r
504     // 3. Some errors may be happened in handshake.\r
505     // TlsDoHandshake() can handle all of those cases.\r
506     //\r
507     if (TlsInHandshake (Instance->TlsConn)) {\r
508       Status = TlsDoHandshake (\r
509                  Instance->TlsConn,\r
510                  RequestBuffer,\r
511                  RequestSize,\r
512                  Buffer,\r
513                  BufferSize\r
514                  );\r
515       if (EFI_ERROR (Status)) {\r
516         goto ON_EXIT;\r
517       }\r
518 \r
519       if (!TlsInHandshake (Instance->TlsConn)) {\r
520         Instance->TlsSessionState = EfiTlsSessionDataTransferring;\r
521       }\r
522     } else {\r
523       //\r
524       // Must be alert message, Decrypt it and build the ResponsePacket.\r
525       //\r
526       ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TlsContentTypeAlert);\r
527 \r
528       Status = TlsHandleAlert (\r
529                  Instance->TlsConn,\r
530                  RequestBuffer,\r
531                  RequestSize,\r
532                  Buffer,\r
533                  BufferSize\r
534                  );\r
535       if (EFI_ERROR (Status)) {\r
536         if (Status != EFI_BUFFER_TOO_SMALL) {\r
537           Instance->TlsSessionState = EfiTlsSessionError;\r
538         }\r
539 \r
540         goto ON_EXIT;\r
541       }\r
542     }\r
543   }\r
544 \r
545 ON_EXIT:\r
546   gBS->RestoreTPL (OldTpl);\r
547   return Status;\r
548 }\r
549 \r
550 /**\r
551   Decrypt or encrypt TLS packet during session. This function is only valid after\r
552   session connected and for application_data content type.\r
553 \r
554   The ProcessPacket () function process each inbound or outbound TLS APP packet.\r
555 \r
556   @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.\r
557   @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take\r
558                                   responsible to handle the original FragmentTable while\r
559                                   it may be reallocated in TLS driver. If CryptMode is\r
560                                   EfiTlsEncrypt, on input these fragments contain the TLS\r
561                                   header and plain text TLS APP payload; on output these\r
562                                   fragments contain the TLS header and cipher text TLS\r
563                                   APP payload. If CryptMode is EfiTlsDecrypt, on input\r
564                                   these fragments contain the TLS header and cipher text\r
565                                   TLS APP payload; on output these fragments contain the\r
566                                   TLS header and plain text TLS APP payload.\r
567   @param[in]       FragmentCount  Number of fragment.\r
568   @param[in]       CryptMode      Crypt mode.\r
569 \r
570   @retval EFI_SUCCESS             The operation completed successfully.\r
571   @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:\r
572                                   This is NULL.\r
573                                   FragmentTable is NULL.\r
574                                   FragmentCount is NULL.\r
575                                   CryptoMode is invalid.\r
576   @retval EFI_NOT_READY           Current TLS session state is NOT\r
577                                   EfiTlsSessionDataTransferring.\r
578   @retval EFI_ABORTED             Something wrong decryption the message. TLS session\r
579                                   status will become EfiTlsSessionError. The caller need\r
580                                   call BuildResponsePacket() to generate Error Alert\r
581                                   message and send it out.\r
582   @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.\r
583 **/\r
584 EFI_STATUS\r
585 EFIAPI\r
586 TlsProcessPacket (\r
587   IN     EFI_TLS_PROTOCOL              *This,\r
588   IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,\r
589   IN     UINT32                        *FragmentCount,\r
590   IN     EFI_TLS_CRYPT_MODE            CryptMode\r
591   )\r
592 {\r
593   EFI_STATUS                Status;\r
594   TLS_INSTANCE              *Instance;\r
595 \r
596   EFI_TPL                   OldTpl;\r
597 \r
598   Status = EFI_SUCCESS;\r
599 \r
600   if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {\r
601     return EFI_INVALID_PARAMETER;\r
602   }\r
603 \r
604   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
605 \r
606   Instance = TLS_INSTANCE_FROM_PROTOCOL (This);\r
607 \r
608   if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {\r
609     Status = EFI_NOT_READY;\r
610     goto ON_EXIT;\r
611   }\r
612 \r
613   //\r
614   // Packet sent or received may have multiple TLS record messages (Application data type).\r
615   // So,on input these fragments contain the TLS header and TLS APP payload;\r
616   // on output these fragments also contain the TLS header and TLS APP payload.\r
617   //\r
618   switch (CryptMode) {\r
619   case EfiTlsEncrypt:\r
620     Status = TlsEncryptPacket (Instance, FragmentTable, FragmentCount);\r
621     break;\r
622   case EfiTlsDecrypt:\r
623     Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);\r
624     break;\r
625   default:\r
626     return EFI_INVALID_PARAMETER;\r
627   }\r
628 \r
629 ON_EXIT:\r
630   gBS->RestoreTPL (OldTpl);\r
631   return Status;\r
632 }\r
633 \r