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