2 The Miscellaneous Routines for TlsDxe driver.
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Encrypt the message listed in fragment.
15 @param[in] TlsInstance The pointer to the TLS instance.
16 @param[in, out] FragmentTable Pointer to a list of fragment.
17 On input these fragments contain the TLS header and
18 plain text TLS payload;
19 On output these fragments contain the TLS header and
20 cipher text TLS payload.
21 @param[in] FragmentCount Number of fragment.
23 @retval EFI_SUCCESS The operation completed successfully.
24 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
25 @retval EFI_ABORTED TLS session state is incorrect.
26 @retval Others Other errors as indicated.
30 IN TLS_INSTANCE
*TlsInstance
,
31 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
32 IN UINT32
*FragmentCount
41 TLS_RECORD_HEADER
*RecordHeaderIn
;
42 UINT16 ThisPlainMessageSize
;
43 TLS_RECORD_HEADER
*TempRecordHeader
;
44 UINT16 ThisMessageSize
;
55 RecordHeaderIn
= NULL
;
56 TempRecordHeader
= NULL
;
63 // Calculate the size according to the fragment table.
65 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
66 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
70 // Allocate buffer for processing data.
72 BufferIn
= AllocateZeroPool (BufferInSize
);
73 if (BufferIn
== NULL
) {
74 Status
= EFI_OUT_OF_RESOURCES
;
79 // Copy all TLS plain record header and payload into BufferIn.
81 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
83 (BufferIn
+ BytesCopied
),
84 (*FragmentTable
)[Index
].FragmentBuffer
,
85 (*FragmentTable
)[Index
].FragmentLength
87 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
91 // Count TLS record number.
93 BufferInPtr
= BufferIn
;
94 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
95 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
96 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
|| RecordHeaderIn
->Length
> TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
) {
97 Status
= EFI_INVALID_PARAMETER
;
100 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ RecordHeaderIn
->Length
;
105 // Allocate enough buffer to hold TLS Ciphertext.
107 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
108 if (BufferOut
== NULL
) {
109 Status
= EFI_OUT_OF_RESOURCES
;
114 // Parsing buffer. Received packet may have multiple TLS record messages.
116 BufferInPtr
= BufferIn
;
117 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
118 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
119 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
121 ThisPlainMessageSize
= RecordHeaderIn
->Length
;
123 TlsWrite (TlsInstance
->TlsConn
, (UINT8
*) (RecordHeaderIn
+ 1), ThisPlainMessageSize
);
125 Ret
= TlsCtrlTrafficOut (TlsInstance
->TlsConn
, (UINT8
*)(TempRecordHeader
), TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
128 ThisMessageSize
= (UINT16
) Ret
;
131 // No data was successfully encrypted, continue to encrypt other messages.
133 DEBUG ((EFI_D_WARN
, "TlsEncryptPacket: No data read from TLS object.\n"));
138 BufferOutSize
+= ThisMessageSize
;
140 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
141 TempRecordHeader
= (TLS_RECORD_HEADER
*)((UINT8
*)TempRecordHeader
+ ThisMessageSize
);
148 // The caller will be responsible to handle the original fragment table.
150 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
151 if (*FragmentTable
== NULL
) {
152 Status
= EFI_OUT_OF_RESOURCES
;
156 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
157 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
164 if (BufferIn
!= NULL
) {
169 if (BufferOut
!= NULL
) {
170 FreePool (BufferOut
);
178 Decrypt the message listed in fragment.
180 @param[in] TlsInstance The pointer to the TLS instance.
181 @param[in, out] FragmentTable Pointer to a list of fragment.
182 On input these fragments contain the TLS header and
183 cipher text TLS payload;
184 On output these fragments contain the TLS header and
185 plain text TLS payload.
186 @param[in] FragmentCount Number of fragment.
188 @retval EFI_SUCCESS The operation completed successfully.
189 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
190 @retval EFI_ABORTED TLS session state is incorrect.
191 @retval Others Other errors as indicated.
195 IN TLS_INSTANCE
*TlsInstance
,
196 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
197 IN UINT32
*FragmentCount
206 TLS_RECORD_HEADER
*RecordHeaderIn
;
207 UINT16 ThisCipherMessageSize
;
208 TLS_RECORD_HEADER
*TempRecordHeader
;
209 UINT16 ThisPlainMessageSize
;
211 UINT32 BufferOutSize
;
215 Status
= EFI_SUCCESS
;
220 RecordHeaderIn
= NULL
;
221 TempRecordHeader
= NULL
;
228 // Calculate the size according to the fragment table.
230 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
231 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
235 // Allocate buffer for processing data
237 BufferIn
= AllocateZeroPool (BufferInSize
);
238 if (BufferIn
== NULL
) {
239 Status
= EFI_OUT_OF_RESOURCES
;
244 // Copy all TLS plain record header and payload to BufferIn
246 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
248 (BufferIn
+ BytesCopied
),
249 (*FragmentTable
)[Index
].FragmentBuffer
,
250 (*FragmentTable
)[Index
].FragmentLength
252 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
256 // Count TLS record number.
258 BufferInPtr
= BufferIn
;
259 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
260 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
261 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
|| NTOHS (RecordHeaderIn
->Length
) > TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
) {
262 Status
= EFI_INVALID_PARAMETER
;
265 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ NTOHS (RecordHeaderIn
->Length
);
270 // Allocate enough buffer to hold TLS Plaintext.
272 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
273 if (BufferOut
== NULL
) {
274 Status
= EFI_OUT_OF_RESOURCES
;
279 // Parsing buffer. Received packet may have multiple TLS record messages.
281 BufferInPtr
= BufferIn
;
282 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
283 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
284 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
286 ThisCipherMessageSize
= NTOHS (RecordHeaderIn
->Length
);
288 Ret
= TlsCtrlTrafficIn (TlsInstance
->TlsConn
, (UINT8
*) (RecordHeaderIn
), TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
);
289 if (Ret
!= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
) {
290 TlsInstance
->TlsSessionState
= EfiTlsSessionError
;
291 Status
= EFI_ABORTED
;
296 Ret
= TlsRead (TlsInstance
->TlsConn
, (UINT8
*) (TempRecordHeader
+ 1), TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
299 ThisPlainMessageSize
= (UINT16
) Ret
;
302 // No data was successfully decrypted, continue to decrypt other messages.
304 DEBUG ((EFI_D_WARN
, "TlsDecryptPacket: No data read from TLS object.\n"));
306 ThisPlainMessageSize
= 0;
309 CopyMem (TempRecordHeader
, RecordHeaderIn
, TLS_RECORD_HEADER_LENGTH
);
310 TempRecordHeader
->Length
= ThisPlainMessageSize
;
311 BufferOutSize
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
313 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
;
314 TempRecordHeader
= (TLS_RECORD_HEADER
*)((UINT8
*)TempRecordHeader
+ TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
);
321 // The caller will be responsible to handle the original fragment table
323 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
324 if (*FragmentTable
== NULL
) {
325 Status
= EFI_OUT_OF_RESOURCES
;
329 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
330 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
337 if (BufferIn
!= NULL
) {
342 if (BufferOut
!= NULL
) {
343 FreePool (BufferOut
);