]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TlsDxe/TlsProtocol.c
NetworkPkg: Convert files to CRLF line ending
[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
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
50EFI_STATUS\r
51EFIAPI\r
52TlsSetSessionData (\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
186ON_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
214EFI_STATUS\r
215EFIAPI\r
216TlsGetSessionData (\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
357ON_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
400EFI_STATUS\r
401EFIAPI\r
402TlsBuildResponsePacket (\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
545ON_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
584EFI_STATUS\r
585EFIAPI\r
586TlsProcessPacket (\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
629ON_EXIT:\r
630 gBS->RestoreTPL (OldTpl);\r
631 return Status;\r
632}\r
633\r