]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - NetworkPkg/TlsDxe/TlsImpl.c
BaseTools: Check PCD DataType and the maxsize.
[mirror_edk2.git] / NetworkPkg / TlsDxe / TlsImpl.c
... / ...
CommitLineData
1/** @file\r
2 The Miscellaneous Routines for TlsDxe driver.\r
3\r
4Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
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
53 INTN Ret;\r
54\r
55 Status = EFI_SUCCESS;\r
56 BytesCopied = 0;\r
57 BufferInSize = 0;\r
58 BufferIn = NULL;\r
59 BufferInPtr = NULL;\r
60 RecordHeaderIn = NULL;\r
61 TempRecordHeader = NULL;\r
62 BufferOutSize = 0;\r
63 BufferOut = NULL;\r
64 Ret = 0;\r
65\r
66 //\r
67 // Calculate the size according to the fragment table.\r
68 //\r
69 for (Index = 0; Index < *FragmentCount; Index++) {\r
70 BufferInSize += (*FragmentTable)[Index].FragmentLength;\r
71 }\r
72\r
73 //\r
74 // Allocate buffer for processing data.\r
75 //\r
76 BufferIn = AllocateZeroPool (BufferInSize);\r
77 if (BufferIn == NULL) {\r
78 Status = EFI_OUT_OF_RESOURCES;\r
79 goto ERROR;\r
80 }\r
81\r
82 //\r
83 // Copy all TLS plain record header and payload into BufferIn.\r
84 //\r
85 for (Index = 0; Index < *FragmentCount; Index++) {\r
86 CopyMem (\r
87 (BufferIn + BytesCopied),\r
88 (*FragmentTable)[Index].FragmentBuffer,\r
89 (*FragmentTable)[Index].FragmentLength\r
90 );\r
91 BytesCopied += (*FragmentTable)[Index].FragmentLength;\r
92 }\r
93\r
94 BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);\r
95 if (BufferOut == NULL) {\r
96 Status = EFI_OUT_OF_RESOURCES;\r
97 goto ERROR;\r
98 }\r
99\r
100 //\r
101 // Parsing buffer.\r
102 //\r
103 BufferInPtr = BufferIn;\r
104 TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;\r
105 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
106 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
107\r
108 if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) {\r
109 Status = EFI_INVALID_PARAMETER;\r
110 goto ERROR;\r
111 }\r
112\r
113 ThisPlainMessageSize = RecordHeaderIn->Length;\r
114\r
115 TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);\r
116\r
117 Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize);\r
118\r
119 if (Ret > 0) {\r
120 ThisMessageSize = (UINT16) Ret;\r
121 } else {\r
122 //\r
123 // No data was successfully encrypted, continue to encrypt other messages.\r
124 //\r
125 DEBUG ((EFI_D_WARN, "TlsEncryptPacket: No data read from TLS object.\n"));\r
126\r
127 ThisMessageSize = 0;\r
128 }\r
129\r
130 BufferOutSize += ThisMessageSize;\r
131\r
132 BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;\r
133 TempRecordHeader += ThisMessageSize;\r
134 }\r
135\r
136 FreePool (BufferIn);\r
137 BufferIn = NULL;\r
138\r
139 //\r
140 // The caller will be responsible to handle the original fragment table.\r
141 //\r
142 *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));\r
143 if (*FragmentTable == NULL) {\r
144 Status = EFI_OUT_OF_RESOURCES;\r
145 goto ERROR;\r
146 }\r
147\r
148 (*FragmentTable)[0].FragmentBuffer = BufferOut;\r
149 (*FragmentTable)[0].FragmentLength = BufferOutSize;\r
150 *FragmentCount = 1;\r
151\r
152 return Status;\r
153\r
154ERROR:\r
155\r
156 if (BufferIn != NULL) {\r
157 FreePool (BufferIn);\r
158 BufferIn = NULL;\r
159 }\r
160\r
161 if (BufferOut != NULL) {\r
162 FreePool (BufferOut);\r
163 BufferOut = NULL;\r
164 }\r
165\r
166 return Status;\r
167}\r
168\r
169/**\r
170 Decrypt the message listed in fragment.\r
171\r
172 @param[in] TlsInstance The pointer to the TLS instance.\r
173 @param[in, out] FragmentTable Pointer to a list of fragment.\r
174 On input these fragments contain the TLS header and\r
175 cipher text TLS payload;\r
176 On output these fragments contain the TLS header and\r
177 plain text TLS payload.\r
178 @param[in] FragmentCount Number of fragment.\r
179\r
180 @retval EFI_SUCCESS The operation completed successfully.\r
181 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
182 @retval EFI_ABORTED TLS session state is incorrect.\r
183 @retval Others Other errors as indicated.\r
184**/\r
185EFI_STATUS\r
186TlsDecryptPacket (\r
187 IN TLS_INSTANCE *TlsInstance,\r
188 IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,\r
189 IN UINT32 *FragmentCount\r
190 )\r
191{\r
192 EFI_STATUS Status;\r
193 UINTN Index;\r
194 UINT32 BytesCopied;\r
195 UINT8 *BufferIn;\r
196 UINT32 BufferInSize;\r
197 UINT8 *BufferInPtr;\r
198 TLS_RECORD_HEADER *RecordHeaderIn;\r
199 UINT16 ThisCipherMessageSize;\r
200 TLS_RECORD_HEADER *TempRecordHeader;\r
201 UINT16 ThisPlainMessageSize;\r
202 UINT8 *BufferOut;\r
203 UINT32 BufferOutSize;\r
204 INTN Ret;\r
205\r
206 Status = EFI_SUCCESS;\r
207 BytesCopied = 0;\r
208 BufferIn = NULL;\r
209 BufferInSize = 0;\r
210 BufferInPtr = NULL;\r
211 RecordHeaderIn = NULL;\r
212 TempRecordHeader = NULL;\r
213 BufferOut = NULL;\r
214 BufferOutSize = 0;\r
215 Ret = 0;\r
216\r
217 //\r
218 // Calculate the size according to the fragment table.\r
219 //\r
220 for (Index = 0; Index < *FragmentCount; Index++) {\r
221 BufferInSize += (*FragmentTable)[Index].FragmentLength;\r
222 }\r
223\r
224 //\r
225 // Allocate buffer for processing data\r
226 //\r
227 BufferIn = AllocateZeroPool (BufferInSize);\r
228 if (BufferIn == NULL) {\r
229 Status = EFI_OUT_OF_RESOURCES;\r
230 goto ERROR;\r
231 }\r
232\r
233 //\r
234 // Copy all TLS plain record header and payload to BufferIn\r
235 //\r
236 for (Index = 0; Index < *FragmentCount; Index++) {\r
237 CopyMem (\r
238 (BufferIn + BytesCopied),\r
239 (*FragmentTable)[Index].FragmentBuffer,\r
240 (*FragmentTable)[Index].FragmentLength\r
241 );\r
242 BytesCopied += (*FragmentTable)[Index].FragmentLength;\r
243 }\r
244\r
245 BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);\r
246 if (BufferOut == NULL) {\r
247 Status = EFI_OUT_OF_RESOURCES;\r
248 goto ERROR;\r
249 }\r
250\r
251 //\r
252 // Parsing buffer. Received packet may have multiple TLS record messages.\r
253 //\r
254 BufferInPtr = BufferIn;\r
255 TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;\r
256 while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {\r
257 RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;\r
258\r
259 if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) {\r
260 Status = EFI_INVALID_PARAMETER;\r
261 goto ERROR;\r
262 }\r
263\r
264 ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);\r
265\r
266 Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);\r
267 if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {\r
268 TlsInstance->TlsSessionState = EfiTlsSessionError;\r
269 Status = EFI_ABORTED;\r
270 goto ERROR;\r
271 }\r
272\r
273 Ret = 0;\r
274 Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize);\r
275\r
276 if (Ret > 0) {\r
277 ThisPlainMessageSize = (UINT16) Ret;\r
278 } else {\r
279 //\r
280 // No data was successfully decrypted, continue to decrypt other messages.\r
281 //\r
282 DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));\r
283\r
284 ThisPlainMessageSize = 0;\r
285 }\r
286\r
287 CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);\r
288 TempRecordHeader->Length = ThisPlainMessageSize;\r
289 BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;\r
290\r
291 BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;\r
292 TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;\r
293 }\r
294\r
295 FreePool (BufferIn);\r
296 BufferIn = NULL;\r
297\r
298 //\r
299 // The caller will be responsible to handle the original fragment table\r
300 //\r
301 *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));\r
302 if (*FragmentTable == NULL) {\r
303 Status = EFI_OUT_OF_RESOURCES;\r
304 goto ERROR;\r
305 }\r
306\r
307 (*FragmentTable)[0].FragmentBuffer = BufferOut;\r
308 (*FragmentTable)[0].FragmentLength = BufferOutSize;\r
309 *FragmentCount = 1;\r
310\r
311 return Status;\r
312\r
313ERROR:\r
314\r
315 if (BufferIn != NULL) {\r
316 FreePool (BufferIn);\r
317 BufferIn = NULL;\r
318 }\r
319\r
320 if (BufferOut != NULL) {\r
321 FreePool (BufferOut);\r
322 BufferOut = NULL;\r
323 }\r
324\r
325 return Status;\r
326}\r
327\r