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