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
;
101 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ RecordHeaderIn
->Length
;
106 // Allocate enough buffer to hold TLS Ciphertext.
108 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
109 if (BufferOut
== NULL
) {
110 Status
= EFI_OUT_OF_RESOURCES
;
115 // Parsing buffer. Received packet may have multiple TLS record messages.
117 BufferInPtr
= BufferIn
;
118 TempRecordHeader
= (TLS_RECORD_HEADER
*)BufferOut
;
119 while ((UINTN
)BufferInPtr
< (UINTN
)BufferIn
+ BufferInSize
) {
120 RecordHeaderIn
= (TLS_RECORD_HEADER
*)BufferInPtr
;
122 ThisPlainMessageSize
= RecordHeaderIn
->Length
;
124 TlsWrite (TlsInstance
->TlsConn
, (UINT8
*)(RecordHeaderIn
+ 1), ThisPlainMessageSize
);
126 Ret
= TlsCtrlTrafficOut (TlsInstance
->TlsConn
, (UINT8
*)(TempRecordHeader
), TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
129 ThisMessageSize
= (UINT16
)Ret
;
132 // No data was successfully encrypted, continue to encrypt other messages.
134 DEBUG ((DEBUG_WARN
, "TlsEncryptPacket: No data read from TLS object.\n"));
139 BufferOutSize
+= ThisMessageSize
;
141 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
142 TempRecordHeader
= (TLS_RECORD_HEADER
*)((UINT8
*)TempRecordHeader
+ ThisMessageSize
);
149 // The caller will be responsible to handle the original fragment table.
151 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
152 if (*FragmentTable
== NULL
) {
153 Status
= EFI_OUT_OF_RESOURCES
;
157 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
158 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
165 if (BufferIn
!= NULL
) {
170 if (BufferOut
!= NULL
) {
171 FreePool (BufferOut
);
179 Decrypt the message listed in fragment.
181 @param[in] TlsInstance The pointer to the TLS instance.
182 @param[in, out] FragmentTable Pointer to a list of fragment.
183 On input these fragments contain the TLS header and
184 cipher text TLS payload;
185 On output these fragments contain the TLS header and
186 plain text TLS payload.
187 @param[in] FragmentCount Number of fragment.
189 @retval EFI_SUCCESS The operation completed successfully.
190 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
191 @retval EFI_ABORTED TLS session state is incorrect.
192 @retval Others Other errors as indicated.
196 IN TLS_INSTANCE
*TlsInstance
,
197 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
198 IN UINT32
*FragmentCount
207 TLS_RECORD_HEADER
*RecordHeaderIn
;
208 UINT16 ThisCipherMessageSize
;
209 TLS_RECORD_HEADER
*TempRecordHeader
;
210 UINT16 ThisPlainMessageSize
;
212 UINT32 BufferOutSize
;
216 Status
= EFI_SUCCESS
;
221 RecordHeaderIn
= NULL
;
222 TempRecordHeader
= NULL
;
229 // Calculate the size according to the fragment table.
231 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
232 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
236 // Allocate buffer for processing data
238 BufferIn
= AllocateZeroPool (BufferInSize
);
239 if (BufferIn
== NULL
) {
240 Status
= EFI_OUT_OF_RESOURCES
;
245 // Copy all TLS plain record header and payload to BufferIn
247 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
249 (BufferIn
+ BytesCopied
),
250 (*FragmentTable
)[Index
].FragmentBuffer
,
251 (*FragmentTable
)[Index
].FragmentLength
253 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
257 // Count TLS record number.
259 BufferInPtr
= BufferIn
;
260 while ((UINTN
)BufferInPtr
< (UINTN
)BufferIn
+ BufferInSize
) {
261 RecordHeaderIn
= (TLS_RECORD_HEADER
*)BufferInPtr
;
262 if ((RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
) || (NTOHS (RecordHeaderIn
->Length
) > TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
)) {
263 Status
= EFI_INVALID_PARAMETER
;
267 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ NTOHS (RecordHeaderIn
->Length
);
272 // Allocate enough buffer to hold TLS Plaintext.
274 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
275 if (BufferOut
== NULL
) {
276 Status
= EFI_OUT_OF_RESOURCES
;
281 // Parsing buffer. Received packet may have multiple TLS record messages.
283 BufferInPtr
= BufferIn
;
284 TempRecordHeader
= (TLS_RECORD_HEADER
*)BufferOut
;
285 while ((UINTN
)BufferInPtr
< (UINTN
)BufferIn
+ BufferInSize
) {
286 RecordHeaderIn
= (TLS_RECORD_HEADER
*)BufferInPtr
;
288 ThisCipherMessageSize
= NTOHS (RecordHeaderIn
->Length
);
290 Ret
= TlsCtrlTrafficIn (TlsInstance
->TlsConn
, (UINT8
*)(RecordHeaderIn
), TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
);
291 if (Ret
!= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
) {
292 TlsInstance
->TlsSessionState
= EfiTlsSessionError
;
293 Status
= EFI_ABORTED
;
298 Ret
= TlsRead (TlsInstance
->TlsConn
, (UINT8
*)(TempRecordHeader
+ 1), TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
301 ThisPlainMessageSize
= (UINT16
)Ret
;
304 // No data was successfully decrypted, continue to decrypt other messages.
306 DEBUG ((DEBUG_WARN
, "TlsDecryptPacket: No data read from TLS object.\n"));
308 ThisPlainMessageSize
= 0;
311 CopyMem (TempRecordHeader
, RecordHeaderIn
, TLS_RECORD_HEADER_LENGTH
);
312 TempRecordHeader
->Length
= ThisPlainMessageSize
;
313 BufferOutSize
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
315 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
;
316 TempRecordHeader
= (TLS_RECORD_HEADER
*)((UINT8
*)TempRecordHeader
+ TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
);
323 // The caller will be responsible to handle the original fragment table
325 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
326 if (*FragmentTable
== NULL
) {
327 Status
= EFI_OUT_OF_RESOURCES
;
331 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
332 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
339 if (BufferIn
!= NULL
) {
344 if (BufferOut
!= NULL
) {
345 FreePool (BufferOut
);