]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TlsDxe/TlsImpl.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / TlsDxe / TlsImpl.c
CommitLineData
7618784b
HW
1/** @file\r
2 The Miscellaneous Routines for TlsDxe driver.\r
3\r
cb3350ec 4Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
7618784b
HW
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT 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/**\r
19 Encrypt the message listed in fragment.\r
20\r
21 @param[in] TlsInstance The pointer to the TLS instance.\r
22 @param[in, out] FragmentTable Pointer to a list of fragment.\r
23 On input these fragments contain the TLS header and\r
24 plain text TLS payload;\r
25 On output these fragments contain the TLS header and\r
26 cipher text TLS payload.\r
27 @param[in] FragmentCount Number of fragment.\r
28\r
29 @retval EFI_SUCCESS The operation completed successfully.\r
30 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
31 @retval EFI_ABORTED TLS session state is incorrect.\r
32 @retval Others Other errors as indicated.\r
33**/\r
34EFI_STATUS\r
35TlsEncryptPacket (\r
36 IN TLS_INSTANCE *TlsInstance,\r
37 IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,\r
38 IN UINT32 *FragmentCount\r
39 )\r
40{\r
41 EFI_STATUS Status;\r
42 UINTN Index;\r
43 UINT32 BytesCopied;\r
44 UINT32 BufferInSize;\r
45 UINT8 *BufferIn;\r
46 UINT8 *BufferInPtr;\r
47 TLS_RECORD_HEADER *RecordHeaderIn;\r
48 UINT16 ThisPlainMessageSize;\r
49 TLS_RECORD_HEADER *TempRecordHeader;\r
50 UINT16 ThisMessageSize;\r
51 UINT32 BufferOutSize;\r
52 UINT8 *BufferOut;\r
cb3350ec 53 UINT32 RecordCount;\r
7618784b
HW
54 INTN Ret;\r
55\r
56 Status = EFI_SUCCESS;\r
57 BytesCopied = 0;\r
58 BufferInSize = 0;\r
59 BufferIn = NULL;\r
60 BufferInPtr = NULL;\r
61 RecordHeaderIn = NULL;\r
62 TempRecordHeader = NULL;\r
63 BufferOutSize = 0;\r
64 BufferOut = NULL;\r
cb3350ec 65 RecordCount = 0;\r
7618784b
HW
66 Ret = 0;\r
67\r
68 //\r
69 // Calculate the size according to the fragment table.\r
70 //\r
71 for (Index = 0; Index < *FragmentCount; Index++) {\r
72 BufferInSize += (*FragmentTable)[Index].FragmentLength;\r
73 }\r
74\r
75 //\r
76 // Allocate buffer for processing data.\r
77 //\r
78 BufferIn = AllocateZeroPool (BufferInSize);\r
79 if (BufferIn == NULL) {\r
80 Status = EFI_OUT_OF_RESOURCES;\r
81 goto ERROR;\r
82 }\r
83\r
84 //\r
85 // Copy all TLS plain record header and payload into BufferIn.\r
86 //\r
87 for (Index = 0; Index < *FragmentCount; Index++) {\r
88 CopyMem (\r
89 (BufferIn + BytesCopied),\r
90 (*FragmentTable)[Index].FragmentBuffer,\r
91 (*FragmentTable)[Index].FragmentLength\r
92 );\r
93 BytesCopied += (*FragmentTable)[Index].FragmentLength;\r
94 }\r
95\r
cb3350ec
JW
96 //\r
97 // Count TLS record number.\r
98 //\r
99 BufferInPtr = BufferIn;\r
100 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
101 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
102 if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData || RecordHeaderIn->Length > TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH) {\r
103 Status = EFI_INVALID_PARAMETER;\r
104 goto ERROR;\r
105 }\r
106 BufferInPtr += TLS_RECORD_HEADER_LENGTH + RecordHeaderIn->Length;\r
107 RecordCount ++;\r
108 }\r
f75a7f56 109\r
cb3350ec
JW
110 //\r
111 // Allocate enough buffer to hold TLS Ciphertext.\r
112 //\r
113 BufferOut = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));\r
7618784b
HW
114 if (BufferOut == NULL) {\r
115 Status = EFI_OUT_OF_RESOURCES;\r
116 goto ERROR;\r
117 }\r
118\r
119 //\r
cb3350ec 120 // Parsing buffer. Received packet may have multiple TLS record messages.\r
7618784b
HW
121 //\r
122 BufferInPtr = BufferIn;\r
123 TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;\r
124 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
125 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
126\r
7618784b
HW
127 ThisPlainMessageSize = RecordHeaderIn->Length;\r
128\r
129 TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);\r
130\r
cb3350ec 131 Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
7618784b
HW
132\r
133 if (Ret > 0) {\r
134 ThisMessageSize = (UINT16) Ret;\r
135 } else {\r
136 //\r
137 // No data was successfully encrypted, continue to encrypt other messages.\r
138 //\r
139 DEBUG ((EFI_D_WARN, "TlsEncryptPacket: No data read from TLS object.\n"));\r
140\r
141 ThisMessageSize = 0;\r
142 }\r
143\r
144 BufferOutSize += ThisMessageSize;\r
145\r
cb3350ec 146 BufferInPtr += TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize;\r
7618784b
HW
147 TempRecordHeader += ThisMessageSize;\r
148 }\r
149\r
150 FreePool (BufferIn);\r
151 BufferIn = NULL;\r
152\r
153 //\r
154 // The caller will be responsible to handle the original fragment table.\r
155 //\r
156 *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));\r
157 if (*FragmentTable == NULL) {\r
158 Status = EFI_OUT_OF_RESOURCES;\r
159 goto ERROR;\r
160 }\r
161\r
162 (*FragmentTable)[0].FragmentBuffer = BufferOut;\r
163 (*FragmentTable)[0].FragmentLength = BufferOutSize;\r
164 *FragmentCount = 1;\r
165\r
166 return Status;\r
167\r
168ERROR:\r
169\r
170 if (BufferIn != NULL) {\r
171 FreePool (BufferIn);\r
172 BufferIn = NULL;\r
173 }\r
174\r
175 if (BufferOut != NULL) {\r
176 FreePool (BufferOut);\r
177 BufferOut = NULL;\r
178 }\r
179\r
180 return Status;\r
181}\r
182\r
183/**\r
184 Decrypt the message listed in fragment.\r
185\r
186 @param[in] TlsInstance The pointer to the TLS instance.\r
187 @param[in, out] FragmentTable Pointer to a list of fragment.\r
188 On input these fragments contain the TLS header and\r
189 cipher text TLS payload;\r
190 On output these fragments contain the TLS header and\r
191 plain text TLS payload.\r
192 @param[in] FragmentCount Number of fragment.\r
193\r
194 @retval EFI_SUCCESS The operation completed successfully.\r
195 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
196 @retval EFI_ABORTED TLS session state is incorrect.\r
197 @retval Others Other errors as indicated.\r
198**/\r
199EFI_STATUS\r
200TlsDecryptPacket (\r
201 IN TLS_INSTANCE *TlsInstance,\r
202 IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,\r
203 IN UINT32 *FragmentCount\r
204 )\r
205{\r
206 EFI_STATUS Status;\r
207 UINTN Index;\r
208 UINT32 BytesCopied;\r
209 UINT8 *BufferIn;\r
210 UINT32 BufferInSize;\r
211 UINT8 *BufferInPtr;\r
212 TLS_RECORD_HEADER *RecordHeaderIn;\r
213 UINT16 ThisCipherMessageSize;\r
214 TLS_RECORD_HEADER *TempRecordHeader;\r
215 UINT16 ThisPlainMessageSize;\r
216 UINT8 *BufferOut;\r
217 UINT32 BufferOutSize;\r
cb3350ec 218 UINT32 RecordCount;\r
7618784b
HW
219 INTN Ret;\r
220\r
221 Status = EFI_SUCCESS;\r
222 BytesCopied = 0;\r
223 BufferIn = NULL;\r
224 BufferInSize = 0;\r
225 BufferInPtr = NULL;\r
226 RecordHeaderIn = NULL;\r
227 TempRecordHeader = NULL;\r
228 BufferOut = NULL;\r
229 BufferOutSize = 0;\r
cb3350ec 230 RecordCount = 0;\r
7618784b
HW
231 Ret = 0;\r
232\r
233 //\r
234 // Calculate the size according to the fragment table.\r
235 //\r
236 for (Index = 0; Index < *FragmentCount; Index++) {\r
237 BufferInSize += (*FragmentTable)[Index].FragmentLength;\r
238 }\r
239\r
240 //\r
241 // Allocate buffer for processing data\r
242 //\r
243 BufferIn = AllocateZeroPool (BufferInSize);\r
244 if (BufferIn == NULL) {\r
245 Status = EFI_OUT_OF_RESOURCES;\r
246 goto ERROR;\r
247 }\r
248\r
249 //\r
250 // Copy all TLS plain record header and payload to BufferIn\r
251 //\r
252 for (Index = 0; Index < *FragmentCount; Index++) {\r
253 CopyMem (\r
254 (BufferIn + BytesCopied),\r
255 (*FragmentTable)[Index].FragmentBuffer,\r
256 (*FragmentTable)[Index].FragmentLength\r
257 );\r
258 BytesCopied += (*FragmentTable)[Index].FragmentLength;\r
259 }\r
260\r
cb3350ec
JW
261 //\r
262 // Count TLS record number.\r
263 //\r
264 BufferInPtr = BufferIn;\r
265 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
266 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
267 if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData || NTOHS (RecordHeaderIn->Length) > TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH) {\r
268 Status = EFI_INVALID_PARAMETER;\r
269 goto ERROR;\r
270 }\r
271 BufferInPtr += TLS_RECORD_HEADER_LENGTH + NTOHS (RecordHeaderIn->Length);\r
272 RecordCount ++;\r
273 }\r
274\r
275 //\r
276 // Allocate enough buffer to hold TLS Plaintext.\r
277 //\r
278 BufferOut = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH));\r
7618784b
HW
279 if (BufferOut == NULL) {\r
280 Status = EFI_OUT_OF_RESOURCES;\r
281 goto ERROR;\r
282 }\r
283\r
284 //\r
285 // Parsing buffer. Received packet may have multiple TLS record messages.\r
286 //\r
287 BufferInPtr = BufferIn;\r
288 TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;\r
289 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
290 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
291\r
7618784b
HW
292 ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);\r
293\r
cb3350ec
JW
294 Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize);\r
295 if (Ret != TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize) {\r
7618784b
HW
296 TlsInstance->TlsSessionState = EfiTlsSessionError;\r
297 Status = EFI_ABORTED;\r
298 goto ERROR;\r
299 }\r
300\r
301 Ret = 0;\r
cb3350ec 302 Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
7618784b
HW
303\r
304 if (Ret > 0) {\r
305 ThisPlainMessageSize = (UINT16) Ret;\r
306 } else {\r
307 //\r
308 // No data was successfully decrypted, continue to decrypt other messages.\r
309 //\r
310 DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));\r
311\r
312 ThisPlainMessageSize = 0;\r
313 }\r
314\r
cb3350ec 315 CopyMem (TempRecordHeader, RecordHeaderIn, TLS_RECORD_HEADER_LENGTH);\r
7618784b 316 TempRecordHeader->Length = ThisPlainMessageSize;\r
cb3350ec 317 BufferOutSize += TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize;\r
7618784b 318\r
cb3350ec
JW
319 BufferInPtr += TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize;\r
320 TempRecordHeader += TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize;\r
7618784b
HW
321 }\r
322\r
323 FreePool (BufferIn);\r
324 BufferIn = NULL;\r
325\r
326 //\r
327 // The caller will be responsible to handle the original fragment table\r
328 //\r
329 *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));\r
330 if (*FragmentTable == NULL) {\r
331 Status = EFI_OUT_OF_RESOURCES;\r
332 goto ERROR;\r
333 }\r
334\r
335 (*FragmentTable)[0].FragmentBuffer = BufferOut;\r
336 (*FragmentTable)[0].FragmentLength = BufferOutSize;\r
337 *FragmentCount = 1;\r
338\r
339 return Status;\r
340\r
341ERROR:\r
342\r
343 if (BufferIn != NULL) {\r
344 FreePool (BufferIn);\r
345 BufferIn = NULL;\r
346 }\r
347\r
348 if (BufferOut != NULL) {\r
349 FreePool (BufferOut);\r
350 BufferOut = NULL;\r
351 }\r
352\r
353 return Status;\r
354}\r
355\r