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