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