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